From a2b3db3afa0d3342ac703aecf3ef98554cfe4cf7 Mon Sep 17 00:00:00 2001 From: "404877757@qq.com" <404877757@qq.com> Date: Mon, 7 Sep 2026 18:03:07 +0800 Subject: [PATCH] fix: show vip marketing promotion flow --- app/Http/Controllers/Business/Pages.php | 33 ++++---- config/business_navigation.php | 2 +- .../PlatformPromotionAccountRepository.php | 52 ++++++++---- .../View/PlatformPromotionAccountPageData.php | 7 +- .../partials/embedded-table.blade.php | 42 +++++----- .../MarketingPlatformPromotionBillsTest.php | 84 +++++++++---------- ...PlatformPromotionAccountRepositoryTest.php | 42 ++++++---- 7 files changed, 150 insertions(+), 112 deletions(-) diff --git a/app/Http/Controllers/Business/Pages.php b/app/Http/Controllers/Business/Pages.php index 8bd465f6..3d81822b 100644 --- a/app/Http/Controllers/Business/Pages.php +++ b/app/Http/Controllers/Business/Pages.php @@ -93,7 +93,7 @@ class Pages extends Controller 'jd-promotion', 'douyin-promotion', 'dewu-promotion', 'vip-promotion', ]; - /** @var list 推广账户流水及唯品会税务数据已合并到营销账户账单页的页签 */ + /** @var list 推广账户流水已合并到营销账户账单页的页签 */ protected const PROMOTION_MARKETING_TABS = [ 'jd-promotion', 'douyin-promotion', 'dewu-promotion', 'vip-promotion', ]; @@ -1166,6 +1166,9 @@ class Pages extends Controller 'shop_name' => mb_substr(trim((string) $request->query('shop_name', '')), 0, 100), 'account' => mb_substr(trim((string) $request->query('account', '')), 0, 100), ]; + if ($platform === 'vip') { + $filters['advertiser_id'] = mb_substr(trim((string) $request->query('advertiser_id', '')), 0, 100); + } try { $repository = app(\Modules\EcommerceFinance\Repositories\PlatformPromotionAccountRepository::class); @@ -1188,24 +1191,20 @@ class Pages extends Controller if ($platform === 'vip') { fputcsv($csv, [ - '平台', '店铺', '平台店铺', '申报金额(元)', '退货订单数', - '退货服务金额(元)', '退货商品金额(元)', '销售订单数', - '销售服务金额(元)', '销售商品金额(元)', '交易笔数', '交易时间', + '平台', '营销账户', '账户名称', '广告主 ID', '广告主名称', + '报表日期', '花费(元)', '曝光量', '更新时间', ]); - foreach ($data['vipTax'] ?? [] as $row) { + foreach ($data['vipMarketingDaily'] ?? [] as $row) { fputcsv($csv, [ - '唯品会税务数据', - $row['shopName'] ?? '', - $row['storeName'] ?? '', - $row['reportAmount'] ?? '', - $row['returnOrderCount'] ?? '', - $row['returnServiceAmount'] ?? '', - $row['returnSkuAmount'] ?? '', - $row['saleOrderCount'] ?? '', - $row['salesServiceAmount'] ?? '', - $row['salesSkuAmount'] ?? '', - $row['transactionNum'] ?? '', - $row['transactionTime'] ?? '', + '唯品会推广流水', + $row['account'] ?? '', + $row['accountName'] ?? '', + $row['advertiserId'] ?? '', + $row['advertiserTitle'] ?? '', + $row['reportDate'] ?? '', + $row['costYuan'] ?? '', + $row['impressionCount'] ?? '', + $row['updatedAt'] ?? '', ]); } fclose($csv); diff --git a/config/business_navigation.php b/config/business_navigation.php index c062e698..2fd1b400 100644 --- a/config/business_navigation.php +++ b/config/business_navigation.php @@ -362,7 +362,7 @@ return [ ['slug' => 'jd-promotion', 'title' => '京东京准通'], ['slug' => 'douyin-promotion', 'title' => '抖音千川'], ['slug' => 'dewu-promotion', 'title' => '得物推广账户'], - ['slug' => 'vip-promotion', 'title' => '唯品会税务数据'], + ['slug' => 'vip-promotion', 'title' => '唯品会推广流水'], ], ], ['slug' => 'deposit-account-balance', 'title' => '店铺保证金账户余额'], diff --git a/modules/EcommerceFinance/Repositories/PlatformPromotionAccountRepository.php b/modules/EcommerceFinance/Repositories/PlatformPromotionAccountRepository.php index 4d14b173..f9cf31f6 100644 --- a/modules/EcommerceFinance/Repositories/PlatformPromotionAccountRepository.php +++ b/modules/EcommerceFinance/Repositories/PlatformPromotionAccountRepository.php @@ -6,7 +6,7 @@ use InvalidArgumentException; use Modules\EcommerceFinance\Services\UpstreamReadOnlyQuery; use Modules\EcommerceFinance\Services\UpstreamReadOnlyQueryFactory; -/** 固定字段、固定表的推广账户及唯品会税务数据只读查询。 */ +/** 固定字段、固定表的推广账户及唯品会营销日报只读查询。 */ class PlatformPromotionAccountRepository { private const SOURCE = 'js_data_middle_platform'; @@ -18,12 +18,13 @@ class PlatformPromotionAccountRepository public function dashboard(array $filters, int $limit = 200, ?string $platform = null): array { if ($platform !== null && ! in_array($platform, ['jd', 'douyin', 'dewu', 'vip'], true)) { - throw new InvalidArgumentException('未知的推广账户或税务数据平台。'); + throw new InvalidArgumentException('未知的推广账户平台。'); } $month = $filters['month']; $shop = $filters['shop_name'] ?? null; $account = $filters['account'] ?? null; + $advertiser = $filters['advertiser_id'] ?? null; $limit = min(max($limit, 1), 5000); $query = $this->queries->forSource(self::SOURCE); @@ -34,7 +35,8 @@ class PlatformPromotionAccountRepository $douyinStatus = []; $dewu = []; $dewuSummary = []; - $vipTax = []; + $vipMarketing = []; + $vipMarketingDaily = []; $vipSummary = []; if ($platform === null || $platform === 'jd') { @@ -54,12 +56,14 @@ class PlatformPromotionAccountRepository } if ($platform === null || $platform === 'vip') { - $vipTax = $this->query($query, "SELECT TOP {$limit} shopName, storeName, reportAmount, returnOrderCount, returnServiceAmount, returnSkuAmount, saleOrderCount, salesServiceAmount, salesSkuAmount, transactionNum, transactionTime FROM JSDataMiddlePlatform.dbo.vip_taxDeclarationDetail WHERE dataMonth = ?", [$month], $shop, null, 'shopName'); + $vipMarketing = $this->query($query, "SELECT TOP {$limit} account, accountName, advertiserId, dataMonth, startDate, endDate, totalCostYuan, totalImpressionCount, recordCount, updatedAt FROM JSDataMiddlePlatform.dbo.vip_marketingMonthlySummary WHERE dataMonth = ?", [$month], null, $account, null, true, $advertiser); + $vipMarketingDaily = $this->query($query, "SELECT TOP {$limit} account, accountName, advertiserId, advertiserTitle, dataMonth, reportDate, reportTimestamp, costYuan, impressionCount, updatedAt FROM JSDataMiddlePlatform.dbo.vip_marketingDailyReport WHERE dataMonth = ?", [$month], null, $account, null, false, $advertiser, 'reportDate, advertiserId, account'); $vipSummary = [ - 'report_amount' => $this->sum($vipTax, 'reportAmount'), - 'return_order_count' => $this->sum($vipTax, 'returnOrderCount'), - 'sale_order_count' => $this->sum($vipTax, 'saleOrderCount'), - 'transaction_num' => $this->sum($vipTax, 'transactionNum'), + 'cost' => $this->sum($vipMarketing, 'totalCostYuan'), + 'impressions' => $this->sum($vipMarketing, 'totalImpressionCount'), + 'record_count' => $this->sum($vipMarketing, 'recordCount'), + 'account_count' => $this->distinctCount($vipMarketing, 'account'), + 'daily_record_count' => count($vipMarketingDaily), ]; } @@ -71,10 +75,11 @@ class PlatformPromotionAccountRepository 'dyStatus' => $douyinStatus, 'dw' => $dewu, 'dwSummary' => $dewuSummary, - // 保留旧键为空数组,避免调用方因契约变更报错;唯品会页签只使用税务明细。 + // 保留旧键为空数组,避免调用方因契约变更报错;唯品会页签只使用营销日报。 'vipSales' => [], - 'vipTax' => $vipTax, - 'vipMarketing' => [], + 'vipTax' => [], + 'vipMarketing' => $vipMarketing, + 'vipMarketingDaily' => $vipMarketingDaily, 'vipSummary' => $vipSummary, ]; } @@ -95,10 +100,12 @@ class PlatformPromotionAccountRepository array $bindings, ?string $shop, ?string $account, - string $shopColumn, + ?string $shopColumn, bool $summary = false, + ?string $advertiser = null, + ?string $orderBy = null, ): array { - if ($shop !== null && $shop !== '') { + if ($shop !== null && $shop !== '' && $shopColumn !== null) { $sql .= " AND {$shopColumn} LIKE ?"; $bindings[] = '%' . $shop . '%'; } @@ -106,8 +113,12 @@ class PlatformPromotionAccountRepository $sql .= ' AND account LIKE ?'; $bindings[] = '%' . $account . '%'; } + if ($advertiser !== null && $advertiser !== '') { + $sql .= ' AND advertiserId LIKE ?'; + $bindings[] = '%' . $advertiser . '%'; + } if (! $summary) { - $sql .= ' ORDER BY 1'; + $sql .= ' ORDER BY ' . ($orderBy ?: '1'); } return $query->select($sql, $bindings); @@ -117,4 +128,17 @@ class PlatformPromotionAccountRepository { return round(array_sum(array_map(static fn (array $row): float => (float) ($row[$key] ?? 0), $rows)), 2); } + + private function distinctCount(array $rows, string $key): int + { + $values = []; + foreach ($rows as $row) { + $value = $row[$key] ?? null; + if ($value !== null && $value !== '') { + $values[(string) $value] = true; + } + } + + return count($values); + } } diff --git a/modules/EcommerceFinance/View/PlatformPromotionAccountPageData.php b/modules/EcommerceFinance/View/PlatformPromotionAccountPageData.php index 9552e021..94b98d8e 100644 --- a/modules/EcommerceFinance/View/PlatformPromotionAccountPageData.php +++ b/modules/EcommerceFinance/View/PlatformPromotionAccountPageData.php @@ -33,6 +33,9 @@ class PlatformPromotionAccountPageData 'shop_name' => $this->text(request('shop_name')), 'account' => $this->text(request('account')), ]; + if ($platform === 'vip') { + $filters['advertiser_id'] = $this->text(request('advertiser_id')); + } try { if ($requestedMonth === '') { $month = $this->repository->latestMonth() ?: $month; @@ -69,7 +72,7 @@ class PlatformPromotionAccountPageData 'platform' => $platform, 'marketingTab' => $tab, 'rows' => $this->emptyPaginator(), - 'error' => '推广账户数据暂时无法读取,请稍后重试。', + 'error' => '平台推广数据暂时无法读取,请稍后重试。', ]; } } @@ -81,7 +84,7 @@ class PlatformPromotionAccountPageData private function paginateRows(array $data, string $tab): LengthAwarePaginator { - $key = ['jd' => 'jd', 'douyin' => 'dy', 'dewu' => 'dw', 'vip' => 'vipTax'][$tab]; + $key = ['jd' => 'jd', 'douyin' => 'dy', 'dewu' => 'dw', 'vip' => 'vipMarketingDaily'][$tab]; $rows = $data[$key] ?? []; $page = max((int) request('page', 1), 1); $perPage = 50; diff --git a/resources/views/banking/marketing_platform_promotion_bills/partials/embedded-table.blade.php b/resources/views/banking/marketing_platform_promotion_bills/partials/embedded-table.blade.php index 229c2671..e1552b9e 100644 --- a/resources/views/banking/marketing_platform_promotion_bills/partials/embedded-table.blade.php +++ b/resources/views/banking/marketing_platform_promotion_bills/partials/embedded-table.blade.php @@ -8,28 +8,25 @@ 'dewu' => $data['dwSummary'] ?? [], default => $data['vipSummary'] ?? [], }; - $titles = ['jd' => '京东京准通', 'douyin' => '抖音千川', 'dewu' => '得物推广账户', 'vip' => '唯品会税务数据']; + $titles = ['jd' => '京东京准通', 'douyin' => '抖音千川', 'dewu' => '得物推广账户', 'vip' => '唯品会推广流水']; $filterLabel = $platform === 'vip' ? $titles[$platform] . '筛选' : $titles[$platform] . '推广账户筛选'; $columns = match ($platform) { 'jd' => [['shop_name', '店铺'], ['account', '账户'], ['show_date', '日期'], ['trade_type_name', '交易类型'], ['amount', '金额'], ['balance_amount', '余额'], ['remark', '备注']], 'douyin' => [['shopName', '店铺'], ['account', '账户'], ['qianchuanAavid', '广告账户'], ['statDate', '日期'], ['cost', '花费'], ['income', '收入'], ['transferIn', '转入'], ['transferOut', '转出'], ['balance', '余额'], ['status', '状态'], ['remark', '备注']], 'dewu' => [['shop_name', '店铺'], ['account', '账户'], ['trade_date', '日期'], ['amount_type', '金额类型'], ['flow_type', '收支类型'], ['trade_amount_yuan', '金额'], ['balance_yuan', '余额'], ['remark', '备注']], default => [ - ['shopName', '店铺'], - ['storeName', '平台店铺'], - ['reportAmount', '申报金额(元)'], - ['returnOrderCount', '退货订单数'], - ['returnServiceAmount', '退货服务金额(元)'], - ['returnSkuAmount', '退货商品金额(元)'], - ['saleOrderCount', '销售订单数'], - ['salesServiceAmount', '销售服务金额(元)'], - ['salesSkuAmount', '销售商品金额(元)'], - ['transactionNum', '交易笔数'], - ['transactionTime', '交易时间'], + ['account', '营销账户'], + ['accountName', '账户名称'], + ['advertiserId', '广告主 ID'], + ['advertiserTitle', '广告主名称'], + ['reportDate', '报表日期'], + ['costYuan', '花费(元)'], + ['impressionCount', '曝光量'], + ['updatedAt', '更新时间'], ], }; - $moneyFields = ['amount', 'balance_amount', 'cost', 'income', 'transferIn', 'transferOut', 'balance', 'trade_amount_yuan', 'balance_yuan', 'reportAmount', 'returnServiceAmount', 'returnSkuAmount', 'salesServiceAmount', 'salesSkuAmount']; - $integerFields = ['returnOrderCount', 'saleOrderCount', 'transactionNum']; + $moneyFields = ['amount', 'balance_amount', 'cost', 'income', 'transferIn', 'transferOut', 'balance', 'trade_amount_yuan', 'balance_yuan', 'costYuan']; + $integerFields = ['impressionCount']; @endphp