mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-10-06 23:56:37 +08:00
fix(frontend): keep browser API on same-origin rewrites in dev
Document that NEXT_PUBLIC_WAVELET_BACKEND_URL must stay unset for local next dev so axios hits /api/* and Next rewrites proxy to the backend.
This commit is contained in:
@@ -16,6 +16,7 @@ import type {
|
||||
} from '@/lib/services/admin';
|
||||
import services from '@/lib/services';
|
||||
import { handleContextError } from '@/lib/utils/error-handling';
|
||||
import { useTranslations } from 'next-intl';
|
||||
|
||||
/** Admin 上下文状态接口 */
|
||||
export interface AdminContextState {
|
||||
@@ -45,6 +46,7 @@ const AdminContext = createContext<AdminContextState | null>(null);
|
||||
*/
|
||||
export function AdminProvider({ children }: { children: React.ReactNode }) {
|
||||
const queryClient = useQueryClient();
|
||||
const t = useTranslations('contexts.admin');
|
||||
const [systemConfigs, setSystemConfigs] = useState<SystemConfig[]>([]);
|
||||
const [systemConfigsLoading, setSystemConfigsLoading] = useState(false);
|
||||
const [systemConfigsError, setSystemConfigsError] = useState<Error | null>(
|
||||
@@ -78,14 +80,14 @@ export function AdminProvider({ children }: { children: React.ReactNode }) {
|
||||
return;
|
||||
}
|
||||
|
||||
const errorObject = handleContextError(error, '加载系统配置失败', {
|
||||
const errorObject = handleContextError(error, t('loadConfigFailed'), {
|
||||
logError: true,
|
||||
});
|
||||
setSystemConfigsError(errorObject);
|
||||
setSystemConfigsLoading(false);
|
||||
}
|
||||
},
|
||||
[],
|
||||
[t],
|
||||
);
|
||||
|
||||
/** 更新系统配置 */
|
||||
@@ -96,11 +98,11 @@ export function AdminProvider({ children }: { children: React.ReactNode }) {
|
||||
await queryClient.invalidateQueries({ queryKey: ['public-config'] });
|
||||
await refetchSystemConfigs(lastConfigTypeRef.current);
|
||||
} catch (error) {
|
||||
handleContextError(error, '更新系统配置失败');
|
||||
handleContextError(error, t('updateConfigFailed'));
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
[queryClient, refetchSystemConfigs],
|
||||
[queryClient, refetchSystemConfigs, t],
|
||||
);
|
||||
|
||||
const value: AdminContextState = {
|
||||
|
||||
@@ -17,6 +17,7 @@ import type {
|
||||
UpdateUserRequest,
|
||||
} from '@/lib/services/admin';
|
||||
import services from '@/lib/services';
|
||||
import { useTranslations } from 'next-intl';
|
||||
|
||||
/** 用户列表查询参数 */
|
||||
export interface UserQueryParams {
|
||||
@@ -69,6 +70,7 @@ export function AdminUsersProvider({
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
const t = useTranslations('contexts.adminUsers');
|
||||
// State
|
||||
const [users, setUsers] = useState<AdminUser[]>([]);
|
||||
const [total, setTotal] = useState(0);
|
||||
@@ -237,7 +239,10 @@ export function AdminUsersProvider({
|
||||
is_active: !user.is_active,
|
||||
});
|
||||
toast.success(
|
||||
`已${!user.is_active ? '启用' : '禁用'}用户 ${user.username}`,
|
||||
t('userStatusChanged', {
|
||||
action: !user.is_active ? t('enabled') : t('disabled'),
|
||||
username: user.username,
|
||||
}),
|
||||
);
|
||||
} catch {
|
||||
// Revert on error
|
||||
@@ -246,7 +251,7 @@ export function AdminUsersProvider({
|
||||
u.id === user.id ? { ...u, is_active: originalStatus } : u,
|
||||
),
|
||||
);
|
||||
toast.error('更新状态失败');
|
||||
toast.error(t('updateStatusFailed'));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -261,10 +266,10 @@ export function AdminUsersProvider({
|
||||
setTotal((prev) => prev + 1);
|
||||
// Clear cache because data changed
|
||||
cacheRef.current = {};
|
||||
toast.success(`已成功创建用户 ${newUser.username}`);
|
||||
toast.success(t('userCreated', { username: newUser.username }));
|
||||
return newUser;
|
||||
} catch (err) {
|
||||
toast.error(err instanceof Error ? err.message : '创建用户失败');
|
||||
toast.error(err instanceof Error ? err.message : t('createUserFailed'));
|
||||
throw err;
|
||||
}
|
||||
};
|
||||
@@ -275,9 +280,9 @@ export function AdminUsersProvider({
|
||||
setUsers((prev) => prev.filter((u) => u.id !== user.id));
|
||||
setTotal((prev) => Math.max(0, prev - 1));
|
||||
cacheRef.current = {};
|
||||
toast.success(`已删除用户 ${user.username}`);
|
||||
toast.success(t('userDeleted', { username: user.username }));
|
||||
} catch (err) {
|
||||
toast.error(err instanceof Error ? err.message : '删除用户失败');
|
||||
toast.error(err instanceof Error ? err.message : t('deleteUserFailed'));
|
||||
throw err;
|
||||
}
|
||||
};
|
||||
@@ -287,9 +292,9 @@ export function AdminUsersProvider({
|
||||
await services.adminUser.updateUser(id, req);
|
||||
setUsers((prev) => prev.map((u) => (u.id === id ? { ...u, ...req } : u)));
|
||||
cacheRef.current = {};
|
||||
toast.success('更新用户信息成功');
|
||||
toast.success(t('updateUserSuccess'));
|
||||
} catch (err) {
|
||||
toast.error(err instanceof Error ? err.message : '更新用户信息失败');
|
||||
toast.error(err instanceof Error ? err.message : t('updateUserFailed'));
|
||||
throw err;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
|
||||
import { AuthService } from '@/lib/services/auth';
|
||||
import { User } from '@/lib/services/auth/types';
|
||||
import { useTranslations } from 'next-intl';
|
||||
|
||||
/** 用户状态接口 */
|
||||
interface UserState {
|
||||
@@ -52,6 +53,7 @@ export function UserProvider({ children }: { children: ReactNode }) {
|
||||
});
|
||||
|
||||
const isMountedRef = useRef(true);
|
||||
const t = useTranslations('contexts.user');
|
||||
|
||||
/** 获取用户信息 */
|
||||
const fetchUser = useCallback(async () => {
|
||||
@@ -68,10 +70,10 @@ export function UserProvider({ children }: { children: ReactNode }) {
|
||||
setState({
|
||||
user: null,
|
||||
loading: false,
|
||||
error: error instanceof Error ? error.message : '获取用户信息失败',
|
||||
error: error instanceof Error ? error.message : t('getUserInfoFailed'),
|
||||
});
|
||||
}
|
||||
}, []);
|
||||
}, [t]);
|
||||
|
||||
/** 重新获取用户信息 */
|
||||
const refetch = useCallback(async () => {
|
||||
@@ -97,14 +99,15 @@ export function UserProvider({ children }: { children: ReactNode }) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
const errorMessage = error instanceof Error ? error.message : '登出失败';
|
||||
const errorMessage =
|
||||
error instanceof Error ? error.message : t('logoutFailed');
|
||||
setState((prev) => ({
|
||||
...prev,
|
||||
error: errorMessage,
|
||||
}));
|
||||
throw new Error(errorMessage);
|
||||
}
|
||||
}, []);
|
||||
}, [t]);
|
||||
|
||||
/** 组件挂载时获取用户信息(登录/注册页跳过,避免无意义请求) */
|
||||
useEffect(() => {
|
||||
|
||||
Reference in New Issue
Block a user