Просмотр исходного кода

feat(db): 改版v1数据层 - problem_domains/user_intents/user_notifications 三表 + task.member_only + package_orders物流字段

E2E Test Bot 1 месяц назад
Родитель
Сommit
86b7ceb4e8

+ 79 - 0
cfc-backend/src/main/java/com/etotem/cfc/config/DatabaseInitializer.java

@@ -8966,5 +8966,84 @@ private void runMigration100() {
 		} catch (Exception ex) {
 			log.warn("activity维度迁移失败: {}", ex.getMessage());
 		}
+
+		// 迁移234: 创建 problem_domains 表(问题域定义,改版v1:需求驱动·逐步解锁)
+		try {
+			jdbcTemplate.execute(
+				"CREATE TABLE IF NOT EXISTS problem_domains (" +
+				"id BIGINT AUTO_INCREMENT PRIMARY KEY, " +
+				"code VARCHAR(50) NOT NULL COMMENT '唯一编码: weight_loss/sleep/constipation', " +
+				"name VARCHAR(50) NOT NULL COMMENT '名称: 减肥/睡眠/便秘', " +
+				"icon VARCHAR(255) DEFAULT '' COMMENT '图标', " +
+				"description VARCHAR(500) DEFAULT '' COMMENT '一句话描述', " +
+				"flow_intro_json TEXT COMMENT '服务流程介绍(7步) JSON', " +
+				"survey_template_id BIGINT DEFAULT NULL COMMENT '专项调研问卷模板ID(SurveyTemplate.id)', " +
+				"content_tags VARCHAR(500) DEFAULT '' COMMENT '内容标签,逗号分隔(过滤文章/知识库)', " +
+				"recommended_product_ids VARCHAR(500) DEFAULT '' COMMENT '推荐产品ID,逗号分隔(Product.id)', " +
+				"task_template_package_ids VARCHAR(500) DEFAULT '' COMMENT '套餐绑定的任务模板包ID(TaskTemplatePackage.id)', " +
+				"reward_cf_value INT DEFAULT 0 COMMENT '全部完成奖励CF值', " +
+				"status TINYINT DEFAULT 1 COMMENT '1启用 0停用', " +
+				"sort_order INT DEFAULT 0, " +
+				"created_at DATETIME DEFAULT CURRENT_TIMESTAMP, " +
+				"updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, " +
+				"UNIQUE KEY uk_code (code)" +
+				") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='问题域定义(改版v1)'"
+			);
+			log.info("已创建problem_domains表");
+		} catch (Exception e) {
+			log.warn("创建problem_domains表失败: " + e.getMessage());
+		}
+
+		// 迁移235: 创建 user_intents 表(用户意图与服务旅程)
+		try {
+			jdbcTemplate.execute(
+				"CREATE TABLE IF NOT EXISTS user_intents (" +
+				"id BIGINT AUTO_INCREMENT PRIMARY KEY, " +
+				"user_id BIGINT NOT NULL COMMENT '用户ID', " +
+				"intent_type VARCHAR(20) DEFAULT '' COMMENT 'A/B/C 用户类型', " +
+				"problem_domain_code VARCHAR(50) DEFAULT '' COMMENT '问题域编码(仅C类)', " +
+				"journey_stage INT DEFAULT 0 COMMENT '旅程阶段 0-7', " +
+				"stage_updated_at DATETIME DEFAULT NULL COMMENT '最近阶段变化时间', " +
+				"survey_template_id BIGINT DEFAULT NULL COMMENT '最近作答问卷模板ID', " +
+				"survey_submitted_at DATETIME DEFAULT NULL COMMENT '最近问卷提交时间', " +
+				"survey_result_json TEXT COMMENT '问卷答案→推荐结果快照', " +
+				"created_at DATETIME DEFAULT CURRENT_TIMESTAMP, " +
+				"updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, " +
+				"UNIQUE KEY uk_user (user_id)" +
+				") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户意图与服务旅程(改版v1)'"
+			);
+			log.info("已创建user_intents表");
+		} catch (Exception e) {
+			log.warn("创建user_intents表失败: " + e.getMessage());
+		}
+
+		// 迁移236: 创建 user_notifications 表(用户级站内主动通知,与notices平台公告并存)
+		try {
+			jdbcTemplate.execute(
+				"CREATE TABLE IF NOT EXISTS user_notifications (" +
+				"id BIGINT AUTO_INCREMENT PRIMARY KEY, " +
+				"user_id BIGINT NOT NULL COMMENT '接收用户ID', " +
+				"type VARCHAR(30) DEFAULT 'report_ready' COMMENT 'report_ready/reward_granted/logistics/system', " +
+				"title VARCHAR(200) NOT NULL, " +
+				"content VARCHAR(1000) DEFAULT '', " +
+				"ref_type VARCHAR(30) DEFAULT '' COMMENT '关联对象类型: report/package/task', " +
+				"ref_id BIGINT DEFAULT NULL COMMENT '关联对象ID', " +
+				"is_read TINYINT DEFAULT 0, " +
+				"created_at DATETIME DEFAULT CURRENT_TIMESTAMP, " +
+				"INDEX idx_user_read (user_id, is_read)" +
+				") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='站内通知(改版v1)'"
+			);
+			log.info("已创建user_notifications表");
+		} catch (Exception e) {
+			log.warn("创建user_notifications表失败: " + e.getMessage());
+		}
+
+		// 迁移237: task 表添加 member_only 字段(1=会员任务,仅方案/套餐生成)
+		ensureColumn("task", "member_only", "TINYINT DEFAULT 0 COMMENT '1=会员任务(方案/套餐生成),执行需会员; 0=普通任务可免费执行'");
+
+		// 迁移238: package_orders 表添加物流状态字段(试剂盒寄送/样本寄回)
+		ensureColumn("package_orders", "logistics_status", "VARCHAR(20) DEFAULT 'none' COMMENT 'none/kit_shipped/kit_received/sample_shipped/sample_received'");
+		ensureColumn("package_orders", "tracking_no", "VARCHAR(100) DEFAULT '' COMMENT '快递单号'");
+		log.info("已添加package_orders物流字段");
 	}
 }

+ 61 - 0
cfc-backend/src/main/java/com/etotem/cfc/entity/ProblemDomain.java

@@ -0,0 +1,61 @@
+package com.etotem.cfc.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 问题域定义(改版v1:需求驱动·逐步解锁)
+ * 首版: weight_loss=减肥 / sleep=睡眠 / constipation=便秘
+ */
+@Data
+@TableName("problem_domains")
+public class ProblemDomain implements Serializable {
+
+    @TableId(type = IdType.AUTO)
+    private Long id;
+
+    /** 唯一编码: weight_loss/sleep/constipation */
+    private String code;
+
+    /** 名称: 减肥/睡眠/便秘 */
+    private String name;
+
+    /** 图标 */
+    private String icon;
+
+    /** 一句话描述 */
+    private String description;
+
+    /** 服务流程介绍(7步) JSON */
+    private String flowIntroJson;
+
+    /** 专项调研问卷模板ID (SurveyTemplate.id) */
+    private Long surveyTemplateId;
+
+    /** 内容标签,逗号分隔(过滤文章/知识库) */
+    private String contentTags;
+
+    /** 推荐产品ID,逗号分隔 (Product.id) */
+    private String recommendedProductIds;
+
+    /** 绑定的任务模板包ID (TaskTemplatePackage.id),逗号分隔 */
+    private String taskTemplatePackageIds;
+
+    /** 全部完成奖励CF值 */
+    private Integer rewardCfValue;
+
+    /** 1启用 0停用 */
+    private Integer status;
+
+    /** 排序号 */
+    private Integer sortOrder;
+
+    private Date createdAt;
+
+    private Date updatedAt;
+}

+ 3 - 0
cfc-backend/src/main/java/com/etotem/cfc/entity/Task.java

@@ -101,6 +101,9 @@ private Date acceptDeadline;
 	    // 来源ID(如文章ID、活动ID)
 	    private Long sourceId;
 
+	    /** 1=会员任务(方案/套餐生成, 执行需会员); 0=普通任务(自建可免费执行) */
+	    private Integer memberOnly;
+
 	    /** 五维维度: body/mind/wisdom/action/wealth */
 	    private String dimensionCode;
 

+ 50 - 0
cfc-backend/src/main/java/com/etotem/cfc/entity/UserIntent.java

@@ -0,0 +1,50 @@
+package com.etotem.cfc.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 用户意图与服务旅程(改版v1)
+ * intent_type: A(目标明确型) / B(观望型) / C(问题导向型)
+ * journey_stage: 0-7,语义见 docs/cfc-redesign-progressive-unlock.md
+ */
+@Data
+@TableName("user_intents")
+public class UserIntent implements Serializable {
+
+    @TableId(type = IdType.AUTO)
+    private Long id;
+
+    /** 用户ID */
+    private Long userId;
+
+    /** A/B/C 用户类型 */
+    private String intentType;
+
+    /** 问题域编码(仅C类) */
+    private String problemDomainCode;
+
+    /** 旅程阶段 0-7 */
+    private Integer journeyStage;
+
+    /** 最近阶段变化时间 */
+    private Date stageUpdatedAt;
+
+    /** 最近作答问卷模板ID */
+    private Long surveyTemplateId;
+
+    /** 最近问卷提交时间 */
+    private Date surveySubmittedAt;
+
+    /** 问卷答案→推荐结果快照 */
+    private String surveyResultJson;
+
+    private Date createdAt;
+
+    private Date updatedAt;
+}

+ 43 - 0
cfc-backend/src/main/java/com/etotem/cfc/entity/UserNotification.java

@@ -0,0 +1,43 @@
+package com.etotem.cfc.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 站内通知(改版v1,用户级主动通知)
+ * type: report_ready=报告完成 / reward_granted=奖励到账 / logistics=物流变化 / system=系统
+ * 与 notices(平台公告) 并存:本表按 user_id 定向推送
+ */
+@Data
+@TableName("user_notifications")
+public class UserNotification implements Serializable {
+
+    @TableId(type = IdType.AUTO)
+    private Long id;
+
+    /** 接收用户ID */
+    private Long userId;
+
+    /** report_ready/reward_granted/logistics/system */
+    private String type;
+
+    private String title;
+
+    private String content;
+
+    /** 关联对象类型: report/package/task */
+    private String refType;
+
+    /** 关联对象ID */
+    private Long refId;
+
+    /** 0未读 1已读 */
+    private Integer isRead;
+
+    private Date createdAt;
+}

+ 7 - 0
cfc-backend/src/main/java/com/etotem/cfc/mapper/ProblemDomainMapper.java

@@ -0,0 +1,7 @@
+package com.etotem.cfc.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.etotem.cfc.entity.ProblemDomain;
+
+public interface ProblemDomainMapper extends BaseMapper<ProblemDomain> {
+}

+ 7 - 0
cfc-backend/src/main/java/com/etotem/cfc/mapper/UserIntentMapper.java

@@ -0,0 +1,7 @@
+package com.etotem.cfc.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.etotem.cfc.entity.UserIntent;
+
+public interface UserIntentMapper extends BaseMapper<UserIntent> {
+}

+ 7 - 0
cfc-backend/src/main/java/com/etotem/cfc/mapper/UserNotificationMapper.java

@@ -0,0 +1,7 @@
+package com.etotem.cfc.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.etotem.cfc.entity.UserNotification;
+
+public interface UserNotificationMapper extends BaseMapper<UserNotification> {
+}

+ 54 - 0
cfc-backend/src/main/resources/schema.sql

@@ -90,6 +90,7 @@ CREATE TABLE IF NOT EXISTS tasks (
     points_expire_days INT DEFAULT 0 COMMENT '积分有效期天数',
     dimension_code VARCHAR(20) COMMENT '五维维度: body/mind/wisdom/action/wealth',
     dimension_weights JSON COMMENT '五维权重: {"body":0,"mind":0,"wisdom":0,"action":0,"wealth":0}',
+    member_only TINYINT DEFAULT 0 COMMENT '1=会员任务(方案/套餐生成),执行需会员; 0=普通任务可免费执行',
     created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
     updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
     INDEX idx_child_id_deadline (child_id, deadline),
@@ -639,6 +640,8 @@ CREATE TABLE IF NOT EXISTS package_orders (
     transaction_id VARCHAR(64) COMMENT '微信支付订单号',
     paid_at DATETIME COMMENT '支付时间',
     notify_data TEXT COMMENT '支付回调数据',
+    logistics_status VARCHAR(20) DEFAULT 'none' COMMENT '物流状态: none/kit_shipped/kit_received/sample_shipped/sample_received',
+    tracking_no VARCHAR(100) DEFAULT '' COMMENT '快递单号',
     created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
     updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
     INDEX idx_user_id (user_id),
@@ -4832,3 +4835,54 @@ INSERT IGNORE INTO admin_menu (parent_id, name, path, icon, sort_order, perm, co
 (0, '系统配置', NULL, 'el-icon-setting', 90, 'system:config', NULL, 1),
 (14, '菜单管理', '/menu-manage', 'el-icon-menu', 1, 'system:menu', 'admin/MenuManage', 1),
 (14, '系统配置', '/sys-config', 'el-icon-setting', 2, 'system:config', 'admin/SysConfig', 1);
+
+-- =============================================
+-- 改版v1: 需求驱动·逐步解锁(问题域/用户意图/站内通知)
+-- =============================================
+
+CREATE TABLE IF NOT EXISTS problem_domains (
+  id BIGINT AUTO_INCREMENT PRIMARY KEY,
+  code VARCHAR(50) NOT NULL COMMENT '唯一编码: weight_loss/sleep/constipation',
+  name VARCHAR(50) NOT NULL COMMENT '名称: 减肥/睡眠/便秘',
+  icon VARCHAR(255) DEFAULT '' COMMENT '图标',
+  description VARCHAR(500) DEFAULT '' COMMENT '一句话描述',
+  flow_intro_json TEXT COMMENT '服务流程介绍(7步) JSON',
+  survey_template_id BIGINT DEFAULT NULL COMMENT '专项调研问卷模板ID(SurveyTemplate.id)',
+  content_tags VARCHAR(500) DEFAULT '' COMMENT '内容标签,逗号分隔(过滤文章/知识库)',
+  recommended_product_ids VARCHAR(500) DEFAULT '' COMMENT '推荐产品ID,逗号分隔(Product.id)',
+  task_template_package_ids VARCHAR(500) DEFAULT '' COMMENT '套餐绑定的任务模板包ID(TaskTemplatePackage.id)',
+  reward_cf_value INT DEFAULT 0 COMMENT '全部完成奖励CF值',
+  status TINYINT DEFAULT 1 COMMENT '1启用 0停用',
+  sort_order INT DEFAULT 0,
+  created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
+  updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  UNIQUE KEY uk_code (code)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='问题域定义(改版v1)';
+
+CREATE TABLE IF NOT EXISTS user_intents (
+  id BIGINT AUTO_INCREMENT PRIMARY KEY,
+  user_id BIGINT NOT NULL COMMENT '用户ID',
+  intent_type VARCHAR(20) DEFAULT '' COMMENT 'A/B/C 用户类型',
+  problem_domain_code VARCHAR(50) DEFAULT '' COMMENT '问题域编码(仅C类)',
+  journey_stage INT DEFAULT 0 COMMENT '旅程阶段 0-7',
+  stage_updated_at DATETIME DEFAULT NULL COMMENT '最近阶段变化时间',
+  survey_template_id BIGINT DEFAULT NULL COMMENT '最近作答问卷模板ID',
+  survey_submitted_at DATETIME DEFAULT NULL COMMENT '最近问卷提交时间',
+  survey_result_json TEXT COMMENT '问卷答案→推荐结果快照',
+  created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
+  updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
+  UNIQUE KEY uk_user (user_id)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户意图与服务旅程(改版v1)';
+
+CREATE TABLE IF NOT EXISTS user_notifications (
+  id BIGINT AUTO_INCREMENT PRIMARY KEY,
+  user_id BIGINT NOT NULL COMMENT '接收用户ID',
+  type VARCHAR(30) DEFAULT 'report_ready' COMMENT 'report_ready/reward_granted/logistics/system',
+  title VARCHAR(200) NOT NULL,
+  content VARCHAR(1000) DEFAULT '',
+  ref_type VARCHAR(30) DEFAULT '' COMMENT '关联对象类型: report/package/task',
+  ref_id BIGINT DEFAULT NULL COMMENT '关联对象ID',
+  is_read TINYINT DEFAULT 0,
+  created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
+  INDEX idx_user_read (user_id, is_read)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='站内通知(改版v1)';