|
|
@@ -1199,7 +1199,7 @@ log.info("已添加template_id列到tasks表");
|
|
|
log.warn("检查/添加个人信息补充字段失败: {}", e.getMessage());
|
|
|
}
|
|
|
|
|
|
- // Phase 0: 溪福俱乐部 — 服务商字段
|
|
|
+ // Phase 0: 汐福俱乐部 — 服务商字段
|
|
|
try {
|
|
|
Integer exists = jdbcTemplate.queryForObject(
|
|
|
"SELECT COUNT(*) FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'users' AND COLUMN_NAME = 'vendor_type'",
|
|
|
@@ -1210,9 +1210,9 @@ log.info("已添加template_id列到tasks表");
|
|
|
jdbcTemplate.execute("ALTER TABLE users ADD COLUMN vendor_reject_reason VARCHAR(500) DEFAULT NULL COMMENT '审核拒绝原因'");
|
|
|
jdbcTemplate.execute("ALTER TABLE users ADD COLUMN is_family_admin TINYINT DEFAULT 0 COMMENT '是否家庭管理员'");
|
|
|
jdbcTemplate.execute("ALTER TABLE users ADD COLUMN vendor_info VARCHAR(2000) DEFAULT NULL COMMENT '服务商资质信息(JSON)'");
|
|
|
- log.info("已添加溪福俱乐部服务商字段到users表");
|
|
|
+ log.info("已添加汐福俱乐部服务商字段到users表");
|
|
|
} else {
|
|
|
- log.info("溪福俱乐部服务商字段已存在,跳过");
|
|
|
+ log.info("汐福俱乐部服务商字段已存在,跳过");
|
|
|
}
|
|
|
} catch (Exception e) {
|
|
|
log.warn("检查/添加服务商字段失败: {}", e.getMessage());
|
|
|
@@ -1230,6 +1230,108 @@ log.info("已添加template_id列到tasks表");
|
|
|
log.warn("迁移规划师到服务商体系失败: {}", e.getMessage());
|
|
|
}
|
|
|
|
|
|
+ // ==================== Phase 1: 汐福俱乐部商品系统 ====================
|
|
|
+
|
|
|
+ // 商品表
|
|
|
+ try {
|
|
|
+ jdbcTemplate.execute(
|
|
|
+ "CREATE TABLE IF NOT EXISTS products (" +
|
|
|
+ " id BIGINT AUTO_INCREMENT PRIMARY KEY," +
|
|
|
+ " name VARCHAR(200) NOT NULL," +
|
|
|
+ " description VARCHAR(1000)," +
|
|
|
+ " intro TEXT," +
|
|
|
+ " cover_image VARCHAR(500)," +
|
|
|
+ " images TEXT," +
|
|
|
+ " price DECIMAL(10,2) NOT NULL DEFAULT 0," +
|
|
|
+ " stock INT NOT NULL DEFAULT 0," +
|
|
|
+ " sales_count INT NOT NULL DEFAULT 0," +
|
|
|
+ " product_type VARCHAR(32) NOT NULL COMMENT 'activity/course/physical/digital/service'," +
|
|
|
+ " vendor_id BIGINT," +
|
|
|
+ " vendor_name VARCHAR(100)," +
|
|
|
+ " status VARCHAR(32) NOT NULL DEFAULT 'draft' COMMENT 'draft/pending/approved/rejected/on_shelf/off_shelf'," +
|
|
|
+ " reject_reason VARCHAR(500)," +
|
|
|
+ " member_price DECIMAL(10,2)," +
|
|
|
+ " member_eligible VARCHAR(32) DEFAULT 'none' COMMENT 'all/budget/none'," +
|
|
|
+ " domain VARCHAR(32) COMMENT 'action/mind/body/wisdom/wealth'," +
|
|
|
+ " external_source VARCHAR(64)," +
|
|
|
+ " external_id VARCHAR(128)," +
|
|
|
+ " external_data TEXT," +
|
|
|
+ " created_at DATETIME," +
|
|
|
+ " updated_at DATETIME" +
|
|
|
+ ")"
|
|
|
+ );
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("创建products表失败: {}", e.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 订单表
|
|
|
+ try {
|
|
|
+ jdbcTemplate.execute(
|
|
|
+ "CREATE TABLE IF NOT EXISTS product_orders (" +
|
|
|
+ " id BIGINT AUTO_INCREMENT PRIMARY KEY," +
|
|
|
+ " order_no VARCHAR(64) NOT NULL," +
|
|
|
+ " product_id BIGINT NOT NULL," +
|
|
|
+ " product_name VARCHAR(200)," +
|
|
|
+ " product_type VARCHAR(32)," +
|
|
|
+ " buyer_id BIGINT NOT NULL," +
|
|
|
+ " family_id BIGINT," +
|
|
|
+ " quantity INT NOT NULL DEFAULT 1," +
|
|
|
+ " unit_price DECIMAL(10,2) NOT NULL," +
|
|
|
+ " total_amount DECIMAL(10,2) NOT NULL," +
|
|
|
+ " status VARCHAR(32) NOT NULL DEFAULT 'pending' COMMENT 'pending/paid/completed/cancelled/refunded'," +
|
|
|
+ " payment_method VARCHAR(32) COMMENT 'wechat/points/membership'," +
|
|
|
+ " remark VARCHAR(500)," +
|
|
|
+ " paid_at DATETIME," +
|
|
|
+ " created_at DATETIME," +
|
|
|
+ " updated_at DATETIME" +
|
|
|
+ ")"
|
|
|
+ );
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("创建product_orders表失败: {}", e.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 系统配置表
|
|
|
+ try {
|
|
|
+ jdbcTemplate.execute(
|
|
|
+ "CREATE TABLE IF NOT EXISTS sys_config (" +
|
|
|
+ " id BIGINT AUTO_INCREMENT PRIMARY KEY," +
|
|
|
+ " config_key VARCHAR(64) NOT NULL," +
|
|
|
+ " config_value TEXT," +
|
|
|
+ " description VARCHAR(500)," +
|
|
|
+ " updated_at DATETIME" +
|
|
|
+ ")"
|
|
|
+ );
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("创建sys_config表失败: {}", e.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ // SysConfig 种子数据
|
|
|
+ try {
|
|
|
+ insertSysConfigSeed("points_exchange_rate", "0.01", "积分兑换汇率(1积分=0.01元)");
|
|
|
+ insertSysConfigSeed("points_deduct_cap", "0.5", "积分抵扣上限(50%)");
|
|
|
+ insertSysConfigSeed("member_fee_standard", "1314", "标准会员年费(元)");
|
|
|
+ insertSysConfigSeed("member_fee_premium", "3650", "高级会员年费(元)");
|
|
|
+ insertSysConfigSeed("member_eligible_budget", "1314", "等值商品选择预算上限(元)");
|
|
|
+ insertSysConfigSeed("renewal_discount_rate", "0.85", "续费折扣率");
|
|
|
+ insertSysConfigSeed("member_discount_standard", "0.9", "标准会员折扣率");
|
|
|
+ insertSysConfigSeed("member_discount_premium", "0.8", "高级会员折扣率");
|
|
|
+ log.info("SysConfig 种子数据已加载");
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("SysConfig 种子数据初始化失败: {}", e.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ // Product 种子数据(5 个示例商品,覆盖全部 5 种 productType)
|
|
|
+ try {
|
|
|
+ insertProductSeed("亲子关系工作坊", "线下半日工作坊,重建家庭对话模式", "activity", new java.math.BigDecimal("388.00"), 1L, "action", "all");
|
|
|
+ insertProductSeed("情绪管理21天训练营", "21天视频课程,识别并管理情绪", "course", new java.math.BigDecimal("199.00"), 1L, "mind", "all");
|
|
|
+ insertProductSeed("肠道菌群检测套装", "家用检测 + 报告解读", "physical", new java.math.BigDecimal("599.00"), 1L, "body", "budget");
|
|
|
+ insertProductSeed("儿童多模态认知测评", "在线测评 + 个性化建议", "digital", new java.math.BigDecimal("99.00"), 1L, "wisdom", "none");
|
|
|
+ insertProductSeed("成长规划师1对1咨询", "60分钟专业规划", "service", new java.math.BigDecimal("500.00"), 1L, "wealth", "budget");
|
|
|
+ log.info("Product 种子数据已加载");
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.warn("Product 种子数据初始化失败: {}", e.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
log.info("数据库迁移完成");
|
|
|
}
|
|
|
|
|
|
@@ -1691,4 +1793,27 @@ try {
|
|
|
|
|
|
log.info("成长规划师模块数据库表初始化完成");
|
|
|
}
|
|
|
+
|
|
|
+ private void insertSysConfigSeed(String key, String value, String desc) {
|
|
|
+ Integer count = jdbcTemplate.queryForObject(
|
|
|
+ "SELECT COUNT(*) FROM sys_config WHERE config_key = ?", Integer.class, key);
|
|
|
+ if (count == null || count == 0) {
|
|
|
+ jdbcTemplate.update(
|
|
|
+ "INSERT INTO sys_config (config_key, config_value, description, updated_at) VALUES (?, ?, ?, NOW())",
|
|
|
+ key, value, desc);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void insertProductSeed(String name, String desc, String type,
|
|
|
+ java.math.BigDecimal price, Long vendorId,
|
|
|
+ String domain, String memberEligible) {
|
|
|
+ Integer count = jdbcTemplate.queryForObject(
|
|
|
+ "SELECT COUNT(*) FROM products WHERE name = ? AND product_type = ?", Integer.class, name, type);
|
|
|
+ if (count == null || count == 0) {
|
|
|
+ jdbcTemplate.update(
|
|
|
+ "INSERT INTO products (name, description, price, product_type, vendor_id, vendor_name, status, domain, member_eligible, created_at, updated_at) " +
|
|
|
+ "VALUES (?, ?, ?, ?, ?, '平台官方', 'on_shelf', ?, ?, NOW(), NOW())",
|
|
|
+ name, desc, price, type, vendorId, domain, memberEligible);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|