feat: setup frontend project with bun and dynamic data fetching
- Create new frontend project directory with Next.js 15 + React 19 - Migrate from pnpm to bun for faster package management - Add TanStack Query + Axios for dynamic data fetching - Create comprehensive Makefile with development commands - Setup API layer with query hooks and error handling - Configure environment variables and bun settings - Add TypeScript type checking and project documentation - Update CLAUDE.md with bun-specific development workflow
This commit is contained in:
91
frontend/lib/queries.ts
Normal file
91
frontend/lib/queries.ts
Normal file
@ -0,0 +1,91 @@
|
||||
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
|
||||
import api from './api'
|
||||
|
||||
// 照片数据类型
|
||||
export interface Photo {
|
||||
id: number
|
||||
src: string
|
||||
title: string
|
||||
description: string
|
||||
category: string
|
||||
tags: string[]
|
||||
date: string
|
||||
exif: {
|
||||
camera: string
|
||||
lens: string
|
||||
settings: string
|
||||
location: string
|
||||
}
|
||||
}
|
||||
|
||||
// 查询键
|
||||
export const queryKeys = {
|
||||
photos: ['photos'] as const,
|
||||
photo: (id: number) => ['photo', id] as const,
|
||||
categories: ['categories'] as const,
|
||||
}
|
||||
|
||||
// 获取所有照片
|
||||
export const usePhotos = () => {
|
||||
return useQuery({
|
||||
queryKey: queryKeys.photos,
|
||||
queryFn: () => api.get('/photos'),
|
||||
staleTime: 5 * 60 * 1000, // 5分钟内不重新获取
|
||||
})
|
||||
}
|
||||
|
||||
// 获取单张照片
|
||||
export const usePhoto = (id: number) => {
|
||||
return useQuery({
|
||||
queryKey: queryKeys.photo(id),
|
||||
queryFn: () => api.get(`/photos/${id}`),
|
||||
enabled: !!id,
|
||||
})
|
||||
}
|
||||
|
||||
// 获取分类列表
|
||||
export const useCategories = () => {
|
||||
return useQuery({
|
||||
queryKey: queryKeys.categories,
|
||||
queryFn: () => api.get('/categories'),
|
||||
staleTime: 10 * 60 * 1000, // 10分钟内不重新获取
|
||||
})
|
||||
}
|
||||
|
||||
// 添加照片
|
||||
export const useAddPhoto = () => {
|
||||
const queryClient = useQueryClient()
|
||||
|
||||
return useMutation({
|
||||
mutationFn: (photo: Omit<Photo, 'id'>) => api.post('/photos', photo),
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({ queryKey: queryKeys.photos })
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// 更新照片
|
||||
export const useUpdatePhoto = () => {
|
||||
const queryClient = useQueryClient()
|
||||
|
||||
return useMutation({
|
||||
mutationFn: ({ id, ...photo }: Partial<Photo> & { id: number }) =>
|
||||
api.put(`/photos/${id}`, photo),
|
||||
onSuccess: (data, variables) => {
|
||||
queryClient.invalidateQueries({ queryKey: queryKeys.photos })
|
||||
queryClient.invalidateQueries({ queryKey: queryKeys.photo(variables.id) })
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// 删除照片
|
||||
export const useDeletePhoto = () => {
|
||||
const queryClient = useQueryClient()
|
||||
|
||||
return useMutation({
|
||||
mutationFn: (id: number) => api.delete(`/photos/${id}`),
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({ queryKey: queryKeys.photos })
|
||||
},
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user