feat(fleet): integrate trip management and fee coverage workflows

This commit is contained in:
2026-10-03 04:35:55 +08:00
parent bca08f8749
commit dc35288a1b
87 changed files with 3774 additions and 233 deletions
+37 -11
View File
@@ -3,6 +3,7 @@ import { dirname, resolve } from 'node:path'
import ts from 'typescript'
import { describe, expect, it } from 'vitest'
import { compileStyle, parse } from 'vue/compiler-sfc'
import { adminNavigation, getNavigationLeaves } from '@/core/navigation/adminNavigation'
// Approved entry/consumer inventory. Do not discover unrelated menus recursively.
const cargoConsumers = [
@@ -61,6 +62,13 @@ const generalCatalogConsumers = [
'overseas-master-data/pages/OverseasQuotesView.vue',
'overseas-master-data/pages/VehiclesView.vue',
'overseas-master-data/pages/VehicleDetailView.vue',
'overseas-master-data/pages/DriversView.vue',
'overseas-master-data/pages/TripsView.vue',
'overseas-master-data/pages/TripDetailView.vue',
'overseas-master-data/components/TripPlanDialog.vue',
'overseas-master-data/pages/DriverDetailView.vue',
'overseas-master-data/components/DriverEditorDialog.vue',
'overseas-master-data/components/DriverLicensePreview.vue',
'master-data/express-companies/pages/ExpressCompaniesView.vue',
'master-data/counterparties/pages/PartnersView.vue',
'fee-items/pages/FeeItemsView.vue',
@@ -151,6 +159,29 @@ const cssRoot = (css: string) => {
}
describe('approved Admin density ownership', () => {
it('shares list status and category tab styles across registered list consumers', () => {
for (const file of [
'unified-orders/pages/UnifiedOrdersView.vue', 'overseas-warehouse/pages/LastMileOrdersView.vue',
'overseas-master-data/pages/VehiclesView.vue', 'suppliers/pages/SuppliersView.vue',
'domestic-containers/pages/DomesticContainersView.vue', 'container-loading/pages/ContainersView.vue',
]) {
const page = parse(read(`modules/${file}`)).descriptor
expect(page.template!.content).toMatch(/class="[^"]*density-status-tabs[^"]*" role="tablist"/)
expect(page.styles.map((style) => style.content).join('\n')).not.toMatch(/\.(status-tabs?|supplier-tabs|container-scope-tabs)\s*[{:.]/)
}
expect(read('modules/overseas-warehouse/pages/ReturnInventoryManagementView.vue')).toContain('class="density-element-tabs density-status-tabs"')
const selectors: string[] = []
cssRoot(shared).walkRules((rule) => { selectors.push(...rule.selectors) })
expect(selectors).toContain('.admin-density .density-status-tabs > button.is-active::after')
expect(selectors).toContain('.admin-density .density-status-tabs > button:focus-visible')
const element = '.admin-density .density-element-tabs.density-status-tabs > .el-tabs__header .el-tabs__nav .el-tabs__item'
const rules: string[][] = []
cssRoot(shared).walkRules((rule) => { rules.push(rule.selectors) })
for (const suffix of ['', '::after', ':hover', ':focus-visible', '.is-active', '.is-active::after']) {
expect(rules.some((rule) => rule.includes('.admin-density .density-status-tabs > button' + suffix) && rule.includes(element + suffix))).toBe(true)
}
})
it('keeps dashboard visualizations outside detail-field table styling', () => {
const dashboard = read('modules/dashboard/pages/DashboardView.vue')
expect(dashboard).toContain('class="dashboard-metrics"')
@@ -248,11 +279,9 @@ describe('approved Admin density ownership', () => {
expect(read('modules/overseas-warehouse/pages/LastMileOrderDetailView.vue')).toContain('density-detail-overview')
})
it('covers all eleven overseas warehouse menus, details and both return inventory modes', () => {
const navigation = read('core/navigation/adminNavigation.ts')
const section = navigation.slice(navigation.indexOf("key: 'overseas-inventory'"), navigation.indexOf("key: 'customer-service'"))
for (const path of ['last-mile-orders', 'inbound-orders', 'locations', 'dispatches', 'outbounds', 'delivery-orders', 'relabel-orders', 'pallets', 'inventory', 'return-inventory', 'return-cartons']) expect(section).toContain("path: '/overseas-warehouse/" + path + "'")
expect([...section.matchAll(/path: '/g)]).toHaveLength(11)
it('covers the approved overseas pages across the latest menu groups, details and both return inventory modes', () => {
const paths = getNavigationLeaves(adminNavigation).map(node => node.path)
expect(paths).toEqual(expect.arrayContaining(['last-mile-orders', 'inbound-orders', 'locations', 'dispatches', 'outbounds', 'delivery-orders', 'relabel-orders', 'pallets', 'inventory', 'return-inventory', 'return-cartons'].map(path => '/overseas-warehouse/' + path)))
const routes = read('modules/overseas-warehouse/routes.ts')
for (const mode of ['inventory', 'cartons']) expect(routes).toContain("mode: '" + mode + "'")
for (const file of overseasConsumers) {
@@ -377,13 +406,10 @@ describe('approved Admin density ownership', () => {
}
})
it('covers all eight domestic menu entries and loads density CSS on direct entry', () => {
const navigation = read('core/navigation/adminNavigation.ts')
const domestic = navigation.slice(navigation.indexOf("key: 'domestic-warehouse'"), navigation.indexOf("key: 'overseas-delivery'"))
expect([...domestic.matchAll(/path: '/g)]).toHaveLength(domesticPages.length)
it('covers approved domestic pages across the latest menu groups and loads density CSS on direct entry', () => {
const paths = getNavigationLeaves(adminNavigation).map(node => node.path)
expect(paths).toEqual(expect.arrayContaining(domesticPages.map(page => page.path)))
for (const page of domesticPages) {
expect(domestic).toContain(`title: '${page.title}'`)
expect(domestic).toContain(`path: '${page.path}'`)
if (page.entry) expect(read(`modules/${page.entry}`)).toContain(`<${page.component} mode="${page.mode}"`)
}
for (const file of densityPages) expect(read(`modules/${file}`), `${file}: direct entry CSS`).toContain('@/styles/adminDensity.css')