截单时间

This commit is contained in:
liu
2026-09-05 19:40:52 +08:00
parent b1bb40a088
commit 52f396c12e
5 changed files with 143 additions and 4 deletions
+3 -3
View File
@@ -106,7 +106,7 @@ class MiniProductTest extends ProcurementTestCase
$this->assertNull($row['price']);
}
/** 商品列表:先按分类树展示顺序(深度优先),同分类内按商品 sort 序、id 升序,未入树分类排最后 */
/** 商品列表:先按分类树展示顺序(深度优先),同分类内按商品 sort 序、id 升序,未入树分类排最后 */
public function test_product_list_ordered_by_category_tree(): void
{
$rootA = ProductCategoryModel::create(['name' => '蔬菜', 'parent_id' => 0, 'sort' => 0, 'status' => 1]);
@@ -123,8 +123,8 @@ class MiniProductTest extends ProcurementTestCase
$ids = array_column($this->getJson('/mini/product/list')->assertOk()->json('data.data'), 'id');
// 树序:rootA → leafA2 → leafA1 → rootBleafA2 内 sort 序;无分类排最后
$this->assertSame([$pA2High->id, $pA2Low->id, $pA1->id, $pB->id, $pNone->id], $ids);
// 树序:rootA → leafA2 → leafA1 → rootBleafA2 内 sort 序;无分类排最后
$this->assertSame([$pA2Low->id, $pA2High->id, $pA1->id, $pB->id, $pNone->id], $ids);
}
/** 商品列表:登录门店附加购物车行ID与数量,响应附悬浮球汇总 */
+93
View File
@@ -9,6 +9,9 @@ use App\Models\PurchaseOrderModel;
use App\Models\StoreModel;
use App\Models\StoreOrderModel;
use Modules\SystemTool\Models\SysFileModel;
use Modules\SystemTool\Models\SysSiteConfigGroupModel;
use Modules\SystemTool\Models\SysSiteConfigItemsModel;
use Modules\SystemTool\Services\SysSiteConfigService;
/**
* 小程序下单:等级上浮价快照、服务端重算总价、取消限制、门店数据隔离
@@ -426,6 +429,96 @@ class StoreOrderTest extends ProcurementTestCase
$this->assertSame(StoreOrderModel::STATUS_SUMMARIZED, $pending1->refresh()->status);
}
/** 写入下单时段业务配置并刷新缓存(value 传 null 表示该项不配置) */
private function setOrderTimeWindow(?string $start, ?string $end): void
{
$group = SysSiteConfigGroupModel::create(['title' => '业务配置', 'key' => 'services', 'remark' => '']);
foreach (['order_time_start' => $start, 'order_time_end' => $end] as $key => $value) {
if ($value === null) {
continue;
}
SysSiteConfigItemsModel::create([
'group_id' => $group->id,
'key' => $key,
'title' => $key,
'describe' => '',
'values' => $value,
'type' => 'Input',
'options' => '',
'sort' => 0,
]);
}
SysSiteConfigService::refreshSiteConfig();
}
/** 截单时间:下单时段外禁止下单,时段内正常下单 */
public function test_place_order_blocked_outside_order_time_window(): void
{
[$store, $product] = $this->makeStoreWithProduct('5.00');
$this->setOrderTimeWindow('08:00', '18:00');
$this->actingAsMiniStore($store);
// 20:00 已截单 → 拒绝且不生成订单
$this->travelTo('2026-09-05 20:00:00');
$response = $this->postJson('/mini/order', ['items' => [['product_id' => $product->id, 'quantity' => 1]]]);
$response->assertOk()->assertJsonPath('success', false);
$this->assertStringContainsString('不在下单时段内', (string) $response->json('msg'));
$this->assertStringContainsString('08:00 - 18:00', (string) $response->json('msg'));
$this->assertSame(0, StoreOrderModel::count());
// 边界:08:00 开始时间与 18:00 截单时间均可下单
$this->travelTo('2026-09-05 08:00:00');
$this->postJson('/mini/order', ['items' => [['product_id' => $product->id, 'quantity' => 1]]])
->assertJsonPath('success', true);
$this->travelTo('2026-09-05 18:00:00');
$this->postJson('/mini/order', ['items' => [['product_id' => $product->id, 'quantity' => 1]]])
->assertJsonPath('success', true);
$this->assertSame(2, StoreOrderModel::count());
}
/** 截单时间:跨天时段(开始时间晚于截单时间,如 20:00-次日06:00 */
public function test_place_order_cross_midnight_time_window(): void
{
[$store, $product] = $this->makeStoreWithProduct('5.00');
$this->setOrderTimeWindow('20:00', '06:00');
$this->actingAsMiniStore($store);
// 当晚 22:00 与 次日 05:00 均在时段内
$this->travelTo('2026-09-05 22:00:00');
$this->postJson('/mini/order', ['items' => [['product_id' => $product->id, 'quantity' => 1]]])
->assertJsonPath('success', true);
$this->travelTo('2026-09-06 05:00:00');
$this->postJson('/mini/order', ['items' => [['product_id' => $product->id, 'quantity' => 1]]])
->assertJsonPath('success', true);
// 中午 12:00 不在时段内 → 拒绝
$this->travelTo('2026-09-06 12:00:00');
$this->postJson('/mini/order', ['items' => [['product_id' => $product->id, 'quantity' => 1]]])
->assertJsonPath('success', false);
$this->assertSame(2, StoreOrderModel::count());
}
/** 截单时间:只配置截单时间时按单边限制(截止后不能下单);格式非法按未配置处理 */
public function test_place_order_only_cutoff_time_and_invalid_config(): void
{
[$store, $product] = $this->makeStoreWithProduct('5.00');
$this->setOrderTimeWindow(null, '18:00');
$this->actingAsMiniStore($store);
$this->travelTo('2026-09-05 17:59:00');
$this->postJson('/mini/order', ['items' => [['product_id' => $product->id, 'quantity' => 1]]])
->assertJsonPath('success', true);
$this->travelTo('2026-09-05 18:01:00');
$this->postJson('/mini/order', ['items' => [['product_id' => $product->id, 'quantity' => 1]]])
->assertJsonPath('success', false);
// 非法格式不拦截(避免误配置导致全天无法下单)
SysSiteConfigItemsModel::query()->update(['values' => 'abc']);
SysSiteConfigService::refreshSiteConfig();
$this->postJson('/mini/order', ['items' => [['product_id' => $product->id, 'quantity' => 1]]])
->assertJsonPath('success', true);
}
/** 订单列表商品预览:附带首图/规格/单位供小程序端展示 */
public function test_order_list_preview_includes_image_spec_and_unit(): void
{