feat: add IM admin P1 operations
This commit is contained in:
@@ -0,0 +1,117 @@
|
||||
package sys
|
||||
|
||||
import (
|
||||
"context"
|
||||
"hotgo/internal/consts"
|
||||
"hotgo/internal/dao"
|
||||
"hotgo/internal/library/imtenant"
|
||||
"hotgo/internal/model/entity"
|
||||
"hotgo/internal/model/input/sysin"
|
||||
"hotgo/internal/service"
|
||||
|
||||
"github.com/gogf/gf/v2/database/gdb"
|
||||
"github.com/gogf/gf/v2/errors/gerror"
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
)
|
||||
|
||||
type sSysImTaskDashboard struct{}
|
||||
|
||||
func NewSysImTaskDashboard() *sSysImTaskDashboard { return &sSysImTaskDashboard{} }
|
||||
|
||||
func init() {
|
||||
service.RegisterSysImTaskDashboard(NewSysImTaskDashboard())
|
||||
}
|
||||
|
||||
func (s *sSysImTaskDashboard) List(ctx context.Context, in *sysin.ImTaskDashboardListInp) (list []*sysin.ImTaskDashboardListModel, totalCount int, err error) {
|
||||
if err = in.Filter(ctx); err != nil {
|
||||
return
|
||||
}
|
||||
scope, err := resolveImAdminScopeWithAll(ctx, in.TenantId, true)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
mod := imtenant.RegistryDB().Model(dao.ImTenant.Table()).Safe().Ctx(ctx)
|
||||
if scope.TenantId > 0 {
|
||||
mod = mod.WherePri(scope.TenantId)
|
||||
}
|
||||
if in.TenantId > 0 {
|
||||
mod = mod.WherePri(in.TenantId)
|
||||
}
|
||||
mod = mod.Page(in.Page, in.PerPage).OrderAsc(dao.ImTenant.Columns().Id)
|
||||
|
||||
var tenants []*entity.ImTenant
|
||||
if err = mod.ScanAndCount(&tenants, &totalCount, false); err != nil {
|
||||
err = gerror.Wrap(err, "获取IM任务看板租户失败,请稍后重试!")
|
||||
return
|
||||
}
|
||||
list = make([]*sysin.ImTaskDashboardListModel, 0, len(tenants))
|
||||
for _, tenant := range tenants {
|
||||
item := s.buildTenantSummary(ctx, tenant)
|
||||
if in.Status != "" && item.Status != in.Status {
|
||||
continue
|
||||
}
|
||||
list = append(list, item)
|
||||
}
|
||||
if in.Status != "" {
|
||||
totalCount = len(list)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (s *sSysImTaskDashboard) buildTenantSummary(ctx context.Context, tenant *entity.ImTenant) *sysin.ImTaskDashboardListModel {
|
||||
item := &sysin.ImTaskDashboardListModel{
|
||||
TenantId: tenant.Id,
|
||||
TenantName: tenant.Name,
|
||||
TenantCode: tenant.Code,
|
||||
TenantState: tenant.State,
|
||||
DbStatus: "ok",
|
||||
Status: consts.ImTaskDashboardStatusHealthy,
|
||||
RecommendedNextAction: "无需处理",
|
||||
}
|
||||
db, _, err := imtenant.DB(ctx, tenant.Id)
|
||||
if err != nil {
|
||||
item.DbStatus = "error"
|
||||
item.Status = consts.ImTaskDashboardStatusError
|
||||
item.RecommendedNextAction = "检查租户数据库连接"
|
||||
return item
|
||||
}
|
||||
item.OutboxPendingCount, _ = s.count(ctx, db, "im_business_events_outbox", "status='pending'")
|
||||
item.OutboxFailedCount, _ = s.count(ctx, db, "im_business_events_outbox", "status='failed'")
|
||||
item.GroupOutboxPending, _ = s.count(ctx, db, "im_group_events_outbox", "status='pending'")
|
||||
item.GroupOutboxFailed, _ = s.count(ctx, db, "im_group_events_outbox", "status='failed'")
|
||||
item.OrphanFileCount, _ = s.countOrphanFiles(ctx, db)
|
||||
item.DeletedFileCount, _ = s.count(ctx, db, "im_fileuploads", "status=3")
|
||||
item.LastOutboxCreatedAt, _ = s.maxTime(ctx, db, "im_business_events_outbox", "created_at")
|
||||
item.LastGroupEventAt, _ = s.maxTime(ctx, db, "im_group_events_outbox", "created_at")
|
||||
item.LastFileUpdatedAt, _ = s.maxTime(ctx, db, "im_fileuploads", "updatedat")
|
||||
if item.OutboxFailedCount > 0 || item.GroupOutboxFailed > 0 {
|
||||
item.Status = consts.ImTaskDashboardStatusError
|
||||
item.RecommendedNextAction = "处理失败Outbox事件"
|
||||
} else if item.OutboxPendingCount > 0 || item.GroupOutboxPending > 0 || item.OrphanFileCount > 0 || item.DeletedFileCount > 0 {
|
||||
item.Status = consts.ImTaskDashboardStatusWarning
|
||||
item.RecommendedNextAction = "检查待处理任务和文件清理"
|
||||
}
|
||||
return item
|
||||
}
|
||||
|
||||
func (s *sSysImTaskDashboard) count(ctx context.Context, db gdb.DB, table string, where string) (int, error) {
|
||||
return db.Model(table).Safe().Ctx(ctx).Where(where).Count()
|
||||
}
|
||||
|
||||
func (s *sSysImTaskDashboard) countOrphanFiles(ctx context.Context, db gdb.DB) (int, error) {
|
||||
return db.Model("im_fileuploads fu").Safe().Ctx(ctx).
|
||||
LeftJoin("im_filemsglinks fml", "fml.fileid=fu.id").
|
||||
Where("fml.id IS NULL").
|
||||
WhereNotIn("fu.status", []int{consts.ImFileStatusDeleted, consts.ImFileStatusQuarantined}).
|
||||
Count()
|
||||
}
|
||||
|
||||
func (s *sSysImTaskDashboard) maxTime(ctx context.Context, db gdb.DB, table string, field string) (res *gtime.Time, err error) {
|
||||
var row struct {
|
||||
Value *gtime.Time `orm:"value"`
|
||||
}
|
||||
if err = db.Model(table).Safe().Ctx(ctx).Fields("MAX(" + field + ") value").Scan(&row); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return row.Value, nil
|
||||
}
|
||||
Reference in New Issue
Block a user