Files
CosScene/admin-web/src/composables/admin-api.ts
T
2026-05-09 16:40:29 +08:00

596 lines
17 KiB
TypeScript

import { clearAdminToken, getAdminToken, setAdminToken, setAdminUser } from './admin-auth'
const API_BASE
= import.meta.env.VITE_API_BASE
|| (import.meta.env.DEV ? 'http://127.0.0.1:8000/api/v1' : '/api/v1')
type RequestError = Error & { status?: number }
async function request<T = any>(path: string, init: RequestInit = {}) {
const token = getAdminToken()
const headers: Record<string, string> = {
'Content-Type': 'application/json',
...(init.headers as Record<string, string> || {}),
}
if (token)
headers.Authorization = `Bearer ${token}`
let resp: Response
try {
resp = await fetch(`${API_BASE}${path}`, {
...init,
headers,
})
}
catch {
throw new Error(`接口连接失败:${API_BASE}${path}`)
}
if (resp.status === 401) {
clearAdminToken()
throw new Error('登录已失效,请重新登录')
}
const data = await resp.json().catch(() => ({}))
if (!resp.ok) {
const message = data?.detail || data?.message || `请求失败(${resp.status})`
const error = new Error(message) as RequestError
error.status = resp.status
throw error
}
return data as T
}
export function isRequestNotFound(error: unknown) {
return (error as RequestError)?.status === 404
}
export async function adminLogin(account: string, password: string) {
const data = await request<{
access_token: string
refresh_token: string
user: Record<string, any>
}>('/admin/auth/login', {
method: 'POST',
body: JSON.stringify({ account, password }),
})
setAdminToken(data.access_token)
setAdminUser(data.user)
return data
}
export function adminMe() {
return request('/admin/auth/me')
}
export function adminDashboard() {
return request('/admin/dashboard')
}
export function adminModuleDesign() {
return request('/admin/module-design')
}
export function adminListUsers(params: Record<string, any>) {
const q = new URLSearchParams()
Object.entries(params || {}).forEach(([k, v]) => {
if (v !== undefined && v !== null && String(v).trim() !== '')
q.set(k, String(v))
})
return request(`/admin/users?${q.toString()}`)
}
export function adminCreateUser(payload: Record<string, any>) {
return request('/admin/users', {
method: 'POST',
body: JSON.stringify(payload),
})
}
export function adminUpdateUser(userId: number, payload: Record<string, any>) {
return request(`/admin/users/${userId}`, {
method: 'PUT',
body: JSON.stringify(payload),
})
}
export function adminDeleteUser(userId: number) {
return request(`/admin/users/${userId}`, {
method: 'DELETE',
})
}
export function adminUserOptions(keyword = '') {
const q = new URLSearchParams()
if (keyword.trim())
q.set('keyword', keyword.trim())
return request(`/admin/user-options?${q.toString()}`)
}
export function adminListSpots(params: Record<string, any>) {
const q = new URLSearchParams()
Object.entries(params || {}).forEach(([k, v]) => {
if (v !== undefined && v !== null && String(v).trim() !== '')
q.set(k, String(v))
})
return request(`/admin/spots?${q.toString()}`)
}
export function adminGetSpot(spotId: number) {
return request(`/spots/${spotId}`).then((detail: any) => ({
id: detail.id,
title: detail.title || '',
city: detail.city || '',
creator_id: detail.creator?.id || detail.creator_id || 0,
longitude: detail.longitude ?? 0,
latitude: detail.latitude ?? 0,
description: detail.description || '',
transport: detail.transport || '',
best_time: detail.best_time || '',
difficulty: detail.difficulty || '',
is_free: detail.is_free ?? true,
price_min: detail.price_min ?? null,
price_max: detail.price_max ?? null,
audit_status: detail.audit_status || 'pending',
reject_reason: detail.reject_reason || '',
tag_ids: (detail.tags || []).map((t: any) => t.id),
image_urls: (detail.images || []).map((img: any) => img.image_url),
images: detail.images || [],
}))
}
export function adminCreateSpot(payload: Record<string, any>) {
return request('/admin/spots', {
method: 'POST',
body: JSON.stringify(payload),
})
}
export function adminUpdateSpot(spotId: number, payload: Record<string, any>) {
return request(`/admin/spots/${spotId}`, {
method: 'PUT',
body: JSON.stringify(payload),
})
}
export function adminDeleteSpot(spotId: number) {
return request(`/admin/spots/${spotId}`, {
method: 'DELETE',
})
}
export function adminSpotTagOptions(keyword = '') {
return request('/tags?sort=hot').then((items: any[]) => {
const key = keyword.trim().toLowerCase()
const normalized = (items || []).map((item: any) => ({
id: item.id,
title: item.name || item.title || '',
}))
if (!key)
return normalized
return normalized.filter(item => String(item.title).toLowerCase().includes(key))
})
}
export function adminAuditSpot(spotId: number, payload: { audit_status: string, reject_reason?: string }) {
return request(`/admin/spots/${spotId}/audit`, {
method: 'PATCH',
body: JSON.stringify(payload),
})
}
export function adminBatchAuditSpots(payload: { ids: number[], audit_status: string, reject_reason?: string }) {
return request('/admin/spots/batch-audit', {
method: 'POST',
body: JSON.stringify(payload),
})
}
export function adminListEvents(params: Record<string, any>) {
const q = new URLSearchParams()
Object.entries(params || {}).forEach(([k, v]) => {
if (v !== undefined && v !== null && String(v).trim() !== '')
q.set(k, String(v))
})
return request(`/admin/events?${q.toString()}`)
}
export function adminGetEvent(eventId: number) {
return request(`/admin/events/${eventId}`)
}
export function adminCreateEvent(payload: Record<string, any>) {
return request('/admin/events', {
method: 'POST',
body: JSON.stringify(payload),
})
}
export function adminUpdateEvent(eventId: number, payload: Record<string, any>) {
return request(`/admin/events/${eventId}`, {
method: 'PUT',
body: JSON.stringify(payload),
})
}
export function adminDeleteEvent(eventId: number) {
return request(`/admin/events/${eventId}`, {
method: 'DELETE',
})
}
export function adminListEventRegistrations(eventId: number) {
return request(`/admin/events/${eventId}/registrations`)
}
export function adminCreateEventRegistration(eventId: number, payload: Record<string, any>) {
return request(`/admin/events/${eventId}/registrations`, {
method: 'POST',
body: JSON.stringify(payload),
})
}
export function adminUpdateEventRegistration(eventId: number, registrationId: number, payload: Record<string, any>) {
return request(`/admin/events/${eventId}/registrations/${registrationId}`, {
method: 'PUT',
body: JSON.stringify(payload),
})
}
export function adminDeleteEventRegistration(eventId: number, registrationId: number) {
return request(`/admin/events/${eventId}/registrations/${registrationId}`, {
method: 'DELETE',
})
}
export function adminListEventPhotos(eventId: number) {
return request(`/admin/events/${eventId}/photos`)
}
export function adminCreateEventPhoto(eventId: number, payload: Record<string, any>) {
return request(`/admin/events/${eventId}/photos`, {
method: 'POST',
body: JSON.stringify(payload),
})
}
export function adminUpdateEventPhoto(eventId: number, photoId: number, payload: Record<string, any>) {
return request(`/admin/events/${eventId}/photos/${photoId}`, {
method: 'PUT',
body: JSON.stringify(payload),
})
}
export function adminDeleteEventPhoto(eventId: number, photoId: number) {
return request(`/admin/events/${eventId}/photos/${photoId}`, {
method: 'DELETE',
})
}
export function adminAuditEvent(eventId: number, payload: { audit_status: string, reject_reason?: string }) {
return request(`/admin/events/${eventId}/audit`, {
method: 'PATCH',
body: JSON.stringify(payload),
})
}
export function adminBatchAuditEvents(payload: { ids: number[], audit_status: string, reject_reason?: string }) {
return request('/admin/events/batch-audit', {
method: 'POST',
body: JSON.stringify(payload),
})
}
export function adminListShooting(params: Record<string, any>) {
const q = new URLSearchParams()
Object.entries(params || {}).forEach(([k, v]) => {
if (v !== undefined && v !== null && String(v).trim() !== '')
q.set(k, String(v))
})
return request(`/admin/shooting?${q.toString()}`)
}
export function adminGetShooting(requestId: number) {
return request(`/admin/shooting/${requestId}`)
}
export function adminCreateShooting(payload: Record<string, any>) {
return request('/admin/shooting', {
method: 'POST',
body: JSON.stringify(payload),
})
}
export function adminUpdateShooting(requestId: number, payload: Record<string, any>) {
return request(`/admin/shooting/${requestId}`, {
method: 'PUT',
body: JSON.stringify(payload),
})
}
export function adminDeleteShooting(requestId: number) {
return request(`/admin/shooting/${requestId}`, {
method: 'DELETE',
})
}
export function adminListShootingApplications(requestId: number) {
return request(`/admin/shooting/${requestId}/applications`)
}
export function adminCreateShootingApplication(requestId: number, payload: Record<string, any>) {
return request(`/admin/shooting/${requestId}/applications`, {
method: 'POST',
body: JSON.stringify(payload),
})
}
export function adminUpdateShootingApplication(requestId: number, applicationId: number, payload: Record<string, any>) {
return request(`/admin/shooting/${requestId}/applications/${applicationId}`, {
method: 'PUT',
body: JSON.stringify(payload),
})
}
export function adminDeleteShootingApplication(requestId: number, applicationId: number) {
return request(`/admin/shooting/${requestId}/applications/${applicationId}`, {
method: 'DELETE',
})
}
export function adminAuditShooting(requestId: number, payload: { audit_status: string, reject_reason?: string }) {
return request(`/admin/shooting/${requestId}/audit`, {
method: 'PATCH',
body: JSON.stringify(payload),
})
}
export function adminBatchAuditShooting(payload: { ids: number[], audit_status: string, reject_reason?: string }) {
return request('/admin/shooting/batch-audit', {
method: 'POST',
body: JSON.stringify(payload),
})
}
export function adminListAppNavConfigs(params: Record<string, any>) {
const q = new URLSearchParams()
Object.entries(params || {}).forEach(([k, v]) => {
if (v !== undefined && v !== null && String(v).trim() !== '')
q.set(k, String(v))
})
return request(`/admin/app-nav-configs?${q.toString()}`)
}
export function adminCreateAppNavConfig(payload: Record<string, any>) {
return request('/admin/app-nav-configs', {
method: 'POST',
body: JSON.stringify(payload),
})
}
export function adminUpdateAppNavConfig(id: number, payload: Record<string, any>) {
return request(`/admin/app-nav-configs/${id}`, {
method: 'PUT',
body: JSON.stringify(payload),
})
}
export function adminDeleteAppNavConfig(id: number) {
return request(`/admin/app-nav-configs/${id}`, {
method: 'DELETE',
})
}
export function adminListPromotions(params: Record<string, any>) {
const q = new URLSearchParams()
Object.entries(params || {}).forEach(([k, v]) => {
if (v !== undefined && v !== null && String(v).trim() !== '')
q.set(k, String(v))
})
return request(`/admin/promotions?${q.toString()}`)
}
export function adminCreatePromotion(payload: Record<string, any>) {
return request('/admin/promotions', {
method: 'POST',
body: JSON.stringify(payload),
})
}
export function adminUpdatePromotion(id: number, payload: Record<string, any>) {
return request(`/admin/promotions/${id}`, {
method: 'PUT',
body: JSON.stringify(payload),
})
}
export function adminDeletePromotion(id: number) {
return request(`/admin/promotions/${id}`, {
method: 'DELETE',
})
}
export function adminPromotionLinkOptions(linkType: 'spot' | 'event' | 'shooting', keyword = '') {
const q = new URLSearchParams()
q.set('link_type', linkType)
if (keyword.trim())
q.set('keyword', keyword.trim())
return request(`/admin/promotion-link-options?${q.toString()}`)
}
export function adminListMembershipPlans(params: Record<string, any>) {
const q = new URLSearchParams()
Object.entries(params || {}).forEach(([k, v]) => {
if (v !== undefined && v !== null && String(v).trim() !== '')
q.set(k, String(v))
})
return request(`/admin/membership/plans?${q.toString()}`)
}
export function adminCreateMembershipPlan(payload: Record<string, any>) {
return request('/admin/membership/plans', {
method: 'POST',
body: JSON.stringify(payload),
})
}
export function adminUpdateMembershipPlan(id: number, payload: Record<string, any>) {
return request(`/admin/membership/plans/${id}`, {
method: 'PUT',
body: JSON.stringify(payload),
})
}
export function adminDeleteMembershipPlan(id: number) {
return request(`/admin/membership/plans/${id}`, {
method: 'DELETE',
})
}
export function adminListUserMemberships(params: Record<string, any>) {
const q = new URLSearchParams()
Object.entries(params || {}).forEach(([k, v]) => {
if (v !== undefined && v !== null && String(v).trim() !== '')
q.set(k, String(v))
})
return request(`/admin/membership/user-memberships?${q.toString()}`)
}
export function adminCreateUserMembership(payload: Record<string, any>) {
return request('/admin/membership/user-memberships', {
method: 'POST',
body: JSON.stringify(payload),
})
}
export function adminUpdateUserMembership(id: number, payload: Record<string, any>) {
return request(`/admin/membership/user-memberships/${id}`, {
method: 'PUT',
body: JSON.stringify(payload),
})
}
export function adminDeleteUserMembership(id: number) {
return request(`/admin/membership/user-memberships/${id}`, {
method: 'DELETE',
})
}
export function adminListPointLedger(params: Record<string, any>) {
const q = new URLSearchParams()
Object.entries(params || {}).forEach(([k, v]) => {
if (v !== undefined && v !== null && String(v).trim() !== '')
q.set(k, String(v))
})
return request(`/admin/points/ledger?${q.toString()}`)
}
export function adminAdjustPoints(payload: Record<string, any>) {
return request('/admin/points/adjust', {
method: 'POST',
body: JSON.stringify(payload),
})
}
export function adminRollbackPointLedger(ledgerId: number) {
return request(`/admin/points/ledger/${ledgerId}/rollback`, {
method: 'POST',
})
}
export function adminListNotifications(params: Record<string, any>) {
const q = new URLSearchParams()
Object.entries(params || {}).forEach(([k, v]) => {
if (v !== undefined && v !== null && String(v).trim() !== '')
q.set(k, String(v))
})
return request(`/admin/notifications?${q.toString()}`)
}
export function adminCreateNotification(payload: Record<string, any>) {
return request('/admin/notifications', {
method: 'POST',
body: JSON.stringify(payload),
})
}
export function adminUpdateNotification(id: number, payload: Record<string, any>) {
return request(`/admin/notifications/${id}`, {
method: 'PUT',
body: JSON.stringify(payload),
})
}
export function adminDeleteNotification(id: number) {
return request(`/admin/notifications/${id}`, {
method: 'DELETE',
})
}
export function adminListAuditLogs(params: Record<string, any>) {
const q = new URLSearchParams()
Object.entries(params || {}).forEach(([k, v]) => {
if (v !== undefined && v !== null && String(v).trim() !== '')
q.set(k, String(v))
})
return request(`/admin/audit-logs?${q.toString()}`)
}
export function adminCreateAuditLog(payload: Record<string, any>) {
return request('/admin/audit-logs', {
method: 'POST',
body: JSON.stringify(payload),
})
}
export function adminListReports(params: Record<string, any>) {
const q = new URLSearchParams()
Object.entries(params || {}).forEach(([k, v]) => {
if (v !== undefined && v !== null && String(v).trim() !== '')
q.set(k, String(v))
})
return request(`/admin/reports?${q.toString()}`)
}
export function adminUpdateReport(id: number, payload: Record<string, any>) {
return request(`/admin/reports/${id}`, {
method: 'PUT',
body: JSON.stringify(payload),
})
}
export function adminDeleteReport(id: number) {
return request(`/admin/reports/${id}`, {
method: 'DELETE',
})
}
export function adminListSystemConfigs(params: Record<string, any>) {
const q = new URLSearchParams()
Object.entries(params || {}).forEach(([k, v]) => {
if (v !== undefined && v !== null && String(v).trim() !== '')
q.set(k, String(v))
})
return request(`/admin/system-configs?${q.toString()}`)
}
export function adminCreateSystemConfig(payload: Record<string, any>) {
return request('/admin/system-configs', {
method: 'POST',
body: JSON.stringify(payload),
})
}
export function adminUpdateSystemConfig(id: number, payload: Record<string, any>) {
return request(`/admin/system-configs/${id}`, {
method: 'PUT',
body: JSON.stringify(payload),
})
}
export function adminDeleteSystemConfig(id: number) {
return request(`/admin/system-configs/${id}`, {
method: 'DELETE',
})
}