feat: 登录持久化修复 + 左下角账号区 + 管理页面(管理员/邀请码)
This commit is contained in:
+34
-9
@@ -5,6 +5,7 @@ import type {
|
||||
} from './types';
|
||||
|
||||
const isTauri = typeof window !== 'undefined' && '__TAURI_INTERNALS__' in window;
|
||||
export function isTauriRef() { return isTauri; }
|
||||
|
||||
const TOKEN_KEY = 'fp-token';
|
||||
export function getToken() { return localStorage.getItem(TOKEN_KEY); }
|
||||
@@ -14,10 +15,10 @@ export const isLocalMode = () => isTauri || !getToken();
|
||||
|
||||
export interface ServerSession { token: string; user_id: string; device_id: string; device_name: string; }
|
||||
|
||||
export async function serverLogin(username: string, password: string): Promise<ServerSession> {
|
||||
const res = await fetch('/auth/login', {
|
||||
export async function serverLogin(username: string, password: string, baseUrl = ''): Promise<ServerSession> {
|
||||
const res = await fetch(baseUrl + '/auth/login', {
|
||||
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ username, password, device_name: 'Web 浏览器' })
|
||||
body: JSON.stringify({ username, password, device_name: isTauri ? '桌面应用' : 'Web 浏览器' })
|
||||
});
|
||||
const json = await res.json();
|
||||
if (!json.ok) throw new Error(json.error || '登录失败');
|
||||
@@ -25,10 +26,10 @@ export async function serverLogin(username: string, password: string): Promise<S
|
||||
return json.data;
|
||||
}
|
||||
|
||||
export async function serverRegister(username: string, password: string, invite_code: string): Promise<ServerSession> {
|
||||
const res = await fetch('/auth/register', {
|
||||
export async function serverRegister(username: string, password: string, invite_code: string, baseUrl = ''): Promise<ServerSession> {
|
||||
const res = await fetch(baseUrl + '/auth/register', {
|
||||
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ username, password, invite_code, device_name: 'Web 浏览器' })
|
||||
body: JSON.stringify({ username, password, invite_code, device_name: isTauri ? '桌面应用' : 'Web 浏览器' })
|
||||
});
|
||||
const json = await res.json();
|
||||
if (!json.ok) throw new Error(json.error || '注册失败');
|
||||
@@ -36,9 +37,9 @@ export async function serverRegister(username: string, password: string, invite_
|
||||
return json.data;
|
||||
}
|
||||
|
||||
export interface MeInfo { user_id: string; username: string; device_id: string; }
|
||||
export async function serverMe(): Promise<MeInfo> {
|
||||
const res = await fetch('/auth/me', { headers: { Authorization: 'Bearer ' + getToken() } });
|
||||
export interface MeInfo { user_id: string; username: string; is_admin?: boolean; device_id: string; }
|
||||
export async function serverMe(baseUrl = ''): Promise<MeInfo> {
|
||||
const res = await fetch(baseUrl + '/auth/me', { headers: { Authorization: 'Bearer ' + getToken() } });
|
||||
const json = await res.json();
|
||||
if (!json.ok) throw new Error(json.error || '会话失效');
|
||||
return json.data;
|
||||
@@ -125,3 +126,27 @@ export const viewList = () => call<{ items: SavedView[] }>('view_list');
|
||||
export const viewUpsert = (p: { id?: number; name: string; filter: Record<string, unknown>; sort?: Record<string, unknown>; is_default?: boolean }) =>
|
||||
call<{ item: SavedView }>('view_upsert', p);
|
||||
export const viewDelete = (id: number) => call<{ ok: true }>('view_delete', { id });
|
||||
|
||||
// ---- 管理端(is_admin) ----
|
||||
export async function adminListInvites(baseUrl = '') {
|
||||
const res = await fetch(baseUrl + '/admin/invites', { headers: { Authorization: 'Bearer ' + getToken() } });
|
||||
return res.json();
|
||||
}
|
||||
export async function adminCreateInvites(count: number, baseUrl = '') {
|
||||
const res = await fetch(baseUrl + '/admin/invites/generate', {
|
||||
method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: 'Bearer ' + getToken() },
|
||||
body: JSON.stringify({ count })
|
||||
});
|
||||
return res.json();
|
||||
}
|
||||
export async function adminRevokeInvite(id: number, baseUrl = '') {
|
||||
const res = await fetch(baseUrl + '/admin/invites/revoke', {
|
||||
method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: 'Bearer ' + getToken() },
|
||||
body: JSON.stringify({ id })
|
||||
});
|
||||
return res.json();
|
||||
}
|
||||
export async function adminListUsers(baseUrl = '') {
|
||||
const res = await fetch(baseUrl + '/admin/users', { headers: { Authorization: 'Bearer ' + getToken() } });
|
||||
return res.json();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user