总账备注匹配:账单项目自动去 wx 前缀再查一次

先原样匹配,不中则去掉开头 wx 前缀(wx基础软件服务费 → 基础软件服务费)再匹配;原样命中优先,不影响既有结果。
科目映射表优先级链路与回落原总账备注链路都按此顺序匹配。
This commit is contained in:
qiuxiang 2026-10-07 15:58:42 +08:00
parent 0933941533
commit ae694004cf

View File

@ -285,8 +285,11 @@ class AccountLedgerRemarkMap
if ($platform === null || $platform === '') {
continue;
}
if (isset($map[$platform][$item])) {
return $map[$platform][$item];
// 先按原样匹配,再按「去掉 wx 前缀」的账单项目匹配(淘系部分行带 wx 前缀)
foreach ($this->itemLookupKeys($item) as $candidate) {
if (isset($map[$platform][$candidate])) {
return $map[$platform][$candidate];
}
}
}
@ -324,27 +327,62 @@ class AccountLedgerRemarkMap
/** 同平台同账单项目的「财务备注」;没有规则或财务备注为空时返回 null(由调用方回落)。 */
private function accountMappingRemark(string $platform, string $item, array $businessRemarks, string $goodsName): ?string
{
$rules = $this->accountMappingIndex()[$this->normalizeKey($platform)][$this->normalizeKey($item)] ?? [];
if ($rules === []) {
return null;
$index = $this->accountMappingIndex();
$platformKey = $this->normalizeKey($platform);
// 先按原样匹配,再按「去掉 wx 前缀」的账单项目匹配(科目映射表里部分项目不带 wx 前缀)
foreach ($this->itemLookupKeys($item) as $candidate) {
$rules = $index[$platformKey][$this->normalizeKey($candidate)] ?? [];
if ($rules === []) {
continue;
}
if (count($rules) === 1) {
$remark = trim((string) ($rules[0]['memo'] ?? ''));
if ($remark !== '') {
return $remark;
}
continue;
}
// 同一账单项目有多条规则时,用映射表自己的匹配器(按商品名称/业务备注关键词取最具体的)
try {
$result = app(AccountMappingMatcher::class)->match($platform, $candidate, $businessRemarks, $goodsName);
} catch (Throwable) {
$result = null;
}
$remark = trim((string) ($result['rule']['memo'] ?? ''));
if ($remark !== '') {
return $remark;
}
}
if (count($rules) === 1) {
$remark = trim((string) ($rules[0]['memo'] ?? ''));
return null;
}
return $remark === '' ? null : $remark;
/**
* 账单项目的查找候选:原样优先,其次去掉 wx 前缀。
*
* 淘系同一笔费用在不同页签/导出里会出现带 wx 前缀(wx基础软件服务费)与不带前缀(基础软件服务费)两种写法,
* 按口径应当是同一个总账备注;去掉前缀后再查一次即可命中同一批规则。
*
* @return list<string>
*/
private function itemLookupKeys(string $item): array
{
$item = trim($item);
$keys = [$item];
if ($item !== '' && stripos($item, 'wx') === 0) {
$withoutPrefix = ltrim(mb_substr($item, 2));
if ($withoutPrefix !== '') {
$keys[] = $withoutPrefix;
}
}
// 同一账单项目有多条规则时,用映射表自己的匹配器(按商品名称/业务备注关键词取最具体的)
try {
$result = app(AccountMappingMatcher::class)->match($platform, $item, $businessRemarks, $goodsName);
} catch (Throwable) {
return null;
}
$remark = trim((string) ($result['rule']['memo'] ?? ''));
return $remark === '' ? null : $remark;
return array_values(array_unique($keys));
}
private function normalizeKey(string $value): string