完善 H5 鉴权与登录流程

This commit is contained in:
inman
2026-07-24 14:55:13 +08:00
parent 160e82197e
commit c820a56e79
18 changed files with 1130 additions and 82 deletions

View File

@@ -153,6 +153,27 @@ export type PublicSiteConfig = {
searchPage?: PublicSearchPageConfig;
};
export type PublicUserProfile = {
id: string;
nickname?: string | null;
avatarUrl?: string | null;
phoneMasked: string | null;
hasPhone: boolean;
status: "active" | "disabled" | "anonymized";
source: string;
firstSeenAt: string;
lastLoginAt: string;
createdAt: string;
leads?: number;
favorites?: number;
history?: number;
};
export type PublicActivity = {
favorites: Array<PublicProduct & { savedAt: string }>;
history: Array<PublicProduct & { viewedAt: string; viewCount: number }>;
};
export type PublicLeadPayload = {
destination?: string;
phone: string;
@@ -175,11 +196,12 @@ export type PublicLeadPayload = {
async function request<T>(path: string, init?: RequestInit) {
const response = await fetch(`${API_BASE}${path}`, {
...init,
credentials: "include",
headers: {
"content-type": "application/json",
...init?.headers,
},
...init,
});
if (!response.ok) {
@@ -190,6 +212,47 @@ async function request<T>(path: string, init?: RequestInit) {
return response.json() as Promise<T>;
}
export async function fetchCurrentUser() {
return request<PublicUserProfile>("/api/public/users/me");
}
export async function exchangeH5Ticket(ticket: string) {
return request<{ user: PublicUserProfile }>("/api/public/auth/h5-exchange", {
method: "POST",
body: JSON.stringify({ ticket }),
});
}
export async function syncPublicActivity(favoriteProductIds: string[], historyProductIds: string[]) {
return request<PublicActivity>("/api/public/users/me/activity/sync", {
method: "POST",
body: JSON.stringify({ favoriteProductIds, historyProductIds }),
});
}
export async function savePublicFavorite(productId: string, saved: boolean) {
const path = "/api/public/users/me/favorites/" + encodeURIComponent(productId);
return request<{ saved: boolean }>(path, { method: saved ? "POST" : "DELETE" });
}
export async function recordPublicHistory(productId: string) {
return request<{ saved: boolean }>("/api/public/users/me/history", {
method: "POST",
body: JSON.stringify({ productId }),
});
}
export async function clearPublicHistory() {
return request<{ cleared: boolean }>("/api/public/users/me/history", { method: "DELETE" });
}
export async function logoutPublicSession() {
return request<{ loggedOut: boolean }>("/api/public/auth/logout", {
method: "POST",
body: JSON.stringify({}),
});
}
export async function fetchPublicContent() {
const [siteConfig, products] = await Promise.all([
request<PublicSiteConfig>("/api/public/site-config"),