Sfoglia il codice sorgente

chore: auto bump version and changelog [skip ci]

iwt 2 mesi fa
parent
commit
fdab515a97

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

@@ -8561,4 +8561,149 @@ private void runMigration100() {
 		// 迁移225: articles 添加 growth_category 列(成长分类筛选,Article 实体已含字段,生产库缺列导致 Unknown column 'growth_category')
 		// 迁移225: articles 添加 growth_category 列(成长分类筛选,Article 实体已含字段,生产库缺列导致 Unknown column 'growth_category')
 		ensureColumn("articles", "growth_category", "VARCHAR(50) DEFAULT NULL COMMENT '成长分类'");
 		ensureColumn("articles", "growth_category", "VARCHAR(50) DEFAULT NULL COMMENT '成长分类'");
 	}
 	}
+	private void seedFullRegionData() {
+		try {
+			Integer count = jdbcTemplate.queryForObject("SELECT COUNT(*) FROM streets WHERE level = 1", Integer.class);
+			if (count != null && count >= 20) {
+				log.info("全国省市区数据已存在({}个省份),跳过导入", count);
+				return;
+			}
+		} catch (Exception e) {
+			log.warn("检查省份数据失败,跳过全量导入: {}", e.getMessage());
+			return;
+		}
+
+		org.springframework.core.io.Resource resource = resourceLoader.getResource("classpath:region_data.json");
+		if (!resource.exists()) {
+			log.warn("region_data.json 不存在,跳过全量省市区数据导入");
+			return;
+		}
+
+		try {
+			String content = new String(StreamUtils.copyToByteArray(resource.getInputStream()), StandardCharsets.UTF_8);
+			com.alibaba.fastjson.JSONArray provinces = com.alibaba.fastjson.JSON.parseArray(content);
+
+			for (int pi = 0; pi < provinces.size(); pi++) {
+				com.alibaba.fastjson.JSONObject prov = provinces.getJSONObject(pi);
+				String provName = prov.getString("name");
+				String provCode = prov.getString("code");
+
+				java.sql.Connection conn = jdbcTemplate.getDataSource().getConnection();
+				java.sql.PreparedStatement ps = conn.prepareStatement(
+					"INSERT INTO streets (province, province_code, full_name, level, parent_id, sort_order) VALUES (?, ?, ?, 1, NULL, ?)",
+					java.sql.Statement.RETURN_GENERATED_KEYS
+				);
+				ps.setString(1, provName);
+				ps.setString(2, provCode);
+				ps.setString(3, provName);
+				ps.setInt(4, pi + 1);
+				ps.executeUpdate();
+				java.sql.ResultSet rs = ps.getGeneratedKeys();
+				long provId = 0;
+				if (rs.next()) provId = rs.getLong(1);
+				rs.close();
+				ps.close();
+
+				com.alibaba.fastjson.JSONArray cities = prov.getJSONArray("cities");
+				if (cities == null) continue;
+
+				for (int ci = 0; ci < cities.size(); ci++) {
+					com.alibaba.fastjson.JSONObject city = cities.getJSONObject(ci);
+					String cityName = city.getString("name");
+					String cityCode = city.getString("code");
+
+					java.sql.PreparedStatement ps2 = conn.prepareStatement(
+						"INSERT INTO streets (province, province_code, city, city_code, full_name, level, parent_id, sort_order) VALUES (?, ?, ?, ?, ?, 2, ?, ?)",
+						java.sql.Statement.RETURN_GENERATED_KEYS
+					);
+					ps2.setString(1, provName);
+					ps2.setString(2, provCode);
+					ps2.setString(3, cityName);
+					ps2.setString(4, cityCode);
+					ps2.setString(5, provName + cityName);
+					ps2.setLong(6, provId);
+					ps2.setInt(7, ci + 1);
+					ps2.executeUpdate();
+					java.sql.ResultSet rs2 = ps2.getGeneratedKeys();
+					long cityId = 0;
+					if (rs2.next()) cityId = rs2.getLong(1);
+					rs2.close();
+					ps2.close();
+
+					com.alibaba.fastjson.JSONArray districts = city.getJSONArray("districts");
+					if (districts == null) continue;
+
+					for (int di = 0; di < districts.size(); di++) {
+						com.alibaba.fastjson.JSONObject dist = districts.getJSONObject(di);
+						String distName = dist.getString("name");
+						String distCode = dist.getString("code");
+
+						java.sql.PreparedStatement ps3 = conn.prepareStatement(
+							"INSERT INTO streets (province, province_code, city, city_code, district, district_code, full_name, level, parent_id, sort_order) VALUES (?, ?, ?, ?, ?, ?, ?, 3, ?, ?)",
+							java.sql.Statement.RETURN_GENERATED_KEYS
+						);
+						ps3.setString(1, provName);
+						ps3.setString(2, provCode);
+						ps3.setString(3, cityName);
+						ps3.setString(4, cityCode);
+						ps3.setString(5, distName);
+						ps3.setString(6, distCode);
+						ps3.setString(7, provName + cityName + distName);
+						ps3.setLong(8, cityId);
+						ps3.setInt(9, di + 1);
+						ps3.executeUpdate();
+						ps3.close();
+					}
+				}
+				conn.close();
+			}
+			log.info("全国省市区数据导入完成:{}省/{}市/{}区", provinces.size(), 0, 0);
+		} catch (Exception e) {
+			log.warn("导入全国省市区数据失败: {}", e.getMessage());
+		}
+
+		// 迁移226: 创建 family_platform_balance 表 + family_platform_balance_log 表 + products.points_multiplier 列
+		try {
+			jdbcTemplate.execute(
+				"CREATE TABLE IF NOT EXISTS family_platform_balance (" +
+				"  id BIGINT AUTO_INCREMENT PRIMARY KEY, " +
+				"  family_id BIGINT NOT NULL COMMENT '家庭ID', " +
+				"  total_earned INT DEFAULT 0 COMMENT '累计获得', " +
+				"  available INT DEFAULT 0 COMMENT '可用余额', " +
+				"  frozen INT DEFAULT 0 COMMENT '冻结(提现审核中)', " +
+				"  withdrawn INT DEFAULT 0 COMMENT '已提现', " +
+				"  exchanged INT DEFAULT 0 COMMENT '已兑换', " +
+				"  created_at DATETIME DEFAULT CURRENT_TIMESTAMP, " +
+				"  updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, " +
+				"  UNIQUE KEY uk_family (family_id)" +
+				") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='家庭平台积分池余额'"
+			);
+			log.info("已创建family_platform_balance表");
+		} catch (Exception e) {
+			log.warn("创建family_platform_balance表失败: " + e.getMessage());
+		}
+		try {
+			jdbcTemplate.execute(
+				"CREATE TABLE IF NOT EXISTS family_platform_balance_log (" +
+				"  id BIGINT AUTO_INCREMENT PRIMARY KEY, " +
+				"  family_id BIGINT NOT NULL COMMENT '家庭ID', " +
+				"  type VARCHAR(20) NOT NULL COMMENT 'earn/spend/freeze/unfreeze/withdraw/adjust/migration', " +
+				"  amount INT NOT NULL COMMENT '变动数量', " +
+				"  balance_after INT NOT NULL COMMENT '变动后可用余额', " +
+				"  ref_type VARCHAR(50) COMMENT 'product_order/referral_dist/activity/withdrawal/adjust/migration/refund', " +
+				"  ref_id BIGINT COMMENT '关联业务ID', " +
+				"  remark VARCHAR(255) COMMENT '备注', " +
+				"  created_at DATETIME DEFAULT CURRENT_TIMESTAMP, " +
+				"  INDEX idx_family (family_id), " +
+				"  INDEX idx_ref (ref_type, ref_id)" +
+				") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='家庭平台积分流水'"
+			);
+			log.info("已创建family_platform_balance_log表");
+		} catch (Exception e) {
+			log.warn("创建family_platform_balance_log表失败: " + e.getMessage());
+		}
+		ensureColumn("products", "points_multiplier", "DECIMAL(4,2) NOT NULL DEFAULT 1.00 COMMENT '平台积分倍数,1元=1积分×倍数'");
+		log.info("已添加products.points_multiplier列");
+
+	}
 }
 }

+ 1 - 1
cfc-web/.last_build_commit

@@ -1 +1 @@
-03724311e3d31c188db9e89e8835e05b72bd58d3
+0c773e51c0dab69dd823984db16e5d6d95c56a95