重构前端:拆分路由模块

This commit is contained in:
yml
2026-05-25 01:32:21 +08:00
parent c5f99608d8
commit eafa6f96b2
6 changed files with 279 additions and 251 deletions
+45
View File
@@ -0,0 +1,45 @@
import type { RouteRecordRaw } from 'vue-router'
export const accountRoutes: RouteRecordRaw[] = [
{
path: '/login',
name: 'login',
component: () => import('@/views/account/LoginView.vue'),
},
{
path: '/orders/create',
name: 'order-create',
component: () => import('@/views/account/OrderCreateView.vue'),
meta: { requiresAuth: true },
},
{
path: '/orders',
name: 'orders',
component: () => import('@/views/account/OrdersView.vue'),
meta: { requiresAuth: true },
},
{
path: '/orders/:id',
name: 'order-detail',
component: () => import('@/views/account/OrderDetailView.vue'),
meta: { requiresAuth: true },
},
{
path: '/wallet',
name: 'wallet',
component: () => import('@/views/account/WalletView.vue'),
meta: { requiresAuth: true },
},
{
path: '/notifications',
name: 'notifications',
component: () => import('@/views/account/NotificationsView.vue'),
meta: { requiresAuth: true },
},
{
path: '/realname',
name: 'realname',
component: () => import('@/views/account/RealnameView.vue'),
meta: { requiresAuth: true },
},
]
+79
View File
@@ -0,0 +1,79 @@
import type { RouteRecordRaw } from 'vue-router'
const adminMeta = { layout: 'admin', requiresAdmin: true }
export const adminRoutes: RouteRecordRaw[] = [
{ path: '/admin', redirect: '/admin/dashboard' },
{
path: '/admin/login',
name: 'admin-login',
component: () => import('@/views/admin/AdminLoginView.vue'),
meta: { layout: 'blank' },
},
{
path: '/admin/dashboard',
name: 'admin-dashboard',
component: () => import('@/views/admin/AdminDashboardView.vue'),
meta: adminMeta,
},
{
path: '/admin/users',
name: 'admin-users',
component: () => import('@/views/admin/AdminUsersView.vue'),
meta: adminMeta,
},
{
path: '/admin/orders',
name: 'admin-orders',
component: () => import('@/views/admin/AdminOrdersView.vue'),
meta: adminMeta,
},
{
path: '/admin/orders/:id',
name: 'admin-order-detail',
component: () => import('@/views/admin/AdminOrderDetailView.vue'),
meta: adminMeta,
},
{
path: '/admin/listings',
name: 'admin-listings',
component: () => import('@/views/admin/AdminListingsView.vue'),
meta: adminMeta,
},
{
path: '/admin/listings/:id',
name: 'admin-listing-detail',
component: () => import('@/views/admin/AdminListingDetailView.vue'),
meta: adminMeta,
},
{
path: '/admin/listings/review',
name: 'admin-listing-review',
component: () => import('@/views/admin/AdminListingReviewView.vue'),
meta: adminMeta,
},
{
path: '/admin/disputes',
name: 'admin-disputes',
component: () => import('@/views/admin/AdminDisputesView.vue'),
meta: adminMeta,
},
{
path: '/admin/wallet-ledger',
name: 'admin-wallet-ledger',
component: () => import('@/views/admin/AdminWalletLedgerView.vue'),
meta: adminMeta,
},
{
path: '/admin/system-configs',
name: 'admin-system-configs',
component: () => import('@/views/admin/AdminSystemConfigsView.vue'),
meta: adminMeta,
},
{
path: '/admin/audit-logs',
name: 'admin-audit-logs',
component: () => import('@/views/admin/AdminAuditLogsView.vue'),
meta: adminMeta,
},
]
+38 -251
View File
@@ -1,289 +1,76 @@
import { createRouter, createWebHistory } from "vue-router";
import { createRouter, createWebHistory } from 'vue-router'
import { useSessionStore } from "@/stores/session";
import { isMobileHost, toMobilePath } from "./mobileHost";
import { useSessionStore } from '@/stores/session'
import { accountRoutes } from './accountRoutes'
import { adminRoutes } from './adminRoutes'
import { isMobileHost, toMobilePath } from './mobileHost'
import { mobileRoutes } from './mobileRoutes'
import { publicRoutes } from './publicRoutes'
import { sellerRoutes } from './sellerRoutes'
const router = createRouter({
history: createWebHistory(),
routes: [
{ path: "/admin", redirect: "/admin/dashboard" },
{
path: "/m",
name: "mobile-home",
component: () => import("@/views/mobile/MobileHomeView.vue"),
meta: { layout: "blank" },
},
{
path: "/m/listings",
name: "mobile-listings",
component: () => import("@/views/mobile/MobileHomeView.vue"),
meta: { layout: "blank" },
},
{
path: "/m/listings/:id",
name: "mobile-listing-detail",
component: () => import("@/views/mobile/MobileListingDetailView.vue"),
meta: { layout: "blank" },
},
{
path: "/m/login",
name: "mobile-login",
component: () => import("@/views/mobile/MobileLoginView.vue"),
meta: { layout: "blank" },
},
{
path: "/m/register",
name: "mobile-register",
component: () => import("@/views/mobile/MobileRegisterView.vue"),
meta: { layout: "blank" },
},
{
path: "/m/messages",
name: "mobile-messages",
component: () => import("@/views/mobile/MobileMessagesView.vue"),
meta: { layout: "blank", requiresAuth: true },
},
{
path: "/m/realname",
name: "mobile-realname",
component: () => import("@/views/mobile/MobileRealnameView.vue"),
meta: { layout: "blank", requiresAuth: true },
},
{
path: "/m/profile",
name: "mobile-profile",
component: () => import("@/views/mobile/MobileProfileView.vue"),
meta: { layout: "blank", requiresAuth: true },
},
{
path: "/m/orders",
name: "mobile-orders",
component: () => import("@/views/mobile/MobileOrdersView.vue"),
meta: { layout: "blank", requiresAuth: true },
},
{
path: "/m/orders/:id",
name: "mobile-order-detail",
component: () => import("@/views/account/OrderDetailView.vue"),
meta: { layout: "blank", requiresAuth: true },
},
{
path: "/m/seller/listings/create",
name: "mobile-seller-listing-create",
component: () =>
import("@/views/mobile/MobileSellerListingCreateView.vue"),
meta: { layout: "blank", requiresAuth: true, requiresRealname: true },
},
{
path: "/",
name: "home",
component: () => import("@/views/public/HomeView.vue"),
},
{
path: "/login",
name: "login",
component: () => import("@/views/account/LoginView.vue"),
},
{
path: "/listings",
name: "listings",
component: () => import("@/views/public/ListingsView.vue"),
},
{
path: "/listings/:id",
name: "listing-detail",
component: () => import("@/views/public/ListingDetailView.vue"),
},
{
path: "/orders/create",
name: "order-create",
component: () => import("@/views/account/OrderCreateView.vue"),
meta: { requiresAuth: true },
},
{
path: "/orders",
name: "orders",
component: () => import("@/views/account/OrdersView.vue"),
meta: { requiresAuth: true },
},
{
path: "/orders/:id",
name: "order-detail",
component: () => import("@/views/account/OrderDetailView.vue"),
meta: { requiresAuth: true },
},
{
path: "/wallet",
name: "wallet",
component: () => import("@/views/account/WalletView.vue"),
meta: { requiresAuth: true },
},
{
path: "/notifications",
name: "notifications",
component: () => import("@/views/account/NotificationsView.vue"),
meta: { requiresAuth: true },
},
{
path: "/realname",
name: "realname",
component: () => import("@/views/account/RealnameView.vue"),
meta: { requiresAuth: true },
},
{
path: "/seller/listings",
name: "seller-listings",
component: () => import("@/views/seller/SellerListingsView.vue"),
meta: { requiresAuth: true },
},
{
path: "/seller/listings/create",
name: "seller-listing-create",
component: () => import("@/views/seller/SellerListingCreateView.vue"),
meta: { requiresAuth: true, requiresRealname: true },
},
{
path: "/seller/handoffs",
name: "seller-handoffs",
component: () => import("@/views/seller/SellerHandoffsView.vue"),
meta: { requiresAuth: true },
},
{
path: "/seller/earnings",
name: "seller-earnings",
component: () => import("@/views/seller/SellerEarningsView.vue"),
meta: { requiresAuth: true },
},
{
path: "/admin/login",
name: "admin-login",
component: () => import("@/views/admin/AdminLoginView.vue"),
meta: { layout: "blank" },
},
{
path: "/admin/dashboard",
name: "admin-dashboard",
component: () => import("@/views/admin/AdminDashboardView.vue"),
meta: { layout: "admin", requiresAdmin: true },
},
{
path: "/admin/users",
name: "admin-users",
component: () => import("@/views/admin/AdminUsersView.vue"),
meta: { layout: "admin", requiresAdmin: true },
},
{
path: "/admin/orders",
name: "admin-orders",
component: () => import("@/views/admin/AdminOrdersView.vue"),
meta: { layout: "admin", requiresAdmin: true },
},
{
path: "/admin/orders/:id",
name: "admin-order-detail",
component: () => import("@/views/admin/AdminOrderDetailView.vue"),
meta: { layout: "admin", requiresAdmin: true },
},
{
path: "/admin/listings",
name: "admin-listings",
component: () => import("@/views/admin/AdminListingsView.vue"),
meta: { layout: "admin", requiresAdmin: true },
},
{
path: "/admin/listings/:id",
name: "admin-listing-detail",
component: () => import("@/views/admin/AdminListingDetailView.vue"),
meta: { layout: "admin", requiresAdmin: true },
},
{
path: "/admin/listings/review",
name: "admin-listing-review",
component: () => import("@/views/admin/AdminListingReviewView.vue"),
meta: { layout: "admin", requiresAdmin: true },
},
{
path: "/admin/disputes",
name: "admin-disputes",
component: () => import("@/views/admin/AdminDisputesView.vue"),
meta: { layout: "admin", requiresAdmin: true },
},
{
path: "/admin/wallet-ledger",
name: "admin-wallet-ledger",
component: () => import("@/views/admin/AdminWalletLedgerView.vue"),
meta: { layout: "admin", requiresAdmin: true },
},
{
path: "/admin/system-configs",
name: "admin-system-configs",
component: () => import("@/views/admin/AdminSystemConfigsView.vue"),
meta: { layout: "admin", requiresAdmin: true },
},
{
path: "/admin/audit-logs",
name: "admin-audit-logs",
component: () => import("@/views/admin/AdminAuditLogsView.vue"),
meta: { layout: "admin", requiresAdmin: true },
},
...adminRoutes,
...mobileRoutes,
...publicRoutes,
...accountRoutes,
...sellerRoutes,
],
});
})
router.beforeEach(async (to) => {
if (isMobileHost() && to.path !== toMobilePath(to.path)) {
return { path: toMobilePath(to.path), query: to.query, hash: to.hash };
return { path: toMobilePath(to.path), query: to.query, hash: to.hash }
}
if (to.meta.requiresAuth) {
const session = useSessionStore();
const hasToken = !!localStorage.getItem("access_token");
const session = useSessionStore()
const hasToken = !!localStorage.getItem('access_token')
if (!hasToken) {
const loginPath = to.path.startsWith("/m") ? "/m/login" : "/login";
return { path: loginPath, query: { redirect: to.fullPath } };
const loginPath = to.path.startsWith('/m') ? '/m/login' : '/login'
return { path: loginPath, query: { redirect: to.fullPath } }
}
if (!session.phone) {
try {
await session.loadMe();
await session.loadMe()
} catch {
const loginPath = to.path.startsWith("/m") ? "/m/login" : "/login";
return { path: loginPath, query: { redirect: to.fullPath } };
const loginPath = to.path.startsWith('/m') ? '/m/login' : '/login'
return { path: loginPath, query: { redirect: to.fullPath } }
}
}
}
if (to.meta.requiresRealname) {
const session = useSessionStore();
const loginPath = to.path.startsWith("/m") ? "/m/login" : "/login";
const realnamePath = to.path.startsWith("/m") ? "/m/realname" : "/realname";
const session = useSessionStore()
const loginPath = to.path.startsWith('/m') ? '/m/login' : '/login'
const realnamePath = to.path.startsWith('/m') ? '/m/realname' : '/realname'
if (session.realnameStatus !== "verified") {
if (session.realnameStatus !== 'verified') {
try {
await session.loadMe();
await session.loadMe()
} catch {
if (!localStorage.getItem("access_token")) {
return { path: loginPath, query: { redirect: to.fullPath } };
if (!localStorage.getItem('access_token')) {
return { path: loginPath, query: { redirect: to.fullPath } }
}
}
}
if (session.realnameStatus !== "verified") {
return { path: realnamePath, query: { redirect: to.fullPath } };
if (session.realnameStatus !== 'verified') {
return { path: realnamePath, query: { redirect: to.fullPath } }
}
}
if (
to.path === "/admin/login" &&
localStorage.getItem("admin_access_token")
) {
return "/admin/dashboard";
if (to.path === '/admin/login' && localStorage.getItem('admin_access_token')) {
return '/admin/dashboard'
}
if (to.meta.requiresAdmin) {
const token = localStorage.getItem("admin_access_token");
const token = localStorage.getItem('admin_access_token')
if (!token) {
return "/admin/login";
return '/admin/login'
}
}
return true;
});
return true
})
export default router;
export default router
+70
View File
@@ -0,0 +1,70 @@
import type { RouteRecordRaw } from 'vue-router'
export const mobileRoutes: RouteRecordRaw[] = [
{
path: '/m',
name: 'mobile-home',
component: () => import('@/views/mobile/MobileHomeView.vue'),
meta: { layout: 'blank' },
},
{
path: '/m/listings',
name: 'mobile-listings',
component: () => import('@/views/mobile/MobileHomeView.vue'),
meta: { layout: 'blank' },
},
{
path: '/m/listings/:id',
name: 'mobile-listing-detail',
component: () => import('@/views/mobile/MobileListingDetailView.vue'),
meta: { layout: 'blank' },
},
{
path: '/m/login',
name: 'mobile-login',
component: () => import('@/views/mobile/MobileLoginView.vue'),
meta: { layout: 'blank' },
},
{
path: '/m/register',
name: 'mobile-register',
component: () => import('@/views/mobile/MobileRegisterView.vue'),
meta: { layout: 'blank' },
},
{
path: '/m/messages',
name: 'mobile-messages',
component: () => import('@/views/mobile/MobileMessagesView.vue'),
meta: { layout: 'blank', requiresAuth: true },
},
{
path: '/m/realname',
name: 'mobile-realname',
component: () => import('@/views/mobile/MobileRealnameView.vue'),
meta: { layout: 'blank', requiresAuth: true },
},
{
path: '/m/profile',
name: 'mobile-profile',
component: () => import('@/views/mobile/MobileProfileView.vue'),
meta: { layout: 'blank', requiresAuth: true },
},
{
path: '/m/orders',
name: 'mobile-orders',
component: () => import('@/views/mobile/MobileOrdersView.vue'),
meta: { layout: 'blank', requiresAuth: true },
},
{
path: '/m/orders/:id',
name: 'mobile-order-detail',
component: () => import('@/views/account/OrderDetailView.vue'),
meta: { layout: 'blank', requiresAuth: true },
},
{
path: '/m/seller/listings/create',
name: 'mobile-seller-listing-create',
component: () => import('@/views/mobile/MobileSellerListingCreateView.vue'),
meta: { layout: 'blank', requiresAuth: true, requiresRealname: true },
},
]
+19
View File
@@ -0,0 +1,19 @@
import type { RouteRecordRaw } from 'vue-router'
export const publicRoutes: RouteRecordRaw[] = [
{
path: '/',
name: 'home',
component: () => import('@/views/public/HomeView.vue'),
},
{
path: '/listings',
name: 'listings',
component: () => import('@/views/public/ListingsView.vue'),
},
{
path: '/listings/:id',
name: 'listing-detail',
component: () => import('@/views/public/ListingDetailView.vue'),
},
]
+28
View File
@@ -0,0 +1,28 @@
import type { RouteRecordRaw } from 'vue-router'
export const sellerRoutes: RouteRecordRaw[] = [
{
path: '/seller/listings',
name: 'seller-listings',
component: () => import('@/views/seller/SellerListingsView.vue'),
meta: { requiresAuth: true },
},
{
path: '/seller/listings/create',
name: 'seller-listing-create',
component: () => import('@/views/seller/SellerListingCreateView.vue'),
meta: { requiresAuth: true, requiresRealname: true },
},
{
path: '/seller/handoffs',
name: 'seller-handoffs',
component: () => import('@/views/seller/SellerHandoffsView.vue'),
meta: { requiresAuth: true },
},
{
path: '/seller/earnings',
name: 'seller-earnings',
component: () => import('@/views/seller/SellerEarningsView.vue'),
meta: { requiresAuth: true },
},
]