lty/qy-lty-admin/lib/api/dances.ts
pmc c0fe1f502b
All checks were successful
Build and Deploy LTY / build-and-deploy (push) Successful in 1h5m35s
feat: update card models, admin pages, and add migrations
- Update card models, serializers, views and URLs
- Update dances, songs, users admin pages and API modules
- Add card migrations (merge furniture into decoration)
- Update middleware and settings

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-26 16:38:48 +08:00

140 lines
4.7 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: [],
status: item.status_display || item.status || "",
statusDisplay: item.status_display || item.status || "",
publishedAt: item.published_at || "",
activeCardsCount: item.active_cards_count || 0,
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)
}
}
// 发布舞蹈
export async function publishDance(id: string) {
const response = await apiClient.post(`/card/templates/${id}/publish/`)
const data = response.data?.template || response.data
return { data: mapBackendDance(data) }
}
// 归档舞蹈
export async function archiveDance(id: string) {
const response = await apiClient.post(`/card/templates/${id}/archive/`)
const data = response.data?.template || response.data
return { data: mapBackendDance(data) }
}