loginAs() ->get(route('business.pages.show', ['section' => 'basic-data'])) ->assertOk() ->assertSeeText('基础数据') ->assertSeeText('商品价格管理') ->assertSee('/workspace/order-data/raw-data', false) ->assertSee('/workspace/refunds/non-jingxi-refund-data', false) ->assertSee('/workspace/product-inventory/normal-products', false) ->assertSee('/workspace/product-inventory/monthly-weighted-average-price', false) ->assertSee('/workspace/product-inventory/inventory-report', false); } public function testInventoryReportMenuPageIsAvailable(): void { $this->loginAs() ->get(route('business.pages.show', [ 'section' => 'product-inventory', 'page' => 'inventory-report', ])) ->assertOk() ->assertSeeText('进销存报表') ->assertSeeTextInOrder([ '货主', '月份', '仓储方', '仓库', '商品编码', '分类', '期初数量', '期末数量', '加工进仓', '加工出仓', '采购进仓', '采购退货', '其它进仓', '其它退货', '销售出仓', '销售退货', '盘点', '调拨出', '调拨入', '期初', '其它出库', ]) ->assertSeeText('进销存总表') ->assertSeeText('仓库名称映射表') ->assertSee('data-inventory-report-tabs', false) ->assertSee('data-inventory-report-tab="mapping"', false) ->assertSee('id="inventory-report-mapping-panel"', false) ->assertDontSeeText('复用“应付款项 → 快递应付 → 三方仓进销存”') ->assertSeeText('进销存共享镜像尚未建立') ->assertDontSeeText('已按附件模板导入 20 条演示数据') ->assertDontSeeText('进销存报表字段和数据来源尚未定义。'); } public function testMonthlyWeightedAveragePricePageIsAvailable(): void { $this->loginAs() ->get(route('business.pages.show', [ 'section' => 'product-inventory', 'page' => 'monthly-weighted-average-price', ])) ->assertOk() ->assertSeeText('商品月加权平均单价') ->assertSeeText('取数规则待确认') ->assertSeeTextInOrder([ '月份', '商品编码', '商品名称', '采购数量', '采购金额', '月加权平均单价', ]) ->assertSeeText('确认取数规则后再接入经营分析副本库数据'); } public function testFinancialRiskControlPageIsAvailableBetweenFinancialReports(): void { $navigation = BusinessNavigation::all(); $slugs = array_column($navigation, 'slug'); $riskControlIndex = array_search('financial-risk-control', $slugs, true); $this->assertNotFalse($riskControlIndex); $this->assertSame('financial-operations', $slugs[$riskControlIndex - 1]); $this->assertSame('financial-sw', $slugs[$riskControlIndex + 1]); $this->assertSame('财务经营风险管控', $navigation[$riskControlIndex]['title']); $this->assertSame('security', $navigation[$riskControlIndex]['icon']); $this->assertSame([ ['slug' => 'store-violation-alert', 'title' => '店铺违规信息预警'], ], $navigation[$riskControlIndex]['pages']); $this->loginAs() ->get(route('business.pages.show', ['section' => 'financial-risk-control'])) ->assertRedirect(route('business.pages.show', [ 'section' => 'financial-risk-control', 'page' => 'store-violation-alert', ])); $this->get(route('business.pages.show', [ 'section' => 'financial-risk-control', 'page' => 'store-violation-alert', ]) . '?platform=jingxi') ->assertOk() ->assertSeeText('财务经营风险管控') ->assertSeeText('店铺违规信息预警') ->assertSeeTextInOrder(['淘系', '阿里巴巴', '京东', '京喜', '拼多多', '抖音']) ->assertSeeText('京喜店铺违规信息预警') ->assertSeeText('暂无京喜风险事项') ->assertSee('data-active-platform="jingxi"', false) ->assertSee('id="financial-risk-control-panel-jingxi"', false) ->assertSee('data-platform-tab="jingxi"', false) ->assertSee('/workspace/financial-risk-control/store-violation-alert', false); } public function testGroupedNavigationKeepsRestrictedPagePermissions(): void { $this->user->roles()->sync([Role::where('name', 'manager')->firstOrFail()->id]); $subject = 'user_' . $this->user->id; setting()->set('system.sidebar_permissions', [ 'configured' => [$subject], 'subjects' => [$subject => ['basic-data', 'refunds/non-jingxi-refund-data']], ]); setting()->save(); $this->loginAs() ->get(route('business.pages.show', ['section' => 'basic-data'])) ->assertOk() ->assertSee('/workspace/refunds/non-jingxi-refund-data', false) ->assertDontSee('/workspace/order-data/raw-data', false) ->assertDontSee('/workspace/product-inventory/normal-products', false); $this->withExceptionHandling() ->get(route('business.pages.show', ['section' => 'order-data'])) ->assertForbidden(); } public function testAdminCanUpdateSidebarLabels() { $this->user->roles()->sync([ Role::where('name', 'admin')->firstOrFail()->id, ]); $this->user->attachPermission( Permission::where('name', 'read-admin-panel')->firstOrFail() ); $this->loginAs() ->get(route('settings.navigation.manage')) ->assertOk() ->assertSeeText('侧边栏功能名称'); $this->patch(route('settings.navigation.save'), [ 'section_titles' => [ 'company-management' => '企业档案', ], 'page_titles' => [ 'company-management' => [ 'subject-operating-report' => '主体经营', ], ], ])->assertOk(); $navigation = BusinessNavigation::all(); $companyRegistration = collect($navigation[0]['pages'])->firstWhere('slug', 'subject-operating-report'); $this->assertSame('企业档案', $navigation[0]['title']); $this->assertSame('主体经营', $companyRegistration['title']); } public function testOrderDataAndRefundAreConfiguredBetweenInvoiceAndReceivablesMenus() { $navigation = BusinessNavigation::all(); $slugs = array_column($navigation, 'slug'); $invoiceIndex = array_search('invoice-management', $slugs, true); $fundIndex = array_search('fund-management', $slugs, true); $orderIndex = array_search('order-data', $slugs, true); $refundIndex = array_search('refunds', $slugs, true); $billingIndex = array_search('billing-transactions', $slugs, true); $balanceIndex = array_search('account-balance-data', $slugs, true); $productIndex = array_search('product-inventory', $slugs, true); $receivablesIndex = array_search('store-receivables', $slugs, true); $orderData = $navigation[$orderIndex] ?? null; $refund = $navigation[$refundIndex] ?? null; $productInventory = $navigation[$productIndex] ?? null; $financialOperations = collect($navigation)->firstWhere('slug', 'financial-operations'); $this->assertNotFalse($invoiceIndex); $this->assertNotFalse($fundIndex); $this->assertNotFalse($orderIndex); $this->assertNotFalse($refundIndex); $this->assertNotFalse($billingIndex); $this->assertNotFalse($balanceIndex); $this->assertNotFalse($productIndex); $this->assertNotFalse($receivablesIndex); $this->assertSame( [ 'invoice-management', 'fund-management', 'order-data', 'refunds', 'billing-transactions', 'account-balance-data', 'product-inventory', ], array_slice($slugs, $invoiceIndex, 7) ); $this->assertSame( [ '票务管理', '资金管理', '订单数据', '退款数据', '账单流水数据', '账单余额数据', '商品价格管理', ], array_column(array_slice($navigation, $invoiceIndex, 7), 'title') ); $this->assertGreaterThan($invoiceIndex, $orderIndex); $this->assertGreaterThan($orderIndex, $refundIndex); $this->assertGreaterThan($refundIndex, $billingIndex); $this->assertGreaterThan($billingIndex, $balanceIndex); $this->assertGreaterThan($balanceIndex, $productIndex); $this->assertLessThan($receivablesIndex, $productIndex); $this->assertSame('订单数据', $orderData['title']); $this->assertSame( ['raw-data', 'bill-offset'], array_column($orderData['pages'], 'slug') ); $this->assertSame( ['原始数据', '账单冲减'], array_column($orderData['pages'], 'title') ); $this->assertSame( ['after-sales-expenses', 'promotion-expenses'], array_column($orderData['pages'][0]['tabs'], 'slug') ); $this->assertSame( ['订单售后费用明细', '商品推广费用明细'], array_column($orderData['pages'][0]['tabs'], 'title') ); $this->assertSame( ['normal-products', 'online-daifa-price', 'monthly-weighted-average-price', 'inventory-report'], array_column($productInventory['pages'], 'slug') ); $this->assertSame( ['普通商品资料', '线上代发价格', '商品月加权平均单价', '进销存报表'], array_column($productInventory['pages'], 'title') ); $this->assertArrayNotHasKey('children', $orderData['pages'][0]); $this->assertSame( ['bill-offset'], array_column(array_slice($orderData['pages'], 1), 'slug') ); $this->assertSame( ['账单冲减'], array_column(array_slice($orderData['pages'], 1), 'title') ); $this->assertSame('退款数据', $refund['title']); $this->assertSame('assignment_return', $refund['icon']); $this->assertSame( ['jingxi-refund-data', 'non-jingxi-refund-data'], array_column($refund['pages'], 'slug') ); $this->assertSame( ['京喜退款数据', '售后(退货退款)'], array_column($refund['pages'], 'title') ); $this->assertNotNull($financialOperations); $smallPayment = collect($financialOperations['pages'])->firstWhere('slug', 'small-payment-work-orders'); $this->assertSame('小额打款', $smallPayment['title'] ?? null); $this->assertGreaterThan( array_search('after-sales-expenses', array_column($financialOperations['pages'], 'slug'), true), array_search('small-payment-work-orders', array_column($financialOperations['pages'], 'slug'), true) ); } }