Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

log related api #141

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions internal/api/admin.go
Original file line number Diff line number Diff line change
Expand Up @@ -336,3 +336,7 @@ func (o *AdminApi) NewUserCount(c *gin.Context) {
resp.Total = total
apiresp.GinSuccess(c, resp)
}

func (o *AdminApi) SearchLogs(c *gin.Context) {
a2r.Call(chat.ChatClient.SearchLogs, o.chatClient, c)
}
8 changes: 8 additions & 0 deletions internal/api/chat.go
Original file line number Diff line number Diff line change
Expand Up @@ -307,3 +307,11 @@ func (o *ChatApi) getClientIP(c *gin.Context) (string, error) {
}
return ip, nil
}

func (o *ChatApi) UploadLogs(c *gin.Context) {
a2r.Call(chat.ChatClient.UploadLogs, o.chatClient, c)
}

func (o *ChatApi) DeleteLogs(c *gin.Context) {
a2r.Call(chat.ChatClient.DeleteLogs, o.chatClient, c)
}
7 changes: 7 additions & 0 deletions internal/api/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ func NewChatRoute(router gin.IRouter, discov discoveryregistry.SvcDiscoveryRegis
router.Group("/client_config").POST("/get", chat.GetClientConfig) // 获取客户端初始化配置

router.Group("/callback").POST("/open_im", chat.OpenIMCallback) // 回调

logs := router.Group("/logs", mw.CheckToken)
logs.POST("/upload", chat.UploadLogs)
logs.POST("/delete", chat.DeleteLogs)
}

func NewAdminRoute(router gin.IRouter, discov discoveryregistry.SvcDiscoveryRegistry) {
Expand Down Expand Up @@ -121,4 +125,7 @@ func NewAdminRoute(router gin.IRouter, discov discoveryregistry.SvcDiscoveryRegi
statistic := router.Group("/statistic", mw.CheckAdmin)
statistic.POST("/new_user_count", admin.NewUserCount)
statistic.POST("/login_user_count", admin.LoginUserCount)

logs := router.Group("/logs", mw.CheckAdmin)
logs.POST("/search", admin.SearchLogs)
}
1 change: 1 addition & 0 deletions internal/rpc/chat/chat.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ func Start(discov discoveryregistry.SvcDiscoveryRegistry, server *grpc.Server) e
chat2.Attribute{},
chat2.VerifyCode{},
chat2.UserLoginRecord{},
chat2.Log{},
}
if err := db.AutoMigrate(tables...); err != nil {
return err
Expand Down
131 changes: 131 additions & 0 deletions internal/rpc/chat/log.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
package chat

import (
"context"
"fmt"
"github.com/OpenIMSDK/chat/pkg/common/constant"
table "github.com/OpenIMSDK/chat/pkg/common/db/table/chat"
"github.com/OpenIMSDK/chat/pkg/common/mctx"
"github.com/OpenIMSDK/chat/pkg/proto/chat"
"github.com/OpenIMSDK/tools/errs"
"github.com/OpenIMSDK/tools/mw/specialerror"
utils2 "github.com/OpenIMSDK/tools/utils"
"gorm.io/gorm/utils"
"math/rand"
"time"
)

func (o *chatSvr) genLogID() string {
const l = 10
data := make([]byte, l)
rand.Read(data)
chars := []byte("0123456789")
for i := 0; i < len(data); i++ {
if i == 0 {
data[i] = chars[1:][data[i]%9]
} else {
data[i] = chars[data[i]%10]
}
}
return string(data)
}

func (o *chatSvr) IsNotFound(err error) bool {
return errs.ErrRecordNotFound.Is(specialerror.ErrCode(errs.Unwrap(err)))
}

func (o *chatSvr) UploadLogs(ctx context.Context, req *chat.UploadLogsReq) (*chat.UploadLogsResp, error) {
var DBlogs []*table.Log
userID, _, err := mctx.Check(ctx)
if _, err := o.Database.GetUser(ctx, userID); err != nil {
return nil, err
}
for _, fileURL := range req.FileURLs {
log := table.Log{
SystemType: req.SystemType,
Platform: utils.ToString(req.Platform),
UserID: userID,
CreateTime: time.Now(),
Url: fileURL.URL,
FileName: fileURL.Filename,
}
for i := 0; i < 20; i++ {
id := o.genLogID()
logs, err := o.Database.GetLogs(ctx, []string{id}, "")
if err != nil {
return nil, err
}
if len(logs) == 0 {
log.LogID = id
break
}
}
if log.LogID == "" {
return nil, errs.ErrData.Wrap("Log id gen error")
}
DBlogs = append(DBlogs, &log)
}
err = o.Database.UploadLogs(ctx, DBlogs)
if err != nil {
return nil, err
}
return &chat.UploadLogsResp{}, nil
}

func (o *chatSvr) DeleteLogs(ctx context.Context, req *chat.DeleteLogsReq) (*chat.DeleteLogsResp, error) {
userID, userType, err := mctx.Check(ctx)
if err != nil {
return nil, err
}
if userType == constant.AdminUser {
userID = ""
}
logs, err := o.Database.GetLogs(ctx, req.LogIDs, userID)
if err != nil {
return nil, err
}
var logIDs []string
for _, log := range logs {
logIDs = append(logIDs, log.LogID)
}
if ids := utils2.Single(req.LogIDs, logIDs); len(ids) > 0 {
return nil, errs.ErrRecordNotFound.Wrap(fmt.Sprintf("logIDs not found%#v", ids))
}
err = o.Database.DeleteLogs(ctx, req.LogIDs, userID)
if err != nil {
return nil, err
}
return &chat.DeleteLogsResp{}, nil
}

func (o *chatSvr) SearchLogs(ctx context.Context, req *chat.SearchLogsReq) (*chat.SearchLogsResp, error) {
var (
resp chat.SearchLogsResp
userIDs []string
)
if req.StartTime > req.EndTime {
return nil, errs.ErrArgs.Wrap("startTime>endTime")
}
total, logs, err := o.Database.SearchLogs(ctx, req.Keyword, time.UnixMilli(req.StartTime), time.UnixMilli(req.EndTime), req.Pagination.PageNumber, req.Pagination.ShowNumber)
if err != nil {
return nil, err
}
pbLogs := DbToPbLogInfos(logs)
for _, log := range logs {
userIDs = append(userIDs, log.UserID)
}
attributes, err := o.Database.FindAttribute(ctx, userIDs)
if err != nil {
return nil, err
}
IDtoName := make(map[string]string)
for _, attribute := range attributes {
IDtoName[attribute.UserID] = attribute.Nickname
}
for _, pbLog := range pbLogs {
pbLog.Nickname = IDtoName[pbLog.UserID]
}
resp.LogsInfos = pbLogs
resp.Total = total
return &resp, nil
}
17 changes: 17 additions & 0 deletions internal/rpc/chat/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,20 @@ func DbToPbUserFullInfo(attribute *chat.Attribute) *common.UserFullInfo {
func DbToPbUserFullInfos(attributes []*chat.Attribute) []*common.UserFullInfo {
return utils.Slice(attributes, DbToPbUserFullInfo)
}

func DbToPbLogInfo(log *chat.Log) *common.LogInfo {
return &common.LogInfo{
Filename: log.FileName,
UserID: log.UserID,
Platform: utils.StringToInt32(log.Platform),
Url: log.Url,
CreateTime: log.CreateTime.UnixMilli(),
LogID: log.LogID,
SystemType: log.SystemType,
Ex: log.Ex,
}
}

func DbToPbLogInfos(logs []*chat.Log) []*common.LogInfo {
return utils.Slice(logs, DbToPbLogInfo)
}
22 changes: 22 additions & 0 deletions pkg/common/db/database/chat.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ type ChatDatabaseInterface interface {
NewUserCountTotal(ctx context.Context, before *time.Time) (int64, error)
UserLoginCountTotal(ctx context.Context, before *time.Time) (int64, error)
UserLoginCountRangeEverydayTotal(ctx context.Context, start *time.Time, end *time.Time) (map[string]int64, int64, error)
UploadLogs(ctx context.Context, logs []*table.Log) error
DeleteLogs(ctx context.Context, logID []string, userID string) error
SearchLogs(ctx context.Context, keyword string, start time.Time, end time.Time, pageNumber int32, showNumber int32) (uint32, []*table.Log, error)
GetLogs(ctx context.Context, LogIDs []string, userID string) ([]*table.Log, error)
}

func NewChatDatabase(db *gorm.DB) ChatDatabaseInterface {
Expand All @@ -65,6 +69,7 @@ func NewChatDatabase(db *gorm.DB) ChatDatabaseInterface {
userLoginRecord: chat.NewUserLoginRecord(db),
verifyCode: chat.NewVerifyCode(db),
forbiddenAccount: admin2.NewForbiddenAccount(db),
log: chat.NewLogs(db),
}
}

Expand All @@ -76,6 +81,23 @@ type ChatDatabase struct {
userLoginRecord table.UserLoginRecordInterface
verifyCode table.VerifyCodeInterface
forbiddenAccount admin.ForbiddenAccountInterface
log table.LogInterface
}

func (o *ChatDatabase) GetLogs(ctx context.Context, LogIDs []string, userID string) ([]*table.Log, error) {
return o.log.Get(ctx, LogIDs, userID)
}

func (o *ChatDatabase) DeleteLogs(ctx context.Context, logID []string, userID string) error {
return o.log.Delete(ctx, logID, userID)
}

func (o *ChatDatabase) SearchLogs(ctx context.Context, keyword string, start time.Time, end time.Time, pageNumber int32, showNumber int32) (uint32, []*table.Log, error) {
return o.log.Search(ctx, keyword, start, end, pageNumber, showNumber)
}

func (o *ChatDatabase) UploadLogs(ctx context.Context, logs []*table.Log) error {
return o.log.Create(ctx, logs)
}

func (o *ChatDatabase) IsNotFound(err error) bool {
Expand Down
44 changes: 44 additions & 0 deletions pkg/common/db/model/chat/log.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package chat

import (
"context"
"github.com/OpenIMSDK/chat/pkg/common/db/table/chat"
"github.com/OpenIMSDK/tools/errs"
"github.com/OpenIMSDK/tools/ormutil"
"gorm.io/gorm"
"time"
)

type Logs struct {
db *gorm.DB
}

func (l *Logs) Create(ctx context.Context, log []*chat.Log) error {
return errs.Wrap(l.db.WithContext(ctx).Create(log).Error)
}

func (l *Logs) Search(ctx context.Context, keyword string, start time.Time, end time.Time, pageNumber int32, showNumber int32) (uint32, []*chat.Log, error) {
db := l.db.WithContext(ctx).Where("create_time >= ?", start)
if end.UnixMilli() != 0 {
db = l.db.WithContext(ctx).Where("create_time <= ?", end)
}
return ormutil.GormSearch[chat.Log](db, []string{"user_id"}, keyword, pageNumber, showNumber)
}

func (l *Logs) Delete(ctx context.Context, logIDs []string, userID string) error {
if userID == "" {
return errs.Wrap(l.db.WithContext(ctx).Where("log_id in ?", logIDs).Delete(&chat.Log{}).Error)
}
return errs.Wrap(l.db.WithContext(ctx).Where("log_id in ? and user_id=?", logIDs, userID).Delete(&chat.Log{}).Error)
}

func (l *Logs) Get(ctx context.Context, logIDs []string, userID string) ([]*chat.Log, error) {
var logs []*chat.Log
if userID == "" {
return logs, errs.Wrap(l.db.WithContext(ctx).Where("log_id in ?", logIDs).Find(&logs).Error)
}
return logs, errs.Wrap(l.db.WithContext(ctx).Where("log_id in ? and user_id=?", logIDs, userID).Find(&logs).Error)
}
func NewLogs(db *gorm.DB) chat.LogInterface {
return &Logs{db: db}
}
24 changes: 24 additions & 0 deletions pkg/common/db/table/chat/log.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package chat

import (
"context"
"time"
)

type Log struct {
LogID string `gorm:"column:log_id;primary_key;type:char(64)"`
Platform string `gorm:"column:platform;type:varchar(32)"`
UserID string `gorm:"column:user_id;type:char(64)"`
CreateTime time.Time `gorm:"index:,sort:desc"`
Url string `gorm:"column:url;type varchar(255)"`
FileName string `gorm:"column:filename;type varchar(255)"`
SystemType string `gorm:"column:system_type;type varchar(255)"`
Ex string `gorm:"column:ex;type varchar(255)"`
}

type LogInterface interface {
Create(ctx context.Context, log []*Log) error
Search(ctx context.Context, keyword string, start time.Time, end time.Time, pageNumber int32, showNumber int32) (uint32, []*Log, error)
Delete(ctx context.Context, logID []string, userID string) error
Get(ctx context.Context, logIDs []string, userID string) ([]*Log, error)
}
33 changes: 33 additions & 0 deletions pkg/proto/chat/chat.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package chat

import (
"github.com/OpenIMSDK/tools/utils"
"regexp"
"strconv"

Expand Down Expand Up @@ -201,6 +202,38 @@ func (x *SearchUserFullInfoReq) Check() error {
return nil
}

func (x *DeleteLogsReq) Check() error {
if x.LogIDs == nil {
return errs.ErrArgs.Wrap("LogIDs is empty")
}
if utils.Duplicate(x.LogIDs) {
return errs.ErrArgs.Wrap("Logs has duplicate")
}
return nil
}

func (x *UploadLogsReq) Check() error {
if x.FileURLs == nil {
return errs.ErrArgs.Wrap("FileUrls is empty")
}
if x.Platform < constant2.IOSPlatformID || x.Platform > constant2.AdminPlatformID {
return errs.ErrArgs.Wrap("Platform is invalid")
}
return nil
}
func (x *SearchLogsReq) Check() error {
if x.Pagination == nil {
return errs.ErrArgs.Wrap("Pagination is empty")
}
if x.Pagination.PageNumber < 1 {
return errs.ErrArgs.Wrap("pageNumber is invalid")
}
if x.Pagination.ShowNumber < 1 {
return errs.ErrArgs.Wrap("showNumber is invalid")
}
return nil
}

func EmailCheck(email string) error {
pattern := `^[0-9a-z][_.0-9a-z-]{0,31}@([0-9a-z][0-9a-z-]{0,30}[0-9a-z]\.){1,4}[a-z]{2,4}$`
if err := regexMatch(pattern, email); err != nil {
Expand Down
Loading
Loading