新增「账单流水数据 › 聚水潭订单标签明细」(紧邻种菜明细表):四列(线上订单号/店铺名称/下单时间/标签),按标签拆行(一个标签一行)、订单不去重、标签不汇总,无标签订单记为「(无标签)」。新增 jst_order_labels 表(含公司/时间/标签/店铺索引)、JstOrderLabel 模型、JstOrderLabelImporter(从镜像 ops_jst_orders 按区间拆行导入,--replace 只清同区间)与 jst-order-labels:import 命令、导出路由与用例。页面筛选:下单时间区间(点整块开日历、可单独清除)、店铺、标签、线上订单号。
117 lines
4.9 KiB
PHP
117 lines
4.9 KiB
PHP
<?php
|
||
|
||
namespace Tests\Feature\Business;
|
||
|
||
use App\Business\JstOrderLabelImporter;
|
||
use App\Models\Auth\Permission;
|
||
use App\Models\Business\JstOrderLabel;
|
||
use Illuminate\Support\Facades\DB;
|
||
use Illuminate\Support\Facades\Schema;
|
||
use Tests\Feature\FeatureTestCase;
|
||
|
||
/**
|
||
* 账单流水数据 › 聚水潭订单标签明细(按标签拆行导入 + 页面 + 筛选 + 导出)。
|
||
*/
|
||
class JstOrderLabelsPageTest extends FeatureTestCase
|
||
{
|
||
protected function setUp(): void
|
||
{
|
||
parent::setUp();
|
||
|
||
config(['database.connections.business_mirror' => [
|
||
'driver' => 'sqlite',
|
||
'database' => ':memory:',
|
||
'prefix' => '',
|
||
]]);
|
||
DB::purge('business_mirror');
|
||
|
||
Schema::connection('business_mirror')->create('ops_jst_orders', function ($table): void {
|
||
$table->integer('Id')->primary();
|
||
$table->string('so_id')->nullable();
|
||
$table->string('shop_name')->nullable();
|
||
$table->dateTime('order_date')->nullable();
|
||
$table->text('labels')->nullable();
|
||
});
|
||
|
||
DB::connection('business_mirror')->table('ops_jst_orders')->insert([
|
||
['Id' => 1, 'so_id' => '260901-391328633273048', 'shop_name' => '拼多多-优乐猫家具旗舰店', 'order_date' => '2026-09-01 00:00:13', 'labels' => '发货前售后,店铺-拼多多'],
|
||
['Id' => 2, 'so_id' => '3608400015164657', 'shop_name' => '京喜-久伴吾家具京喜自营工厂店', 'order_date' => '2026-09-01 00:00:44', 'labels' => '京东供销订单, 京喜'],
|
||
['Id' => 3, 'so_id' => '110211297173802010', 'shop_name' => '得物-全米', 'order_date' => '2026-08-31 23:59:00', 'labels' => '品牌直发'],
|
||
['Id' => 4, 'so_id' => '260915-000000000000001', 'shop_name' => '得物-全米', 'order_date' => '2026-09-15 10:00:00', 'labels' => ''],
|
||
]);
|
||
}
|
||
|
||
public function test_import_splits_labels_without_deduping_orders(): void
|
||
{
|
||
$this->allowPage();
|
||
|
||
$result = app(JstOrderLabelImporter::class)->import('2026-09-01', '2026-09-15', $this->company->id, true);
|
||
|
||
$this->assertSame(3, $result['orders']);
|
||
$this->assertSame(5, $result['rows']);
|
||
$this->assertSame(1, $result['no_label_orders']);
|
||
|
||
$rows = JstOrderLabel::query()->where('company_id', $this->company->id)->orderBy('id')->get();
|
||
$this->assertSame(['发货前售后', '店铺-拼多多', '京东供销订单', '京喜', '(无标签)'], $rows->pluck('label')->all());
|
||
// 同一订单拆成多行,订单不去重
|
||
$this->assertSame(2, $rows->where('order_no', '260901-391328633273048')->count());
|
||
$this->assertSame('2026-09-15 10:00:00', $rows->last()->ordered_at->format('Y-m-d H:i:s'));
|
||
}
|
||
|
||
public function test_import_window_excludes_out_of_range_orders(): void
|
||
{
|
||
$this->allowPage();
|
||
|
||
// 8-31 的订单不在 9 月窗口内
|
||
$result = app(JstOrderLabelImporter::class)->import('2026-09-01', '2026-09-15', $this->company->id, true);
|
||
$orders = JstOrderLabel::query()->where('company_id', $this->company->id)->pluck('order_no')->unique()->all();
|
||
|
||
$this->assertNotContains('110211297173802010', $orders);
|
||
$this->assertSame(3, $result['orders']);
|
||
}
|
||
|
||
public function test_page_filters_and_export(): void
|
||
{
|
||
$this->allowPage();
|
||
app(JstOrderLabelImporter::class)->import('2026-09-01', '2026-09-15', $this->company->id, true);
|
||
|
||
$page = $this->loginAs()->get(route('business.pages.show', [
|
||
'section' => 'billing-transactions',
|
||
'page' => 'jst-order-labels',
|
||
]));
|
||
|
||
$page->assertOk()
|
||
->assertSee('聚水潭订单标签明细')
|
||
->assertSee('260901-391328633273048')
|
||
->assertSee('店铺-拼多多')
|
||
->assertSee('(无标签)')
|
||
->assertSee('id="jst-label-date-from"', false)
|
||
->assertSee('data-jst-labels-clear="jst-label-date-to"', false);
|
||
|
||
$filtered = $this->loginAs()->get(route('business.pages.show', [
|
||
'section' => 'billing-transactions',
|
||
'page' => 'jst-order-labels',
|
||
'label' => '京喜',
|
||
]));
|
||
$filtered->assertOk()
|
||
->assertSee('3608400015164657')
|
||
->assertDontSee('260901-391328633273048');
|
||
|
||
$export = $this->loginAs()->get(route('business.billing-transactions.jst-order-labels.export', [
|
||
'label' => '京喜',
|
||
]));
|
||
$export->assertOk()->assertDownload();
|
||
$csv = $export->streamedContent();
|
||
$this->assertStringContainsString('线上订单号,店铺名称,下单时间,标签', explode("\n", $csv)[0]);
|
||
$this->assertStringContainsString('3608400015164657', $csv);
|
||
$this->assertStringNotContainsString('260901-391328633273048', $csv);
|
||
}
|
||
|
||
private function allowPage(): void
|
||
{
|
||
$this->user->attachPermission(
|
||
Permission::where('name', 'read-admin-panel')->firstOrFail()
|
||
);
|
||
}
|
||
}
|