朋友圈

This commit is contained in:
2025-12-08 09:07:56 +08:00
parent c26c3ad1be
commit 05a8422007
23 changed files with 3229 additions and 9 deletions

View File

@@ -6,9 +6,20 @@ import type { Attachment, PaginatedResponse } from '@/types/api'
*/
// 上传附件
export function uploadAttachment(file: File, type: 'image' | 'video' | 'file') {
export function uploadAttachment(file: File, type?: 'image' | 'video' | 'file') {
const formData = new FormData()
formData.append('file', file)
// 自动检测类型
if (!type) {
if (file.type.startsWith('image/')) {
type = 'image'
} else if (file.type.startsWith('video/')) {
type = 'video'
} else {
type = 'file'
}
}
formData.append('type', type)
return request.post<Attachment>('/attachments/upload', formData, {

135
src/api/modules/moment.ts Normal file
View File

@@ -0,0 +1,135 @@
/**
* 朋友圈相关 API
*/
import request from '../request'
import type {
Moment,
MomentLike,
MomentComment,
MomentNotification,
CreateMomentRequest,
CreateCommentRequest,
MarkReadRequest,
PaginatedResponse,
} from '@/types/moment'
// ==========================================
// 动态相关
// ==========================================
/**
* 发布动态
*/
export const createMoment = (data: CreateMomentRequest) => {
return request.post<Moment>('/moments', data)
}
/**
* 获取好友动态列表
*/
export const getMoments = (page = 1, pageSize = 20) => {
return request.get<PaginatedResponse<Moment>>('/moments', {
params: { page, page_size: pageSize },
})
}
/**
* 获取动态详情
*/
export const getMomentDetail = (id: number) => {
return request.get<Moment>(`/moments/${id}`)
}
/**
* 删除动态
*/
export const deleteMoment = (id: number) => {
return request.delete(`/moments/${id}`)
}
/**
* 获取指定用户的动态列表
*/
export const getUserMoments = (userId: string, page = 1, pageSize = 20) => {
return request.get<PaginatedResponse<Moment>>(`/moments/user/${userId}`, {
params: { page, page_size: pageSize },
})
}
// ==========================================
// 点赞相关
// ==========================================
/**
* 点赞动态
*/
export const likeMoment = (id: number) => {
return request.post(`/moments/${id}/like`)
}
/**
* 取消点赞
*/
export const unlikeMoment = (id: number) => {
return request.delete(`/moments/${id}/like`)
}
/**
* 获取动态的点赞列表
*/
export const getMomentLikes = (momentId: number) => {
return request.get<MomentLike[]>(`/moments/${momentId}/likes`)
}
// ==========================================
// 评论相关
// ==========================================
/**
* 获取动态的评论列表
*/
export const getMomentComments = (momentId: number) => {
return request.get<MomentComment[]>(`/moments/${momentId}/comments`)
}
/**
* 发表评论
*/
export const createComment = (momentId: number, data: CreateCommentRequest) => {
return request.post<MomentComment>(`/moments/${momentId}/comments`, data)
}
/**
* 删除评论
*/
export const deleteComment = (commentId: number) => {
return request.delete(`/moments/comments/${commentId}`)
}
// ==========================================
// 通知相关
// ==========================================
/**
* 获取朋友圈通知列表
*/
export const getNotifications = (page = 1, pageSize = 20) => {
return request.get<PaginatedResponse<MomentNotification>>('/moments/notifications', {
params: { page, page_size: pageSize },
})
}
/**
* 标记通知为已读
*/
export const markNotificationsRead = (data: MarkReadRequest) => {
return request.post('/moments/notifications/read', data)
}
/**
* 获取未读通知数量
*/
export const getUnreadCount = () => {
return request.get<{ count: number }>('/moments/notifications/unread-count')
}

View File

@@ -1,13 +1,15 @@
import type { ChatMessage } from '@/types/api'
import type { MomentNotifPayload } from '@/types/moment'
export interface WebSocketMessage {
request_type?: string
clientId?: string
data?: ChatMessage
data?: ChatMessage | MomentNotifPayload
}
export type MessageHandler = (message: ChatMessage) => void
export type SignalHandler = (message: ChatMessage) => void
export type MomentNotifHandler = (payload: MomentNotifPayload) => void
class WebSocketManager {
private ws: WebSocket | null = null
@@ -15,6 +17,7 @@ class WebSocketManager {
private userId: string | null = null
private messageHandlers: MessageHandler[] = []
private signalHandlers: SignalHandler[] = []
private momentNotifHandlers: MomentNotifHandler[] = []
private reconnectAttempts = 0
private maxReconnectAttempts = 5
private reconnectDelay = 3000
@@ -58,7 +61,12 @@ class WebSocketManager {
// 处理接收消息
if (payload.request_type === 'receive_message' && payload.data) {
this.handleMessage(payload.data)
this.handleMessage(payload.data as ChatMessage)
}
// 处理朋友圈通知
if (payload.request_type === 'moment_notification' && payload.data) {
this.handleMomentNotification(payload.data as MomentNotifPayload)
}
} catch (e) {
// Ignore single line parse error
@@ -97,6 +105,7 @@ class WebSocketManager {
this.userId = null
this.messageHandlers = []
this.signalHandlers = []
this.momentNotifHandlers = []
}
/**
@@ -140,6 +149,30 @@ class WebSocketManager {
}
}
/**
* 添加朋友圈通知处理器
*/
onMomentNotification(handler: MomentNotifHandler) {
this.momentNotifHandlers.push(handler)
}
/**
* 移除朋友圈通知处理器
*/
offMomentNotification(handler: MomentNotifHandler) {
const index = this.momentNotifHandlers.indexOf(handler)
if (index > -1) {
this.momentNotifHandlers.splice(index, 1)
}
}
/**
* 内部处理朋友圈通知
*/
private handleMomentNotification(payload: MomentNotifPayload) {
this.momentNotifHandlers.forEach(handler => handler(payload))
}
/**
* 内部处理接收到的消息
*/