账单明细:财务备注/财务类型筛选按平台限定,修同项目跨平台串行(优惠收入带出冲减收入)
This commit is contained in:
parent
a0faaa116b
commit
cfdda94da8
@ -737,22 +737,10 @@ class BillingDetailsPageData
|
||||
$conditions[] = '(' . implode(' OR ', $haystack) . ')';
|
||||
}
|
||||
if ($filters['type'] !== []) {
|
||||
$allowed = $this->itemsForTypes($filters['type']);
|
||||
if ($allowed === []) {
|
||||
$conditions[] = '1 = 0';
|
||||
} else {
|
||||
// 与页面带出财务备注/类型时一致:wx 前缀的账单项目按去前缀后的名称归类。
|
||||
// 项目名以字面量内联:MySQL 对字面量 IN 列表会排序后二分查找,
|
||||
// 参数化 IN 会逐行线性比对,161 个项目 × 130 万行会退化到 30 秒以上。
|
||||
$conditions[] = $this->normalizedItemSql() . ' IN (' . $this->literals($allowed) . ')';
|
||||
}
|
||||
$conditions[] = $this->platformItemCondition('category', $filters['type'], $label);
|
||||
}
|
||||
if (($filters['remark'] ?? []) !== []) {
|
||||
// 财务备注筛选:与财务类型同一口径,先落回「账单项目」集合再下推 SQL。
|
||||
$allowed = $this->itemsForRemarks($filters['remark']);
|
||||
$conditions[] = $allowed === []
|
||||
? '1 = 0'
|
||||
: $this->normalizedItemSql() . ' IN (' . $this->literals($allowed) . ')';
|
||||
$conditions[] = $this->platformItemCondition('memo', $filters['remark'], $label);
|
||||
}
|
||||
|
||||
$dateBind = $dateCol === 'bill_date'
|
||||
@ -902,6 +890,57 @@ class BillingDetailsPageData
|
||||
return "(CASE WHEN bill_item LIKE 'wx%' THEN LTRIM(SUBSTRING(bill_item, 3)) ELSE bill_item END)";
|
||||
}
|
||||
|
||||
/**
|
||||
* 「财务类型 / 财务备注」→ 按平台限定的 SQL 条件。
|
||||
*
|
||||
* 同一账单项目在不同平台可能挂不同的财务备注/类型,只按项目名过滤会把其它平台的同名项目一起带出来,
|
||||
* 所以这里再按店铺前缀限定平台;项目名仍以字面量内联,避免参数化 IN 在千万行上退化成线性比对。
|
||||
*
|
||||
* @param string $field category(财务类型)或 memo(财务备注)
|
||||
* @param list<string> $values
|
||||
*/
|
||||
private function platformItemCondition(string $field, array $values, string $branchLabel): string
|
||||
{
|
||||
$wanted = array_flip($values);
|
||||
$byPlatform = [];
|
||||
foreach ($this->rules() as $key => $rule) {
|
||||
$value = (string) ($rule[$field] ?? '');
|
||||
if ($value === '' || ! isset($wanted[$value])) {
|
||||
continue;
|
||||
}
|
||||
[$platform, $item] = array_pad(explode('|', $key, 2), 2, '');
|
||||
if ($platform === '' || $item === '') {
|
||||
continue;
|
||||
}
|
||||
$byPlatform[$platform][$item] = true;
|
||||
}
|
||||
|
||||
$branchPlatforms = self::BRANCH_PLATFORMS[$branchLabel] ?? [];
|
||||
$parts = [];
|
||||
foreach ($byPlatform as $platform => $items) {
|
||||
if ($branchPlatforms !== [] && ! in_array($platform, $branchPlatforms, true)) {
|
||||
continue;
|
||||
}
|
||||
$parts[] = '(' . $this->storePrefixCondition($platform) . ' AND '
|
||||
. $this->normalizedItemSql() . ' IN (' . $this->literals(array_keys($items)) . '))';
|
||||
}
|
||||
|
||||
return $parts === [] ? '1 = 0' : '(' . implode(' OR ', $parts) . ')';
|
||||
}
|
||||
|
||||
/** 科目映射表平台 → 对应的店铺名前缀条件(阿里巴巴含新佰广1688 / 淘工厂等)。 */
|
||||
private function storePrefixCondition(string $platform): string
|
||||
{
|
||||
$parts = [];
|
||||
foreach (self::PLATFORM_PREFIX as $prefix => $mapped) {
|
||||
if ($mapped === $platform) {
|
||||
$parts[] = 'store_name LIKE ' . $this->likeLiteral($prefix);
|
||||
}
|
||||
}
|
||||
|
||||
return $parts === [] ? '1 = 1' : '(' . implode(' OR ', $parts) . ')';
|
||||
}
|
||||
|
||||
/**
|
||||
* 取与查询区间有交集的账期的 active_generation(与 JD / 抖音账单页仓储同一口径)。
|
||||
*
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user