library-picturebook-activity/frontend/src/api/public.ts

420 lines
11 KiB
TypeScript
Raw Normal View History

import axios from "axios"
// 公众端专用 axios 实例
const publicApi = axios.create({
baseURL: import.meta.env.VITE_API_BASE_URL || "/api",
timeout: 15000,
})
// 请求拦截器
publicApi.interceptors.request.use((config) => {
const token = localStorage.getItem("public_token")
if (token) {
config.headers.Authorization = `Bearer ${token}`
}
return config
})
// 响应拦截器
publicApi.interceptors.response.use(
(response) => response.data?.data ?? response.data,
(error) => {
if (error.response?.status === 401) {
localStorage.removeItem("public_token")
localStorage.removeItem("public_user")
// 如果在公众端页面,跳转到公众端登录
if (window.location.pathname.startsWith("/p/")) {
window.location.href = "/p/login"
}
}
return Promise.reject(error)
},
)
// ==================== 认证 ====================
export interface PublicRegisterParams {
username: string
password: string
nickname: string
phone?: string
city?: string
}
export interface PublicLoginParams {
username: string
password: string
}
export interface PublicUser {
id: number
username: string
nickname: string
phone: string | null
city: string | null
avatar: string | null
tenantId: number
tenantCode: string
userSource: string
userType: "adult" | "child"
parentUserId: number | null
roles: string[]
permissions: string[]
children?: any[]
childrenCount?: number
}
export interface LoginResponse {
token: string
user: PublicUser
}
export const publicAuthApi = {
register: (data: PublicRegisterParams): Promise<LoginResponse> =>
publicApi.post("/public/auth/register", data),
login: (data: PublicLoginParams): Promise<LoginResponse> =>
publicApi.post("/public/auth/login", data),
}
// ==================== 个人信息 ====================
export const publicProfileApi = {
getProfile: (): Promise<PublicUser> => publicApi.get("/public/mine/profile"),
updateProfile: (data: {
nickname?: string
city?: string
avatar?: string
gender?: string
}) => publicApi.put("/public/mine/profile", data),
}
// ==================== 子女管理 ====================
export interface Child {
id: number
parentId: number
name: string
gender: string | null
birthday: string | null
grade: string | null
city: string | null
schoolName: string | null
avatar: string | null
}
export interface CreateChildParams {
name: string
gender?: string
birthday?: string
grade?: string
city?: string
schoolName?: string
}
export const publicChildrenApi = {
list: (): Promise<Child[]> => publicApi.get("/public/mine/children"),
create: (data: CreateChildParams): Promise<Child> =>
publicApi.post("/public/mine/children", data),
get: (id: number): Promise<Child> =>
publicApi.get(`/public/mine/children/${id}`),
update: (id: number, data: Partial<CreateChildParams>): Promise<Child> =>
publicApi.put(`/public/mine/children/${id}`, data),
delete: (id: number) => publicApi.delete(`/public/mine/children/${id}`),
}
// ==================== 子女独立账号管理 ====================
export interface CreateChildAccountParams {
username: string
password: string
nickname: string
gender?: string
birthday?: string
city?: string
avatar?: string
relationship?: string
}
export interface ChildAccount {
id: number
username: string
nickname: string
avatar: string | null
gender: string | null
birthday: string | null
city: string | null
status: string
userType: string
createTime: string
relationship: string | null
controlMode: string
}
export const publicChildAccountApi = {
// 家长为子女创建独立账号
create: (data: CreateChildAccountParams): Promise<any> =>
publicApi.post("/public/children/create-account", data),
// 获取子女账号列表
list: (): Promise<ChildAccount[]> =>
publicApi.get("/public/children/accounts"),
// 家长切换到子女身份
switchToChild: (childUserId: number): Promise<LoginResponse> =>
publicApi.post("/public/auth/switch-child", { childUserId }),
// 更新子女账号信息
update: (id: number, data: {
nickname?: string
password?: string
gender?: string
birthday?: string
city?: string
avatar?: string
controlMode?: string
}): Promise<any> =>
publicApi.put(`/public/children/accounts/${id}`, data),
// 子女查看家长信息
getParentInfo: (): Promise<{
parentId: number
nickname: string
avatar: string | null
relationship: string | null
} | null> =>
publicApi.get("/public/mine/parent-info"),
}
// ==================== 活动 ====================
export interface PublicActivity {
id: number
contestName: string
contestType: string
contestState: string
status: string
startTime: string
endTime: string
coverUrl: string | null
posterUrl: string | null
registerStartTime: string
registerEndTime: string
submitStartTime: string
submitEndTime: string
organizers: any
visibility: string
}
export const publicActivitiesApi = {
list: (params?: {
page?: number
pageSize?: number
keyword?: string
contestType?: string
}): Promise<{ list: PublicActivity[]; total: number }> =>
publicApi.get("/public/activities", { params }),
detail: (id: number) => publicApi.get(`/public/activities/${id}`),
register: (
id: number,
data: { participantType: "self" | "child"; childId?: number },
) => publicApi.post(`/public/activities/${id}/register`, data),
getMyRegistration: (id: number) =>
publicApi.get(`/public/activities/${id}/my-registration`),
submitWork: (
id: number,
data: {
registrationId: number
title: string
description?: string
files?: string[]
previewUrl?: string
attachments?: { fileName: string; fileUrl: string; fileType?: string; size?: string }[]
},
) => publicApi.post(`/public/activities/${id}/submit-work`, data),
}
// ==================== 我的报名 ====================
export const publicMineApi = {
registrations: (params?: { page?: number; pageSize?: number }) =>
publicApi.get("/public/mine/registrations", { params }),
}
// ==================== 点赞 & 收藏 ====================
export const publicInteractionApi = {
like: (workId: number) =>
publicApi.post(`/public/works/${workId}/like`),
favorite: (workId: number) =>
publicApi.post(`/public/works/${workId}/favorite`),
getInteraction: (workId: number) =>
publicApi.get(`/public/works/${workId}/interaction`),
batchStatus: (workIds: number[]) =>
publicApi.post("/public/works/batch-interaction", { workIds }),
myFavorites: (params?: { page?: number; pageSize?: number }) =>
publicApi.get("/public/mine/favorites", { params }),
}
// ==================== 用户作品库 ====================
export interface UserWork {
id: number
userId: number
title: string
coverUrl: string | null
description: string | null
visibility: string
status: string
reviewNote: string | null
originalImageUrl: string | null
voiceInputUrl: string | null
textInput: string | null
aiMeta: any
viewCount: number
likeCount: number
favoriteCount: number
commentCount: number
shareCount: number
publishTime: string | null
createTime: string
modifyTime: string
pages?: UserWorkPage[]
tags?: Array<{ tag: { id: number; name: string; category: string } }>
creator?: { id: number; nickname: string; avatar: string | null; username: string }
_count?: { pages: number; likes: number; favorites: number; comments: number }
}
export interface UserWorkPage {
id: number
workId: number
pageNo: number
imageUrl: string | null
text: string | null
audioUrl: string | null
}
export const publicUserWorksApi = {
// 创建作品
create: (data: {
title: string
coverUrl?: string
description?: string
visibility?: string
originalImageUrl?: string
voiceInputUrl?: string
textInput?: string
aiMeta?: any
pages?: Array<{ pageNo: number; imageUrl?: string; text?: string; audioUrl?: string }>
tagIds?: number[]
}): Promise<UserWork> => publicApi.post("/public/works", data),
// 我的作品列表
list: (params?: {
page?: number
pageSize?: number
status?: string
keyword?: string
}): Promise<{ list: UserWork[]; total: number }> =>
publicApi.get("/public/works", { params }),
// 作品详情
detail: (id: number): Promise<UserWork> =>
publicApi.get(`/public/works/${id}`),
// 更新作品
update: (id: number, data: {
title?: string
description?: string
coverUrl?: string
visibility?: string
tagIds?: number[]
}): Promise<UserWork> => publicApi.put(`/public/works/${id}`, data),
// 删除作品
delete: (id: number) => publicApi.delete(`/public/works/${id}`),
// 发布作品(进入审核)
publish: (id: number) => publicApi.post(`/public/works/${id}/publish`),
// 获取绘本分页
getPages: (id: number): Promise<UserWorkPage[]> =>
publicApi.get(`/public/works/${id}/pages`),
// 保存绘本分页
savePages: (id: number, pages: Array<{ pageNo: number; imageUrl?: string; text?: string; audioUrl?: string }>) =>
publicApi.post(`/public/works/${id}/pages`, { pages }),
}
// ==================== AI 创作流程 ====================
export const publicCreationApi = {
// 提交创作请求
submit: (data: {
originalImageUrl: string
voiceInputUrl?: string
textInput?: string
}): Promise<{ id: number; status: string; message: string }> =>
publicApi.post("/public/creation/submit", data),
// 查询生成进度
getStatus: (id: number): Promise<{ id: number; status: string; title: string; createdAt: string }> =>
publicApi.get(`/public/creation/${id}/status`),
// 获取生成结果
getResult: (id: number): Promise<UserWork> =>
publicApi.get(`/public/creation/${id}/result`),
// 创作历史
history: (params?: { page?: number; pageSize?: number }): Promise<{ list: any[]; total: number }> =>
publicApi.get("/public/creation/history", { params }),
}
// ==================== 标签 ====================
export interface WorkTag {
id: number
name: string
category: string | null
usageCount: number
}
export const publicTagsApi = {
list: (): Promise<WorkTag[]> => publicApi.get("/public/tags"),
hot: (): Promise<WorkTag[]> => publicApi.get("/public/tags/hot"),
}
// ==================== 作品广场 ====================
export const publicGalleryApi = {
recommended: (): Promise<UserWork[]> =>
publicApi.get("/public/gallery/recommended"),
list: (params?: {
page?: number
pageSize?: number
tagId?: number
category?: string
sortBy?: string
keyword?: string
}): Promise<{ list: UserWork[]; total: number }> =>
publicApi.get("/public/gallery", { params }),
detail: (id: number): Promise<UserWork> =>
publicApi.get(`/public/gallery/${id}`),
userWorks: (userId: number, params?: { page?: number; pageSize?: number }): Promise<{ list: UserWork[]; total: number }> =>
publicApi.get(`/public/users/${userId}/works`, { params }),
}
export default publicApi