Merge pull request #434 from DuckyProject/feat/announcement-system-pr-upstream

feat(announcements): admin/user announcement system
This commit is contained in:
Wesley Liddick
2026-02-02 10:50:26 +08:00
committed by GitHub
70 changed files with 12358 additions and 71 deletions

View File

@@ -0,0 +1,71 @@
/**
* Admin Announcements API endpoints
*/
import { apiClient } from '../client'
import type {
Announcement,
AnnouncementUserReadStatus,
BasePaginationResponse,
CreateAnnouncementRequest,
UpdateAnnouncementRequest
} from '@/types'
export async function list(
page: number = 1,
pageSize: number = 20,
filters?: {
status?: string
search?: string
}
): Promise<BasePaginationResponse<Announcement>> {
const { data } = await apiClient.get<BasePaginationResponse<Announcement>>('/admin/announcements', {
params: { page, page_size: pageSize, ...filters }
})
return data
}
export async function getById(id: number): Promise<Announcement> {
const { data } = await apiClient.get<Announcement>(`/admin/announcements/${id}`)
return data
}
export async function create(request: CreateAnnouncementRequest): Promise<Announcement> {
const { data } = await apiClient.post<Announcement>('/admin/announcements', request)
return data
}
export async function update(id: number, request: UpdateAnnouncementRequest): Promise<Announcement> {
const { data } = await apiClient.put<Announcement>(`/admin/announcements/${id}`, request)
return data
}
export async function deleteAnnouncement(id: number): Promise<{ message: string }> {
const { data } = await apiClient.delete<{ message: string }>(`/admin/announcements/${id}`)
return data
}
export async function getReadStatus(
id: number,
page: number = 1,
pageSize: number = 20,
search: string = ''
): Promise<BasePaginationResponse<AnnouncementUserReadStatus>> {
const { data } = await apiClient.get<BasePaginationResponse<AnnouncementUserReadStatus>>(
`/admin/announcements/${id}/read-status`,
{ params: { page, page_size: pageSize, search } }
)
return data
}
const announcementsAPI = {
list,
getById,
create,
update,
delete: deleteAnnouncement,
getReadStatus
}
export default announcementsAPI

View File

@@ -10,6 +10,7 @@ import accountsAPI from './accounts'
import proxiesAPI from './proxies'
import redeemAPI from './redeem'
import promoAPI from './promo'
import announcementsAPI from './announcements'
import settingsAPI from './settings'
import systemAPI from './system'
import subscriptionsAPI from './subscriptions'
@@ -30,6 +31,7 @@ export const adminAPI = {
proxies: proxiesAPI,
redeem: redeemAPI,
promo: promoAPI,
announcements: announcementsAPI,
settings: settingsAPI,
system: systemAPI,
subscriptions: subscriptionsAPI,
@@ -48,6 +50,7 @@ export {
proxiesAPI,
redeemAPI,
promoAPI,
announcementsAPI,
settingsAPI,
systemAPI,
subscriptionsAPI,

View File

@@ -0,0 +1,26 @@
/**
* User Announcements API endpoints
*/
import { apiClient } from './client'
import type { UserAnnouncement } from '@/types'
export async function list(unreadOnly: boolean = false): Promise<UserAnnouncement[]> {
const { data } = await apiClient.get<UserAnnouncement[]>('/announcements', {
params: unreadOnly ? { unread_only: 1 } : {}
})
return data
}
export async function markRead(id: number): Promise<{ message: string }> {
const { data } = await apiClient.post<{ message: string }>(`/announcements/${id}/read`)
return data
}
const announcementsAPI = {
list,
markRead
}
export default announcementsAPI

View File

@@ -16,6 +16,7 @@ export { userAPI } from './user'
export { redeemAPI, type RedeemHistoryItem } from './redeem'
export { userGroupsAPI } from './groups'
export { totpAPI } from './totp'
export { default as announcementsAPI } from './announcements'
// Admin APIs
export { adminAPI } from './admin'