package api import ( "time" "github.com/gin-gonic/gin" "gorm.io/gorm" "eai_agentplatform/backend/internal/middleware" "eai_agentplatform/backend/internal/model" "eai_agentplatform/backend/internal/store" "eai_agentplatform/backend/internal/web" ) // —— 积分规则(游戏化成长值,集中一处便于调整,见 docs/01_System_Overall/变更日志.md 待确认项)—— const ( ptFirstCompany = 10 // 首次浏览公司介绍 ptFirstProduct = 2 // 首次浏览单个产品 ptFirstCourse = 5 // 首次浏览单门课程 ptSelfTestSubmit = 5 // 自测提交一次 ptFormalPass = 50 // 正式考试通过 ptMistakeResolved = 3 // 错题标记已掌握 ) // awardPoints 记录积分流水并累加到 user.learning_points(points<=0 直接忽略,避免负分刷分)。 func awardPoints(userID uint, eventType string, points int, refType string, refID uint) { if userID == 0 || points <= 0 { return } store.DB.Create(&model.PointEvent{ UserID: userID, EventType: eventType, Points: points, RefType: refType, RefID: refID, }) store.DB.Model(&model.User{}).Where("id = ?", userID). UpdateColumn("learning_points", gorm.Expr("learning_points + ?", points)) } // awardFirstView 首次浏览公司/产品/课程加分(由 RecordLearningProgress 幂等触发)。 func awardFirstView(userID uint, itemType string, itemID uint) { switch itemType { case "company": awardPoints(userID, "first_company", ptFirstCompany, itemType, itemID) case "product": awardPoints(userID, "first_product", ptFirstProduct, itemType, itemID) case "course": awardPoints(userID, "first_course", ptFirstCourse, itemType, itemID) } } // MyPoints GET /api/points/me —— 我的积分 + 最近积分流水 func MyPoints(c *gin.Context) { u := middleware.CurrentUser(c) if u == nil { web.Fail(c, web.NewAuthError("未登录")) return } var total int store.DB.Raw(`SELECT COALESCE(SUM(points), 0) FROM point_event WHERE user_id = ?`, u.ID).Scan(&total) var events []model.PointEvent store.DB.Where("user_id = ?", u.ID).Order("created_at DESC, id DESC").Limit(50).Find(&events) web.OK(c, gin.H{"total": total, "events": events}) } // Leaderboard GET /api/points/leaderboard —— 学习积分排行榜(全员,含我的名次) func Leaderboard(c *gin.Context) { u := middleware.CurrentUser(c) var users []model.User store.DB.Where("role = ? AND status = ?", "employee", "active"). Order("learning_points DESC, id ASC").Find(&users) out := make([]gin.H, 0, len(users)) myRank := 0 for i, usr := range users { out = append(out, gin.H{ "rank": i + 1, "user_id": usr.ID, "full_name": usr.FullName, "department": usr.Department, "learning_points": usr.LearningPoints, "is_me": u != nil && usr.ID == u.ID, }) if u != nil && usr.ID == u.ID { myRank = i + 1 } } web.OK(c, gin.H{"items": out, "my_rank": myRank, "total": len(out), "updated_at": time.Now()}) }