CaiWuXiTong/modules/EcommerceFinance/JdBillPlatform.php
qiuxiang a0c99c3e8d 新增店铺收款京喜账单页签并从京东账单切分
在京东账单右侧新增京喜账单页签,复用京东日账单的取数、列定义、筛选、排序、分页与导出,只增加平台维度过滤:京东账单排除京喜店铺,京喜账单只取京喜店铺。平台口径集中在 config/jd_bill_platform.php 与 JdBillPlatform(含口径切换起始日期参数,默认全量历史),仓库通过 forPlatform() 收窄,两个口径互补、总额守恒,底层镜像数据不修改不删除。真实镜像实测:京喜 488,464 笔 + 京东 210,983 笔 = 拆分前 699,447 笔,收入/支出/差额逐项误差为 0。
2026-09-28 19:25:53 +08:00

85 lines
3.1 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.

<?php
namespace Modules\EcommerceFinance;
/**
* 京东账单的平台口径(单一数据源)。
*
* 京东日账单导出里没有平台字段:单据类型(订单/取消退款单/售后服务单/非销售单)两边都有,
* 费用项与账户代码、京东门店编码、品牌门店编号、门店名称均为空,账单项目只有「直营服务费」
* 单独属于京喜。全量 699,447 笔实测里只有店铺维度能可靠区分:
* 京喜 213 个店铺(488,464 笔)与京东 46 个店铺(210,983 笔)互不重叠,店铺号也不跨两边。
*
* 因此「京东账单」与「京喜账单」共用同一份取数逻辑,只用店铺名关键字拆数据:
* - 京东账单 = 排除京喜店铺
* - 京喜账单 = 只取京喜店铺
* 两个口径落点互补,笔数与金额之和恒等于拆分前,且不修改任何底层数据。
*/
final class JdBillPlatform
{
/** 店铺收款账户账单 › 京东账单。 */
public const BILL_TYPE_JD = 'jd-transactions';
/** 店铺收款账户账单 › 京喜账单。 */
public const BILL_TYPE_JINGXI = 'jingxi';
/** 口径配置(关键字、起始日期)统一在 config/jd_bill_platform.php,这里只读不定义。 */
private const CONFIG_KEY = 'jd_bill_platform';
/** @return list<string> 与京东日账单共用取数与渲染逻辑的页签。 */
public static function tabs(): array
{
return [self::BILL_TYPE_JD, self::BILL_TYPE_JINGXI];
}
public static function isJdBillTab(string $billType): bool
{
return in_array($billType, self::tabs(), true);
}
/** 页签对应的平台口径:'jingxi'、'jd',非京东系列页签返回 null。 */
public static function platformForBillType(string $billType): ?string
{
return match ($billType) {
self::BILL_TYPE_JINGXI => 'jingxi',
self::BILL_TYPE_JD => 'jd',
default => null,
};
}
/** 京喜店铺名关键字。 */
public static function storeNameKeyword(): string
{
$keyword = trim((string) config(self::CONFIG_KEY . '.jingxi_store_name_keyword', '京喜'));
return $keyword === '' ? '京喜' : $keyword;
}
/** 口径切换起始日期;null = 全量历史。 */
public static function scopeStartDate(): ?string
{
$start = config(self::CONFIG_KEY . '.scope_start_date');
return is_string($start) && preg_match('/^\d{4}-\d{2}-\d{2}$/', $start) === 1 ? $start : null;
}
/**
* 店铺维度的过滤条件。
*
* @param 'jingxi'|'jd'|null $platform
* @return array{mode:string,keyword:string,start_date:?string}|null mode: only=只取该平台,exclude=排除该平台
*/
public static function storeNameScope(?string $platform): ?array
{
if (! in_array($platform, ['jingxi', 'jd'], true)) {
return null;
}
return [
'mode' => $platform === 'jingxi' ? 'only' : 'exclude',
'keyword' => self::storeNameKeyword(),
'start_date' => self::scopeStartDate(),
];
}
}