Files
36Wisdom/biz/dao/dao_level.go
T
2026-08-14 16:11:10 +08:00

116 lines
4.1 KiB
Go

package dao
import (
"context"
"github.com/gogf/gf/v2/database/gdb"
"github.com/gogf/gf/v2/frame/g"
"36wisdom/biz/consts"
"36wisdom/biz/model/entity"
"36wisdom/common"
)
type levelDao struct{ common.BaseDao }
var Level = &levelDao{BaseDao: common.BaseDao{Table: consts.TableLevel}}
func (d *levelDao) Init(ctx context.Context) error {
_, err := g.DB().Exec(ctx, `
CREATE TABLE IF NOT EXISTS level (
id INTEGER PRIMARY KEY AUTOINCREMENT,
strategy_id INTEGER NOT NULL,
title TEXT NOT NULL,
scene_id INTEGER,
scene_content TEXT NOT NULL,
scene_content_pinyin TEXT,
scene_image TEXT,
scene_audio TEXT,
age_group TEXT NOT NULL DEFAULT '4-6',
content_version INTEGER NOT NULL DEFAULT 1,
sort_order INTEGER NOT NULL,
status INTEGER NOT NULL DEFAULT 1
);
CREATE INDEX IF NOT EXISTS idx_level_strategy ON level(strategy_id, sort_order);`)
common.EnsureColumn(ctx, consts.TableLevel, "scene_content_pinyin", "TEXT")
return err
}
// GetByPk 主键查询(无缓存);不存在返回 nil, nil。
func (d *levelDao) GetByPk(ctx context.Context, id int64) (*entity.Level, error) {
return common.GetOne[entity.Level](d.Model().Ctx(ctx).WherePri(id))
}
// GetByPkCached 主键查询(内容缓存);不存在返回 nil, nil。
func (d *levelDao) GetByPkCached(ctx context.Context, id int64) (*entity.Level, error) {
return common.GetOne[entity.Level](d.Model().Ctx(ctx).Cache(d.ContentCache(ctx)).WherePri(id))
}
// ListEnabledByStrategyIds 指定计策下、匹配年龄段且启用的关卡(内容缓存)。
func (d *levelDao) ListEnabledByStrategyIds(ctx context.Context, strategyIds []int64, ageGroup string) ([]*entity.Level, error) {
if len(strategyIds) == 0 {
return []*entity.Level{}, nil
}
return common.GetList[entity.Level](d.Model().Ctx(ctx).Cache(d.ContentCache(ctx)).
WhereIn("strategy_id", strategyIds).Where("status", consts.StatusEnabled).
Where("age_group", ageGroup).Order("sort_order ASC"))
}
// ListByStrategyId 指定计策下全部关卡(含下架,后台全量展示),按序号排序。
func (d *levelDao) ListByStrategyId(ctx context.Context, strategyId int64) ([]*entity.Level, error) {
return common.GetList[entity.Level](d.Model().Ctx(ctx).Where("strategy_id", strategyId).Order("sort_order ASC"))
}
// ListByIds 按 id 批量取(含下架)。
func (d *levelDao) ListByIds(ctx context.Context, ids []int64) ([]*entity.Level, error) {
if len(ids) == 0 {
return []*entity.Level{}, nil
}
return common.GetList[entity.Level](d.Model().Ctx(ctx).WhereIn("id", ids))
}
// ListEnabledByStrategyInTx 事务内取指定计策下启用关卡(完美判定用)。
func (d *levelDao) ListEnabledByStrategyInTx(ctx context.Context, tx gdb.TX, strategyId int64) ([]*entity.Level, error) {
recs, err := tx.Model(consts.TableLevel).Ctx(ctx).
Where("strategy_id", strategyId).Where("status", consts.StatusEnabled).All()
if err != nil {
return nil, err
}
if len(recs) == 0 {
return []*entity.Level{}, nil
}
var items []*entity.Level
if err = recs.Structs(&items); err != nil {
return nil, err
}
return items, nil
}
// CountEnabledByStrategyIds 各计策启用关卡数(单表 GROUP BY 聚合)。
func (d *levelDao) CountEnabledByStrategyIds(ctx context.Context, strategyIds []int64) (map[int64]int, error) {
m := make(map[int64]int, len(strategyIds))
if len(strategyIds) == 0 {
return m, nil
}
recs, err := d.Model().Ctx(ctx).WhereIn("strategy_id", strategyIds).
Where("status", consts.StatusEnabled).Group("strategy_id").
Fields("strategy_id, COUNT(*) AS cnt").All()
if err != nil {
return nil, err
}
for _, r := range recs {
m[r["strategy_id"].Int64()] = r["cnt"].Int()
}
return m, nil
}
// ProgressStatsByLevel 关卡参与孩子数与完美通关数(单表聚合)。
func (d *levelDao) ProgressStatsByLevel(ctx context.Context, levelId int64) (players, perfectCount int, err error) {
rec, err := d.Model().Ctx(ctx).Fields("COUNT(*) AS total, COALESCE(SUM(perfect), 0) AS perfect").
Where("level_id", levelId).One()
if err != nil {
return 0, 0, err
}
return rec["total"].Int(), rec["perfect"].Int(), nil
}