116 lines
4.1 KiB
Go
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
|
|
}
|