Files
pj0235-eai_agentplatform/eai_agentplatform/backend-go/internal/api/points.go
T
eaiadmin b7238ad667 refactor: 收口技能与专员目录定义
统一 skill 与 specialist 清单,移除旧的 office 执行包与下线对象,并补入 text_to_speech、customer_followup 等当前目录定义与种子数据。
2026-09-22 23:38:56 +08:00

91 lines
2.9 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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()})
}