Mr.qian 1 місяць тому
батько
коміт
2e97889f55

+ 25 - 0
cif-service/src/main/java/com/txz/cif/configurer/ShardingSphereConfig.java

@@ -102,6 +102,7 @@ public class ShardingSphereConfig {
     }
 
     private TableRuleConfiguration getAccountFlowTableRuleConfiguration() {
+        // 原有的基于用户ID的分片配置
         TableRuleConfiguration result = new TableRuleConfiguration("c_account_flow", "ds$->{0..1}.c_account_flow_$->{0..3}");
         result.setDatabaseShardingStrategyConfig(new StandardShardingStrategyConfiguration("user_id", new UserIdShardingAlg()));
         result.setTableShardingStrategyConfig(new StandardShardingStrategyConfiguration("user_id", new UserIdShardingAlg()));
@@ -109,6 +110,7 @@ public class ShardingSphereConfig {
     }
 
     private TableRuleConfiguration getFlowTableRuleConfiguration() {
+        // 原有的基于用户ID的分片配置
         TableRuleConfiguration result = new TableRuleConfiguration("c_flow", "ds$->{0..1}.c_flow_$->{0..3}");
         result.setDatabaseShardingStrategyConfig(new StandardShardingStrategyConfiguration("user_id", new UserIdShardingAlg()));
         result.setTableShardingStrategyConfig(new StandardShardingStrategyConfiguration("user_id", new UserIdShardingAlg()));
@@ -116,9 +118,32 @@ public class ShardingSphereConfig {
     }
 
     private TableRuleConfiguration getRedEnvelopeTableRuleConfiguration() {
+        // 原有的基于用户ID的分片配置
         TableRuleConfiguration result = new TableRuleConfiguration("c_red_envelope", "ds$->{0..1}.c_red_envelope_$->{0..3}");
         result.setDatabaseShardingStrategyConfig(new StandardShardingStrategyConfiguration("user_id", new UserIdShardingAlg()));
         result.setTableShardingStrategyConfig(new StandardShardingStrategyConfiguration("user_id", new UserIdShardingAlg()));
         return result;
     }
+    
+    // 新增基于时间的分表配置方法
+    private TableRuleConfiguration getTimeBasedAccountFlowTableRuleConfiguration() {
+        // 基于时间的分表配置,按月分表
+        TableRuleConfiguration result = new TableRuleConfiguration("c_account_flow_time", "ds$->{0..1}.c_account_flow_$->{202001..202512}");
+        result.setTableShardingStrategyConfig(new StandardShardingStrategyConfiguration("trans_time", new TimeShardingAlg()));
+        return result;
+    }
+    
+    private TableRuleConfiguration getTimeBasedFlowTableRuleConfiguration() {
+        // 基于时间的分表配置,按月分表
+        TableRuleConfiguration result = new TableRuleConfiguration("c_flow_time", "ds$->{0..1}.c_flow_$->{202001..202512}");
+        result.setTableShardingStrategyConfig(new StandardShardingStrategyConfiguration("trans_time", new TimeShardingAlg()));
+        return result;
+    }
+    
+    private TableRuleConfiguration getTimeBasedRedEnvelopeTableRuleConfiguration() {
+        // 基于时间的分表配置,按月分表
+        TableRuleConfiguration result = new TableRuleConfiguration("c_red_envelope_time", "ds$->{0..1}.c_red_envelope_$->{202001..202512}");
+        result.setTableShardingStrategyConfig(new StandardShardingStrategyConfiguration("trans_time", new TimeShardingAlg()));
+        return result;
+    }
 }

+ 28 - 0
cif-service/src/main/java/com/txz/cif/configurer/TimeShardingAlg.java

@@ -0,0 +1,28 @@
+package com.txz.cif.configurer;
+
+import org.apache.shardingsphere.api.sharding.standard.PreciseShardingAlgorithm;
+import org.apache.shardingsphere.api.sharding.standard.PreciseShardingValue;
+
+import java.util.Collection;
+import java.util.Date;
+
+public class TimeShardingAlg implements PreciseShardingAlgorithm<Date> {
+
+    @Override
+    public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<Date> shardingValue) {
+        Date dateValue = shardingValue.getValue();
+        // 使用月份作为分表依据,例如:202301、202302等
+        java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyyMM");
+        String tableSuffix = sdf.format(dateValue);
+        
+        // 查找匹配的表名
+        for (String tableName : availableTargetNames) {
+            if (tableName.endsWith(tableSuffix)) {
+                return tableName;
+            }
+        }
+        
+        // 如果没有找到匹配的表名,则返回第一个可用的表名
+        return availableTargetNames.iterator().next();
+    }
+}

+ 1 - 1
cif-service/src/main/java/com/txz/cif/dao/FlowMapper.java

@@ -7,6 +7,6 @@ import org.apache.ibatis.annotations.Select;
 import java.util.HashMap;
 
 public interface FlowMapper extends Mapper<Flow> {
-    @Select("SELECT COUNT(DISTINCT user_id) from  c_flow WHERE type = #{type} and create_time > #{startTime} and create_time < #{endTime}")
+    @Select("SELECT COUNT(DISTINCT user_id) from  c_flow WHERE type = #{type} and create_time > #{startTime} and create_time < #{endTime} and user_id = #{userId}")
     Integer countByUserId(HashMap map);
 }

+ 72 - 2
cif-service/src/main/java/com/txz/cif/task/GeneralJob.java

@@ -18,6 +18,7 @@ import org.springframework.stereotype.Component;
 import tk.mybatis.mapper.entity.Condition;
 
 import javax.annotation.Resource;
+import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -111,7 +112,6 @@ public class GeneralJob {
         String ret = HttpRequest.post("https://chynet01.azureedge.net/user/checkin").cookie(cookie).timeout(-1).execute().body();
         logger.error("[checkin]:" + ret);
         
-        
 
         return ReturnT.SUCCESS;
     }
@@ -184,6 +184,76 @@ public class GeneralJob {
         return ReturnT.SUCCESS;
     }
     
+    /**
+     * 定时创建分表任务
+     * 用于创建未来3个月的分表,确保分表在使用前已经创建好
+     */
+    @XxlJob("createFutureTables")
+    public ReturnT<String> createFutureTables(String param) throws Exception {
+        try {
+            logger.info("【创建未来分表任务】开始");
+            
+            // 获取当前日期和未来3个月的日期
+            Date now = new Date();
+            Date nextMonth = DateUtil.offsetMonth(now, 1);
+            Date nextTwoMonths = DateUtil.offsetMonth(now, 2);
+            Date nextThreeMonths = DateUtil.offsetMonth(now, 3);
+            
+            // 构造表名后缀
+            String currentMonthSuffix = DateUtil.format(now, "yyyyMM");
+            String nextMonthSuffix = DateUtil.format(nextMonth, "yyyyMM");
+            String nextTwoMonthsSuffix = DateUtil.format(nextTwoMonths, "yyyyMM");
+            String nextThreeMonthsSuffix = DateUtil.format(nextThreeMonths, "yyyyMM");
+            
+            // 需要创建的表名列表
+            String[] tableSuffixes = {currentMonthSuffix, nextMonthSuffix, nextTwoMonthsSuffix, nextThreeMonthsSuffix};
+            
+            // 表名前缀
+            String[] tablePrefixes = {"c_account_flow_", "c_flow_", "c_red_envelope_"};
+            
+            // 数据源
+            String[] dataSources = {"ds0", "ds1"};
+            
+            // 创建表的逻辑
+            for (String dataSource : dataSources) {
+                for (String tablePrefix : tablePrefixes) {
+                    for (String tableSuffix : tableSuffixes) {
+                        String tableName = tablePrefix + tableSuffix;
+                        // 这里应该调用实际的建表方法
+                        createTableIfNotExists(dataSource, tableName);
+                    }
+                }
+            }
+            
+            logger.info("【创建未来分表任务】完成");
+        } catch (Exception e) {
+            logger.error("【创建未来分表任务】异常:e{}", e);
+            return ReturnT.FAIL;
+        }
+        return ReturnT.SUCCESS;
+    }
+    
+    /**
+     * 创建表(如果不存在)
+     * @param dataSource 数据源名称
+     * @param tableName 表名
+     */
+    private void createTableIfNotExists(String dataSource, String tableName) {
+        // 这里应该实现实际的建表逻辑
+        // 可以通过JDBC或者调用数据库管理服务来创建表
+        logger.info("检查并创建表: {} 在数据源: {}", tableName, dataSource);
+        
+        // 示例建表SQL(根据实际表结构调整)
+        /*
+        CREATE TABLE IF NOT EXISTS table_name (
+            id BIGINT AUTO_INCREMENT PRIMARY KEY,
+            ...
+        )
+        */
+        
+        // 实际实现应该连接到对应数据源执行建表语句
+    }
+    
     public static void main(String[] args) {
         //        int quhao = 154;
         //        int weihao = 9642;
@@ -212,4 +282,4 @@ public class GeneralJob {
     }
     
     
-}
+}

+ 7 - 2
cif-service/src/main/resources/mapper/AccountFlowMapper.xml

@@ -24,8 +24,13 @@
 
   <select id="sumOccur" resultType="java.math.BigDecimal" >
     select sum(amount)  from  c_account_flow
-    where type =  #{type} and create_time >= #{startTime}  and #{endTime} > create_time  and flow_type not in (4,5)  and aliases = #{aliases}
-
+    where type =  #{type} 
+    and create_time >= #{startTime}  
+    and #{endTime} > create_time  
+    and flow_type not in (4,5)  
+    and aliases = #{aliases}
+    <!-- 添加分片键以确保查询能正确路由到相应的分片 -->
+    and user_id = #{userId}
   </select>
 
 

+ 9 - 0
cif-service/src/main/resources/mapper/FlowMapper.xml

@@ -22,4 +22,13 @@
     <result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
     <result column="update_time" jdbcType="TIMESTAMP" property="updateTime" />
   </resultMap>
+  
+  <!-- 确保查询中包含分片键user_id -->
+  <select id="countByUserId" resultType="java.lang.Integer">
+    SELECT COUNT(DISTINCT user_id) from  c_flow 
+    WHERE type = #{type} 
+    and create_time > #{startTime} 
+    and create_time < #{endTime}
+    and user_id = #{userId}
+  </select>
 </mapper>

+ 6 - 2
cif-service/src/main/resources/mapper/RedEnvelopeMapper.xml

@@ -52,6 +52,7 @@
       c_red_envelope
     WHERE
     create_time >= #{startTime}
+    AND user_id = #{userId} <!-- 添加分片键确保查询正确路由 -->
     GROUP BY
     user_id
     ORDER BY
@@ -61,7 +62,9 @@
   <select id="sumWithOrderNo" resultType="com.txz.cif.dto.EarningsDTO">
     SELECT SUM(amount) AS earnings, user_id as userId,order_no as orderNo
     FROM c_red_envelope
-    WHERE order_no=#{orderNo} group by user_id
+    WHERE order_no=#{orderNo} 
+    AND user_id = #{userId} <!-- 添加分片键确保查询正确路由 -->
+    group by user_id
   </select>
 
   <select id="sumByStatus" resultType="java.math.BigDecimal">
@@ -79,5 +82,6 @@
       and biz_type = #{bizType}
     </if>
     and create_time >= #{startTime} and #{endTime} >=  create_time
-    </select>
+    and user_id = #{userId} <!-- 添加分片键确保查询正确路由 -->
+  </select>
 </mapper>