feat: add im kafka admin integration

This commit is contained in:
richjohnrambo
2026-08-28 00:05:54 +08:00
parent d53b0c1b62
commit 4779214591
75 changed files with 9053 additions and 185 deletions
@@ -0,0 +1,130 @@
// Package sysin
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2026 HotGo
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package sysin
import (
"context"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/os/gtime"
)
type ImDeadLetterListInp struct {
TenantId int64 `json:"tenantId" dc:"租户ID"`
Status string `json:"status" dc:"状态"`
BizType string `json:"bizType" dc:"业务类型"`
BizId string `json:"bizId" dc:"业务ID"`
EventType string `json:"eventType" dc:"事件类型"`
Cursor string `json:"cursor" dc:"游标"`
Limit int `json:"limit" dc:"数量"`
}
func (in *ImDeadLetterListInp) Filter(ctx context.Context) (err error) {
if in.TenantId <= 0 {
return gerror.New("请选择IM租户")
}
if in.Limit <= 0 || in.Limit > 200 {
in.Limit = 50
}
return nil
}
type ImDeadLetterListModel struct {
Id int64 `json:"id" dc:"ID"`
DeadId string `json:"deadId" dc:"死信ID"`
EventId string `json:"eventId" dc:"事件ID"`
ParentEventId string `json:"parentEventId" dc:"父事件ID"`
SourceTopic string `json:"sourceTopic" dc:"来源Topic"`
ConsumerGroup string `json:"consumerGroup" dc:"消费组"`
EventType string `json:"eventType" dc:"事件类型"`
BizType string `json:"bizType" dc:"业务类型"`
BizId string `json:"bizId" dc:"业务ID"`
RetryCount int `json:"retryCount" dc:"重试次数"`
LastReason string `json:"lastReason" dc:"最后原因"`
LastError string `json:"lastError" dc:"最后错误"`
Status string `json:"status" dc:"状态"`
ReplayCount int `json:"replayCount" dc:"重放次数"`
CreatedAt *gtime.Time `json:"createdAt" dc:"创建时间"`
UpdatedAt *gtime.Time `json:"updatedAt" dc:"更新时间"`
}
type ImDeadLetterListModelRaw struct {
Id int64 `json:"id"`
DeadId string `json:"dead_id"`
EventId string `json:"event_id"`
ParentEventId string `json:"parent_event_id"`
SourceTopic string `json:"source_topic"`
ConsumerGroup string `json:"consumer_group"`
EventType string `json:"event_type"`
BizType string `json:"biz_type"`
BizId string `json:"biz_id"`
RetryCount int `json:"retry_count"`
LastReason string `json:"last_reason"`
LastError string `json:"last_error"`
Status string `json:"status"`
ReplayCount int `json:"replay_count"`
CreatedAt *gtime.Time `json:"created_at"`
UpdatedAt *gtime.Time `json:"updated_at"`
}
type ImDeadLetterPageModel struct {
List []*ImDeadLetterListModel `json:"list" dc:"数据列表"`
NextCursor string `json:"nextCursor" dc:"下一页游标"`
HasMore bool `json:"hasMore" dc:"是否还有更多"`
}
type ImDeadLetterPageRaw struct {
Items []*ImDeadLetterListModelRaw `json:"items"`
NextCursor string `json:"next_cursor"`
HasMore bool `json:"has_more"`
}
type ImDeadLetterViewInp struct {
TenantId int64 `json:"tenantId" dc:"租户ID"`
DeadId string `json:"deadId" dc:"死信ID"`
}
func (in *ImDeadLetterViewInp) Filter(ctx context.Context) (err error) {
if in.TenantId <= 0 {
return gerror.New("请选择IM租户")
}
if in.DeadId == "" {
return gerror.New("请选择Kafka死信")
}
return nil
}
type ImDeadLetterViewModel struct {
ImDeadLetterListModel
Envelope string `json:"envelope" dc:"Envelope"`
EnvelopeRaw string `json:"envelopeRaw" dc:"Envelope Raw"`
}
type ImDeadLetterViewRaw struct {
ImDeadLetterListModelRaw
Envelope any `json:"envelope"`
EnvelopeRaw string `json:"envelope_raw"`
}
type ImDeadLetterActionInp struct {
TenantId int64 `json:"tenantId" dc:"租户ID"`
DeadId string `json:"deadId" dc:"死信ID"`
ActorUserId int64 `json:"actorUserId" dc:"操作IM用户ID"`
Note string `json:"note" dc:"备注"`
}
func (in *ImDeadLetterActionInp) Filter(ctx context.Context) (err error) {
if in.TenantId <= 0 {
return gerror.New("请选择IM租户")
}
if in.DeadId == "" {
return gerror.New("请选择Kafka死信")
}
if in.ActorUserId <= 0 {
return gerror.New("操作IM用户ID不能为空")
}
return nil
}
@@ -198,6 +198,30 @@ func (in *ImGroupGovernanceUpdateInp) Filter(ctx context.Context) (err error) {
return
}
type ImGroupProfileUpdateInp struct {
ImGroupTopicInp
Name string `json:"name" dc:"群名称"`
AvatarFileId string `json:"avatarFileId" dc:"头像文件ID"`
Description string `json:"description" dc:"简介"`
Version int64 `json:"version" dc:"版本"`
}
func (in *ImGroupProfileUpdateInp) Filter(ctx context.Context) (err error) {
if err = in.ImGroupTopicInp.Filter(ctx); err != nil {
return
}
if in.Name == "" && in.AvatarFileId == "" && in.Description == "" {
return gerror.New("请填写需要修改的群资料")
}
if len([]rune(in.Name)) > 80 {
return gerror.New("群名称不能超过80个字符")
}
if len([]rune(in.Description)) > 500 {
return gerror.New("群简介不能超过500个字符")
}
return
}
type ImGroupDissolveInp struct {
ImGroupTopicInp
Reason string `json:"reason" dc:"解散原因"`
@@ -458,3 +482,32 @@ type ImGroupAdminLogListModel struct {
IdempotencyKey string `json:"idempotencyKey" dc:"幂等键"`
CreatedAt *gtime.Time `json:"createdAt" dc:"创建时间"`
}
type ImGroupMemberRemoveInp struct {
ImGroupTopicInp
UserId int64 `json:"userId" v:"required#用户ID不能为空" dc:"用户ID"`
Reason string `json:"reason" dc:"原因"`
}
func (in *ImGroupMemberRemoveInp) Filter(ctx context.Context) (err error) {
if err = in.ImGroupTopicInp.Filter(ctx); err != nil {
return
}
if in.UserId <= 0 {
return gerror.New("用户ID不能为空")
}
if len([]rune(in.Reason)) > 200 {
return gerror.New("原因不能超过200个字符")
}
return
}
type ImGroupCommandModel struct {
CommandID string `json:"commandId" dc:"命令ID"`
EventID string `json:"eventId" dc:"Kafka事件ID"`
Status string `json:"status" dc:"状态"`
TenantID int64 `json:"tenantId" dc:"租户ID"`
TenantCode string `json:"tenantCode" dc:"租户编码"`
EventType string `json:"eventType" dc:"事件类型"`
IdempotencyKey string `json:"idempotencyKey" dc:"幂等键"`
}
@@ -0,0 +1,65 @@
package sysin
import (
"context"
"hotgo/internal/model/input/form"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/os/gtime"
)
type ImKafkaAuditListInp struct {
form.PageReq
TenantCode string `json:"tenantCode" dc:"租户编码"`
EventId string `json:"eventId" dc:"事件ID"`
EventType string `json:"eventType" dc:"事件类型"`
BizType string `json:"bizType" dc:"业务类型"`
BizId string `json:"bizId" dc:"业务ID"`
ActorType string `json:"actorType" dc:"操作者类型"`
ActorId string `json:"actorId" dc:"操作者ID"`
Action string `json:"action" dc:"动作"`
Resource string `json:"resource" dc:"资源"`
ResourceId string `json:"resourceId" dc:"资源ID"`
Result string `json:"result" dc:"结果"`
CreatedAt []*gtime.Time `json:"createdAt" dc:"接收时间"`
}
func (in *ImKafkaAuditListInp) Filter(ctx context.Context) (err error) {
return nil
}
type ImKafkaAuditListModel struct {
Id int64 `json:"id" dc:"ID"`
EventId string `json:"eventId" dc:"事件ID"`
TenantCode string `json:"tenantCode" dc:"租户编码"`
EventType string `json:"eventType" dc:"事件类型"`
BizType string `json:"bizType" dc:"业务类型"`
BizId string `json:"bizId" dc:"业务ID"`
ActorType string `json:"actorType" dc:"操作者类型"`
ActorId string `json:"actorId" dc:"操作者ID"`
Action string `json:"action" dc:"动作"`
Resource string `json:"resource" dc:"资源"`
ResourceId string `json:"resourceId" dc:"资源ID"`
Result string `json:"result" dc:"结果"`
Reason string `json:"reason" dc:"原因"`
Payload string `json:"payload" dc:"Payload"`
Envelope string `json:"envelope" dc:"Envelope"`
OccurredAt *gtime.Time `json:"occurredAt" dc:"发生时间"`
ReceivedAt *gtime.Time `json:"receivedAt" dc:"接收时间"`
}
type ImKafkaAuditViewInp struct {
Id int64 `json:"id" dc:"ID"`
EventId string `json:"eventId" dc:"事件ID"`
}
func (in *ImKafkaAuditViewInp) Filter(ctx context.Context) (err error) {
if in.Id <= 0 && in.EventId == "" {
return gerror.New("请选择IM Kafka审计事件")
}
return nil
}
type ImKafkaAuditViewModel struct {
ImKafkaAuditListModel
}
@@ -0,0 +1,126 @@
// Package sysin
// @Link https://github.com/bufanyun/hotgo
// @Copyright Copyright (c) 2026 HotGo
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
package sysin
import (
"context"
"hotgo/internal/model/input/form"
"strings"
"github.com/gogf/gf/v2/errors/gerror"
"github.com/gogf/gf/v2/os/gtime"
)
type ImKafkaCommandListInp struct {
form.PageReq
TenantId int64 `json:"tenantId" dc:"租户ID"`
CommandId string `json:"commandId" dc:"命令ID"`
EventId string `json:"eventId" dc:"事件ID"`
EventType string `json:"eventType" dc:"事件类型"`
BizType string `json:"bizType" dc:"业务类型"`
BizId string `json:"bizId" dc:"业务ID"`
Status string `json:"status" dc:"状态"`
CreatedAt []*gtime.Time `json:"createdAt" dc:"创建时间"`
}
func (in *ImKafkaCommandListInp) Filter(ctx context.Context) (err error) {
return nil
}
type ImKafkaCommandListModel struct {
Id int64 `json:"id" dc:"ID"`
CommandId string `json:"commandId" dc:"命令ID"`
TenantId int64 `json:"tenantId" dc:"租户ID"`
TenantCode string `json:"tenantCode" dc:"租户编码"`
EventId string `json:"eventId" dc:"事件ID"`
EventType string `json:"eventType" dc:"事件类型"`
BizType string `json:"bizType" dc:"业务类型"`
BizId string `json:"bizId" dc:"业务ID"`
IdempotencyKey string `json:"idempotencyKey" dc:"幂等键"`
Status string `json:"status" dc:"状态"`
Reason string `json:"reason" dc:"错误码"`
Message string `json:"message" dc:"消息"`
SentAt *gtime.Time `json:"sentAt" dc:"投递时间"`
CompletedAt *gtime.Time `json:"completedAt" dc:"完成时间"`
CreatedBy int64 `json:"createdBy" dc:"创建人"`
CreatedAt *gtime.Time `json:"createdAt" dc:"创建时间"`
UpdatedAt *gtime.Time `json:"updatedAt" dc:"更新时间"`
}
type ImKafkaCommandViewInp struct {
Id int64 `json:"id" dc:"ID"`
CommandId string `json:"commandId" dc:"命令ID"`
}
func (in *ImKafkaCommandViewInp) Filter(ctx context.Context) (err error) {
if in.Id <= 0 && in.CommandId == "" {
return gerror.New("请选择IM后台命令")
}
return nil
}
type ImKafkaCommandViewModel struct {
ImKafkaCommandListModel
Payload string `json:"payload" dc:"Payload"`
Envelope string `json:"envelope" dc:"Envelope"`
Result string `json:"result" dc:"Result"`
}
type ImKafkaCacheInvalidateInp struct {
TenantCode string `json:"tenantCode" dc:"租户编码"`
Namespace string `json:"namespace" dc:"缓存命名空间"`
Keys []string `json:"keys" dc:"缓存Key"`
Reason string `json:"reason" dc:"原因"`
}
func (in *ImKafkaCacheInvalidateInp) Filter(ctx context.Context) (err error) {
in.TenantCode = strings.TrimSpace(in.TenantCode)
in.Namespace = strings.TrimSpace(in.Namespace)
if in.TenantCode == "" {
return gerror.New("请选择租户")
}
if in.Namespace == "" {
return gerror.New("请输入缓存命名空间")
}
keys := make([]string, 0, len(in.Keys))
for _, key := range in.Keys {
if key = strings.TrimSpace(key); key != "" {
keys = append(keys, key)
}
}
in.Keys = keys
return nil
}
type ImKafkaEventModel struct {
EventId string `json:"eventId" dc:"Kafka事件ID"`
}
type ImKafkaWorkbenchEventInp struct {
TenantCode string `json:"tenantCode" dc:"租户编码"`
EventType string `json:"eventType" dc:"事件类型"`
BizId string `json:"bizId" dc:"业务ID"`
Payload map[string]any `json:"payload" dc:"Payload"`
}
func (in *ImKafkaWorkbenchEventInp) Filter(ctx context.Context) (err error) {
in.TenantCode = strings.TrimSpace(in.TenantCode)
in.EventType = strings.TrimSpace(in.EventType)
in.BizId = strings.TrimSpace(in.BizId)
if in.TenantCode == "" {
return gerror.New("请选择租户")
}
if in.EventType == "" {
in.EventType = "workbench.connectivity.test"
}
if in.BizId == "" {
in.BizId = "admin_connectivity_test"
}
if in.Payload == nil {
in.Payload = map[string]any{}
}
return nil
}
+44 -2
View File
@@ -37,7 +37,7 @@ func (in *ImUserListInp) Filter(ctx context.Context) (err error) {
type ImUserListModel struct {
TenantId int64 `json:"tenantId" dc:"租户ID"`
TenantName string `json:"tenantName" dc:"租户名称"`
UserId string `json:"userId" dc:"用户ID"`
UserId int64 `json:"userId" dc:"用户ID"`
Username string `json:"username" dc:"登录账号"`
Phone string `json:"phone" dc:"手机号"`
Nickname string `json:"nickname" dc:"昵称"`
@@ -139,7 +139,7 @@ func (in *ImUserDeviceListInp) Filter(ctx context.Context) (err error) {
type ImUserDeviceListModel struct {
TenantId int64 `json:"tenantId" dc:"租户ID"`
TenantName string `json:"tenantName" dc:"租户名称"`
UserId string `json:"userId" dc:"用户ID"`
UserId int64 `json:"userId" dc:"用户ID"`
DeviceId string `json:"deviceId" dc:"设备ID"`
Platform string `json:"platform" dc:"平台"`
Lang string `json:"lang" dc:"语言"`
@@ -150,3 +150,45 @@ type ImUserDeviceListModel struct {
PushTokenConfigured bool `json:"pushTokenConfigured" dc:"是否配置Push Token"`
PushUpdatedAt *gtime.Time `json:"pushUpdatedAt" dc:"Push更新时间"`
}
type ImUserGovernanceInp struct {
TenantId int64 `json:"tenantId" dc:"租户ID"`
UserId int64 `json:"userId" dc:"目标用户ID"`
ActorUserId int64 `json:"actorUserId" dc:"操作IM用户ID"`
DeviceId string `json:"deviceId" dc:"设备ID"`
Reason string `json:"reason" dc:"原因"`
Hard bool `json:"hard" dc:"硬删除"`
}
func (in *ImUserGovernanceInp) Filter(ctx context.Context) (err error) {
if in.TenantId <= 0 {
return gerror.New("请选择租户")
}
if in.UserId <= 0 {
return gerror.New("用户ID不能为空")
}
if in.ActorUserId <= 0 {
return gerror.New("操作IM用户ID不能为空")
}
return nil
}
func (in *ImUserGovernanceInp) FilterDevice(ctx context.Context) (err error) {
if err = in.Filter(ctx); err != nil {
return err
}
if in.DeviceId == "" {
return gerror.New("设备ID不能为空")
}
return nil
}
type ImUserCommandModel struct {
CommandID string `json:"commandId" dc:"命令ID"`
EventID string `json:"eventId" dc:"Kafka事件ID"`
Status string `json:"status" dc:"状态"`
TenantID int64 `json:"tenantId" dc:"租户ID"`
TenantCode string `json:"tenantCode" dc:"租户编码"`
EventType string `json:"eventType" dc:"事件类型"`
IdempotencyKey string `json:"idempotencyKey" dc:"幂等键"`
}