lty/qy-lty-admin/lib/api/dances.ts
pmc bd95ba470c feat: update admin panel, API modules, and add migrations
- Update food, outfits, props, home-decor pages and components
- Add permissions page and sidebar updates
- Update API client and all API modules (auth, food, dances, etc.)
- Add card model migrations for optional fields
- Update Django views, serializers, and authentication
- Add affinity level migrations and user app updates
- Add project documentation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-20 13:06:50 +08:00

122 lines
4.0 KiB
TypeScript

import type { Dance } from "./types"
import { apiClient } from "./client"
import { handleApiError } from "./error-handler"
// 将后端 CardTemplate(dance) 数据映射到前端 Dance 类型
function mapBackendDance(item: any): Dance {
const attrs = item.attributes || {}
return {
id: String(item.id),
name: item.name,
choreographer: attrs.choreographer || "",
duration: attrs.duration || "",
difficulty: attrs.difficulty || "",
videoUrl: attrs.tutorial_video || item.model_url || "",
coverUrl: item.image_url || "/placeholder.svg?height=300&width=400",
description: item.description || "",
motionFile: item.model_url || "",
category: attrs.style || "",
tags: [],
createdAt: item.created_at || "",
updatedAt: item.updated_at || "",
}
}
// 获取舞蹈列表
export async function getDances(page = 1, limit = 10, search = "") {
try {
const searchParam = search ? `&search=${encodeURIComponent(search)}` : ""
const response = await apiClient.get(
`/card/category/dance/?page=${page}&page_size=${limit}${searchParam}`
)
const data = response.data?.data || response.data
const results: any[] = data.results || data
const total = data.count || results.length
return {
data: results.map(mapBackendDance),
pagination: {
page,
limit,
totalItems: total,
totalPages: Math.ceil(total / limit),
},
}
} catch (error) {
return handleApiError(error)
}
}
// 获取单个舞蹈详情
export async function getDance(id: string) {
try {
const response = await apiClient.get(`/card/templates/${id}/`)
const data = response.data?.data || response.data
return { data: mapBackendDance(data) }
} catch (error) {
return handleApiError(error)
}
}
// 创建新舞蹈(需要管理员权限)
export async function createDance(danceData: Omit<Dance, "id" | "createdAt" | "updatedAt">) {
try {
const payload: any = {
name: danceData.name,
category: "dance",
description: danceData.description || "",
dance_attributes: {
choreographer: danceData.choreographer || "",
duration: danceData.duration || "",
difficulty: danceData.difficulty || "",
tutorial_video: danceData.videoUrl || "",
style: danceData.category || "",
},
}
if (danceData.coverUrl && !danceData.coverUrl.includes("placeholder")) {
payload.image_url = danceData.coverUrl
}
const response = await apiClient.post(`/card/templates/`, payload)
const data = response.data?.data || response.data
return { data: mapBackendDance(data) }
} catch (error) {
return handleApiError(error)
}
}
// 更新舞蹈(需要管理员权限)
export async function updateDance(id: string, danceData: Partial<Dance>) {
try {
const payload: any = {}
if (danceData.name !== undefined) payload.name = danceData.name
if (danceData.description !== undefined) payload.description = danceData.description
const attrs: any = {}
if (danceData.choreographer !== undefined) attrs.choreographer = danceData.choreographer
if (danceData.duration !== undefined) attrs.duration = danceData.duration
if (danceData.difficulty !== undefined) attrs.difficulty = danceData.difficulty
if (danceData.videoUrl !== undefined) attrs.tutorial_video = danceData.videoUrl
if (danceData.category !== undefined) attrs.style = danceData.category
if (Object.keys(attrs).length > 0) payload.dance_attributes = attrs
if (danceData.coverUrl !== undefined) payload.image_url = danceData.coverUrl
const response = await apiClient.patch(`/card/templates/${id}/`, payload)
const data = response.data?.data || response.data
return { data: mapBackendDance(data) }
} catch (error) {
return handleApiError(error)
}
}
// 删除舞蹈(需要管理员权限)
export async function deleteDance(id: string) {
try {
await apiClient.delete(`/card/templates/${id}/`)
return { data: { id } }
} catch (error) {
return handleApiError(error)
}
}