Files
pixiv/ui/src/services/artwork.ts
T

103 lines
3.5 KiB
TypeScript

import apiService from './api';
import type { ApiResponse, Artwork, SearchParams, PaginatedResponse } from '@/types';
export interface ArtworkDetailOptions {
include_user?: boolean;
include_series?: boolean;
}
export interface ArtworkImagesResponse {
artwork_id: number;
total_pages: number;
images: Array<{
page: number;
original: string;
large: string;
medium: string;
square_medium: string;
}>;
selected_size: string;
}
class ArtworkService {
/**
* 获取作品详情
*/
async getArtworkDetail(id: number, options: ArtworkDetailOptions = {}): Promise<ApiResponse<Artwork>> {
const params = new URLSearchParams();
if (options.include_user !== undefined) {
params.append('include_user', options.include_user.toString());
}
if (options.include_series !== undefined) {
params.append('include_series', options.include_series.toString());
}
const query = params.toString();
const url = query ? `/api/artwork/${id}?${query}` : `/api/artwork/${id}`;
return apiService.get<Artwork>(url);
}
/**
* 获取作品预览信息
*/
async getArtworkPreview(id: number): Promise<ApiResponse<Artwork>> {
return apiService.get<Artwork>(`/api/artwork/${id}/preview`);
}
/**
* 获取作品图片URL
*/
async getArtworkImages(id: number, size: string = 'medium'): Promise<ApiResponse<ArtworkImagesResponse>> {
return apiService.get<ArtworkImagesResponse>(`/api/artwork/${id}/images?size=${size}`);
}
/**
* 搜索作品
*/
async searchArtworks(params: SearchParams): Promise<ApiResponse<{ artworks: Artwork[]; next_url?: string; total: number }>> {
const queryParams = new URLSearchParams();
// 处理关键词搜索
if (params.keyword) {
queryParams.append('keyword', params.keyword);
}
// 处理标签搜索
if (params.tags && params.tags.length > 0) {
params.tags.forEach(tag => {
queryParams.append('tags', tag);
});
}
if (params.type) queryParams.append('type', params.type);
if (params.sort) queryParams.append('sort', params.sort);
if (params.duration) queryParams.append('duration', params.duration);
if (params.offset !== undefined) queryParams.append('offset', params.offset.toString());
if (params.limit !== undefined) queryParams.append('limit', params.limit.toString());
return apiService.get<{ artworks: Artwork[]; next_url?: string; total: number }>(`/api/artwork/search?${queryParams.toString()}`);
}
/**
* 收藏/取消收藏作品
*/
async toggleBookmark(artworkId: number, action: 'add' | 'remove'): Promise<ApiResponse<{ artwork_id: number; is_bookmarked: boolean; message: string }>> {
return apiService.post<{ artwork_id: number; is_bookmarked: boolean; message: string }>(`/api/artwork/${artworkId}/bookmark`, { action });
}
/**
* 获取用户收藏的作品列表
*/
async getBookmarks(params: { type?: string; offset?: number; limit?: number } = {}): Promise<ApiResponse<{ artworks: Artwork[]; next_url?: string; total: number }>> {
const queryParams = new URLSearchParams();
if (params.type) queryParams.append('type', params.type);
if (params.offset !== undefined) queryParams.append('offset', params.offset.toString());
if (params.limit !== undefined) queryParams.append('limit', params.limit.toString());
return apiService.get<{ artworks: Artwork[]; next_url?: string; total: number }>(`/api/artwork/bookmarks?${queryParams.toString()}`);
}
}
export const artworkService = new ArtworkService();
export default artworkService;