Files
frontend/src/services/groupService.ts
lafay 26ae288470
All checks were successful
Frontend CI / build-and-push-web (push) Successful in 5m8s
Frontend CI / ota-android (push) Successful in 11m22s
Frontend CI / build-android-apk (push) Successful in 45m46s
refactor: standardize pagination response structure and enhance cursor handling
- Update various services and hooks to replace 'items' with 'list' for consistency in pagination responses.
- Modify PostRepository, commentService, groupService, messageService, and postService to align with the new response structure.
- Enhance cursor pagination logic in hooks and components to ensure proper handling of pagination states.
- Refactor HomeScreen, PostDetailScreen, SearchScreen, and other components to utilize the updated pagination structure.
2026-03-23 03:58:26 +08:00

428 lines
11 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 群组服务
* 处理群组管理、成员管理、群设置、群公告等功能
* 使用 RESTful API: /api/v1/groups
*/
import { api } from './api';
import {
GroupResponse,
GroupMemberResponse,
GroupAnnouncementResponse,
GroupListResponse,
GroupMemberListResponse,
GroupAnnouncementListResponse,
CreateGroupRequest,
InviteMembersRequest,
TransferOwnerRequest,
SetRoleRequest,
SetNicknameRequest,
SetMuteAllRequest,
SetJoinTypeRequest,
CreateAnnouncementRequest,
MyMemberInfoResponse,
SetGroupAvatarRequest,
HandleGroupRequestAction,
CursorPaginationRequest,
CursorPaginationResponse,
} from '../types/dto';
// 群组服务类(纯 API 层)
// SQLite/内存缓存编排由 groupManager 统一处理
class GroupService {
async fetchGroupsFromApi(page = 1, pageSize = 20): Promise<GroupListResponse> {
const response = await api.get<GroupListResponse>('/groups', {
page,
page_size: pageSize,
});
return response.data;
}
async fetchGroupFromApi(id: number | string): Promise<GroupResponse> {
const response = await api.get<GroupResponse>(`/groups/${encodeURIComponent(String(id))}`);
return response.data;
}
async fetchMembersFromApi(
groupId: number | string,
page = 1,
pageSize = 50
): Promise<GroupMemberListResponse> {
const response = await api.get<GroupMemberListResponse>(
`/groups/${encodeURIComponent(String(groupId))}/members`,
{
page,
page_size: pageSize,
}
);
return response.data;
}
// ==================== 群组管理 ====================
/**
* 创建群组
* POST /api/v1/groups
*/
async createGroup(data: CreateGroupRequest): Promise<GroupResponse> {
const response = await api.post<GroupResponse>('/groups', data);
return response.data;
}
/**
* 获取群组列表
* GET /api/v1/groups
*/
async getGroups(page = 1, pageSize = 20): Promise<GroupListResponse> {
return this.fetchGroupsFromApi(page, pageSize);
}
/**
* 获取群组详情
* GET /api/v1/groups/:id
*/
async getGroup(id: number | string): Promise<GroupResponse> {
return this.fetchGroupFromApi(id);
}
/**
* 获取当前用户在群组中的成员信息
* GET /api/v1/groups/:id/me
*/
async getMyMemberInfo(groupId: number | string): Promise<MyMemberInfoResponse> {
const response = await api.get<MyMemberInfoResponse>(
`/groups/${encodeURIComponent(String(groupId))}/me`
);
return response.data;
}
/**
* 解散群组
* DELETE /api/v1/groups/:id
*/
async dissolveGroup(id: number | string): Promise<void> {
await api.delete(`/groups/${encodeURIComponent(String(id))}`);
}
/**
* 转让群主
* POST /api/v1/groups/:id/transfer
*/
async transferOwner(id: number | string, data: TransferOwnerRequest): Promise<void> {
await api.post(`/groups/${encodeURIComponent(String(id))}/transfer`, data);
}
// ==================== 成员管理 ====================
/**
* 邀请成员加入群组
* POST /api/v1/groups/:id/invitations
*/
async inviteMembers(groupId: number | string, data: InviteMembersRequest): Promise<void> {
await api.post(`/groups/${encodeURIComponent(String(groupId))}/invitations`, data);
}
/**
* 申请加入群组
* POST /api/v1/groups/:id/join-requests
*/
async joinGroup(groupId: number | string): Promise<void> {
await api.post(`/groups/${encodeURIComponent(String(groupId))}/join-requests`);
}
/**
* 响应群邀请/申请
* POST /api/v1/groups/:id/join-requests/respond
*/
async respondInvite(groupId: number | string, data: HandleGroupRequestAction): Promise<void> {
await api.post(
`/groups/${encodeURIComponent(String(groupId))}/join-requests/respond`,
data
);
}
/**
* 审批主动加群申请
* POST /api/v1/groups/:id/join-requests/handle
*/
async reviewJoinRequest(groupId: number | string, data: HandleGroupRequestAction): Promise<void> {
await api.post(
`/groups/${encodeURIComponent(String(groupId))}/join-requests/handle`,
data
);
}
/**
* 退出群组
* POST /api/v1/groups/:id/leave
*/
async leaveGroup(groupId: number | string): Promise<void> {
await api.post(`/groups/${encodeURIComponent(String(groupId))}/leave`);
}
/**
* 获取群组成员列表
* GET /api/v1/groups/:id/members
*/
async getMembers(groupId: number | string, page = 1, pageSize = 50): Promise<GroupMemberListResponse> {
return this.fetchMembersFromApi(groupId, page, pageSize);
}
/**
* 移除群成员(踢人)
* POST /api/v1/groups/:id/members/kick
*/
async removeMember(groupId: number | string, userId: string): Promise<void> {
await api.post(`/groups/${encodeURIComponent(String(groupId))}/members/kick`, {
user_id: userId,
reject_add_request: false,
});
}
/**
* 设置成员角色(设置/取消管理员)
* PUT /api/v1/groups/:id/members/:user_id/admin
*/
async setMemberRole(
groupId: number | string,
userId: string,
data: SetRoleRequest
): Promise<void> {
await api.put(
`/groups/${encodeURIComponent(String(groupId))}/members/${encodeURIComponent(userId)}/admin`,
{
enable: data.role === 'admin',
}
);
}
/**
* 设置群昵称
* PUT /api/v1/groups/:id/members/me/nickname
*/
async setNickname(groupId: number | string, data: SetNicknameRequest): Promise<void> {
await api.put(`/groups/${encodeURIComponent(String(groupId))}/members/me/nickname`, data);
}
/**
* 禁言/解禁成员
* POST /api/v1/groups/:id/members/ban
* @param groupId 群组ID
* @param userId 用户ID
* @param duration 禁言时长0表示解除禁言
*/
async muteMember(
groupId: number | string,
userId: string,
duration: number = 0
): Promise<void> {
await api.post(`/groups/${encodeURIComponent(String(groupId))}/members/ban`, {
user_id: userId,
duration: duration,
});
}
// ==================== 群设置 ====================
/**
* 设置全员禁言
* PUT /api/v1/groups/:id/ban
*/
async setMuteAll(groupId: number | string, data: SetMuteAllRequest): Promise<void> {
await api.put(`/groups/${encodeURIComponent(String(groupId))}/ban`, {
enable: data.mute_all,
});
}
/**
* 设置加群方式
* PUT /api/v1/groups/:id/join-type
*/
async setJoinType(groupId: number | string, data: SetJoinTypeRequest): Promise<void> {
await api.put(`/groups/${encodeURIComponent(String(groupId))}/join-type`, data);
}
/**
* 设置群名称
* PUT /api/v1/groups/:id/name
*/
async setGroupName(groupId: number | string, groupName: string): Promise<void> {
await api.put(`/groups/${encodeURIComponent(String(groupId))}/name`, {
group_name: groupName,
});
}
/**
* 设置群头像
* PUT /api/v1/groups/:id/avatar
*/
async setGroupAvatar(groupId: number | string, avatarUrl: string): Promise<GroupResponse> {
const response = await api.put<GroupResponse>(
`/groups/${encodeURIComponent(String(groupId))}/avatar`,
{
avatar: avatarUrl,
}
);
return response.data;
}
// ==================== 群公告 ====================
/**
* 创建群公告
* POST /api/v1/groups/:id/announcements
*/
async createAnnouncement(
groupId: number | string,
data: CreateAnnouncementRequest
): Promise<GroupAnnouncementResponse> {
const response = await api.post<GroupAnnouncementResponse>(
`/groups/${encodeURIComponent(String(groupId))}/announcements`,
data
);
return response.data;
}
/**
* 获取群公告列表
* GET /api/v1/groups/:id/announcements
*/
async getAnnouncements(
groupId: number | string,
page = 1,
pageSize = 20
): Promise<GroupAnnouncementListResponse> {
try {
const response = await api.get<GroupAnnouncementListResponse>(
`/groups/${encodeURIComponent(String(groupId))}/announcements`,
{
page,
page_size: pageSize,
}
);
return response.data;
} catch (error) {
console.error('获取群公告列表失败:', error);
return {
list: [],
total: 0,
page: 1,
page_size: pageSize,
total_pages: 0,
};
}
}
/**
* 删除群公告
* DELETE /api/v1/groups/:id/announcements/:announcement_id
*/
async deleteAnnouncement(groupId: number | string, announcementId: number): Promise<void> {
await api.delete(
`/groups/${encodeURIComponent(String(groupId))}/announcements/${encodeURIComponent(String(announcementId))}`
);
}
// ==================== 游标分页方法 ====================
/**
* 获取群组列表(游标分页)
* GET /api/v1/groups/cursor
* @param params 游标分页请求参数
*/
async getGroupsCursor(
params: CursorPaginationRequest = {}
): Promise<CursorPaginationResponse<GroupResponse>> {
try {
const response = await api.get<CursorPaginationResponse<GroupResponse>>('/groups/cursor', {
params,
});
return response.data;
} catch (error) {
console.error('获取群组列表失败:', error);
return {
list: [],
next_cursor: null,
prev_cursor: null,
has_more: false,
};
}
}
/**
* 获取群组成员列表(游标分页)
* GET /api/v1/groups/:id/members/cursor
* @param groupId 群组ID
* @param params 游标分页请求参数
*/
async getGroupMembersCursor(
groupId: number | string,
params: CursorPaginationRequest = {}
): Promise<CursorPaginationResponse<GroupMemberResponse>> {
try {
const response = await api.get<CursorPaginationResponse<GroupMemberResponse>>(
`/groups/${encodeURIComponent(String(groupId))}/members/cursor`,
{ params }
);
return response.data;
} catch (error) {
console.error('获取群组成员列表失败:', error);
return {
list: [],
next_cursor: null,
prev_cursor: null,
has_more: false,
};
}
}
/**
* 获取群公告列表(游标分页)
* GET /api/v1/groups/:id/announcements/cursor
* @param groupId 群组ID
* @param params 游标分页请求参数
*/
async getGroupAnnouncementsCursor(
groupId: number | string,
params: CursorPaginationRequest = {}
): Promise<CursorPaginationResponse<GroupAnnouncementResponse>> {
try {
const response = await api.get<CursorPaginationResponse<GroupAnnouncementResponse>>(
`/groups/${encodeURIComponent(String(groupId))}/announcements/cursor`,
{ params }
);
return response.data;
} catch (error) {
console.error('获取群公告列表失败:', error);
return {
list: [],
next_cursor: null,
prev_cursor: null,
has_more: false,
};
}
}
}
// 导出群组服务实例
export const groupService = new GroupService();
// 导出类型以方便使用
export type {
GroupResponse,
GroupMemberResponse,
GroupAnnouncementResponse,
GroupListResponse,
GroupMemberListResponse,
GroupAnnouncementListResponse,
CreateGroupRequest,
InviteMembersRequest,
TransferOwnerRequest,
SetRoleRequest,
SetNicknameRequest,
SetMuteAllRequest,
SetJoinTypeRequest,
CreateAnnouncementRequest,
SetGroupAvatarRequest,
};