|
|
@@ -3060,6 +3060,9 @@ insertSysConfigSeed("gift_membership_pay_price", "198000", "送会员商品达
|
|
|
// 迁移374: 创建 user_content_weights 表(用户内容偏好权重表)
|
|
|
addUserContentWeightsTable();
|
|
|
|
|
|
+ // 迁移375: 修复 article_quiz_records 表结构(旧表缺 member_id/total_questions/cf_earned/energy_earned,questions/answers 需为 TEXT)
|
|
|
+ fixArticleQuizRecordsTable();
|
|
|
+
|
|
|
// 迁移376: health_status 添加 lifestyle JSON 列(心情/睡眠/排便/抗生素/过敏表现)
|
|
|
ensureColumn("health_status", "lifestyle", "JSON DEFAULT NULL COMMENT '生活方式与肠道健康 {mood,sleepDuration,bedtime,bowelFrequency,bowelForm,antibioticHistory,allergySymptoms}'");
|
|
|
|
|
|
@@ -12637,6 +12640,56 @@ log.info("迁移298: 已为无 openid 的 child 账号补齐 family_members 记
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ // 迁移375: 修复 article_quiz_records 表结构(旧表由迁移299创建时已存在导致缺列)
|
|
|
+ private void fixArticleQuizRecordsTable() {
|
|
|
+ try {
|
|
|
+ if (!columnExists("article_quiz_records", "member_id")) {
|
|
|
+ jdbcTemplate.execute("ALTER TABLE article_quiz_records ADD COLUMN member_id BIGINT DEFAULT NULL COMMENT '家庭成员ID(作答人)'");
|
|
|
+ log.info("迁移375: 已添加 member_id 列到 article_quiz_records");
|
|
|
+ }
|
|
|
+ if (!columnExists("article_quiz_records", "total_questions")) {
|
|
|
+ jdbcTemplate.execute("ALTER TABLE article_quiz_records ADD COLUMN total_questions INT DEFAULT 0 COMMENT '题目总数'");
|
|
|
+ log.info("迁移375: 已添加 total_questions 列到 article_quiz_records");
|
|
|
+ }
|
|
|
+ if (!columnExists("article_quiz_records", "cf_earned")) {
|
|
|
+ jdbcTemplate.execute("ALTER TABLE article_quiz_records ADD COLUMN cf_earned INT DEFAULT 0 COMMENT '发放的CF值'");
|
|
|
+ log.info("迁移375: 已添加 cf_earned 列到 article_quiz_records");
|
|
|
+ }
|
|
|
+ if (!columnExists("article_quiz_records", "energy_earned")) {
|
|
|
+ jdbcTemplate.execute("ALTER TABLE article_quiz_records ADD COLUMN energy_earned INT DEFAULT 0 COMMENT '发放的能量值'");
|
|
|
+ log.info("迁移375: 已添加 energy_earned 列到 article_quiz_records");
|
|
|
+ }
|
|
|
+ // questions/answers 旧表为 VARCHAR(255),实体存 JSON 快照会超长,与 schema.sql 对齐为 TEXT
|
|
|
+ if (!columnTypeStartsWith("article_quiz_records", "questions", "text")) {
|
|
|
+ jdbcTemplate.execute("ALTER TABLE article_quiz_records MODIFY COLUMN questions TEXT COMMENT '题目快照JSON(含正确答案与维度)'");
|
|
|
+ log.info("迁移375: questions 列已改为 TEXT");
|
|
|
+ }
|
|
|
+ if (!columnTypeStartsWith("article_quiz_records", "answers", "text")) {
|
|
|
+ jdbcTemplate.execute("ALTER TABLE article_quiz_records MODIFY COLUMN answers TEXT COMMENT '用户作答JSON(含每题所选选项),作答前为NULL'");
|
|
|
+ log.info("迁移375: answers 列已改为 TEXT");
|
|
|
+ }
|
|
|
+ // 补充索引(幂等;重复创建会报 Duplicate key name,捕获忽略)
|
|
|
+ try {
|
|
|
+ jdbcTemplate.execute("ALTER TABLE article_quiz_records ADD INDEX idx_member (member_id)");
|
|
|
+ } catch (Exception ignored) {
|
|
|
+ }
|
|
|
+ log.info("迁移375: article_quiz_records 表结构修复完成");
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("迁移375: 修复 article_quiz_records 表结构失败: {}", e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private boolean columnTypeStartsWith(String table, String column, String typePrefix) {
|
|
|
+ try {
|
|
|
+ String t = jdbcTemplate.queryForObject(
|
|
|
+ "SELECT DATA_TYPE FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? AND COLUMN_NAME = ?",
|
|
|
+ String.class, table, column);
|
|
|
+ return t != null && t.toLowerCase().startsWith(typePrefix);
|
|
|
+ } catch (Exception e) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
// 迁移372: nutrition_product 添加 efficacy_tags 列(成分功效标签)
|
|
|
private void addNutritionProductEfficacyTags() {
|
|
|
if (!columnExists("nutrition_product", "efficacy_tags")) {
|