289 lines
8.7 KiB
TypeScript
289 lines
8.7 KiB
TypeScript
import type { Dance } from "./types"
|
||
import { handleApiError } from "./error-handler"
|
||
|
||
// 模拟舞蹈数据
|
||
const mockDances: Dance[] = [
|
||
{
|
||
id: "1",
|
||
name: "千本樱",
|
||
choreographer: "洛天依工作室",
|
||
duration: "3:45",
|
||
difficulty: "中等",
|
||
videoUrl: "/placeholder.svg?height=300&width=400",
|
||
coverUrl: "/placeholder.svg?height=300&width=400",
|
||
description: "基于《千本樱》歌曲的经典舞蹈编排,动作流畅优美,适合中等水平的舞者。",
|
||
motionFile: "senbonzakura_motion.fbx",
|
||
category: "日式",
|
||
tags: ["经典", "流行", "日式"],
|
||
createdAt: "2023-01-15T08:30:00Z",
|
||
updatedAt: "2023-02-20T14:15:00Z",
|
||
},
|
||
{
|
||
id: "2",
|
||
name: "权御天下",
|
||
choreographer: "洛天依动作组",
|
||
duration: "4:20",
|
||
difficulty: "高级",
|
||
videoUrl: "/placeholder.svg?height=300&width=400",
|
||
coverUrl: "/placeholder.svg?height=300&width=400",
|
||
description: "中国风舞蹈,动作幅度大,需要较高的舞蹈基础,展现古风韵味。",
|
||
motionFile: "quanyutianxia_motion.fbx",
|
||
category: "中国风",
|
||
tags: ["高难度", "中国风", "古风"],
|
||
createdAt: "2023-03-10T10:45:00Z",
|
||
updatedAt: "2023-04-05T16:30:00Z",
|
||
},
|
||
{
|
||
id: "3",
|
||
name: "达拉崩吧",
|
||
choreographer: "洛天依舞蹈工作室",
|
||
duration: "3:10",
|
||
difficulty: "初级",
|
||
videoUrl: "/placeholder.svg?height=300&width=400",
|
||
coverUrl: "/placeholder.svg?height=300&width=400",
|
||
description: "轻松欢快的舞蹈,适合初学者,动作简单易学。",
|
||
motionFile: "dalabengba_motion.fbx",
|
||
category: "流行",
|
||
tags: ["简单", "欢快", "流行"],
|
||
createdAt: "2023-05-20T09:15:00Z",
|
||
updatedAt: "2023-05-25T11:20:00Z",
|
||
},
|
||
{
|
||
id: "4",
|
||
name: "普通DISCO",
|
||
choreographer: "洛天依动作设计组",
|
||
duration: "3:30",
|
||
difficulty: "中等",
|
||
videoUrl: "/placeholder.svg?height=300&width=400",
|
||
coverUrl: "/placeholder.svg?height=300&width=400",
|
||
description: "现代disco风格舞蹈,节奏感强,动作活力四射。",
|
||
motionFile: "disco_motion.fbx",
|
||
category: "现代",
|
||
tags: ["活力", "现代", "disco"],
|
||
createdAt: "2023-06-05T14:30:00Z",
|
||
updatedAt: "2023-06-10T17:45:00Z",
|
||
},
|
||
{
|
||
id: "5",
|
||
name: "华灯宴",
|
||
choreographer: "古风舞蹈团队",
|
||
duration: "4:50",
|
||
difficulty: "高级",
|
||
videoUrl: "/placeholder.svg?height=300&width=400",
|
||
coverUrl: "/placeholder.svg?height=300&width=400",
|
||
description: "古风舞蹈,动作优美细腻,需要较高的舞蹈技巧和表现力。",
|
||
motionFile: "hualangyan_motion.fbx",
|
||
category: "中国风",
|
||
tags: ["古风", "优美", "高难度"],
|
||
createdAt: "2023-07-12T11:20:00Z",
|
||
updatedAt: "2023-07-18T13:40:00Z",
|
||
},
|
||
{
|
||
id: "6",
|
||
name: "炉心融解",
|
||
choreographer: "日系舞蹈组",
|
||
duration: "3:55",
|
||
difficulty: "中高级",
|
||
videoUrl: "/placeholder.svg?height=300&width=400",
|
||
coverUrl: "/placeholder.svg?height=300&width=400",
|
||
description: "日系风格舞蹈,动作精准,需要良好的节奏感和协调性。",
|
||
motionFile: "meltdown_motion.fbx",
|
||
category: "日式",
|
||
tags: ["日系", "精准", "流行"],
|
||
createdAt: "2023-08-03T16:10:00Z",
|
||
updatedAt: "2023-08-10T09:25:00Z",
|
||
},
|
||
{
|
||
id: "7",
|
||
name: "芒种",
|
||
choreographer: "中国舞蹈团",
|
||
duration: "4:05",
|
||
difficulty: "中等",
|
||
videoUrl: "/placeholder.svg?height=300&width=400",
|
||
coverUrl: "/placeholder.svg?height=300&width=400",
|
||
description: "中国传统节气主题舞蹈,动作舒缓优美,富有诗意。",
|
||
motionFile: "mangzhong_motion.fbx",
|
||
category: "中国风",
|
||
tags: ["传统", "优美", "诗意"],
|
||
createdAt: "2023-09-15T10:30:00Z",
|
||
updatedAt: "2023-09-20T14:15:00Z",
|
||
},
|
||
{
|
||
id: "8",
|
||
name: "寄明月",
|
||
choreographer: "古风舞蹈设计师",
|
||
duration: "4:30",
|
||
difficulty: "高级",
|
||
videoUrl: "/placeholder.svg?height=300&width=400",
|
||
coverUrl: "/placeholder.svg?height=300&width=400",
|
||
description: "古风舞蹈,动作优美流畅,需要较高的舞蹈功底和表现力。",
|
||
motionFile: "jimingyue_motion.fbx",
|
||
category: "中国风",
|
||
tags: ["古风", "优美", "高难度"],
|
||
createdAt: "2023-10-08T13:45:00Z",
|
||
updatedAt: "2023-10-15T11:20:00Z",
|
||
},
|
||
{
|
||
id: "9",
|
||
name: "极乐净土",
|
||
choreographer: "日系动作组",
|
||
duration: "3:40",
|
||
difficulty: "中等",
|
||
videoUrl: "/placeholder.svg?height=300&width=400",
|
||
coverUrl: "/placeholder.svg?height=300&width=400",
|
||
description: "日系风格舞蹈,动作活泼可爱,节奏感强。",
|
||
motionFile: "jiletutu_motion.fbx",
|
||
category: "日式",
|
||
tags: ["日系", "活泼", "流行"],
|
||
createdAt: "2023-11-05T15:30:00Z",
|
||
updatedAt: "2023-11-12T10:45:00Z",
|
||
},
|
||
{
|
||
id: "10",
|
||
name: "牵丝戏",
|
||
choreographer: "中国古典舞团",
|
||
duration: "4:15",
|
||
difficulty: "高级",
|
||
videoUrl: "/placeholder.svg?height=300&width=400",
|
||
coverUrl: "/placeholder.svg?height=300&width=400",
|
||
description: "中国古典舞蹈,动作细腻优美,需要较高的舞蹈技巧和表现力。",
|
||
motionFile: "qiansixi_motion.fbx",
|
||
category: "中国风",
|
||
tags: ["古典", "优美", "高难度"],
|
||
createdAt: "2023-12-10T09:20:00Z",
|
||
updatedAt: "2023-12-18T14:35:00Z",
|
||
},
|
||
]
|
||
|
||
// 获取舞蹈列表
|
||
export async function getDances(page = 1, limit = 10, search = "") {
|
||
try {
|
||
// 模拟API请求延迟
|
||
await new Promise((resolve) => setTimeout(resolve, 500))
|
||
|
||
let filteredDances = [...mockDances]
|
||
|
||
// 如果有搜索关键词,过滤结果
|
||
if (search) {
|
||
const searchLower = search.toLowerCase()
|
||
filteredDances = filteredDances.filter(
|
||
(dance) =>
|
||
dance.name.toLowerCase().includes(searchLower) ||
|
||
dance.choreographer?.toLowerCase().includes(searchLower) ||
|
||
dance.category?.toLowerCase().includes(searchLower) ||
|
||
dance.tags?.some((tag) => tag.toLowerCase().includes(searchLower)),
|
||
)
|
||
}
|
||
|
||
// 计算分页
|
||
const totalItems = filteredDances.length
|
||
const totalPages = Math.ceil(totalItems / limit)
|
||
const startIndex = (page - 1) * limit
|
||
const paginatedDances = filteredDances.slice(startIndex, startIndex + limit)
|
||
|
||
return {
|
||
data: paginatedDances,
|
||
pagination: {
|
||
page,
|
||
limit,
|
||
totalItems,
|
||
totalPages,
|
||
},
|
||
}
|
||
} catch (error) {
|
||
return handleApiError(error)
|
||
}
|
||
}
|
||
|
||
// 获取单个舞蹈详情
|
||
export async function getDance(id: string) {
|
||
try {
|
||
// 模拟API请求延迟
|
||
await new Promise((resolve) => setTimeout(resolve, 300))
|
||
|
||
const dance = mockDances.find((dance) => dance.id === id)
|
||
|
||
if (!dance) {
|
||
throw new Error("舞蹈不存在")
|
||
}
|
||
|
||
return { data: dance }
|
||
} catch (error) {
|
||
return handleApiError(error)
|
||
}
|
||
}
|
||
|
||
// 创建新舞蹈
|
||
export async function createDance(danceData: Omit<Dance, "id" | "createdAt" | "updatedAt">) {
|
||
try {
|
||
// 模拟API请求延迟
|
||
await new Promise((resolve) => setTimeout(resolve, 700))
|
||
|
||
const newDance: Dance = {
|
||
id: `${mockDances.length + 1}`,
|
||
...danceData,
|
||
createdAt: new Date().toISOString(),
|
||
updatedAt: new Date().toISOString(),
|
||
}
|
||
|
||
// 在实际应用中,这里会调用API将数据保存到数据库
|
||
// 这里我们只是模拟添加到本地数组
|
||
mockDances.push(newDance)
|
||
|
||
return { data: newDance }
|
||
} catch (error) {
|
||
return handleApiError(error)
|
||
}
|
||
}
|
||
|
||
// 更新舞蹈
|
||
export async function updateDance(id: string, danceData: Partial<Dance>) {
|
||
try {
|
||
// 模拟API请求延迟
|
||
await new Promise((resolve) => setTimeout(resolve, 600))
|
||
|
||
const index = mockDances.findIndex((dance) => dance.id === id)
|
||
|
||
if (index === -1) {
|
||
throw new Error("舞蹈不存在")
|
||
}
|
||
|
||
// 更新舞蹈数据
|
||
const updatedDance = {
|
||
...mockDances[index],
|
||
...danceData,
|
||
updatedAt: new Date().toISOString(),
|
||
}
|
||
|
||
// 在实际应用中,这里会调用API将更新保存到数据库
|
||
// 这里我们只是模拟更新本地数组
|
||
mockDances[index] = updatedDance
|
||
|
||
return { data: updatedDance }
|
||
} catch (error) {
|
||
return handleApiError(error)
|
||
}
|
||
}
|
||
|
||
// 删除舞蹈
|
||
export async function deleteDance(id: string) {
|
||
try {
|
||
// 模拟API请求延迟
|
||
await new Promise((resolve) => setTimeout(resolve, 500))
|
||
|
||
const index = mockDances.findIndex((dance) => dance.id === id)
|
||
|
||
if (index === -1) {
|
||
throw new Error("舞蹈不存在")
|
||
}
|
||
|
||
// 在实际应用中,这里会调用API从数据库中删除
|
||
// 这里我们只是模拟从本地数组中删除
|
||
const deletedDance = mockDances.splice(index, 1)[0]
|
||
|
||
return { data: deletedDance }
|
||
} catch (error) {
|
||
return handleApiError(error)
|
||
}
|
||
}
|