diff --git a/biz/service/seed/interaction.go b/biz/service/seed/interaction.go index a99a084..d9e59f5 100644 --- a/biz/service/seed/interaction.go +++ b/biz/service/seed/interaction.go @@ -119,8 +119,11 @@ func ensureLevelInteraction(ctx context.Context, lv gdb.Record, kind int) error for id := range elementNames { ids = append(ids, id) } - if recs, err := dao.Element.Model().Ctx(ctx). - WhereIn("id", uniqueInt64(ids)).Where("status", consts.StatusEnabled).All(); err == nil { + recs, err := dao.Element.Model().Ctx(ctx). + WhereIn("id", uniqueInt64(ids)).Where("status", consts.StatusEnabled).All() + if err != nil { + g.Log().Warningf(ctx, "seed: 元素名加载失败 level=%d: %v", levelId, err) + } else { for _, r := range recs { elementNames[r["id"].Int64()] = r["name"].String() } @@ -184,7 +187,7 @@ func planInteraction(kind int, entryID int64, nodes, options []gdb.Record, eleme p.answerOrder = append(p.answerOrder, items[i].ID) } case "link_match": - p.persons, p.pairs = pairsOf(nodes, options) + p.persons, p.pairs = pairsOf(nodes, options, elementNames) if len(p.pairs) < 2 { // 配对不足退化为道具选择 p.kind = "prop_pick" @@ -249,7 +252,7 @@ func bestPropOf(options []gdb.Record, nodes []gdb.Record) int64 { } // pairsOf 人物-道具配对:每个去重人物取其最后一个带道具选项的道具,返回人物列表与配对。 -func pairsOf(nodes, options []gdb.Record) ([]configItem, [][2]int64) { +func pairsOf(nodes, options []gdb.Record, elementNames map[int64]string) ([]configItem, [][2]int64) { propOf := map[int64]int64{} // node_id → 最后一个带道具选项的道具 for _, o := range options { pid := o["prop_id"].Int64() @@ -270,7 +273,7 @@ func pairsOf(nodes, options []gdb.Record) ([]configItem, [][2]int64) { pairs = append(pairs, [2]int64{cid, pid}) if !seen[cid] { seen[cid] = true - persons = append(persons, configItem{ID: cid}) + persons = append(persons, configItem{ID: cid, Name: elementNames[cid]}) } } } @@ -291,7 +294,11 @@ func nodeIdsOf(nodes []gdb.Record) []int64 { return ids } -// insertInteractionNode 事务:原入口 is_entry=0 → 插互动节点(is_entry=1) → 插成功/失败出口选项。 +// insertInteractionNode 写入 scene_node / node_option,两表读查询走 contentCache。 +// 本函数仅在 EnsureSeeded 启动期调用(先于 HTTP 服务监听),内存 gcache 无并发读者, +// 无脏读可能,故按 annotateAll 先例不清缓存;若将来改为运行期调用须先清对应缓存。 +// +// 事务:原入口 is_entry=0 → 插互动节点(is_entry=1) → 插成功/失败出口选项。 func insertInteractionNode(ctx context.Context, levelId int64, kind int, plan *interactionPlan) error { promptPinyin := common.AnnotatePinyin(plan.prompt) return g.DB().Transaction(ctx, func(ctx context.Context, tx gdb.TX) error {