Skip to content

Frontend Structure

The React and Vue templates use the same feature split: APIs and types are split by business domain, pages live under pages/, and shared technical code lives under components/ and lib/ (stores/, composables/ for Vue).

The frontend HTTP layer is a lightweight native fetch wrapper, src/api/client.ts, and does not use axios.

  • The base URL is fixed at /api; during development Vite proxies it to localhost:8088.
  • Automatically attaches Authorization: Bearer <token>.
  • On a 401 response, clears the login state and redirects to the login page.
  • Uniformly parses { code, message, data } and throws an error message when code !== 0.
  • Supports binary downloads, FormData uploads, and custom status headers for export, import, and job polling.

The calls for each business domain are split under src/api/: auth.ts, user.ts, role.ts, permission.ts, menu.ts, system.ts, dashboard.ts, ai-model.ts, audit-log.ts, data-management.ts.

// src/api/client.ts (illustrative)
const BASE_URL = '/api';
export async function request<T>(path: string, options?: RequestInit): Promise<T> {
const res = await fetch(`${BASE_URL}${path}`, {
...options,
headers: { 'Content-Type': 'application/json', ...options?.headers },
});
// 401 → clear token and redirect to /login
// code !== 0 → throw new Error(message)
return body.data;
}
  • Routing uses react-router (React) or vue-router (Vue).
  • ProtectedRoute (a route guard in Vue) checks only whether the user is logged in; if not, it redirects to the login page.
  • The sidebar is loaded dynamically from GET /api/menus/navigation; the backend filters by current-user permissions and omits groups with no visible items.
  • Menu order, groups, routes, and icons come from menu_groups / menu_items instead of hard-coded data in AppSidebar.
  • The real access control is in the backend: hiding menus on the frontend is only a UX improvement, and the backend still rejects unauthorized requests by permission point.

Security tip: do not rely solely on frontend routing for permission decisions; the server is authoritative. See Permission System.

React Vue
Auth state lib/auth-context.tsx stores/auth.ts (Pinia)
Site config lib/site-config.tsx stores/site-config.ts
Theme components/theme-provider.tsx stores/theme.ts

Site config comes from the public endpoint GET /api/public/config and is used on the login page to display the site name and maintenance message, and to determine whether registration is open.

  • The admin UI is designed for computers and tablets; accessing it from a phone shows a “Please switch devices” (请更换设备) prompt component (UnsupportedViewport).
  • Light/dark theme switching is provided (ThemeToggle), and the preference is persisted.
  • The React version integrates shadcn/ui, and the Vue version uses DaisyUI; shared components such as forms, tables, pagination, and delete confirmation live under components/shared/.

The React version includes PWA support, so the build output can be installed as a desktop/mobile app. Icons use lucide-react.

Taking React as an example:

  1. Create a new page component under src/pages/.
  2. Register the route in router.tsx.
  3. Define a permission code, then create or synchronize the menu item with its route and icon in menu management.
  4. Add the domain’s calls and types under src/api/ and src/types/.

For Vue, modify the corresponding pages/, router/index.ts, api/, and types/; menu configuration is still performed in the admin panel.