XuqmGroup-Server/im-service/src/main/java/com/xuqm/im/controller/ImAdminController.java

552 行
27 KiB
Java

package com.xuqm.im.controller;
import com.xuqm.common.model.ApiResponse;
import com.xuqm.common.exception.BusinessException;
import com.xuqm.im.entity.ImBlacklistEntity;
import com.xuqm.im.entity.ImAccountEntity;
import com.xuqm.im.entity.ImGlobalMuteEntity;
import com.xuqm.im.entity.ImGroupEntity;
import com.xuqm.im.entity.ImFriendRequestEntity;
import com.xuqm.im.entity.ImGroupJoinRequestEntity;
import com.xuqm.im.entity.ImMessageEntity;
import com.xuqm.im.entity.KeywordFilterEntity;
import com.xuqm.im.entity.WebhookConfigEntity;
import com.xuqm.im.repository.ImAccountRepository;
import com.xuqm.im.repository.ImGroupRepository;
import com.xuqm.im.repository.ImMessageRepository;
import com.xuqm.im.service.ImAccountService;
import com.xuqm.im.service.BlacklistService;
import com.xuqm.im.service.FriendRequestService;
import com.xuqm.im.service.ImGroupService;
import com.xuqm.im.service.GlobalMuteService;
import com.xuqm.im.service.KeywordFilterService;
import com.xuqm.im.service.MessageService;
import com.xuqm.im.service.OperationLogService;
import com.xuqm.im.service.WebhookConfigService;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/api/im/admin")
public class ImAdminController {
private final ImAccountRepository accountRepository;
private final ImGroupRepository groupRepository;
private final ImMessageRepository messageRepository;
private final ImAccountService accountService;
private final FriendRequestService friendRequestService;
private final BlacklistService blacklistService;
private final ImGroupService groupService;
private final MessageService messageService;
private final WebhookConfigService webhookConfigService;
private final KeywordFilterService keywordFilterService;
private final GlobalMuteService globalMuteService;
private final OperationLogService operationLogService;
public ImAdminController(ImAccountRepository accountRepository,
ImGroupRepository groupRepository,
ImMessageRepository messageRepository,
ImAccountService accountService,
FriendRequestService friendRequestService,
BlacklistService blacklistService,
ImGroupService groupService,
MessageService messageService,
WebhookConfigService webhookConfigService,
KeywordFilterService keywordFilterService,
GlobalMuteService globalMuteService,
OperationLogService operationLogService) {
this.accountRepository = accountRepository;
this.groupRepository = groupRepository;
this.messageRepository = messageRepository;
this.accountService = accountService;
this.friendRequestService = friendRequestService;
this.blacklistService = blacklistService;
this.groupService = groupService;
this.messageService = messageService;
this.webhookConfigService = webhookConfigService;
this.keywordFilterService = keywordFilterService;
this.globalMuteService = globalMuteService;
this.operationLogService = operationLogService;
}
/** List all registered IM users for the given appId. */
@GetMapping("/users")
public ResponseEntity<ApiResponse<Page<ImAccountEntity>>> listUsers(
@RequestParam String appId,
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "20") int size) {
return ResponseEntity.ok(ApiResponse.success(
accountRepository.findByAppId(appId, PageRequest.of(page, size))));
}
/** Ban or unban a user. */
@PutMapping("/users/{userId}/status")
public ResponseEntity<ApiResponse<ImAccountEntity>> updateUserStatus(
@RequestParam String appId,
@PathVariable String userId,
@AuthenticationPrincipal String operatorId,
@RequestBody Map<String, String> body) {
ImAccountEntity account = accountRepository.findByAppIdAndUserId(appId, userId)
.orElseThrow(() -> new BusinessException(404, "账号不存在"));
String status = body.get("status");
if (status == null || status.isBlank()) {
throw new BusinessException(400, "状态不能为空");
}
account.setStatus(ImAccountEntity.Status.valueOf(status.toUpperCase()));
ImAccountEntity saved = accountRepository.save(account);
operationLogService.record(appId, operatorId, "UPDATE_USER_STATUS", "ACCOUNT", userId, status);
return ResponseEntity.ok(ApiResponse.success(saved));
}
2026-04-29 10:04:17 +08:00
/** Update a registered IM user profile without changing userId. */
@PutMapping("/users/{userId}")
public ResponseEntity<ApiResponse<ImAccountEntity>> updateUser(
@RequestParam String appId,
@PathVariable String userId,
@AuthenticationPrincipal String operatorId,
@RequestBody UpdateUserRequest req) {
ImAccountEntity saved = accountService.updateAccount(
appId,
userId,
req.nickname(),
req.avatar(),
req.gender(),
req.status());
operationLogService.record(appId, operatorId, "UPDATE_USER", "ACCOUNT", userId, req.nickname());
return ResponseEntity.ok(ApiResponse.success(saved));
}
/** List all groups for the given appId. */
@GetMapping("/groups")
public ResponseEntity<ApiResponse<List<ImGroupEntity>>> listGroups(@RequestParam String appId) {
return ResponseEntity.ok(ApiResponse.success(groupRepository.findByAppId(appId)));
}
/** Admin registers a new IM user (or returns existing). */
@PostMapping("/users")
public ResponseEntity<ApiResponse<ImAccountEntity>> registerUser(
@RequestParam String appId,
@AuthenticationPrincipal String operatorId,
@RequestBody RegisterUserRequest req) {
2026-04-29 10:04:17 +08:00
ImAccountEntity account = accountService.importAccount(
appId,
req.userId(),
req.nickname(),
req.avatar(),
req.gender(),
req.status());
operationLogService.record(appId, operatorId, "REGISTER_USER", "ACCOUNT", req.userId(), req.nickname());
return ResponseEntity.ok(ApiResponse.success(account));
}
/** Admin creates a group. */
@PostMapping("/groups")
public ResponseEntity<ApiResponse<ImGroupEntity>> createGroup(
@RequestParam String appId,
@AuthenticationPrincipal String operatorId,
@RequestBody CreateGroupRequest req) {
2026-04-29 10:04:17 +08:00
ImGroupEntity group = groupService.create(
appId,
req.name(),
req.creatorId(),
req.memberIds(),
req.groupType(),
req.announcement());
operationLogService.record(appId, operatorId, "CREATE_GROUP", "GROUP", group.getId(), group.getName());
return ResponseEntity.ok(ApiResponse.success(group));
}
2026-04-29 10:04:17 +08:00
/** Admin updates a group without changing its id. */
@PutMapping("/groups/{groupId}")
public ResponseEntity<ApiResponse<ImGroupEntity>> updateGroup(
@RequestParam String appId,
@PathVariable String groupId,
@AuthenticationPrincipal String operatorId,
@RequestBody UpdateGroupRequest req) {
ImGroupEntity group = groupService.update(
groupId,
operatorId,
req.name(),
req.groupType(),
req.announcement());
operationLogService.record(appId, operatorId, "UPDATE_GROUP", "GROUP", groupId, req.name());
return ResponseEntity.ok(ApiResponse.success(group));
}
/** Fuzzy search users by userId or nickname. */
@GetMapping("/users/search")
public ResponseEntity<ApiResponse<List<ImAccountEntity>>> searchUsers(
@RequestParam String appId,
@AuthenticationPrincipal String operatorId,
@RequestParam String keyword,
@RequestParam(defaultValue = "20") int size) {
List<ImAccountEntity> results = accountRepository.searchByKeyword(appId, keyword, PageRequest.of(0, size));
operationLogService.record(appId, operatorId, "SEARCH_USERS", "ACCOUNT", null, keyword);
return ResponseEntity.ok(ApiResponse.success(results));
}
/** Fuzzy search groups by id, name, creator or announcement. */
@GetMapping("/groups/search")
public ResponseEntity<ApiResponse<List<ImGroupEntity>>> searchGroups(
@RequestParam String appId,
@AuthenticationPrincipal String operatorId,
@RequestParam String keyword,
@RequestParam(defaultValue = "20") int size) {
List<ImGroupEntity> results = groupRepository.searchByKeyword(appId, keyword, PageRequest.of(0, size));
operationLogService.record(appId, operatorId, "SEARCH_GROUPS", "GROUP", null, keyword);
return ResponseEntity.ok(ApiResponse.success(results));
}
/** Search messages across the application. */
@GetMapping("/messages/search")
public ResponseEntity<ApiResponse<Page<ImMessageEntity>>> searchMessages(
@RequestParam String appId,
@AuthenticationPrincipal String operatorId,
@RequestParam(required = false) ImMessageEntity.ChatType chatType,
@RequestParam(required = false) ImMessageEntity.MsgType msgType,
@RequestParam(required = false) String keyword,
@RequestParam(required = false) LocalDateTime startTime,
@RequestParam(required = false) LocalDateTime endTime,
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "20") int size) {
operationLogService.record(appId, operatorId, "SEARCH_MESSAGES", "MESSAGE", null, keyword);
return ResponseEntity.ok(ApiResponse.success(
messageRepository.searchByKeyword(
appId, chatType, msgType, keyword, startTime, endTime, PageRequest.of(page, size))));
}
/** Message statistics for the given appId. */
@GetMapping("/stats")
public ResponseEntity<ApiResponse<Map<String, Object>>> stats(
@RequestParam String appId,
@AuthenticationPrincipal String operatorId) {
long totalMessages = messageRepository.countByAppId(appId);
long totalUsers = accountRepository.countByAppId(appId);
long totalGroups = groupRepository.countByAppId(appId);
long todayMessages = messageRepository.countTodayByAppId(appId);
operationLogService.record(appId, operatorId, "VIEW_STATS", "STATS", null, "summary");
return ResponseEntity.ok(ApiResponse.success(Map.of(
"totalMessages", totalMessages,
"totalUsers", totalUsers,
"totalGroups", totalGroups,
"todayMessages", todayMessages
)));
}
/** Admin queries conversation history between any two users. */
@GetMapping("/messages")
public ResponseEntity<ApiResponse<Page<com.xuqm.im.entity.ImMessageEntity>>> history(
@RequestParam String appId,
@AuthenticationPrincipal String operatorId,
@RequestParam String userA,
@RequestParam String userB,
@RequestParam(required = false) com.xuqm.im.entity.ImMessageEntity.MsgType msgType,
@RequestParam(required = false) String keyword,
@RequestParam(required = false) LocalDateTime startTime,
@RequestParam(required = false) LocalDateTime endTime,
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "20") int size) {
operationLogService.record(appId, operatorId, "VIEW_HISTORY", "MESSAGE", userA + "," + userB, keyword);
return ResponseEntity.ok(ApiResponse.success(
messageRepository.findSingleConversationFiltered(
appId, userA, userB, msgType, keyword, startTime, endTime, PageRequest.of(page, size))));
}
/** Admin revokes an arbitrary message. */
@PostMapping("/messages/{messageId}/revoke")
public ResponseEntity<ApiResponse<com.xuqm.im.entity.ImMessageEntity>> adminRevoke(
@RequestParam String appId,
@AuthenticationPrincipal String operatorId,
@PathVariable String messageId) {
ImMessageEntity revoked = messageService.adminRevoke(appId, messageId);
operationLogService.record(appId, operatorId, "ADMIN_REVOKE_MESSAGE", "MESSAGE", messageId, null);
return ResponseEntity.ok(ApiResponse.success(revoked));
}
/** Admin force dismisses a group. */
@DeleteMapping("/groups/{groupId}")
public ResponseEntity<ApiResponse<Void>> adminDismissGroup(
@RequestParam String appId,
@AuthenticationPrincipal String operatorId,
@PathVariable String groupId) {
groupService.adminDismiss(groupId);
operationLogService.record(appId, operatorId, "ADMIN_DISMISS_GROUP", "GROUP", groupId, null);
return ResponseEntity.ok(ApiResponse.ok());
}
@GetMapping("/friend-requests")
public ResponseEntity<ApiResponse<List<ImFriendRequestEntity>>> listFriendRequests(@RequestParam String appId) {
return ResponseEntity.ok(ApiResponse.success(friendRequestService.listByApp(appId)));
}
@PostMapping("/friend-requests")
public ResponseEntity<ApiResponse<ImFriendRequestEntity>> createFriendRequest(
@RequestParam String appId,
@AuthenticationPrincipal String operatorId,
@RequestBody FriendRequestCreateRequest req) {
ImFriendRequestEntity saved = friendRequestService.send(appId, req.fromUserId(), req.toUserId(), req.remark());
operationLogService.record(appId, operatorId, "CREATE_FRIEND_REQUEST", "FRIEND_REQUEST", saved.getId(), req.toUserId());
return ResponseEntity.ok(ApiResponse.success(saved));
}
@PostMapping("/friend-requests/{requestId}/accept")
public ResponseEntity<ApiResponse<ImFriendRequestEntity>> acceptFriendRequest(
@RequestParam String appId,
@PathVariable String requestId,
@AuthenticationPrincipal String operatorId) {
ImFriendRequestEntity saved = friendRequestService.adminAccept(appId, requestId);
operationLogService.record(appId, operatorId, "ACCEPT_FRIEND_REQUEST", "FRIEND_REQUEST", requestId, null);
return ResponseEntity.ok(ApiResponse.success(saved));
}
@PostMapping("/friend-requests/{requestId}/reject")
public ResponseEntity<ApiResponse<ImFriendRequestEntity>> rejectFriendRequest(
@RequestParam String appId,
@PathVariable String requestId,
@AuthenticationPrincipal String operatorId) {
ImFriendRequestEntity saved = friendRequestService.adminReject(appId, requestId);
operationLogService.record(appId, operatorId, "REJECT_FRIEND_REQUEST", "FRIEND_REQUEST", requestId, null);
return ResponseEntity.ok(ApiResponse.success(saved));
}
@GetMapping("/blacklist")
public ResponseEntity<ApiResponse<List<ImBlacklistEntity>>> listBlacklist(@RequestParam String appId) {
return ResponseEntity.ok(ApiResponse.success(blacklistService.listByApp(appId)));
}
@PostMapping("/blacklist")
public ResponseEntity<ApiResponse<ImBlacklistEntity>> addBlacklist(
@RequestParam String appId,
@AuthenticationPrincipal String operatorId,
@RequestBody BlacklistRequest req) {
ImBlacklistEntity saved = blacklistService.add(appId, req.userId(), req.blockedUserId());
operationLogService.record(appId, operatorId, "ADD_BLACKLIST", "BLACKLIST", saved.getId(), req.blockedUserId());
return ResponseEntity.ok(ApiResponse.success(saved));
}
@DeleteMapping("/blacklist")
public ResponseEntity<ApiResponse<Void>> removeBlacklist(
@RequestParam String appId,
@RequestParam String userId,
@RequestParam String blockedUserId,
@AuthenticationPrincipal String operatorId) {
blacklistService.remove(appId, userId, blockedUserId);
operationLogService.record(appId, operatorId, "REMOVE_BLACKLIST", "BLACKLIST", userId, blockedUserId);
return ResponseEntity.ok(ApiResponse.ok());
}
@GetMapping("/groups/{groupId}/members")
public ResponseEntity<ApiResponse<List<ImAccountEntity>>> listGroupMembers(
@RequestParam String appId,
@PathVariable String groupId) {
return ResponseEntity.ok(ApiResponse.success(groupService.adminListMembers(appId, groupId)));
}
@GetMapping("/groups/{groupId}/members/search")
public ResponseEntity<ApiResponse<List<ImAccountEntity>>> searchGroupMembers(
@RequestParam String appId,
@PathVariable String groupId,
@RequestParam String keyword,
@RequestParam(defaultValue = "20") int size) {
return ResponseEntity.ok(ApiResponse.success(groupService.adminSearchMembers(appId, groupId, keyword, size)));
}
@PostMapping("/groups/{groupId}/members")
public ResponseEntity<ApiResponse<ImGroupEntity>> addGroupMember(
@RequestParam String appId,
@PathVariable String groupId,
@AuthenticationPrincipal String operatorId,
@RequestBody MemberRequest req) {
ImGroupEntity saved = groupService.adminAddMember(appId, groupId, req.userId());
operationLogService.record(appId, operatorId, "ADMIN_ADD_GROUP_MEMBER", "GROUP", groupId, req.userId());
return ResponseEntity.ok(ApiResponse.success(saved));
}
@DeleteMapping("/groups/{groupId}/members/{userId}")
public ResponseEntity<ApiResponse<ImGroupEntity>> removeGroupMember(
@RequestParam String appId,
@PathVariable String groupId,
@PathVariable String userId,
@AuthenticationPrincipal String operatorId) {
ImGroupEntity saved = groupService.adminRemoveMember(appId, groupId, userId);
operationLogService.record(appId, operatorId, "ADMIN_REMOVE_GROUP_MEMBER", "GROUP", groupId, userId);
return ResponseEntity.ok(ApiResponse.success(saved));
}
@PostMapping("/groups/{groupId}/roles")
public ResponseEntity<ApiResponse<ImGroupEntity>> setGroupRole(
@RequestParam String appId,
@PathVariable String groupId,
@AuthenticationPrincipal String operatorId,
@RequestBody SetRoleRequest req) {
ImGroupEntity saved = groupService.adminSetRole(appId, groupId, req.userId(), req.role());
operationLogService.record(appId, operatorId, "ADMIN_SET_GROUP_ROLE", "GROUP", groupId, req.userId() + ":" + req.role());
return ResponseEntity.ok(ApiResponse.success(saved));
}
@PostMapping("/groups/{groupId}/mute")
public ResponseEntity<ApiResponse<ImGroupEntity>> muteGroupMember(
@RequestParam String appId,
@PathVariable String groupId,
@AuthenticationPrincipal String operatorId,
@RequestBody MuteMemberRequest req) {
ImGroupEntity saved = groupService.adminMuteMember(appId, groupId, req.userId(), req.minutes());
operationLogService.record(appId, operatorId, "ADMIN_MUTE_GROUP_MEMBER", "GROUP", groupId, req.userId() + ":" + req.minutes());
return ResponseEntity.ok(ApiResponse.success(saved));
}
@GetMapping("/groups/{groupId}/join-requests")
public ResponseEntity<ApiResponse<List<ImGroupJoinRequestEntity>>> listGroupJoinRequests(
@RequestParam String appId,
@PathVariable String groupId) {
return ResponseEntity.ok(ApiResponse.success(groupService.adminListJoinRequests(appId, groupId)));
}
@PostMapping("/groups/{groupId}/join-requests/{requestId}/accept")
public ResponseEntity<ApiResponse<ImGroupJoinRequestEntity>> acceptGroupJoinRequest(
@RequestParam String appId,
@PathVariable String groupId,
@PathVariable String requestId,
@AuthenticationPrincipal String operatorId) {
ImGroupJoinRequestEntity saved = groupService.adminAcceptJoinRequest(appId, groupId, requestId);
operationLogService.record(appId, operatorId, "ADMIN_ACCEPT_GROUP_JOIN_REQUEST", "GROUP_JOIN_REQUEST", requestId, null);
return ResponseEntity.ok(ApiResponse.success(saved));
}
@PostMapping("/groups/{groupId}/join-requests/{requestId}/reject")
public ResponseEntity<ApiResponse<ImGroupJoinRequestEntity>> rejectGroupJoinRequest(
@RequestParam String appId,
@PathVariable String groupId,
@PathVariable String requestId,
@AuthenticationPrincipal String operatorId) {
ImGroupJoinRequestEntity saved = groupService.adminRejectJoinRequest(appId, groupId, requestId);
operationLogService.record(appId, operatorId, "ADMIN_REJECT_GROUP_JOIN_REQUEST", "GROUP_JOIN_REQUEST", requestId, null);
return ResponseEntity.ok(ApiResponse.success(saved));
}
@GetMapping("/webhooks")
public ResponseEntity<ApiResponse<List<WebhookConfigEntity>>> listWebhooks(@RequestParam String appId) {
return ResponseEntity.ok(ApiResponse.success(webhookConfigService.list(appId)));
}
@PostMapping("/webhooks")
public ResponseEntity<ApiResponse<WebhookConfigEntity>> createWebhook(
@RequestParam String appId,
@AuthenticationPrincipal String operatorId,
@RequestBody WebhookConfigRequest req) {
WebhookConfigEntity saved = webhookConfigService.create(appId, req.url(), req.secret(), req.enabled());
operationLogService.record(appId, operatorId, "CREATE_WEBHOOK", "WEBHOOK", saved.getId(), req.url());
return ResponseEntity.ok(ApiResponse.success(saved));
}
@PutMapping("/webhooks/{id}")
public ResponseEntity<ApiResponse<WebhookConfigEntity>> updateWebhook(
@RequestParam String appId,
@PathVariable String id,
@AuthenticationPrincipal String operatorId,
@RequestBody WebhookConfigRequest req) {
WebhookConfigEntity saved = webhookConfigService.update(appId, id, req.url(), req.secret(), req.enabled());
operationLogService.record(appId, operatorId, "UPDATE_WEBHOOK", "WEBHOOK", id, req.url());
return ResponseEntity.ok(ApiResponse.success(saved));
}
@DeleteMapping("/webhooks/{id}")
public ResponseEntity<ApiResponse<Void>> deleteWebhook(
@RequestParam String appId,
@AuthenticationPrincipal String operatorId,
@PathVariable String id) {
webhookConfigService.delete(appId, id);
operationLogService.record(appId, operatorId, "DELETE_WEBHOOK", "WEBHOOK", id, null);
return ResponseEntity.ok(ApiResponse.ok());
}
@GetMapping("/keyword-filters")
public ResponseEntity<ApiResponse<List<KeywordFilterEntity>>> listKeywordFilters(@RequestParam String appId) {
return ResponseEntity.ok(ApiResponse.success(keywordFilterService.list(appId)));
}
@PostMapping("/keyword-filters")
public ResponseEntity<ApiResponse<KeywordFilterEntity>> createKeywordFilter(
@RequestParam String appId,
@AuthenticationPrincipal String operatorId,
@RequestBody KeywordFilterRequest req) {
KeywordFilterEntity saved = keywordFilterService.add(appId, req.pattern(), req.replacement(), req.action());
operationLogService.record(appId, operatorId, "CREATE_KEYWORD_FILTER", "KEYWORD_FILTER", saved.getId(), req.pattern());
return ResponseEntity.ok(ApiResponse.success(saved));
}
@PutMapping("/keyword-filters/{id}")
public ResponseEntity<ApiResponse<KeywordFilterEntity>> updateKeywordFilter(
@RequestParam String appId,
@PathVariable String id,
@AuthenticationPrincipal String operatorId,
@RequestBody KeywordFilterRequest req) {
KeywordFilterEntity saved = keywordFilterService.update(appId, id, req.pattern(), req.replacement(), req.action(), req.enabled());
operationLogService.record(appId, operatorId, "UPDATE_KEYWORD_FILTER", "KEYWORD_FILTER", id, req.pattern());
return ResponseEntity.ok(ApiResponse.success(saved));
}
@DeleteMapping("/keyword-filters/{id}")
public ResponseEntity<ApiResponse<Void>> deleteKeywordFilter(
@RequestParam String appId,
@AuthenticationPrincipal String operatorId,
@PathVariable String id) {
keywordFilterService.delete(appId, id);
operationLogService.record(appId, operatorId, "DELETE_KEYWORD_FILTER", "KEYWORD_FILTER", id, null);
return ResponseEntity.ok(ApiResponse.ok());
}
@GetMapping("/global-mute")
public ResponseEntity<ApiResponse<ImGlobalMuteEntity>> getGlobalMute(@RequestParam String appId) {
return ResponseEntity.ok(ApiResponse.success(globalMuteService.get(appId)));
}
@PutMapping("/global-mute")
public ResponseEntity<ApiResponse<ImGlobalMuteEntity>> setGlobalMute(
@RequestParam String appId,
@AuthenticationPrincipal String operatorId,
@RequestParam boolean enabled) {
ImGlobalMuteEntity saved = globalMuteService.setEnabled(appId, enabled);
operationLogService.record(appId, operatorId, "SET_GLOBAL_MUTE", "GLOBAL_MUTE", saved.getId(), String.valueOf(enabled));
return ResponseEntity.ok(ApiResponse.success(saved));
}
@GetMapping("/operation-logs")
public ResponseEntity<ApiResponse<Page<com.xuqm.im.entity.ImOperationLogEntity>>> operationLogs(
@RequestParam String appId,
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "20") int size) {
return ResponseEntity.ok(ApiResponse.success(
operationLogService.list(appId, PageRequest.of(page, size))));
}
2026-04-29 10:04:17 +08:00
public record RegisterUserRequest(
String userId,
String nickname,
String avatar,
ImAccountEntity.Gender gender,
ImAccountEntity.Status status) {}
public record UpdateUserRequest(
String nickname,
String avatar,
ImAccountEntity.Gender gender,
ImAccountEntity.Status status) {}
public record CreateGroupRequest(String name, String creatorId, List<String> memberIds, String groupType, String announcement) {}
public record UpdateGroupRequest(String name, String groupType, String announcement) {}
public record WebhookConfigRequest(String url, String secret, Boolean enabled) {}
public record KeywordFilterRequest(String pattern, String replacement, String action, Boolean enabled) {}
public record FriendRequestCreateRequest(String fromUserId, String toUserId, String remark) {}
public record BlacklistRequest(String userId, String blockedUserId) {}
public record MemberRequest(String userId) {}
public record SetRoleRequest(String userId, String role) {}
public record MuteMemberRequest(String userId, long minutes) {}
}