lty/qy-lty-admin/lib/api/achievements.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

118 lines
4.2 KiB
TypeScript

import type { Achievement } from "./types"
import { apiClient } from "./client"
import type { PaginatedResponse, PaginationParams } from "./client"
// 将后端成就数据映射到前端 Achievement 类型
function mapBackendAchievement(a: any): Achievement {
// 后端 achievement_type → 前端 category 映射
const categoryMap: Record<string, Achievement["category"]> = {
login: "互动",
activity: "互动",
social: "互动",
usage: "收集",
special: "特殊",
hidden: "隐藏",
}
return {
id: String(a.id),
name: a.name,
description: a.description,
icon: undefined,
category: categoryMap[a.achievement_type] || "特殊",
requirement: a.conditions ? JSON.stringify(a.conditions) : "",
rewardType: "经验值",
rewardAmount: a.points || 0,
isHidden: a.is_hidden || false,
unlockRate: undefined,
createdAt: a.created_at ? a.created_at.split("T")[0] : "",
updatedAt: a.updated_at ? a.updated_at.split("T")[0] : "",
}
}
// 获取成就列表
export const getAchievements = async (params?: PaginationParams): Promise<PaginatedResponse<Achievement>> => {
const page = params?.page || 1
const pageSize = params?.pageSize || 10
const searchParam = params?.search ? `&search=${encodeURIComponent(params.search)}` : ""
const response = await apiClient.get(
`/achievement/achievements/?page=${page}&page_size=${pageSize}&show_hidden=true${searchParam}`
)
const data = response.data?.data || response.data
const results: any[] = data.results || data
const total = data.count || results.length
return {
items: results.map(mapBackendAchievement),
total,
page,
pageSize,
totalPages: Math.ceil(total / pageSize),
}
}
// 获取单个成就
export const getAchievement = async (id: string): Promise<Achievement> => {
const response = await apiClient.get(`/achievement/achievements/${id}/`)
const data = response.data?.data || response.data
return mapBackendAchievement(data)
}
// 创建成就(需要管理员权限)
export const createAchievement = async (achievementData: Partial<Achievement>): Promise<Achievement> => {
const typeReverseMap: Record<string, string> = {
: "activity",
: "activity",
: "usage",
: "activity",
: "special",
: "hidden",
}
const payload = {
name: achievementData.name,
description: achievementData.description,
achievement_type: typeReverseMap[achievementData.category || "特殊"] || "special",
is_hidden: achievementData.isHidden || false,
points: achievementData.rewardAmount || 0,
rarity: "common",
conditions: achievementData.requirement ? { description: achievementData.requirement } : {},
}
const response = await apiClient.post(`/achievement/achievements/`, payload)
const data = response.data?.data || response.data
return mapBackendAchievement(data)
}
// 更新成就(需要管理员权限)
export const updateAchievement = async (id: string, achievementData: Partial<Achievement>): Promise<Achievement> => {
const typeReverseMap: Record<string, string> = {
: "activity",
: "activity",
: "usage",
: "activity",
: "special",
: "hidden",
}
const payload: any = {}
if (achievementData.name !== undefined) payload.name = achievementData.name
if (achievementData.description !== undefined) payload.description = achievementData.description
if (achievementData.category !== undefined) payload.achievement_type = typeReverseMap[achievementData.category] || "special"
if (achievementData.isHidden !== undefined) payload.is_hidden = achievementData.isHidden
if (achievementData.rewardAmount !== undefined) payload.points = achievementData.rewardAmount
if (achievementData.requirement !== undefined) payload.conditions = { description: achievementData.requirement }
const response = await apiClient.patch(`/achievement/achievements/${id}/`, payload)
const data = response.data?.data || response.data
return mapBackendAchievement(data)
}
// 删除成就(需要管理员权限)
export const deleteAchievement = async (id: string): Promise<boolean> => {
await apiClient.delete(`/achievement/achievements/${id}/`)
return true
}