Files
36Wisdom/biz/service/user_progress.go
T
2026-08-14 12:13:02 +08:00

79 lines
2.6 KiB
Go

package service
import (
"context"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
"36wisdom/biz/consts"
"36wisdom/biz/dao"
)
type userProgress struct{}
var UserProgress = &userProgress{}
// GetByChildLevel 孩子某关进度(不缓存,随闯关更新)。
func (s *userProgress) GetByChildLevel(ctx context.Context, childId, levelId int64) (gdb.Record, error) {
return dao.UserProgress.Model().Ctx(ctx).
Where("child_id", childId).Where("level_id", levelId).One()
}
// ListByChildLevelIds 孩子多关进度(不缓存)。
func (s *userProgress) ListByChildLevelIds(ctx context.Context, childId int64, levelIds []int64) ([]gdb.Record, error) {
return dao.UserProgress.Model().Ctx(ctx).
Where("child_id", childId).
WhereIn("level_id", levelIds).All()
}
// CountPerfectByChild 孩子完美通关关卡数。
func (s *userProgress) CountPerfectByChild(ctx context.Context, childId int64) (int, error) {
return dao.UserProgress.Model().Ctx(ctx).
Where("child_id", childId).Where("perfect", 1).Count()
}
// CountPerfectByChildIds 批量孩子的完美通关数(按 child_id 分组)。
func (s *userProgress) CountPerfectByChildIds(ctx context.Context, childIds []int64) ([]gdb.Record, error) {
return dao.UserProgress.Model().Ctx(ctx).
Fields("child_id", "COUNT(*) AS cnt").
Where("perfect", 1).
WhereIn("child_id", childIds).
Group("child_id").All()
}
// GetInTx 事务内读孩子某关进度。
func (s *userProgress) GetInTx(ctx context.Context, tx gdb.TX, childId, levelId int64) (gdb.Record, error) {
return tx.Model(consts.TableUserProgress).Ctx(ctx).
Where("child_id", childId).Where("level_id", levelId).One()
}
// UpsertInTx 事务内合并写入进度:星星取历史最高、完美取并集;不存在则插入。
func (s *userProgress) UpsertInTx(ctx context.Context, tx gdb.TX, childId, levelId int64, stars, perfect, contentVersion int) error {
rec, err := tx.Model(consts.TableUserProgress).Ctx(ctx).
Where("child_id", childId).Where("level_id", levelId).One()
if err != nil {
return err
}
if stars < rec["stars"].Int() {
stars = rec["stars"].Int()
}
perfect = rec["perfect"].Int() | perfect
data := g.Map{
"stars": stars,
"perfect": perfect,
"content_version": contentVersion,
"completed_at": gtime.Now(),
}
if rec.IsEmpty() {
data["child_id"] = childId
data["level_id"] = levelId
_, err = tx.Model(consts.TableUserProgress).Ctx(ctx).Data(data).Insert()
} else {
_, err = tx.Model(consts.TableUserProgress).Ctx(ctx).Data(data).
Where("child_id", childId).Where("level_id", levelId).Update()
}
return err
}