adminHttp.ts
3.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
import { apiUsesSameOrigin, getApiBase } from "@/config/api";
const ADMIN_TOKEN_KEY = "admin_api_token";
export function getAdminToken(): string {
try {
return (uni.getStorageSync(ADMIN_TOKEN_KEY) as string) || "";
} catch {
return "";
}
}
export function setAdminToken(token: string): void {
uni.setStorageSync(ADMIN_TOKEN_KEY, token);
}
export function clearAdminToken(): void {
try {
uni.removeStorageSync(ADMIN_TOKEN_KEY);
} catch {
/* ignore */
}
}
function headers(): Record<string, string> {
const t = getAdminToken();
return t ? { Authorization: `Bearer ${t}` } : {};
}
export interface ApiEnvelope<T> {
code: number;
msg: string;
data: T;
}
function toQueryString(query?: Record<string, string>): string {
if (!query) {
return "";
}
const parts: string[] = [];
for (const [k, v] of Object.entries(query)) {
if (v === undefined || v === "") {
continue;
}
parts.push(`${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`);
}
return parts.join("&");
}
export function adminGet<T>(path: string, query?: Record<string, string>): Promise<ApiEnvelope<T>> {
const base = getApiBase();
if (!base && !apiUsesSameOrigin()) {
return Promise.reject(new Error("API 未配置"));
}
let url = `${base}${path}`;
if (query && Object.keys(query).length) {
const q = toQueryString(query);
url += (url.includes("?") ? "&" : "?") + q;
}
return new Promise((resolve, reject) => {
uni.request({
url,
method: "GET",
header: { ...headers() },
success: (res) => {
const body = res.data as ApiEnvelope<T>;
if (!body || typeof body.code !== "number") {
reject(new Error("响应格式错误"));
return;
}
if (body.code === 401) {
clearAdminToken();
}
if (body.code !== 0) {
reject(body);
return;
}
resolve(body);
},
fail: reject,
});
});
}
export function adminPost<T>(path: string, data?: Record<string, unknown>): Promise<ApiEnvelope<T>> {
const base = getApiBase();
if (!base && !apiUsesSameOrigin()) {
return Promise.reject(new Error("API 未配置"));
}
return new Promise((resolve, reject) => {
uni.request({
url: `${base}${path}`,
method: "POST",
header: {
"Content-Type": "application/json",
...headers(),
},
data: data ?? {},
success: (res) => {
const body = res.data as ApiEnvelope<T>;
if (!body || typeof body.code !== "number") {
reject(new Error("响应格式错误"));
return;
}
if (body.code === 401) {
clearAdminToken();
}
if (body.code !== 0) {
reject(body);
return;
}
resolve(body);
},
fail: reject,
});
});
}
export async function adminLogin(username: string, password: string): Promise<void> {
const base = getApiBase();
if (!base && !apiUsesSameOrigin()) {
throw new Error("API 未配置");
}
const res = await new Promise<ApiEnvelope<{ token: string }>>((resolve, reject) => {
uni.request({
url: `${base}/admin/v1/login`,
method: "POST",
header: { "Content-Type": "application/json" },
data: { username, password },
success: (r) => resolve(r.data as ApiEnvelope<{ token: string }>),
fail: reject,
});
});
if (res.code !== 0 || !res.data?.token) {
throw new Error(res.msg || "登录失败");
}
setAdminToken(res.data.token);
}