更新+mock部分

This commit is contained in:
2026-04-16 18:12:09 +08:00
parent d5c06eca28
commit adadb3bf1d
40 changed files with 884 additions and 174 deletions

View File

@@ -10,5 +10,11 @@ interface LoginInput {
}
export async function login(input: LoginInput) {
return http.post<ApiResponse<{ accessToken: string; refreshToken: string }>>("/auth/login", input);
return http.post<ApiResponse<{ accessToken: string; refreshToken: string }>>("/auth/tokens", input);
}
export async function refreshToken(refreshToken: string) {
return http.post<ApiResponse<{ accessToken: string; refreshToken: string }>>("/auth/tokens/refresh", {
refreshToken
});
}

View File

@@ -1,13 +1,55 @@
import type { ApiResponse } from "../types/api";
import {
getUpmsAreasRemote,
getUpmsCurrentUserRemote,
getUpmsDepartmentsRemote,
getUpmsRoutesRemote,
getUpmsTenantsRemote
} from "../remote/upmsRemote";
import type { CurrentRouteUser, RouteNode } from "../types/route";
import { http } from "../utils/http";
import type { UpmsAreaNode, UpmsDeptNode, UpmsTenantNode } from "../types/upms";
function normalizeAreaNodes(nodes: UpmsAreaNode[]): UpmsAreaNode[] {
return nodes.map((node) => ({
...node,
children: normalizeAreaNodes(node.children ?? [])
}));
}
function normalizeTenantNodes(nodes: UpmsTenantNode[]): UpmsTenantNode[] {
return nodes.map((node) => ({
...node,
children: normalizeTenantNodes(node.children ?? [])
}));
}
function normalizeDeptNodes(nodes: UpmsDeptNode[]): UpmsDeptNode[] {
return nodes.map((node) => ({
...node,
children: normalizeDeptNodes(node.children ?? [])
}));
}
export async function fetchDynamicRoutes(): Promise<RouteNode[]> {
const response = await http.get<ApiResponse<RouteNode[]>>("/upms/routes");
const response = await getUpmsRoutesRemote();
return response.data as RouteNode[];
}
export async function fetchCurrentUser(): Promise<CurrentRouteUser> {
const response = await http.get<ApiResponse<CurrentRouteUser>>("/upms/current-user");
const response = await getUpmsCurrentUserRemote();
return response.data as CurrentRouteUser;
}
export async function fetchAreas(): Promise<UpmsAreaNode[]> {
const response = await getUpmsAreasRemote();
return normalizeAreaNodes(response.data as UpmsAreaNode[]);
}
export async function fetchTenants(): Promise<UpmsTenantNode[]> {
const response = await getUpmsTenantsRemote();
return normalizeTenantNodes(response.data as UpmsTenantNode[]);
}
export async function fetchDepartments(): Promise<UpmsDeptNode[]> {
const response = await getUpmsDepartmentsRemote();
return normalizeDeptNodes(response.data as UpmsDeptNode[]);
}

View File

@@ -0,0 +1,23 @@
import type { ApiResponse } from "../types/api";
import type { UpmsAreaNode, UpmsCurrentUser, UpmsDeptNode, UpmsRouteNode, UpmsTenantNode } from "../types/upms";
import { http } from "../utils/http";
export function getUpmsRoutesRemote() {
return http.get<ApiResponse<UpmsRouteNode[]>>("/upms/routes");
}
export function getUpmsCurrentUserRemote() {
return http.get<ApiResponse<UpmsCurrentUser>>("/upms/users/current");
}
export function getUpmsAreasRemote() {
return http.get<ApiResponse<UpmsAreaNode[]>>("/upms/areas");
}
export function getUpmsTenantsRemote() {
return http.get<ApiResponse<UpmsTenantNode[]>>("/upms/tenants");
}
export function getUpmsDepartmentsRemote() {
return http.get<ApiResponse<UpmsDeptNode[]>>("/upms/departments");
}

View File

@@ -1,27 +1,11 @@
export type LayoutType = "DEFAULT" | "SIDEBAR";
import type {
UpmsCurrentUser,
UpmsLayoutType,
UpmsRouteMeta,
UpmsRouteNode
} from "./upms";
export interface RouteMeta {
title: string;
icon?: string;
permissionCodes?: string[];
hidden?: boolean;
}
export interface RouteNode {
id: string;
path: string;
name: string;
component: string;
layout: LayoutType;
meta: RouteMeta;
children: RouteNode[];
}
export interface CurrentRouteUser {
userId: string;
username: string;
displayName: string;
tenantId: string;
deptId: string;
permissionCodes: string[];
}
export type LayoutType = UpmsLayoutType;
export type RouteMeta = UpmsRouteMeta;
export type RouteNode = UpmsRouteNode;
export type CurrentRouteUser = UpmsCurrentUser;

View File

@@ -0,0 +1,60 @@
export type UpmsLayoutType = "DEFAULT" | "SIDEBAR";
export interface UpmsRouteMeta {
title: string;
icon?: string;
permissionCodes?: string[];
hidden?: boolean;
}
export interface UpmsRouteNode {
id: string;
path: string;
name: string;
component: string;
layout: UpmsLayoutType;
meta: UpmsRouteMeta;
children: UpmsRouteNode[];
}
export interface UpmsCurrentUser {
userId: string;
username: string;
displayName: string;
adcode: string;
tenantId: string;
tenantPath: string;
deptId: string;
deptPath: string;
permissionCodes: string[];
}
export interface UpmsAreaNode {
areaCode: string;
parentCode: string;
areaName: string;
areaLevel: string;
children: UpmsAreaNode[];
}
export interface UpmsTenantNode {
tenantId: string;
parentTenantId: string | null;
tenantName: string;
tenantType: string;
adcode: string;
tenantPath: string;
children: UpmsTenantNode[];
}
export interface UpmsDeptNode {
deptId: string;
parentDeptId: string | null;
deptName: string;
deptType: string;
tenantId: string;
adcode: string;
tenantPath: string;
deptPath: string;
children: UpmsDeptNode[];
}

View File

@@ -1,3 +1,4 @@
import type { ApiResponse } from "../types/api";
import { getAccessToken } from "./storage";
const BASE_URL = import.meta.env.VITE_API_BASE_URL ?? "/api";
@@ -12,6 +13,14 @@ interface RequestOptions {
timeout?: number;
}
function isApiResponse(payload: unknown): payload is ApiResponse<unknown> {
if (typeof payload !== "object" || payload === null) {
return false;
}
return "code" in payload && "message" in payload && "data" in payload;
}
function buildUrl(path: string) {
if (/^https?:\/\//.test(path)) {
return path;
@@ -57,6 +66,9 @@ async function request<T>(path: string, options: RequestOptions = {}): Promise<T
: `Request failed with status ${response.status}`;
throw new Error(message);
}
if (isApiResponse(payload) && payload.code !== 0) {
throw new Error(payload.message || `Business request failed with code ${payload.code}`);
}
return payload as T;
} finally {