diff --git a/biz/dao/dao_element.go b/biz/dao/dao_element.go index dad67d3..fab0bec 100644 --- a/biz/dao/dao_element.go +++ b/biz/dao/dao_element.go @@ -19,12 +19,16 @@ CREATE TABLE IF NOT EXISTS element ( id INTEGER PRIMARY KEY AUTOINCREMENT, e_type INTEGER NOT NULL, name TEXT NOT NULL, + name_pinyin TEXT, image TEXT, audio TEXT, description TEXT, + description_pinyin TEXT, status INTEGER NOT NULL DEFAULT 1, sort_order INTEGER NOT NULL DEFAULT 1 ); CREATE INDEX IF NOT EXISTS idx_element_type ON element(e_type);`) + common.EnsureColumn(ctx, consts.TableElement, "name_pinyin", "TEXT") + common.EnsureColumn(ctx, consts.TableElement, "description_pinyin", "TEXT") return err } diff --git a/biz/dao/dao_level.go b/biz/dao/dao_level.go index 41ba415..52b40b8 100644 --- a/biz/dao/dao_level.go +++ b/biz/dao/dao_level.go @@ -21,6 +21,7 @@ CREATE TABLE IF NOT EXISTS level ( 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', @@ -29,5 +30,6 @@ CREATE TABLE IF NOT EXISTS level ( 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 } diff --git a/biz/dao/dao_node_option.go b/biz/dao/dao_node_option.go index 7f6e157..0109695 100644 --- a/biz/dao/dao_node_option.go +++ b/biz/dao/dao_node_option.go @@ -19,14 +19,22 @@ CREATE TABLE IF NOT EXISTS node_option ( id INTEGER PRIMARY KEY AUTOINCREMENT, node_id INTEGER NOT NULL, text TEXT NOT NULL, + text_pinyin TEXT, prop_id INTEGER, audio TEXT, next_node_id INTEGER, feedback TEXT NOT NULL, + feedback_pinyin TEXT, + feedback_pros TEXT, -- 对比点评:好处 + feedback_cons TEXT, -- 对比点评:不足/错过的更好选择 feedback_audio TEXT, sort_order INTEGER NOT NULL DEFAULT 1, status INTEGER NOT NULL DEFAULT 1 ); CREATE INDEX IF NOT EXISTS idx_option_node ON node_option(node_id);`) + common.EnsureColumn(ctx, consts.TableNodeOption, "text_pinyin", "TEXT") + common.EnsureColumn(ctx, consts.TableNodeOption, "feedback_pinyin", "TEXT") + common.EnsureColumn(ctx, consts.TableNodeOption, "feedback_pros", "TEXT") + common.EnsureColumn(ctx, consts.TableNodeOption, "feedback_cons", "TEXT") return err } diff --git a/biz/dao/dao_scene_node.go b/biz/dao/dao_scene_node.go index 495aafb..2228fcc 100644 --- a/biz/dao/dao_scene_node.go +++ b/biz/dao/dao_scene_node.go @@ -21,6 +21,7 @@ CREATE TABLE IF NOT EXISTS scene_node ( title TEXT, character_id INTEGER, content TEXT NOT NULL, + content_pinyin TEXT, image TEXT, audio TEXT, node_type INTEGER NOT NULL DEFAULT 1, @@ -32,5 +33,6 @@ CREATE TABLE IF NOT EXISTS scene_node ( status INTEGER NOT NULL DEFAULT 1 ); CREATE INDEX IF NOT EXISTS idx_node_level ON scene_node(level_id);`) + common.EnsureColumn(ctx, consts.TableSceneNode, "content_pinyin", "TEXT") return err } diff --git a/biz/dao/dao_strategy.go b/biz/dao/dao_strategy.go index 91af543..109c65c 100644 --- a/biz/dao/dao_strategy.go +++ b/biz/dao/dao_strategy.go @@ -21,12 +21,16 @@ CREATE TABLE IF NOT EXISTS strategy ( pinyin TEXT NOT NULL, group_no INTEGER NOT NULL, group_name TEXT NOT NULL, - meaning TEXT NOT NULL, - teach_content TEXT, + meaning TEXT NOT NULL, -- 儿童语言释义 + meaning_pinyin TEXT, -- 释义拼音(逐字对齐 JSON) + teach_content TEXT, -- 计策学堂:儿童化讲解(名称/释义/使用时机) + teach_content_pinyin TEXT, teach_image TEXT, teach_audio TEXT, - summary_q TEXT, - summary_options TEXT, + summary_q TEXT, -- 智慧总结反思题 + summary_q_pinyin TEXT, + summary_options TEXT, -- 反思题选项 JSON(含正确答案) + summary_options_pinyin TEXT, summary_audio TEXT, icon TEXT, sort_order INTEGER NOT NULL, @@ -34,5 +38,9 @@ CREATE TABLE IF NOT EXISTS strategy ( status INTEGER NOT NULL DEFAULT 1 ); CREATE INDEX IF NOT EXISTS idx_strategy_group ON strategy(group_no, sort_order);`) + common.EnsureColumn(ctx, consts.TableStrategy, "meaning_pinyin", "TEXT") + common.EnsureColumn(ctx, consts.TableStrategy, "teach_content_pinyin", "TEXT") + common.EnsureColumn(ctx, consts.TableStrategy, "summary_q_pinyin", "TEXT") + common.EnsureColumn(ctx, consts.TableStrategy, "summary_options_pinyin", "TEXT") return err } diff --git a/common/migrate.go b/common/migrate.go new file mode 100644 index 0000000..82b5bf2 --- /dev/null +++ b/common/migrate.go @@ -0,0 +1,28 @@ +package common + +import ( + "context" + "fmt" + + "github.com/gogf/gf/v2/frame/g" +) + +// EnsureColumn 幂等加列:PRAGMA 查列不存在则 ALTER TABLE ADD COLUMN。 +// 失败只记警告,不阻断启动(列缺失时后续查询只会取到空值)。 +func EnsureColumn(ctx context.Context, table, col, sqlType string) { + cols, err := g.DB().GetAll(ctx, fmt.Sprintf("PRAGMA table_info(%s)", table)) + if err != nil { + g.Log().Warningf(ctx, "migrate: %s 表结构读取失败: %v", table, err) + return + } + for _, c := range cols { + if c["name"].String() == col { + return + } + } + if _, err := g.DB().Exec(ctx, fmt.Sprintf("ALTER TABLE %s ADD COLUMN %s %s", table, col, sqlType)); err != nil { + g.Log().Warningf(ctx, "migrate: %s.%s 加列失败: %v", table, col, err) + return + } + g.Log().Infof(ctx, "migrate: %s.%s 已添加", table, col) +}