## 任务背景 订单数据页面已完成附件表头,本任务由 renshen 接入聚水潭上游真实只读数据。 ## 任务目标 - 订单售后费用明细:按附件字段展示订单、商品、SKU 成本及售后关联数据。 - 商品推广费用明细:按商品/款式汇总推广费用。 - 不硬编码附件演示值;缺失字段保持空值或零。 ## 预计修改路径 - modules/EcommerceFinance/Repositories/OrderDataRepository.php - modules/EcommerceFinance/View/Composers/OrderDataPageComposer.php - modules/EcommerceFinance/Providers/Main.php - resources/views/business/pages/order-data/*.blade.php - tests/Unit/EcommerceFinance/OrderDataRepositoryTest.php - tests/Feature/Business/OrderDataPagesUpstreamTest.php ## 页面和路由 复用 order-data/after-sales-expenses、order-data/promotion-expenses 和 business.pages.show;不新增或修改 routes。 ## Controller / Repository 新增 OrderDataRepository 和专用 View Composer;不修改 app/Http/Controllers/Business/Pages.php。 ## 数据源、表和字段 source_key=operations_replica,数据库 JSReportReplica,schema=rpt。固定参数化只读查询使用 jst_Orders、jst_OrderItem、jst_sku、jst_skumap、jst_returnAndRefundInfo、jst_returnAndRefundItem、jst_warehouseInfo、ads_itemid_sales_cost_ratio_v2_di。字段限于订单/商品标识、时间、店铺、SKU 元数据、金额、售后数量金额及 push_fee。 ## scope - order-data.after-sales.list - order-data.promotion.list ## 权限、菜单和公共组件 复用现有页面权限、菜单、UpstreamReadOnlyQueryFactory 和 UpstreamQueryCacheFactory;不修改权限和导航。 ## 明确不修改 不修改 routes、Pages Controller、数据库迁移、上游连接配置、权限、菜单、京东钱包功能、共享数据库结构或任何上游数据。 ## 范围补充:后台快照刷新 - modules/EcommerceFinance/Services/OperationsReplicaSnapshotRefresher.php - tests/Unit/EcommerceFinance/OperationsReplicaSnapshotRefresherTest.php 刷新器仅为 order-data.after-sales.list 和 order-data.promotion.list 分派同一 OrderDataRepository 固定查询;其他 scope 继续复用现有 UpstreamBusinessInformation。 Reviewed-on: http://git.1080p.hk/WuYongJie/CaiWuXiTong/pulls/27
103 lines
3.8 KiB
PHP
103 lines
3.8 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature\Business;
|
|
|
|
use App\Models\Auth\Permission;
|
|
use Mockery;
|
|
use Modules\EcommerceFinance\Services\UpstreamQueryCache;
|
|
use Modules\EcommerceFinance\Services\UpstreamQueryCacheFactory;
|
|
use Symfony\Component\HttpKernel\Exception\ServiceUnavailableHttpException;
|
|
use Tests\Feature\FeatureTestCase;
|
|
|
|
class OrderDataPagesUpstreamTest extends FeatureTestCase
|
|
{
|
|
public function test_order_data_pages_render_cached_upstream_rows_and_filters(): void
|
|
{
|
|
$this->allowOrderDataPages();
|
|
$cache = Mockery::mock(UpstreamQueryCache::class);
|
|
$cache->shouldReceive('remember')->twice()->andReturnUsing(
|
|
function (string $scope, array $parameters): array {
|
|
if ($scope === 'order-data.after-sales.list') {
|
|
$this->assertSame('ORDER-1', $parameters['filters']['order_no']);
|
|
|
|
return ['rows' => [[
|
|
'internal_order_no' => 'ORDER-1',
|
|
'shop_name' => '测试店铺',
|
|
'product_amount' => 123.45,
|
|
]]];
|
|
}
|
|
|
|
$this->assertSame('order-data.promotion.list', $scope);
|
|
|
|
return [
|
|
'date' => '2026-08-09',
|
|
'rows' => [[
|
|
'shop_name' => '推广测试店铺',
|
|
'product_code' => 'SKU-1',
|
|
'promotion_fee' => 9.05,
|
|
]],
|
|
];
|
|
},
|
|
);
|
|
$cache->shouldReceive('responseHeaders')->twice()->andReturn([
|
|
'X-Caiwu-Data-Status' => 'direct',
|
|
]);
|
|
$factory = Mockery::mock(UpstreamQueryCacheFactory::class);
|
|
$factory->shouldReceive('forSource')->twice()->with('operations_replica')->andReturn($cache);
|
|
$this->app->instance(UpstreamQueryCacheFactory::class, $factory);
|
|
|
|
$this->loginAs()
|
|
->get(route('business.pages.show', [
|
|
'section' => 'order-data',
|
|
'page' => 'after-sales-expenses',
|
|
'order_no' => 'ORDER-1',
|
|
'from' => '2026-08-01',
|
|
'to' => '2026-08-09',
|
|
]))
|
|
->assertOk()
|
|
->assertSeeText('ORDER-1')
|
|
->assertSeeText('测试店铺')
|
|
->assertSeeText('123.45')
|
|
->assertSeeText('DIRECT');
|
|
|
|
$this->get(route('business.pages.show', [
|
|
'section' => 'order-data',
|
|
'page' => 'promotion-expenses',
|
|
]))
|
|
->assertOk()
|
|
->assertSeeText('推广测试店铺')
|
|
->assertSeeText('SKU-1')
|
|
->assertSeeText('9.05')
|
|
->assertSee('value="2026-08-09"', false);
|
|
}
|
|
|
|
public function test_order_data_page_keeps_rendering_when_the_upstream_is_unavailable(): void
|
|
{
|
|
$this->allowOrderDataPages();
|
|
$cache = Mockery::mock(UpstreamQueryCache::class);
|
|
$cache->shouldReceive('remember')->once()->andThrow(
|
|
new ServiceUnavailableHttpException(30, '首份共享快照正在准备。')
|
|
);
|
|
$factory = Mockery::mock(UpstreamQueryCacheFactory::class);
|
|
$factory->shouldReceive('forSource')->once()->with('operations_replica')->andReturn($cache);
|
|
$this->app->instance(UpstreamQueryCacheFactory::class, $factory);
|
|
|
|
$this->loginAs()
|
|
->get(route('business.pages.show', [
|
|
'section' => 'order-data',
|
|
'page' => 'promotion-expenses',
|
|
]))
|
|
->assertOk()
|
|
->assertSeeText('首份共享快照正在准备。')
|
|
->assertSeeText('暂无数据');
|
|
}
|
|
|
|
private function allowOrderDataPages(): void
|
|
{
|
|
$this->user->update(['locale' => 'zh-CN']);
|
|
$this->user->attachPermission(
|
|
Permission::where('name', 'read-admin-panel')->firstOrFail()
|
|
);
|
|
}
|
|
}
|