From 173ca7c2ec36149205a93cf7a84b0ca4bc2a50c7 Mon Sep 17 00:00:00 2001 From: yueyang <2495544247@qq.com> Date: Thu, 15 Oct 2026 17:50:55 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=9A=E7=BB=A9=E6=98=8E=E7=BB=86=EF=BC=9A?= =?UTF-8?q?=E5=B7=AE=E9=A2=9D=E5=88=A4=E5=AE=9A=E6=94=B9=E4=B8=BA=E3=80=8C?= =?UTF-8?q?=E5=8E=9F=E5=9B=A0=E4=BC=98=E5=85=88=20=E2=86=92=20=E5=AE=9E?= =?UTF-8?q?=E6=94=B6/=E5=BA=94=E4=BB=98=E5=8F=A3=E5=BE=84=E5=85=9C?= =?UTF-8?q?=E5=BA=95=20=E2=86=92=20=E5=BE=85=E6=A0=B8=E5=AE=9E=E3=80=8D?= =?UTF-8?q?=EF=BC=9B=E5=8F=A3=E5=BE=84=E5=91=BD=E4=B8=AD=E4=B8=8D=E5=86=8D?= =?UTF-8?q?=E6=8A=B9=E5=B7=AE=E9=A2=9D=E3=80=81=E9=A1=B5=E9=9D=A2=E4=B8=8E?= =?UTF-8?q?=E5=90=88=E8=AE=A1/=E7=AD=9B=E9=80=89/=E8=81=94=E5=8A=A8?= =?UTF-8?q?=E5=90=8C=E4=B8=80=E5=A5=97=E5=88=A4=E5=AE=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Commands/SyncStoreReceiptOrderMatches.php | 10 ++--- app/Http/Controllers/Business/Pages.php | 37 +++++++++++++++++-- 2 files changed, 38 insertions(+), 9 deletions(-) diff --git a/app/Console/Commands/SyncStoreReceiptOrderMatches.php b/app/Console/Commands/SyncStoreReceiptOrderMatches.php index a8648cfe..fc8855bd 100644 --- a/app/Console/Commands/SyncStoreReceiptOrderMatches.php +++ b/app/Console/Commands/SyncStoreReceiptOrderMatches.php @@ -745,6 +745,9 @@ class SyncStoreReceiptOrderMatches extends Command // 差额归零、订单实付列显示实收金额。用于京东这类「账单收款=卖家实收」的平台, // 避免把口径差当成对不上的差额。 if ($basis === 'paid' && $difference !== null && abs($difference) > 0.005) { + // 原因优先:这里只登记「口径能对上」的标识,不动差额(差额与原因由页面按 + // 「先备注规则、后口径兜底」的顺序判定),避免把有明确原因的行悄悄抹平。 + { [$altStatus, $altAmount] = $this->matchOrderSide( $core, (string) $group['shop_key'], @@ -777,16 +780,11 @@ class SyncStoreReceiptOrderMatches extends Command if ($altMatched && $altValue > 0.005 && abs($income + $promoAmount - $altValue) <= 0.02) { - $paidAmount = round((float) $altAmount, 2); - $basisAmount = $paidAmount; - $difference = 0.0; $remark = self::REMARK_SELLER_INCOME_BASIS; } elseif ($payAmount !== null && abs($income + $promoAmount - $payAmount) <= 0.02) { - $paidAmount = round($payAmount, 2); - $basisAmount = $paidAmount; - $difference = 0.0; $remark = self::REMARK_PAYABLE_BASIS; } + } } if ($productAmount !== null) { $goodsTotal += $productAmount; diff --git a/app/Http/Controllers/Business/Pages.php b/app/Http/Controllers/Business/Pages.php index c2c7add7..27c4d148 100644 --- a/app/Http/Controllers/Business/Pages.php +++ b/app/Http/Controllers/Business/Pages.php @@ -362,6 +362,22 @@ class Pages extends Controller } /** 单行的「差额异常备注」(与筛选条件同一套口径,页面与导出共用)。 */ + /** + * 页面口径的「有效差额」SQL:口径兜底行(备注为空、但能对上实收/应付)按 0 计。 + * 合计、差额筛选、联动计数共用,保证三个地方的数字一致。 + */ + private static function receiptEffectiveDifferenceSql(): string + { + $ruleUnion = '(' . implode(' OR ', array_map( + static fn (string $condition): string => '(' . $condition . ')', + self::receiptDifferenceRemarkConditions() + )) . ')'; + + return "CASE WHEN remark IN ('订单实付按卖家实收核对','订单实付按应付/已付核对')" + . " AND NOT COALESCE({$ruleUnion}, 0) THEN 0" + . ' ELSE COALESCE(difference, COALESCE(income_amount, 0) + COALESCE(discount_amount, 0) + COALESCE(offset_amount, 0)) END'; + } + private static function receiptDifferenceRemark(object $row): ?string { $basis = self::differenceBasis(); @@ -463,6 +479,13 @@ class Pages extends Controller } } + // 原因优先:上面的规则都没命中时,如果这行的口径(卖家实收 / 应付已付)能对上账单, + // 就按口径兜底——差额按 0 展示、口径标识在「匹配原因」列,不再当异常。 + $rawRemark = trim((string) ($row->remark ?? '')); + if (in_array($rawRemark, ['订单实付按卖家实收核对', '订单实付按应付/已付核对'], true)) { + return null; + } + // 有差额但没命中任何已知原因:标「差额待核实」,页面上不再出现"有差额但备注空白"的行。 return '差额待核实'; } @@ -1036,6 +1059,8 @@ class Pages extends Controller // 计数与合计合并为一次全表扫描:重筛选项(如按备注筛选)下少一次全表重算。 $aggQuery = $base(); $applyFilters($aggQuery); + // 口径兜底行(备注为空、口径对上)的差额按 0 计——与页面行展示、差额筛选同一套判定。 + $differenceExpr = self::receiptEffectiveDifferenceSql(); $agg = $aggQuery->selectRaw(" COUNT(*) as total, SUM(payment_count) as payments, @@ -1046,7 +1071,7 @@ class Pages extends Controller SUM(planting_amount) as planting_total, SUM(product_amount) as goods_total, SUM(paid_amount) as paid_total, - SUM(COALESCE(difference, COALESCE(income_amount, 0) + COALESCE(discount_amount, 0) + COALESCE(offset_amount, 0))) as difference_total, + SUM({$differenceExpr}) as difference_total, SUM(CASE WHEN payment_count > 1 THEN 1 ELSE 0 END) as multi_pay, SUM(CASE WHEN income_amount = 0 THEN 1 ELSE 0 END) as zero_income, SUM(CASE WHEN match_status = '已匹配' THEN 1 ELSE 0 END) as matched, @@ -1148,6 +1173,12 @@ class Pages extends Controller ); } + // 口径兜底(原因优先之后):备注为空但带口径标识 → 差额按 0 展示。 + if ($row->remark === null + && in_array($rawRemark, ['订单实付按卖家实收核对', '订单实付按应付/已付核对'], true)) { + $row->difference = 0.0; + } + return $row; }); @@ -1226,7 +1257,7 @@ class Pages extends Controller if ($has === $none) { return; } - $effective = 'COALESCE(difference, COALESCE(income_amount, 0) + COALESCE(discount_amount, 0) + COALESCE(offset_amount, 0))'; + $effective = self::receiptEffectiveDifferenceSql(); $query->whereRaw($has ? 'ABS(' . $effective . ') > 0.005' : 'ABS(' . $effective . ') <= 0.005'); } @@ -1261,7 +1292,7 @@ class Pages extends Controller $query->where('online_order_no', 'like', '%' . addcslashes($orderNo, '%_\\') . '%'); } - $effective = 'COALESCE(difference, COALESCE(income_amount, 0) + COALESCE(discount_amount, 0) + COALESCE(offset_amount, 0))'; + $effective = self::receiptEffectiveDifferenceSql(); $row = $query->selectRaw('SUM(CASE WHEN ABS(' . $effective . ') > 0.005 THEN 1 ELSE 0 END) as has_diff, ' . 'SUM(CASE WHEN ABS(' . $effective . ') <= 0.005 THEN 1 ELSE 0 END) as none_diff')->first();