✨ feat: 完整应用重构 - 优化界面架构与用户体验
主要变更: - 重构应用界面:优化首页、登录、认证流程 - 新增用户档案模块:包含完整的档案管理组件 - 优化路由结构:重新组织页面布局和导航 - 改进API集成:新增活动、内容分类等API模块 - 删除冗余组件:清理不必要的文件和依赖 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
26
lib/api/activities.ts
Normal file
26
lib/api/activities.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import { apiRequest } from './client';
|
||||
|
||||
export interface Activity {
|
||||
id: string;
|
||||
title: string;
|
||||
titleEn: string;
|
||||
desc: string;
|
||||
descEn: string;
|
||||
coverUrl: string;
|
||||
videoUrl: string;
|
||||
link: string;
|
||||
isActive: boolean;
|
||||
sortOrder: number;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
export interface GetActivitiesParams {
|
||||
isActive?: boolean;
|
||||
}
|
||||
|
||||
export async function getActivities(params: GetActivitiesParams = {}): Promise<Activity[]> {
|
||||
return apiRequest<{ data: Activity[] }>(`/api/activities`, {
|
||||
params
|
||||
}).then(res => res.data);
|
||||
}
|
||||
8
lib/api/categories-with-children.ts
Normal file
8
lib/api/categories-with-children.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import { CategoriesWithChildrenResponse } from '../types/template';
|
||||
import { apiClient } from './client';
|
||||
|
||||
export async function categoriesWithChildren(): Promise<CategoriesWithChildrenResponse> {
|
||||
return apiClient<CategoriesWithChildrenResponse>('/api/categories-with-children', {
|
||||
method: 'GET',
|
||||
});
|
||||
}
|
||||
@@ -1,82 +1,73 @@
|
||||
import { fetch, FetchRequestInit } from 'expo/fetch';
|
||||
import { getAuthHeaders, tokenManager } from '../auth/token-manager';
|
||||
import { storage } from '../storage';
|
||||
|
||||
const BASE_URL = 'https://api-test.mixvideo.bowong.cc';
|
||||
|
||||
export interface ApiRequestOptions extends FetchRequestInit {
|
||||
params?: Record<string, string | number | boolean | undefined>;
|
||||
export interface ApiRequestOptions {
|
||||
method?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
|
||||
body?: string;
|
||||
params?: Record<string, any>;
|
||||
headers?: Record<string, string>;
|
||||
requiresAuth?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* 标准API请求函数
|
||||
*/
|
||||
async function getAuthToken(): Promise<string> {
|
||||
return (await storage.getItem(`bestaibest.better-auth.session_token`)) || '';
|
||||
}
|
||||
|
||||
export async function apiRequest<T = any>(
|
||||
endpoint: string,
|
||||
options: ApiRequestOptions = {}
|
||||
): Promise<T> {
|
||||
const { params, requiresAuth = false, ...fetchOptions } = options;
|
||||
const {
|
||||
method = 'GET',
|
||||
body,
|
||||
params,
|
||||
headers = {},
|
||||
requiresAuth = true,
|
||||
} = options;
|
||||
|
||||
let url = `${BASE_URL}${endpoint}`;
|
||||
// 构建 URL
|
||||
const url = new URL(endpoint, BASE_URL);
|
||||
|
||||
// 添加查询参数
|
||||
if (params) {
|
||||
const queryParams = new URLSearchParams();
|
||||
Object.entries(params).forEach(([key, value]) => {
|
||||
if (value !== undefined) {
|
||||
queryParams.append(key, String(value));
|
||||
if (value !== undefined && value !== null) {
|
||||
url.searchParams.append(key, String(value));
|
||||
}
|
||||
});
|
||||
const queryString = queryParams.toString();
|
||||
if (queryString) {
|
||||
url += `?${queryString}`;
|
||||
}
|
||||
}
|
||||
|
||||
const headers: any = {
|
||||
// 准备请求头
|
||||
const requestHeaders: Record<string, string> = {
|
||||
'Content-Type': 'application/json',
|
||||
...fetchOptions.headers,
|
||||
...headers,
|
||||
};
|
||||
|
||||
// 如果需要认证,自动添加认证头
|
||||
// 如果需要认证,添加 Bearer token
|
||||
if (requiresAuth) {
|
||||
const authHeaders = await getAuthHeaders();
|
||||
Object.assign(headers, authHeaders);
|
||||
const token = await getAuthToken();
|
||||
if (token) {
|
||||
requestHeaders['Authorization'] = `Bearer ${token}`;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch(url, {
|
||||
...fetchOptions,
|
||||
headers,
|
||||
});
|
||||
// 发起请求
|
||||
const response = await fetch(url.toString(), {
|
||||
method,
|
||||
headers: requestHeaders,
|
||||
body: method !== 'GET' ? body : undefined,
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const errorText = await response.text();
|
||||
const errorMessage = `API Error: ${response.status} - ${errorText}`;
|
||||
|
||||
// 如果是401错误且需要认证,尝试自动处理
|
||||
if (response.status === 401 && requiresAuth) {
|
||||
console.log('检测到认证失败,清除token...');
|
||||
await tokenManager.clearToken();
|
||||
}
|
||||
|
||||
throw new Error(errorMessage);
|
||||
}
|
||||
|
||||
const contentType = response.headers.get('content-type');
|
||||
if (contentType && contentType.includes('application/json')) {
|
||||
return response.json();
|
||||
}
|
||||
|
||||
return response.text() as unknown as T;
|
||||
} catch (error: any) {
|
||||
console.error('API请求失败:', error);
|
||||
throw error;
|
||||
// 检查响应状态
|
||||
if (!response.ok) {
|
||||
const errorText = await response.text();
|
||||
throw new Error(`HTTP ${response.status}: ${errorText}`);
|
||||
}
|
||||
|
||||
return response.json();
|
||||
}
|
||||
|
||||
/**
|
||||
* 带认证的API客户端
|
||||
*/
|
||||
export async function apiClient<T = any>(
|
||||
endpoint: string,
|
||||
options: ApiRequestOptions = {}
|
||||
|
||||
46
lib/api/template-generations.ts
Normal file
46
lib/api/template-generations.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
import { apiRequest } from './client';
|
||||
|
||||
export interface TemplateGeneration {
|
||||
id: string;
|
||||
userId: string;
|
||||
templateId: string;
|
||||
type: 'VIDEO' | 'IMAGE' | 'TEXT';
|
||||
resultUrl: string[];
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
status: 'pending' | 'processing' | 'completed' | 'failed';
|
||||
creditsCost: number;
|
||||
creditsTransactionId: string | null;
|
||||
template: {
|
||||
id: string;
|
||||
title: string;
|
||||
titleEn: string;
|
||||
};
|
||||
}
|
||||
|
||||
export interface GetTemplateGenerationsParams {
|
||||
page?: number;
|
||||
limit?: number;
|
||||
type?: 'VIDEO' | 'IMAGE';
|
||||
}
|
||||
|
||||
export interface TemplateGenerationsResponseData {
|
||||
generations: TemplateGeneration[];
|
||||
total: number;
|
||||
page: number;
|
||||
limit: number;
|
||||
}
|
||||
|
||||
export interface TemplateGenerationsResponse {
|
||||
success: boolean;
|
||||
data: TemplateGenerationsResponseData;
|
||||
}
|
||||
|
||||
export async function getTemplateGenerations(
|
||||
params: GetTemplateGenerationsParams = {}
|
||||
): Promise<TemplateGenerationsResponse> {
|
||||
return apiRequest<TemplateGenerationsResponse>('/api/template-generations', {
|
||||
method: 'GET',
|
||||
params
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user