392 lines
10 KiB
TypeScript
392 lines
10 KiB
TypeScript
|
|
/**
|
|||
|
|
* 群组服务
|
|||
|
|
* 处理群组管理、成员管理、群设置、群公告等功能
|
|||
|
|
* 使用新的 API 接口: /api/v1/groups (RESTful action 风格)
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
import { api } from './api';
|
|||
|
|
import {
|
|||
|
|
GroupResponse,
|
|||
|
|
GroupMemberResponse,
|
|||
|
|
GroupAnnouncementResponse,
|
|||
|
|
GroupListResponse,
|
|||
|
|
GroupMemberListResponse,
|
|||
|
|
GroupAnnouncementListResponse,
|
|||
|
|
CreateGroupRequest,
|
|||
|
|
InviteMembersRequest,
|
|||
|
|
TransferOwnerRequest,
|
|||
|
|
SetRoleRequest,
|
|||
|
|
SetNicknameRequest,
|
|||
|
|
SetMuteAllRequest,
|
|||
|
|
SetJoinTypeRequest,
|
|||
|
|
CreateAnnouncementRequest,
|
|||
|
|
MyMemberInfoResponse,
|
|||
|
|
SetGroupAvatarRequest,
|
|||
|
|
HandleGroupRequestAction,
|
|||
|
|
} from '../types/dto';
|
|||
|
|
|
|||
|
|
// 群组服务类(纯 API 层)
|
|||
|
|
// SQLite/内存缓存编排由 groupManager 统一处理
|
|||
|
|
class GroupService {
|
|||
|
|
async fetchGroupsFromApi(page = 1, pageSize = 20): Promise<GroupListResponse> {
|
|||
|
|
const response = await api.get<GroupListResponse>('/groups/list', {
|
|||
|
|
page,
|
|||
|
|
page_size: pageSize,
|
|||
|
|
});
|
|||
|
|
return response.data;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
async fetchGroupFromApi(id: number | string): Promise<GroupResponse> {
|
|||
|
|
const response = await api.get<GroupResponse>('/groups/get', {
|
|||
|
|
group_id: String(id),
|
|||
|
|
});
|
|||
|
|
return response.data;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
async fetchMembersFromApi(
|
|||
|
|
groupId: number | string,
|
|||
|
|
page = 1,
|
|||
|
|
pageSize = 50
|
|||
|
|
): Promise<GroupMemberListResponse> {
|
|||
|
|
const response = await api.get<GroupMemberListResponse>(
|
|||
|
|
'/groups/get_members',
|
|||
|
|
{
|
|||
|
|
group_id: String(groupId),
|
|||
|
|
page,
|
|||
|
|
page_size: pageSize,
|
|||
|
|
}
|
|||
|
|
);
|
|||
|
|
return response.data;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// ==================== 群组管理 ====================
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 创建群组
|
|||
|
|
* POST /api/v1/groups/create
|
|||
|
|
*/
|
|||
|
|
async createGroup(data: CreateGroupRequest): Promise<GroupResponse> {
|
|||
|
|
const response = await api.post<GroupResponse>('/groups/create', data);
|
|||
|
|
return response.data;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 获取群组列表
|
|||
|
|
* GET /api/v1/groups/list
|
|||
|
|
*/
|
|||
|
|
async getGroups(page = 1, pageSize = 20): Promise<GroupListResponse> {
|
|||
|
|
return this.fetchGroupsFromApi(page, pageSize);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 获取群组详情
|
|||
|
|
* GET /api/v1/groups/get?group_id=xxx
|
|||
|
|
*/
|
|||
|
|
async getGroup(id: number | string): Promise<GroupResponse> {
|
|||
|
|
return this.fetchGroupFromApi(id);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 获取当前用户在群组中的成员信息
|
|||
|
|
* GET /api/v1/groups/get_my_info?group_id=xxx
|
|||
|
|
*/
|
|||
|
|
async getMyMemberInfo(groupId: number | string): Promise<MyMemberInfoResponse> {
|
|||
|
|
const response = await api.get<MyMemberInfoResponse>('/groups/get_my_info', {
|
|||
|
|
group_id: String(groupId),
|
|||
|
|
});
|
|||
|
|
return response.data;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 解散群组
|
|||
|
|
* POST /api/v1/groups/dissolve
|
|||
|
|
* Body: { "group_id": "xxx" }
|
|||
|
|
*/
|
|||
|
|
async dissolveGroup(id: number | string): Promise<void> {
|
|||
|
|
await api.post('/groups/dissolve', {
|
|||
|
|
group_id: String(id),
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 转让群主
|
|||
|
|
* POST /api/v1/groups/transfer
|
|||
|
|
* Body: { "group_id": "xxx", "new_owner_id": "xxx" }
|
|||
|
|
*/
|
|||
|
|
async transferOwner(id: number | string, data: TransferOwnerRequest): Promise<void> {
|
|||
|
|
await api.post('/groups/transfer', {
|
|||
|
|
group_id: String(id),
|
|||
|
|
...data,
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// ==================== 成员管理 ====================
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 邀请成员加入群组
|
|||
|
|
* POST /api/v1/groups/invite_members
|
|||
|
|
* Body: { "group_id": "xxx", "user_ids": [...] }
|
|||
|
|
*/
|
|||
|
|
async inviteMembers(groupId: number | string, data: InviteMembersRequest): Promise<void> {
|
|||
|
|
await api.post('/groups/invite_members', {
|
|||
|
|
group_id: String(groupId),
|
|||
|
|
...data,
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 申请加入群组
|
|||
|
|
* POST /api/v1/groups/join
|
|||
|
|
* Body: { "group_id": "xxx" }
|
|||
|
|
*/
|
|||
|
|
async joinGroup(groupId: number | string): Promise<void> {
|
|||
|
|
await api.post('/groups/join', {
|
|||
|
|
group_id: String(groupId),
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 响应群邀请
|
|||
|
|
* POST /api/v1/groups/respond_invite
|
|||
|
|
*/
|
|||
|
|
async respondInvite(data: HandleGroupRequestAction): Promise<void> {
|
|||
|
|
await api.post('/groups/respond_invite', data);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 审批主动加群申请
|
|||
|
|
* POST /api/v1/groups/set_group_add_request
|
|||
|
|
*/
|
|||
|
|
async reviewJoinRequest(data: HandleGroupRequestAction): Promise<void> {
|
|||
|
|
await api.post('/groups/set_group_add_request', data);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 退出群组
|
|||
|
|
* POST /api/v1/groups/set_group_leave
|
|||
|
|
* Body: { "group_id": "xxx" }
|
|||
|
|
*/
|
|||
|
|
async leaveGroup(groupId: number | string): Promise<void> {
|
|||
|
|
await api.post('/groups/set_group_leave', {
|
|||
|
|
group_id: String(groupId),
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 获取群组成员列表
|
|||
|
|
* GET /api/v1/groups/get_members?group_id=xxx
|
|||
|
|
*/
|
|||
|
|
async getMembers(groupId: number | string, page = 1, pageSize = 50): Promise<GroupMemberListResponse> {
|
|||
|
|
return this.fetchMembersFromApi(groupId, page, pageSize);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 移除群成员(踢人)
|
|||
|
|
* POST /api/v1/groups/set_group_kick
|
|||
|
|
* Body: { "group_id": "xxx", "user_id": "xxx", "reject_add_request": false }
|
|||
|
|
*/
|
|||
|
|
async removeMember(groupId: number | string, userId: string): Promise<void> {
|
|||
|
|
await api.post('/groups/set_group_kick', {
|
|||
|
|
group_id: String(groupId),
|
|||
|
|
user_id: userId,
|
|||
|
|
reject_add_request: false,
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 设置成员角色(设置/取消管理员)
|
|||
|
|
* POST /api/v1/groups/set_group_admin
|
|||
|
|
* Body: { "group_id": "xxx", "user_id": "xxx", "enable": true }
|
|||
|
|
*/
|
|||
|
|
async setMemberRole(
|
|||
|
|
groupId: number | string,
|
|||
|
|
userId: string,
|
|||
|
|
data: SetRoleRequest
|
|||
|
|
): Promise<void> {
|
|||
|
|
await api.post('/groups/set_group_admin', {
|
|||
|
|
group_id: String(groupId),
|
|||
|
|
user_id: userId,
|
|||
|
|
enable: data.role === 'admin',
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 设置群昵称
|
|||
|
|
* POST /api/v1/groups/set_nickname
|
|||
|
|
* Body: { "group_id": "xxx", "nickname": "xxx" }
|
|||
|
|
*/
|
|||
|
|
async setNickname(groupId: number | string, data: SetNicknameRequest): Promise<void> {
|
|||
|
|
await api.post('/groups/set_nickname', {
|
|||
|
|
group_id: String(groupId),
|
|||
|
|
...data,
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 禁言/解禁成员
|
|||
|
|
* POST /api/v1/groups/set_group_ban
|
|||
|
|
* Body: { "group_id": "xxx", "user_id": "xxx", "duration": 3600 }
|
|||
|
|
* @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/set_group_ban', {
|
|||
|
|
group_id: String(groupId),
|
|||
|
|
user_id: userId,
|
|||
|
|
duration: duration,
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// ==================== 群设置 ====================
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 设置全员禁言
|
|||
|
|
* POST /api/v1/groups/set_group_whole_ban
|
|||
|
|
* Body: { "group_id": "xxx", "enable": true }
|
|||
|
|
*/
|
|||
|
|
async setMuteAll(groupId: number | string, data: SetMuteAllRequest): Promise<void> {
|
|||
|
|
await api.post('/groups/set_group_whole_ban', {
|
|||
|
|
group_id: String(groupId),
|
|||
|
|
enable: data.mute_all,
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 设置加群方式
|
|||
|
|
* POST /api/v1/groups/set_join_type
|
|||
|
|
* Body: { "group_id": "xxx", "join_type": 1 }
|
|||
|
|
*/
|
|||
|
|
async setJoinType(groupId: number | string, data: SetJoinTypeRequest): Promise<void> {
|
|||
|
|
await api.post('/groups/set_join_type', {
|
|||
|
|
group_id: String(groupId),
|
|||
|
|
...data,
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 设置群名称
|
|||
|
|
* POST /api/v1/groups/set_group_name
|
|||
|
|
* Body: { "group_id": "xxx", "group_name": "xxx" }
|
|||
|
|
*/
|
|||
|
|
async setGroupName(groupId: number | string, groupName: string): Promise<void> {
|
|||
|
|
await api.post('/groups/set_group_name', {
|
|||
|
|
group_id: String(groupId),
|
|||
|
|
group_name: groupName,
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 设置群头像
|
|||
|
|
* POST /api/v1/groups/set_group_avatar
|
|||
|
|
* Body: { "group_id": "xxx", "avatar": "xxx" }
|
|||
|
|
*/
|
|||
|
|
async setGroupAvatar(groupId: number | string, avatarUrl: string): Promise<GroupResponse> {
|
|||
|
|
const response = await api.post<GroupResponse>('/groups/set_group_avatar', {
|
|||
|
|
group_id: String(groupId),
|
|||
|
|
avatar: avatarUrl,
|
|||
|
|
});
|
|||
|
|
return response.data;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// ==================== 群公告 ====================
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 创建群公告
|
|||
|
|
* POST /api/v1/groups/create_announcement
|
|||
|
|
* Body: { "group_id": "xxx", "content": "xxx" }
|
|||
|
|
*/
|
|||
|
|
async createAnnouncement(
|
|||
|
|
groupId: number | string,
|
|||
|
|
data: CreateAnnouncementRequest
|
|||
|
|
): Promise<GroupAnnouncementResponse> {
|
|||
|
|
const response = await api.post<GroupAnnouncementResponse>(
|
|||
|
|
'/groups/create_announcement',
|
|||
|
|
{
|
|||
|
|
group_id: String(groupId),
|
|||
|
|
...data,
|
|||
|
|
}
|
|||
|
|
);
|
|||
|
|
return response.data;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 获取群公告列表
|
|||
|
|
* GET /api/v1/groups/get_announcements?group_id=xxx
|
|||
|
|
*/
|
|||
|
|
async getAnnouncements(
|
|||
|
|
groupId: number | string,
|
|||
|
|
page = 1,
|
|||
|
|
pageSize = 20
|
|||
|
|
): Promise<GroupAnnouncementListResponse> {
|
|||
|
|
try {
|
|||
|
|
const response = await api.get<GroupAnnouncementListResponse>(
|
|||
|
|
'/groups/get_announcements',
|
|||
|
|
{
|
|||
|
|
group_id: String(groupId),
|
|||
|
|
page,
|
|||
|
|
page_size: pageSize,
|
|||
|
|
}
|
|||
|
|
);
|
|||
|
|
return response.data;
|
|||
|
|
} catch (error) {
|
|||
|
|
console.error('获取群公告列表失败:', error);
|
|||
|
|
return {
|
|||
|
|
list: [],
|
|||
|
|
total: 0,
|
|||
|
|
page: 1,
|
|||
|
|
page_size: pageSize,
|
|||
|
|
total_pages: 0,
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* 删除群公告
|
|||
|
|
* POST /api/v1/groups/delete_announcement
|
|||
|
|
* Body: { "group_id": "xxx", "announcement_id": "xxx" }
|
|||
|
|
*/
|
|||
|
|
async deleteAnnouncement(groupId: number | string, announcementId: number): Promise<void> {
|
|||
|
|
await api.post('/groups/delete_announcement', {
|
|||
|
|
group_id: String(groupId),
|
|||
|
|
announcement_id: announcementId,
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// ==================== 兼容旧API的方法(将逐步废弃) ====================
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* @deprecated 使用 setGroupName 代替
|
|||
|
|
*/
|
|||
|
|
async updateGroup(id: number, data: { name: string }): Promise<GroupResponse> {
|
|||
|
|
await this.setGroupName(id, data.name);
|
|||
|
|
return this.getGroup(id);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 导出群组服务实例
|
|||
|
|
export const groupService = new GroupService();
|
|||
|
|
|
|||
|
|
// 导出类型以方便使用
|
|||
|
|
export type {
|
|||
|
|
GroupResponse,
|
|||
|
|
GroupMemberResponse,
|
|||
|
|
GroupAnnouncementResponse,
|
|||
|
|
GroupListResponse,
|
|||
|
|
GroupMemberListResponse,
|
|||
|
|
GroupAnnouncementListResponse,
|
|||
|
|
CreateGroupRequest,
|
|||
|
|
InviteMembersRequest,
|
|||
|
|
TransferOwnerRequest,
|
|||
|
|
SetRoleRequest,
|
|||
|
|
SetNicknameRequest,
|
|||
|
|
SetMuteAllRequest,
|
|||
|
|
SetJoinTypeRequest,
|
|||
|
|
CreateAnnouncementRequest,
|
|||
|
|
SetGroupAvatarRequest,
|
|||
|
|
};
|