diff --git a/internal/core/cs/metrics.go b/internal/core/cs/metrics.go index c9d2a5c0..7493c0dc 100644 --- a/internal/core/cs/metrics.go +++ b/internal/core/cs/metrics.go @@ -1,41 +1,41 @@ -// Copyright 2023 ROC. All rights reserved. +// Copyright 2022 ROC. All rights reserved. // Use of this source code is governed by a MIT style // license that can be found in the LICENSE file. package cs const ( - MetricActionCreateTweet uint8 = iota + MetricActionCreateTweet = iota + 1 MetricActionDeleteTweet ) type TweetMetric struct { - PostId int64 - CommentCount int64 - UpvoteCount int64 - CollectionCount int64 - ShareCount int64 - ThumbsUpCount int64 - ThumbsDownCount int64 + PostId int64 + IncentiveScore int + DecayFactor int +} + +func (m *TweetMetric) RankScore(motivationFactor int) int64 { + return int64(m.IncentiveScore * motivationFactor / m.DecayFactor) } type CommentMetric struct { CommentId int64 + IncentiveScore int + DecayFactor int ReplyCount int32 ThumbsUpCount int32 ThumbsDownCount int32 } -func (m *TweetMetric) RankScore(motivationFactor int) int64 { - if motivationFactor == 0 { - motivationFactor = 1 - } - return (m.CommentCount + m.UpvoteCount*2 + m.CollectionCount*4 + m.ShareCount*8) * int64(motivationFactor) +func (m *CommentMetric) RankScore(motivationFactor int) int64 { + return int64(m.IncentiveScore * motivationFactor / m.DecayFactor) } -func (m *CommentMetric) RankScore(motivationFactor int) int64 { - if motivationFactor == 0 { - motivationFactor = 1 - } - return int64(m.ReplyCount*2+m.ThumbsUpCount*4-m.ThumbsDownCount) * int64(motivationFactor) +// UserMetric 用户指标结构体 +type UserMetric struct { + UserId int64 + TweetsCount int + LatestTrendsOn int64 + Experience int } diff --git a/internal/core/metrics.go b/internal/core/metrics.go index d2dbc0fb..1112e609 100644 --- a/internal/core/metrics.go +++ b/internal/core/metrics.go @@ -18,10 +18,13 @@ type CommentMetricServantA interface { UpdateCommentMetric(metric *cs.CommentMetric) error AddCommentMetric(commentId int64) error DeleteCommentMetric(commentId int64) error + GetCommentMetric(commentId int64) (*cs.CommentMetric, error) } type UserMetricServantA interface { UpdateUserMetric(userId int64, action uint8) error AddUserMetric(userId int64) error DeleteUserMetric(userId int64) error + UpdateUserExperience(userId int64, Experience int) error + GetUserMetric(userId int64) (*cs.UserMetric, error) } diff --git a/internal/dao/jinzhu/dbr/experience.go b/internal/dao/jinzhu/dbr/experience.go new file mode 100644 index 00000000..e37caa3c --- /dev/null +++ b/internal/dao/jinzhu/dbr/experience.go @@ -0,0 +1,39 @@ +package dbr + +import ( + "time" + + "gorm.io/gorm" +) + +// ExperienceChangeLog 经验值变动日志模型 +type ExperienceChangeLog struct { + LogID int `gorm:"column:log_id;primaryKey" json:"log_id"` // 日志ID(主键) + UserID int `gorm:"column:user_id" json:"user_id"` // 用户ID + Action int `gorm:"column:action" json:"action"` // 触发行为(对应动作类型编码) + Amount int `gorm:"column:amount" json:"amount"` // 经验值变动量 + Remark int `gorm:"column:remark" json:"remark"` // 备注(若为状态码可对应文本说明) + UpdatedAt time.Time `gorm:"column:updated_at" json:"updated_at"` // 变动时间 +} + +// TableName 指定表名映射 +func (e *ExperienceChangeLog) TableName() string { + return "p_experience_change_log" +} + +// Create 创建经验值变动记录 +func (e *ExperienceChangeLog) Create(db *gorm.DB) (*ExperienceChangeLog, error) { + err := db.Create(&e).Error + return e, err +} + +// ListByUserID 根据用户ID查询日志(示例方法) +func (e *ExperienceChangeLog) ListByUserID(db *gorm.DB, userID int, page, size int) ([]*ExperienceChangeLog, error) { + var logs []*ExperienceChangeLog + err := db.Where("user_id = ?", userID). + Offset((page - 1) * size). + Limit(size). + Order("updated_at DESC"). + Find(&logs).Error + return logs, err +} diff --git a/internal/dao/jinzhu/dbr/metrics.go b/internal/dao/jinzhu/dbr/metrics.go index 4210c701..72f3346d 100644 --- a/internal/dao/jinzhu/dbr/metrics.go +++ b/internal/dao/jinzhu/dbr/metrics.go @@ -26,6 +26,9 @@ type CommentMetric struct { IncentiveScore int DecayFactor int MotivationFactor int + ReplyCount int32 + ThumbsUpCount int32 + ThumbsDownCount int32 } type UserMetric struct { @@ -33,6 +36,7 @@ type UserMetric struct { UserId int64 TweetsCount int LatestTrendsOn int64 + Experience int } func (m *PostMetric) Create(db *gorm.DB) (*PostMetric, error) { @@ -70,3 +74,11 @@ func (m *UserMetric) Delete(db *gorm.DB) error { "is_del": 1, }).Error } + +func (m *UserMetric) Get(db *gorm.DB) error { + return db.Model(m).Where("user_id = ? AND is_del = ?", m.UserId, 0).First(m).Error +} + +func (m *CommentMetric) Get(db *gorm.DB) error { + return db.Model(m).Where("comment_id = ? AND is_del = ?", m.CommentId, 0).First(m).Error +} diff --git a/internal/dao/jinzhu/dbr/user.go b/internal/dao/jinzhu/dbr/user.go index 4d7f7f6d..2b3e2e11 100644 --- a/internal/dao/jinzhu/dbr/user.go +++ b/internal/dao/jinzhu/dbr/user.go @@ -16,15 +16,16 @@ const ( type User struct { *Model - Nickname string `json:"nickname"` - Username string `json:"username"` - Phone string `json:"phone"` - Password string `json:"password"` - Salt string `json:"salt"` - Status int `json:"status"` - Avatar string `json:"avatar"` - Balance int64 `json:"balance"` - IsAdmin bool `json:"is_admin"` + Nickname string `json:"nickname"` + Username string `json:"username"` + Phone string `json:"phone"` + Password string `json:"password"` + Salt string `json:"salt"` + Status int `json:"status"` + Avatar string `json:"avatar"` + Balance int64 `json:"balance"` + IsAdmin bool `json:"is_admin"` + Experience int `gorm:"-" json:"experience"` } type UserFormated struct { diff --git a/internal/dao/jinzhu/metrics.go b/internal/dao/jinzhu/metrics.go index 14bf4735..c39886f4 100644 --- a/internal/dao/jinzhu/metrics.go +++ b/internal/dao/jinzhu/metrics.go @@ -25,6 +25,14 @@ type userMetricSrvA struct { db *gorm.DB } +func (s *userMetricSrvA) UpdateUserExperience(userId int64, Experience int) error { + metric := &dbr.UserMetric{UserId: userId} + s.db.Model(metric).Where("user_id=?", userId).First(metric) + metric.LatestTrendsOn = time.Now().Unix() + metric.Experience += Experience + return s.db.Save(metric).Error +} + func (s *tweetMetricSrvA) UpdateTweetMetric(metric *cs.TweetMetric) error { return s.db.Transaction(func(tx *gorm.DB) error { postMetric := &dbr.PostMetric{PostId: metric.PostId} @@ -48,6 +56,9 @@ func (s *commentMetricSrvA) UpdateCommentMetric(metric *cs.CommentMetric) error commentMetric := &dbr.CommentMetric{CommentId: metric.CommentId} tx.Model(commentMetric).Where("comment_id=?", metric.CommentId).First(commentMetric) commentMetric.RankScore = metric.RankScore(commentMetric.MotivationFactor) + commentMetric.ReplyCount = metric.ReplyCount + commentMetric.ThumbsUpCount = metric.ThumbsUpCount + commentMetric.ThumbsDownCount = metric.ThumbsDownCount return tx.Save(commentMetric).Error }) } @@ -61,6 +72,23 @@ func (s *commentMetricSrvA) DeleteCommentMetric(commentId int64) (err error) { return (&dbr.CommentMetric{CommentId: commentId}).Delete(s.db) } +func (s *commentMetricSrvA) GetCommentMetric(commentId int64) (*cs.CommentMetric, error) { + metric := &dbr.CommentMetric{CommentId: commentId} + err := metric.Get(s.db) + if err != nil { + return nil, err + } + + return &cs.CommentMetric{ + CommentId: metric.CommentId, + IncentiveScore: metric.IncentiveScore, + DecayFactor: metric.DecayFactor, + ReplyCount: metric.ReplyCount, + ThumbsUpCount: metric.ThumbsUpCount, + ThumbsDownCount: metric.ThumbsDownCount, + }, nil +} + func (s *userMetricSrvA) UpdateUserMetric(userId int64, action uint8) error { metric := &dbr.UserMetric{UserId: userId} s.db.Model(metric).Where("user_id=?", userId).First(metric) @@ -73,6 +101,7 @@ func (s *userMetricSrvA) UpdateUserMetric(userId int64, action uint8) error { metric.TweetsCount-- } } + return s.db.Save(metric).Error } @@ -85,6 +114,21 @@ func (s *userMetricSrvA) DeleteUserMetric(userId int64) (err error) { return (&dbr.UserMetric{UserId: userId}).Delete(s.db) } +func (s *userMetricSrvA) GetUserMetric(userId int64) (*cs.UserMetric, error) { + metric := &dbr.UserMetric{UserId: userId} + err := metric.Get(s.db) + if err != nil { + return nil, err + } + + return &cs.UserMetric{ + UserId: metric.UserId, + TweetsCount: metric.TweetsCount, + LatestTrendsOn: metric.LatestTrendsOn, + Experience: metric.Experience, + }, nil +} + func newTweetMetricServentA(db *gorm.DB) core.TweetMetricServantA { return &tweetMetricSrvA{ db: db, diff --git a/internal/dao/jinzhu/user.go b/internal/dao/jinzhu/user.go index 6f5c2c71..3af09980 100644 --- a/internal/dao/jinzhu/user.go +++ b/internal/dao/jinzhu/user.go @@ -23,9 +23,9 @@ type userManageSrv struct { db *gorm.DB ums core.UserMetricServantA - _userProfileJoins string - _userProfileWhere string - _userProfileColoumns []string + _userProfileJoins string + _userProfileWhere string + _userProfileColumns []string } type userRelationSrv struct { @@ -38,7 +38,7 @@ func newUserManageService(db *gorm.DB, ums core.UserMetricServantA) core.UserMan ums: ums, _userProfileJoins: fmt.Sprintf("LEFT JOIN %s m ON %s.id=m.user_id", _userMetric_, _user_), _userProfileWhere: fmt.Sprintf("%s.username=? AND %s.is_del=0", _user_, _user_), - _userProfileColoumns: []string{ + _userProfileColumns: []string{ fmt.Sprintf("%s.id", _user_), fmt.Sprintf("%s.username", _user_), fmt.Sprintf("%s.nickname", _user_), @@ -65,7 +65,13 @@ func (s *userManageSrv) GetUserByID(id int64) (*ms.User, error) { ID: id, }, } - return user.Get(s.db) + user, err := user.Get(s.db) + metric, err := s.ums.GetUserMetric(id) + if err != nil { + return nil, err + } + user.Experience = metric.Experience + return user, nil } func (s *userManageSrv) GetUserByUsername(username string) (*ms.User, error) { @@ -78,7 +84,7 @@ func (s *userManageSrv) GetUserByUsername(username string) (*ms.User, error) { func (s *userManageSrv) UserProfileByName(username string) (res *cs.UserProfile, err error) { err = s.db.Table(_user_).Joins(s._userProfileJoins). Where(s._userProfileWhere, username). - Select(s._userProfileColoumns). + Select(s._userProfileColumns). First(&res).Error return } diff --git a/scripts/paopao-mysql.sql b/scripts/paopao-mysql.sql index 3e47c691..a0615d4a 100644 --- a/scripts/paopao-mysql.sql +++ b/scripts/paopao-mysql.sql @@ -513,4 +513,6 @@ UNION SELECT user_id, follow_id he_uid, 10 AS style FROM p_following WHERE is_del=0; +ALTER TABLE `p_user_metric` ADD `experience` INT UNSIGNED NOT NULL DEFAULT '0' AFTER `deleted_on`; + SET FOREIGN_KEY_CHECKS = 1;