Browse Source

分库分表

yubin 1 month ago
parent
commit
1e4c41844a
41 changed files with 1707 additions and 231 deletions
  1. 13 1
      mall-service/pom.xml
  2. 1 1
      mall-service/src/main/java/com/txz/mall/business/PinkServiceBusiness.java
  3. 17 13
      mall-service/src/main/java/com/txz/mall/business/impl/OrderServiceBusinessImpl.java
  4. 34 7
      mall-service/src/main/java/com/txz/mall/business/impl/PinkServiceBusinessImpl.java
  5. 169 0
      mall-service/src/main/java/com/txz/mall/configurer/DatabaseShardingAlgorithm.java
  6. 331 0
      mall-service/src/main/java/com/txz/mall/configurer/ShardingJdbcConfig.java
  7. 0 124
      mall-service/src/main/java/com/txz/mall/configurer/ShardingSphereConfig.java
  8. 168 0
      mall-service/src/main/java/com/txz/mall/configurer/StoreOrderInfoDatabaseShardingAlgorithm.java
  9. 51 0
      mall-service/src/main/java/com/txz/mall/configurer/StoreOrderInfoTableShardingAlgorithm.java
  10. 168 0
      mall-service/src/main/java/com/txz/mall/configurer/StoreOrderStatusDatabaseShardingAlgorithm.java
  11. 51 0
      mall-service/src/main/java/com/txz/mall/configurer/StoreOrderStatusTableShardingAlgorithm.java
  12. 168 0
      mall-service/src/main/java/com/txz/mall/configurer/StorePinkSummaryDatabaseShardingAlgorithm.java
  13. 51 0
      mall-service/src/main/java/com/txz/mall/configurer/StorePinkSummaryTableShardingAlgorithm.java
  14. 50 0
      mall-service/src/main/java/com/txz/mall/configurer/TableShardingAlgorithm.java
  15. 27 0
      mall-service/src/main/java/com/txz/mall/configurer/UidModuloDatabaseShardingAlgorithm.java
  16. 23 0
      mall-service/src/main/java/com/txz/mall/configurer/UidModuloTableShardingAlgorithm.java
  17. 0 32
      mall-service/src/main/java/com/txz/mall/configurer/UserIdShardingAlg.java
  18. 31 0
      mall-service/src/main/java/com/txz/mall/configurer/UserIdTableShardingAlgorithm.java
  19. 148 0
      mall-service/src/main/java/com/txz/mall/configurer/UserSignDatabaseShardingAlgorithm.java
  20. 44 0
      mall-service/src/main/java/com/txz/mall/configurer/UserSignTableShardingAlgorithm.java
  21. 2 2
      mall-service/src/main/java/com/txz/mall/controller/OrderController.java
  22. 2 2
      mall-service/src/main/java/com/txz/mall/controller/PinkController.java
  23. 2 2
      mall-service/src/main/java/com/txz/mall/controller/appcontroller/AppOrderController.java
  24. 2 2
      mall-service/src/main/java/com/txz/mall/controller/appcontroller/AppPinkController.java
  25. 5 0
      mall-service/src/main/java/com/txz/mall/model/StoreOrderStatus.java
  26. 5 0
      mall-service/src/main/java/com/txz/mall/model/StorePink.java
  27. 11 1
      mall-service/src/main/java/com/txz/mall/model/StorePinkSummary.java
  28. 3 0
      mall-service/src/main/java/com/txz/mall/service/StoreOrderService.java
  29. 2 2
      mall-service/src/main/java/com/txz/mall/service/StoreOrderStatusService.java
  30. 1 1
      mall-service/src/main/java/com/txz/mall/service/StorePinkSummaryService.java
  31. 63 12
      mall-service/src/main/java/com/txz/mall/service/impl/StoreOrderServiceImpl.java
  32. 4 3
      mall-service/src/main/java/com/txz/mall/service/impl/StoreOrderStatusServiceImpl.java
  33. 3 3
      mall-service/src/main/java/com/txz/mall/service/impl/StorePinkServiceImpl.java
  34. 34 0
      mall-service/src/main/java/com/txz/mall/service/impl/StorePinkSummaryServiceImpl.java
  35. 8 4
      mall-service/src/main/java/com/txz/mall/service/impl/UserSignServiceImpl.java
  36. 2 3
      mall-service/src/main/java/com/txz/mall/util/OrderUtils.java
  37. 4 0
      mall-service/src/main/java/dto/GoPinkDTO.java
  38. 2 0
      mall-service/src/main/java/vo/StorePinkDetailVO.java
  39. 1 14
      mall-service/src/main/resources/bootstrap.properties
  40. 4 1
      mall-service/src/main/resources/i18n/messages_en_US.properties
  41. 2 1
      mall-service/src/main/resources/i18n/messages_zh_CN.properties

+ 13 - 1
mall-service/pom.xml

@@ -185,9 +185,21 @@
             <version>0.0.15</version>
         </dependency>
 
+<!--        <dependency>-->
+<!--            <groupId>org.apache.shardingsphere</groupId>-->
+<!--            <artifactId>sharding-jdbc-spring-boot-starter</artifactId>-->
+<!--            <version>4.1.1</version>-->
+<!--            <exclusions>-->
+<!--                &lt;!&ndash; 排除自动配置类,防止 Spring 自动加载默认配置 &ndash;&gt;-->
+<!--                <exclusion>-->
+<!--                    <groupId>org.apache.shardingsphere</groupId>-->
+<!--                    <artifactId>shardingsphere-spring-boot-starter</artifactId>-->
+<!--                </exclusion>-->
+<!--            </exclusions>-->
+<!--        </dependency>-->
         <dependency>
             <groupId>org.apache.shardingsphere</groupId>
-            <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
+            <artifactId>sharding-jdbc-core</artifactId>
             <version>4.1.1</version>
         </dependency>
 

+ 1 - 1
mall-service/src/main/java/com/txz/mall/business/PinkServiceBusiness.java

@@ -16,7 +16,7 @@ public interface PinkServiceBusiness {
      * @param pinkId 团长pinkId
      * @return
      */
-    List<StorePinkDetailVO> getAdminList(Long pinkId,String terminal);
+    List<StorePinkDetailVO> getAdminList(String orderNo,String terminal);
 
     /**
      * 拼团失败----到点自动退回余额

+ 17 - 13
mall-service/src/main/java/com/txz/mall/business/impl/OrderServiceBusinessImpl.java

@@ -56,28 +56,30 @@ public class OrderServiceBusinessImpl implements OrderServiceBusiness {
     @Override
     public StoreOrderVO orderDetail(Long id, String orderNo) {
         StoreOrderVO vo = new StoreOrderVO();
-        StoreOrder storeOrder = null;
-        if (!ObjectUtils.isEmpty(id)) {
-            storeOrder = storeOrderService.findById(id);
-        } else if (!ObjectUtils.isEmpty(orderNo)) {
-            storeOrder = storeOrderService.findBy("orderId", orderNo);
-        }
+
+//        if (!ObjectUtils.isEmpty(id)) {
+//            storeOrder = storeOrderService.findById(id);
+//        } else if (!ObjectUtils.isEmpty(orderNo)) {
+        StoreOrder storeOrder = storeOrderService.findBy("orderId", orderNo);
+       // }
 
         if (ObjectUtils.isEmpty(storeOrder)) {
-            throw new ServiceException(I18nUtil.get("order.does.not.exist.id") + id);
+            throw new ServiceException(I18nUtil.get("order.does.not.exist.id") + orderNo);
         }
-        id = storeOrder.getId();
+       // id = storeOrder.getId();
         Condition infoCondition = new Condition(StoreOrderInfo.class);
         Example.Criteria infoCriteria = infoCondition.createCriteria();
         infoCriteria.andEqualTo("isDelete", 0);
-        infoCriteria.andEqualTo("orderId", storeOrder.getId());
+       // infoCriteria.andEqualTo("orderId", storeOrder.getId());
+
+        infoCriteria.andEqualTo("orderNo", orderNo);
         List<StoreOrderInfo> infoList = storeOrderInfoService.findByCondition(infoCondition);
-        List<StoreOrderStatus> logList = storeOrderStatusService.getLogList(storeOrder.getId());
+        List<StoreOrderStatus> logList = storeOrderStatusService.getLogList(orderNo);
 
         Condition storePinkCondition = new Condition(StorePink.class);
         Example.Criteria storePinkCriteria = storePinkCondition.createCriteria();
         storePinkCriteria.andEqualTo("isDelete", 0);
-        storePinkCriteria.andEqualTo("orderIdKey", id);
+        storePinkCriteria.andEqualTo("orderId", orderNo);
 
         List<StorePink> byCondition = storePinkService.findByCondition(storePinkCondition);
         if (!org.springframework.util.CollectionUtils.isEmpty(byCondition)) {
@@ -85,8 +87,10 @@ public class OrderServiceBusinessImpl implements OrderServiceBusiness {
             vo.setStorePink(storePink);
         }
         //        UserDTO user = userDubboServiceClient.getUser(storeOrder.getUid());
-        UserAddress userAddress = userAddressService.findById(storeOrder.getAddressId());
-
+        UserAddress userAddress = null;
+        if(!ObjectUtils.isEmpty(storeOrder.getAddressId())){
+            userAddress = userAddressService.findById(storeOrder.getAddressId());
+        }
 
         List<OrderParam> orderCodeList = new ArrayList<>();
         OrderParam orderParam = new OrderParam();

+ 34 - 7
mall-service/src/main/java/com/txz/mall/business/impl/PinkServiceBusinessImpl.java

@@ -2,6 +2,7 @@ package com.txz.mall.business.impl;
 
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.ObjectUtil;
+import com.alibaba.fastjson.JSONObject;
 import com.txz.cif.dto.EarningsDTO;
 import com.txz.cif.dto.OrderParam;
 import com.txz.cif.dto.UserDTO;
@@ -13,9 +14,11 @@ import com.txz.mall.enums.PinkOrderStatusEnum;
 import com.txz.mall.enums.StorePinkStatusEnum;
 import com.txz.mall.model.StoreOrder;
 import com.txz.mall.model.StorePink;
+import com.txz.mall.model.StorePinkSummary;
 import com.txz.mall.service.StoreCombinationService;
 import com.txz.mall.service.StoreOrderService;
 import com.txz.mall.service.StorePinkService;
+import com.txz.mall.service.StorePinkSummaryService;
 import com.txz.mall.util.I18nUtil;
 import lombok.AllArgsConstructor;
 import org.springframework.beans.BeanUtils;
@@ -23,6 +26,7 @@ import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.CollectionUtils;
 import org.springframework.util.ObjectUtils;
+import org.springframework.util.StringUtils;
 import tk.mybatis.mapper.entity.Condition;
 import tk.mybatis.mapper.entity.Example;
 import vo.OrderRefundApplyVO;
@@ -46,25 +50,45 @@ public class PinkServiceBusinessImpl implements PinkServiceBusiness {
     private final StoreCombinationService storeCombinationService;
     private final CifUserDubboServiceClient cifUserDubboServiceClient;
     private final CifRedEnvelopeDubboServiceClient cifRedEnvelopeDubboServiceClient;
+    private final StorePinkSummaryService storePinkSummaryService;
     @Override
-    public List<StorePinkDetailVO> getAdminList(Long pinkId,String terminal) {
+    public List<StorePinkDetailVO> getAdminList(String orderNo,String terminal) {
 
-        if (ObjectUtils.isEmpty(pinkId)) {
-            throw new ServiceException(I18nUtil.get("group.buying.id.is.empty"));
+        if (ObjectUtils.isEmpty(orderNo)) {
+            throw new ServiceException(I18nUtil.get("group.buying.id.is.empty")+orderNo);
         }
-        StorePink storePink = storePinkService.findById(pinkId);
-
+      //  StorePink storePink = storePinkService.findById(pinkId);
+        //**分库整改
+        StorePink storePink = storePinkService.findBy("orderId", orderNo);
 
         if (ObjectUtils.isEmpty(storePink)) {
-            throw new ServiceException(I18nUtil.get("group.buying.data.does.not.exist.id")+pinkId);
+            throw new ServiceException(I18nUtil.get("group.buying.data.does.not.exist.id")+orderNo);
+        }
+        //**分库整改
+        String spsCode = storePink.getSpsCode();
+
+        StorePinkSummary storePinkSummary = storePinkSummaryService.findBy("code", spsCode);
+        if(ObjectUtils.isEmpty(storePinkSummary)){
+            throw new ServiceException(I18nUtil.get("the.group.buying.summary.data.does.not.exist")+spsCode);
+        }
+        String orderNoSet = storePinkSummary.getOrderNoSet();
+        if(StringUtils.isEmpty(orderNoSet)){
+            throw new ServiceException(I18nUtil.get("the.order.code.set.data.is.empty")+spsCode);
         }
+
+        List<String> orderNoSetList = JSONObject.parseArray(orderNoSet, String.class);
+        if(CollectionUtils.isEmpty(orderNoSetList)){
+            throw new ServiceException(I18nUtil.get("the.order.code.set.data.is.empty")+spsCode);
+        }
+
+
         List<StorePinkDetailVO> resultList = new ArrayList<>();
       //  if (StorePinkStatusEnum.RESULTS_ANNOUNCED.getKey().equals(storePink.getStatus())) {
 
             Condition condition = new Condition(StorePink.class);
             Example.Criteria criteria = condition.createCriteria();
             criteria.andEqualTo("isDelete", 0);
-            criteria.andEqualTo("spsId", storePink.getSpsId());
+       //     criteria.andEqualTo("spsId", storePink.getSpsId());
             ArrayList<Integer> integers = CollUtil.newArrayList(
                     PinkOrderStatusEnum.GROUP_ORDER_CLOSED.getKey(),
                     PinkOrderStatusEnum.GROUP_ORDER_COMPLETED.getKey(),
@@ -72,6 +96,8 @@ public class PinkServiceBusinessImpl implements PinkServiceBusiness {
                     PinkOrderStatusEnum.GROUP_ORDER_TO_RECEIVE.getKey(),
                     PinkOrderStatusEnum.GROUP_ORDER_PAID.getKey()
             );
+            //**分库整改
+            criteria.andIn("orderId", orderNoSetList);
             criteria.andIn("orderStatus", integers);
 //        criteria.andEqualTo("kId", pinkId);
             List<StorePink> pinkList = storePinkService.findByCondition(condition);
@@ -149,6 +175,7 @@ public class PinkServiceBusinessImpl implements PinkServiceBusiness {
                         storePinkDetailVO.setLId(pink.getLId());
                         storePinkDetailVO.setKId(pink.getKId());
                         storePinkDetailVO.setSpsId(pink.getSpsId());
+                        storePinkDetailVO.setSpsCode(pink.getSpsCode());
                     }
                     resultList.add(storePinkDetailVO);
                 }

+ 169 - 0
mall-service/src/main/java/com/txz/mall/configurer/DatabaseShardingAlgorithm.java

@@ -0,0 +1,169 @@
+package com.txz.mall.configurer;
+
+import org.apache.shardingsphere.api.sharding.complex.ComplexKeysShardingAlgorithm;
+import org.apache.shardingsphere.api.sharding.complex.ComplexKeysShardingValue;
+
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+public class DatabaseShardingAlgorithm implements ComplexKeysShardingAlgorithm<Comparable<?>> {
+
+
+    private static final SimpleDateFormat SDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+    private static final SimpleDateFormat SDFORDERNO = new SimpleDateFormat("yyyyMMdd");
+    private static final Set<Integer> FIRST_HALF_MONTHS = new HashSet<>(Arrays.asList(1, 2, 3, 4, 5, 6));
+    private static final Set<Integer> SECOND_HALF_MONTHS = new HashSet<>(Arrays.asList(7, 8, 9, 10, 11, 12));
+
+    @Override
+    public Collection<String> doSharding(Collection<String> availableTargets, ComplexKeysShardingValue<Comparable<?>> shardingValue) {
+        // 判断操作类型
+        boolean isInsert = isInsertOperation(shardingValue);
+
+        // 提取分片键
+        Date createTime = getCreateTime(shardingValue);
+        Long userId = getUserId(shardingValue);
+
+
+
+        // 插入操作必须包含create_time和user_id
+        if (isInsert && (createTime == null || userId == null)) {
+          //  throw new IllegalArgumentException("插入数据必须包含create_time和user_id");
+        }
+
+        // 1-6月数据处理(维持原逻辑)
+        if (createTime != null && isFirstHalfYear(createTime)) {
+            return routeFirstHalf(availableTargets, userId);
+        }
+
+        // 7-12月数据处理
+        if (createTime != null && isSecondHalfYear(createTime)) {
+            return routeSecondHalf(availableTargets, userId);
+        }
+
+        // 查询时无create_time:扫描所有符合条件的库
+        return filterAllDatabases(availableTargets, userId);
+    }
+
+    // 1-6月路由逻辑(维持原逻辑:mall_0/mall_1)
+    private Collection<String> routeFirstHalf(Collection<String> availableTargets, Long userId) {
+        if (userId != null) {
+           // String lastFour = getLastFourDigits(userId);
+            long dbIndex = userId % 2; // 0→mall_0,1→mall_1
+            String targetDb = "ds" + dbIndex;
+            if (availableTargets.contains(targetDb)) {
+                return Collections.singleton(targetDb);
+            }
+        }
+        // 查询时无user_id:扫描1-6月的库
+        return Arrays.asList("ds0", "ds1");
+    }
+
+    // 7-12月路由逻辑(mall_1/mall_2)
+    private Collection<String> routeSecondHalf(Collection<String> availableTargets, Long userId) {
+        if (userId != null) {
+            //String lastFour = getLastFourDigits(userId);
+            long dbIndex = 1 + (userId % 2); // 1→mall_1,2→mall_2
+            String targetDb = "ds" + dbIndex;
+            if (availableTargets.contains(targetDb)) {
+                return Collections.singleton(targetDb);
+            }
+        }
+        // 查询时无user_id:扫描7-12月的库
+        return Arrays.asList("ds1", "ds2");
+    }
+
+    // 判断是否为插入操作
+    private boolean isInsertOperation(ComplexKeysShardingValue<?> shardingValue) {
+        //return shardingValue.getSqlType() != null && shardingValue.getSqlType().name().startsWith("INSERT");
+
+        //shardingValue
+        return true;
+    }
+
+    // 提取并解析create_time
+    private Date getCreateTime(ComplexKeysShardingValue<Comparable<?>> shardingValue) {
+        Map<String, Collection<Comparable<?>>> values = shardingValue.getColumnNameAndShardingValuesMap();
+        if (values.containsKey("create_time") && !values.get("create_time").isEmpty()) {
+            Object value = values.get("create_time").iterator().next();
+            if (value instanceof Date) return (Date) value;
+            try {
+                return SDF.parse(value.toString());
+            } catch (ParseException e) {
+                throw new RuntimeException("create_time格式错误,应为yyyy-MM-dd HH:mm:ss");
+            }
+        }
+
+
+        if (values.containsKey("order_id") && !values.get("order_id").isEmpty()) {
+            String  orderId = (String) values.get("order_id").iterator().next();
+            // 提取日期位并转换为Date类型
+            String dateStr = "20"+orderId.substring(2, 8);
+            try {
+                return SDFORDERNO.parse(dateStr);
+            } catch (ParseException e) {
+                throw new RuntimeException("从订单号中提取日期错误"+dateStr);
+            }
+
+        }
+
+
+        return null;
+    }
+
+    // 提取user_id
+    private Long getUserId(ComplexKeysShardingValue<Comparable<?>> shardingValue) {
+        Map<String, Collection<Comparable<?>>> values = shardingValue.getColumnNameAndShardingValuesMap();
+        if (values.containsKey("uid") && !values.get("uid").isEmpty()) {
+            Long uid = (Long) values.get("uid").iterator().next();
+            return uid % 10000;
+        }
+
+        if (values.containsKey("order_id") && !values.get("order_id").isEmpty()) {
+            String  orderId = (String) values.get("order_id").iterator().next();
+            // 提取后4位并转换为long类型
+            String lastFourStr = orderId.substring(orderId.length() - 4);
+            return Long.parseLong(lastFourStr);
+        }
+
+
+        return null;
+    }
+
+    // 判断是否为1-6月
+    private boolean isFirstHalfYear(Date date) {
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(date);
+        return FIRST_HALF_MONTHS.contains(calendar.get(Calendar.MONTH) + 1);
+    }
+
+    // 判断是否为7-12月
+    private boolean isSecondHalfYear(Date date) {
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(date);
+        return SECOND_HALF_MONTHS.contains(calendar.get(Calendar.MONTH) + 1);
+    }
+
+    // 获取user_id后四位
+    private String getLastFourDigits(String value) {
+        if (value == null || value.isEmpty()) return "0";
+        return value.substring(Math.max(0, value.length() - 4));
+    }
+
+    // 无create_time时的全量库过滤
+    private Collection<String> filterAllDatabases(Collection<String> availableTargets, Long userId) {
+        if (userId != null) {
+            // 有user_id但无时间时,需扫描所有可能的库(mall_0/mall_1/mall_2)
+            return Arrays.asList("ds0", "ds1", "ds2","ds3");
+        }
+        // 无任何条件时扫描所有库
+        return availableTargets;
+    }
+
+
+
+
+
+
+}

+ 331 - 0
mall-service/src/main/java/com/txz/mall/configurer/ShardingJdbcConfig.java

@@ -0,0 +1,331 @@
+package com.txz.mall.configurer;
+
+import com.zaxxer.hikari.HikariConfig;
+import com.zaxxer.hikari.HikariDataSource;
+import org.apache.shardingsphere.api.config.sharding.KeyGeneratorConfiguration;
+import org.apache.shardingsphere.api.config.sharding.ShardingRuleConfiguration;
+import org.apache.shardingsphere.api.config.sharding.TableRuleConfiguration;
+import org.apache.shardingsphere.api.config.sharding.strategy.ComplexShardingStrategyConfiguration;
+import org.apache.shardingsphere.api.config.sharding.strategy.StandardShardingStrategyConfiguration;
+import org.apache.shardingsphere.shardingjdbc.api.ShardingDataSourceFactory;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.context.annotation.*;
+import org.springframework.jdbc.datasource.DataSourceTransactionManager;
+import org.springframework.transaction.PlatformTransactionManager;
+
+import javax.sql.DataSource;
+import java.sql.SQLException;
+import java.util.*;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class ShardingJdbcConfig {
+
+    /**
+     * 配置数据源
+     */
+//    @Bean("shardingDataSource")
+//    @Primary
+//    public DataSource dataSource() throws SQLException {
+//        // 配置分片规则
+//        ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration();
+//
+//        // 配置m_store_order表的分片规则
+//        TableRuleConfiguration orderTableRuleConfig = new TableRuleConfiguration("m_store_order",
+//                "mall_${0..1}.m_store_order_${0..1}");
+//
+//        // 设置分库策略
+//        orderTableRuleConfig.setDatabaseShardingStrategyConfig(
+//                new StandardShardingStrategyConfiguration("uid", new UidModuloDatabaseShardingAlgorithm()));
+//
+//        // 设置分表策略
+//        orderTableRuleConfig.setTableShardingStrategyConfig(
+//                new StandardShardingStrategyConfiguration("uid", new UidModuloTableShardingAlgorithm()));
+//
+//        shardingRuleConfig.getTableRuleConfigs().add(orderTableRuleConfig);
+//
+//        // 获取数据源映射
+//        Map<String, DataSource> dataSources = createDataSources();
+//
+//        // 创建并返回分片数据源
+//        return ShardingDataSourceFactory.createDataSource(dataSources, shardingRuleConfig, getProperties());
+//    }
+//
+//    /**
+//     * 创建数据源映射
+//     */
+//    private Map<String, DataSource> createDataSources() {
+//        Map<String, DataSource> dataSources = new HashMap<>(2);
+//
+//        // 配置第一个数据库
+//        dataSources.put("mall_0", createHikariDataSource(
+//                "jdbc:mysql://124.222.152.234:3306/mall_0?useUnicode=true&characterEncoding=utf-8&useSSL=false",
+//                "root",
+//                "hy123456"
+//        ));
+//
+//        // 配置第二个数据库
+//        dataSources.put("mall_1", createHikariDataSource(
+//                "jdbc:mysql://124.222.152.234:3306/mall_1?useUnicode=true&characterEncoding=utf-8&useSSL=false",
+//                "root",
+//                "hy123456"
+//        ));
+//
+//        return dataSources;
+//    }
+//
+//    /**
+//     * 创建Hikari数据源
+//     */
+//    private DataSource createHikariDataSource(String jdbcUrl, String username, String password) {
+//        HikariConfig config = new HikariConfig();
+//        config.setJdbcUrl(jdbcUrl);
+//        config.setUsername(username);
+//        config.setPassword(password);
+//        config.setDriverClassName("com.mysql.cj.jdbc.Driver");
+//        // 可以根据需要配置其他Hikari参数
+//        config.setMaximumPoolSize(10);
+//        config.setMinimumIdle(5);
+//        return new HikariDataSource(config);
+//    }
+//
+//    /**
+//     * 设置Sharding-JDBC的其他属性
+//     */
+//    private Properties getProperties() {
+//        Properties properties = new Properties();
+//        // 打印SQL,方便调试
+//        properties.setProperty("sql.show", "true");
+//        // 执行线程池大小
+//        properties.setProperty("executor.size", "10");
+//        return properties;
+//    }
+
+
+
+    /**
+     * 配置数据源
+     */
+    @Bean
+    public DataSource dataSource() throws SQLException {
+
+        // 1. 配置多个数据源
+        Map<String, DataSource> dataSources = new HashMap<>();
+        dataSources.put("ds0", createDataSource("jdbc:mysql://124.222.152.234:3306/mall_0?serverTimezone=GMT%2b8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false", "root", "hy123456","ds0"));
+        dataSources.put("ds1", createDataSource("jdbc:mysql://124.222.152.234:3306/mall_1?serverTimezone=GMT%2b8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false", "root", "hy123456","ds1"));
+        dataSources.put("ds2", createDataSource("jdbc:mysql://124.222.152.234:3306/mall_2?serverTimezone=GMT%2b8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false", "root", "hy123456","ds2"));
+        dataSources.put("ds3", createDataSource("jdbc:mysql://124.222.152.234:3306/mall_3?serverTimezone=GMT%2b8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false", "root", "hy123456","ds3"));
+        // 添加默认数据库(非分库分表的表使用)
+        dataSources.put("default_ds", createDataSource("jdbc:mysql://124.222.152.234:3306/mall?serverTimezone=GMT%2b8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false", "root", "hy123456","ds4"));
+
+
+
+
+        // 4. 配置分表策略(用户ID取模)
+//        orderTableRule.setTableShardingStrategyConfig(
+//                new StandardShardingStrategyConfiguration("uid,order_id", )
+//        );
+
+        // 5. 配置分片规则
+        ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration();
+        Collection<TableRuleConfiguration> tableRuleConfigs = shardingRuleConfig.getTableRuleConfigs();
+
+        TableRuleConfiguration storeOrderTableRule = storeOrderTableRuleConfiguration();
+        tableRuleConfigs.add(storeOrderTableRule);
+
+
+        TableRuleConfiguration storePinkTableRuleConfiguration = storePinkTableRuleConfiguration();
+        tableRuleConfigs.add(storePinkTableRuleConfiguration);
+
+
+        TableRuleConfiguration storeOrderInfoTableRuleConfiguration = storeOrderInfoTableRuleConfiguration();
+        tableRuleConfigs.add(storeOrderInfoTableRuleConfiguration);
+
+
+        TableRuleConfiguration storeOrderStatusTableRuleConfiguration = storeOrderStatusTableRuleConfiguration();
+        tableRuleConfigs.add(storeOrderStatusTableRuleConfiguration);
+
+        //     这个表分起来有点麻烦,不如不分  查询sql 用的是 cid(活动商品id) 或者 create_time(定时关单)   可以采用定时清理无效数据的方式处理。一般这个数据只在活动持续时间内有效
+//        TableRuleConfiguration storePinkSummaryTableRuleConfiguration = storePinkSummaryTableRuleConfiguration();
+//        tableRuleConfigs.add(storePinkSummaryTableRuleConfiguration);
+
+
+        TableRuleConfiguration userSignTableRuleConfiguration = userSignTableRuleConfiguration();
+        tableRuleConfigs.add(userSignTableRuleConfiguration);
+
+        // 设置默认数据源(非分片表使用)
+        shardingRuleConfig.setDefaultDataSourceName("default_ds");
+
+        Properties props = new Properties();
+        props.setProperty("sql.show", "true");
+        // 允许缺少分片键的查询执行全表扫描(默认false,会报错)
+        props.setProperty("shardingsphere.sharding.allow.full.table.scan", "true");
+
+        // 6. 创建并返回分片数据源
+        return ShardingDataSourceFactory.createDataSource(dataSources, shardingRuleConfig, props);
+    }
+
+
+    @Bean
+    public PlatformTransactionManager transactionManager(DataSource dataSource) {
+        return new DataSourceTransactionManager(dataSource);
+    }
+
+
+    /**
+     * 创建数据源工具方法
+     */
+    private DataSource createDataSource(String url, String username, String password,String dataSourceName) {
+
+        com.zaxxer.hikari.HikariConfig config = new com.zaxxer.hikari.HikariConfig();
+        config.setJdbcUrl(url);
+        config.setUsername(username);
+        config.setPassword(password);
+        config.setDriverClassName("com.mysql.cj.jdbc.Driver");
+        config.setPoolName("dataSourceName");
+        HikariDataSource hikariDataSource = new HikariDataSource(config);
+        try {
+            hikariDataSource.getConnection().close();
+            System.out.println("数据源 " + dataSourceName + " 初始化成功");
+        } catch (SQLException e) {
+            throw new RuntimeException(e);
+        }
+
+        return hikariDataSource;
+    }
+
+    private TableRuleConfiguration storeOrderTableRuleConfiguration(){
+        // 2. 配置订单表分库分表规则
+        TableRuleConfiguration orderTableRule = new TableRuleConfiguration("m_store_order", "ds${0..3}.m_store_order_${0..4}");
+        // 3. 配置分库策略(时间+用户ID)
+
+        orderTableRule.setDatabaseShardingStrategyConfig(
+                new ComplexShardingStrategyConfiguration(
+                        "create_time,uid,order_id",  // 多分片键
+                        new DatabaseShardingAlgorithm()      // 复合分片算法
+                )
+        );
+        orderTableRule.setTableShardingStrategyConfig(
+                new ComplexShardingStrategyConfiguration(
+                        "uid,order_id",  // 多分片键
+                        new TableShardingAlgorithm()      // 复合分片算法
+                )
+        );
+
+        return orderTableRule;
+    }
+
+    private TableRuleConfiguration storePinkTableRuleConfiguration(){
+        // 2. 配置订单表分库分表规则
+        TableRuleConfiguration orderTableRule = new TableRuleConfiguration("m_store_pink", "ds${0..3}.m_store_pink_${0..4}");
+        // 3. 配置分库策略(时间+用户ID)
+
+        orderTableRule.setDatabaseShardingStrategyConfig(
+                new ComplexShardingStrategyConfiguration(
+                        "create_time,uid,order_id",  // 多分片键
+                        new DatabaseShardingAlgorithm()      // 复合分片算法
+                )
+        );
+        orderTableRule.setTableShardingStrategyConfig(
+                new ComplexShardingStrategyConfiguration(
+                        "uid,order_id",  // 多分片键
+                        new TableShardingAlgorithm()      // 复合分片算法
+                )
+        );
+
+        return orderTableRule;
+    }
+
+
+
+    private TableRuleConfiguration storeOrderInfoTableRuleConfiguration(){
+        // 2. 配置订单表分库分表规则
+        TableRuleConfiguration orderTableRule = new TableRuleConfiguration("m_store_order_info", "ds${0..3}.m_store_order_info_${0..4}");
+        // 3. 配置分库策略(时间+用户ID)
+
+        orderTableRule.setDatabaseShardingStrategyConfig(
+                new ComplexShardingStrategyConfiguration(
+                        "order_no",  // 多分片键
+                        new StoreOrderInfoDatabaseShardingAlgorithm()      // 复合分片算法
+                )
+        );
+        orderTableRule.setTableShardingStrategyConfig(
+                new ComplexShardingStrategyConfiguration(
+                        "order_no",  // 多分片键
+                        new StoreOrderInfoTableShardingAlgorithm()      // 复合分片算法
+                )
+        );
+
+        return orderTableRule;
+    }
+
+
+    private TableRuleConfiguration storeOrderStatusTableRuleConfiguration(){
+        // 2. 配置订单表分库分表规则
+        TableRuleConfiguration orderTableRule = new TableRuleConfiguration("m_store_order_status", "ds${0..3}.m_store_order_status_${0..4}");
+        // 3. 配置分库策略(时间+用户ID)
+
+        orderTableRule.setDatabaseShardingStrategyConfig(
+                new ComplexShardingStrategyConfiguration(
+                        "order_id",  // 多分片键
+                        new StoreOrderStatusDatabaseShardingAlgorithm()      // 复合分片算法
+                )
+        );
+        orderTableRule.setTableShardingStrategyConfig(
+                new ComplexShardingStrategyConfiguration(
+                        "order_id",  // 多分片键
+                        new StoreOrderStatusTableShardingAlgorithm()      // 复合分片算法
+                )
+        );
+
+        return orderTableRule;
+    }
+
+
+
+//    private TableRuleConfiguration storePinkSummaryTableRuleConfiguration(){
+//        // 2. 配置订单表分库分表规则
+//        TableRuleConfiguration orderTableRule = new TableRuleConfiguration("m_store_pink_summary", "ds${0..3}.m_store_pink_summary_${0..4}");
+//        // 3. 配置分库策略(时间+用户ID)
+//
+//        orderTableRule.setDatabaseShardingStrategyConfig(
+//                new ComplexShardingStrategyConfiguration(
+//                        "cid",  // 多分片键
+//                        new StorePinkSummaryDatabaseShardingAlgorithm()      // 复合分片算法
+//                )
+//        );
+//        orderTableRule.setTableShardingStrategyConfig(
+//                new ComplexShardingStrategyConfiguration(
+//                        "cid",  // 多分片键
+//                        new StorePinkSummaryTableShardingAlgorithm()      // 复合分片算法
+//                )
+//        );
+//
+//        return orderTableRule;
+//    }
+
+    private TableRuleConfiguration userSignTableRuleConfiguration(){
+        // 2. 配置订单表分库分表规则
+        TableRuleConfiguration orderTableRule = new TableRuleConfiguration("m_user_sign", "ds${0..3}.m_user_sign_${0..4}");
+        // 3. 配置分库策略(时间+用户ID)
+
+        orderTableRule.setDatabaseShardingStrategyConfig(
+                new ComplexShardingStrategyConfiguration(
+                        "uid,create_day",  // 多分片键
+                        new UserSignDatabaseShardingAlgorithm()      // 复合分片算法
+                )
+        );
+        orderTableRule.setTableShardingStrategyConfig(
+                new ComplexShardingStrategyConfiguration(
+                        "uid,create_day",  // 多分片键
+                        new UserSignTableShardingAlgorithm()      // 复合分片算法
+                )
+        );
+
+        return orderTableRule;
+    }
+
+
+}

+ 0 - 124
mall-service/src/main/java/com/txz/mall/configurer/ShardingSphereConfig.java

@@ -1,124 +0,0 @@
-package com.txz.mall.configurer;
-
-import com.zaxxer.hikari.HikariDataSource;
-import org.apache.shardingsphere.api.config.sharding.ShardingRuleConfiguration;
-import org.apache.shardingsphere.api.config.sharding.TableRuleConfiguration;
-import org.apache.shardingsphere.api.config.sharding.strategy.StandardShardingStrategyConfiguration;
-import org.apache.shardingsphere.shardingjdbc.api.ShardingDataSourceFactory;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.context.annotation.Primary;
-
-import javax.sql.DataSource;
-import java.sql.SQLException;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Properties;
-
-@Configuration
-public class ShardingSphereConfig {
-
-    @Value("${sharding.datasource.ds0.driver-class-name}")
-    private String ds0DriverClassName;
-    
-    @Value("${sharding.datasource.ds0.jdbc-url}")
-    private String ds0JdbcUrl;
-    
-    @Value("${sharding.datasource.ds0.username}")
-    private String ds0Username;
-    
-    @Value("${sharding.datasource.ds0.password}")
-    private String ds0Password;
-    
-    @Value("${sharding.datasource.ds1.driver-class-name}")
-    private String ds1DriverClassName;
-    
-    @Value("${sharding.datasource.ds1.jdbc-url}")
-    private String ds1JdbcUrl;
-    
-    @Value("${sharding.datasource.ds1.username}")
-    private String ds1Username;
-    
-    @Value("${sharding.datasource.ds1.password}")
-    private String ds1Password;
-    
-    @Value("${sharding.datasource.dsdefault.driver-class-name}")
-    private String dsDefaultDriverClassName;
-    
-    @Value("${sharding.datasource.dsdefault.jdbc-url}")
-    private String dsDefaultJdbcUrl;
-    
-    @Value("${sharding.datasource.dsdefault.username}")
-    private String dsDefaultUsername;
-    
-    @Value("${sharding.datasource.dsdefault.password}")
-    private String dsDefaultPassword;
-
-    @Bean("shardingDataSource")
-    @Primary
-    public DataSource shardingDataSource() throws SQLException {
-        Map<String, DataSource> dataSourceMap = new HashMap<>();
-
-        HikariDataSource dataSource0 = new HikariDataSource();
-        dataSource0.setDriverClassName(ds0DriverClassName);
-        dataSource0.setJdbcUrl(ds0JdbcUrl);
-        dataSource0.setUsername(ds0Username);
-        dataSource0.setPassword(ds0Password);
-        dataSourceMap.put("ds0", dataSource0);
-
-        HikariDataSource dataSource1 = new HikariDataSource();
-        dataSource1.setDriverClassName(ds1DriverClassName);
-        dataSource1.setJdbcUrl(ds1JdbcUrl);
-        dataSource1.setUsername(ds1Username);
-        dataSource1.setPassword(ds1Password);
-        dataSourceMap.put("ds1", dataSource1);
-
-        HikariDataSource dataSourceFault = new HikariDataSource();
-        dataSourceFault.setDriverClassName(dsDefaultDriverClassName);
-        dataSourceFault.setJdbcUrl(dsDefaultJdbcUrl);
-        dataSourceFault.setUsername(dsDefaultUsername);
-        dataSourceFault.setPassword(dsDefaultPassword);
-        dataSourceMap.put("dsdefault", dataSourceFault);
-
-        if (dataSourceMap.isEmpty()) {
-            throw new IllegalArgumentException("数据源配置不能为空");
-        }
-
-        ShardingRuleConfiguration shardingRuleConfig = new ShardingRuleConfiguration();
-        
-        shardingRuleConfig.getTableRuleConfigs().add(getAccountFlowTableRuleConfiguration());
-        
-        shardingRuleConfig.getTableRuleConfigs().add(getFlowTableRuleConfiguration());
-        
-        shardingRuleConfig.getTableRuleConfigs().add(getRedEnvelopeTableRuleConfiguration());
-        
-        shardingRuleConfig.setDefaultDataSourceName("dsdefault");
-
-        Properties props = new Properties();
-        props.setProperty("sql.show", "true");
-
-        return ShardingDataSourceFactory.createDataSource(dataSourceMap, shardingRuleConfig, props);
-    }
-
-    private TableRuleConfiguration getAccountFlowTableRuleConfiguration() {
-        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()));
-        return result;
-    }
-
-    private TableRuleConfiguration getFlowTableRuleConfiguration() {
-        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()));
-        return result;
-    }
-
-    private TableRuleConfiguration getRedEnvelopeTableRuleConfiguration() {
-        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;
-    }
-}

+ 168 - 0
mall-service/src/main/java/com/txz/mall/configurer/StoreOrderInfoDatabaseShardingAlgorithm.java

@@ -0,0 +1,168 @@
+package com.txz.mall.configurer;
+
+import org.apache.shardingsphere.api.sharding.complex.ComplexKeysShardingAlgorithm;
+import org.apache.shardingsphere.api.sharding.complex.ComplexKeysShardingValue;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+public class StoreOrderInfoDatabaseShardingAlgorithm implements ComplexKeysShardingAlgorithm<Comparable<?>> {
+
+
+    private static final SimpleDateFormat SDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+    private static final SimpleDateFormat SDFORDERNO = new SimpleDateFormat("yyyyMMdd");
+    private static final Set<Integer> FIRST_HALF_MONTHS = new HashSet<>(Arrays.asList(1, 2, 3, 4, 5, 6));
+    private static final Set<Integer> SECOND_HALF_MONTHS = new HashSet<>(Arrays.asList(7, 8, 9, 10, 11, 12));
+
+    @Override
+    public Collection<String> doSharding(Collection<String> availableTargets, ComplexKeysShardingValue<Comparable<?>> shardingValue) {
+        // 判断操作类型
+        boolean isInsert = isInsertOperation(shardingValue);
+
+        // 提取分片键
+        Date createTime = getCreateTime(shardingValue);
+        Long userId = getUserId(shardingValue);
+
+
+
+        // 插入操作必须包含create_time和user_id
+        if (isInsert && (createTime == null || userId == null)) {
+          //  throw new IllegalArgumentException("插入数据必须包含create_time和user_id");
+        }
+
+        // 1-6月数据处理(维持原逻辑)
+        if (createTime != null && isFirstHalfYear(createTime)) {
+            return routeFirstHalf(availableTargets, userId);
+        }
+
+        // 7-12月数据处理
+        if (createTime != null && isSecondHalfYear(createTime)) {
+            return routeSecondHalf(availableTargets, userId);
+        }
+
+        // 查询时无create_time:扫描所有符合条件的库
+        return filterAllDatabases(availableTargets, userId);
+    }
+
+    // 1-6月路由逻辑(维持原逻辑:mall_0/mall_1)
+    private Collection<String> routeFirstHalf(Collection<String> availableTargets, Long userId) {
+        if (userId != null) {
+           // String lastFour = getLastFourDigits(userId);
+            long dbIndex = userId % 2; // 0→mall_0,1→mall_1
+            String targetDb = "ds" + dbIndex;
+            if (availableTargets.contains(targetDb)) {
+                return Collections.singleton(targetDb);
+            }
+        }
+        // 查询时无user_id:扫描1-6月的库
+        return Arrays.asList("ds0", "ds1");
+    }
+
+    // 7-12月路由逻辑(mall_1/mall_2)
+    private Collection<String> routeSecondHalf(Collection<String> availableTargets, Long userId) {
+        if (userId != null) {
+            //String lastFour = getLastFourDigits(userId);
+            long dbIndex = 1 + (userId % 2); // 1→mall_1,2→mall_2
+            String targetDb = "ds" + dbIndex;
+            if (availableTargets.contains(targetDb)) {
+                return Collections.singleton(targetDb);
+            }
+        }
+        // 查询时无user_id:扫描7-12月的库
+        return Arrays.asList("ds1", "ds2");
+    }
+
+    // 判断是否为插入操作
+    private boolean isInsertOperation(ComplexKeysShardingValue<?> shardingValue) {
+        //return shardingValue.getSqlType() != null && shardingValue.getSqlType().name().startsWith("INSERT");
+
+        //shardingValue
+        return true;
+    }
+
+    // 提取并解析create_time
+    private Date getCreateTime(ComplexKeysShardingValue<Comparable<?>> shardingValue) {
+        Map<String, Collection<Comparable<?>>> values = shardingValue.getColumnNameAndShardingValuesMap();
+//        if (values.containsKey("create_time") && !values.get("create_time").isEmpty()) {
+//            Object value = values.get("create_time").iterator().next();
+//            if (value instanceof Date) return (Date) value;
+//            try {
+//                return SDF.parse(value.toString());
+//            } catch (ParseException e) {
+//                throw new RuntimeException("create_time格式错误,应为yyyy-MM-dd HH:mm:ss");
+//            }
+//        }
+
+
+        if (values.containsKey("order_no") && !values.get("order_no").isEmpty()) {
+            String  orderId = (String) values.get("order_no").iterator().next();
+            // 提取日期位并转换为Date类型
+            String dateStr = "20"+orderId.substring(2, 8);
+            try {
+                return SDFORDERNO.parse(dateStr);
+            } catch (ParseException e) {
+                throw new RuntimeException("StoreOrderInfoDatabaseShardingAlgorithm从订单号中提取日期错误"+dateStr);
+            }
+
+        }
+
+
+        return null;
+    }
+
+    // 提取user_id
+    private Long getUserId(ComplexKeysShardingValue<Comparable<?>> shardingValue) {
+        Map<String, Collection<Comparable<?>>> values = shardingValue.getColumnNameAndShardingValuesMap();
+//        if (values.containsKey("uid") && !values.get("uid").isEmpty()) {
+//            Long uid = (Long) values.get("uid").iterator().next();
+//            return uid % 10000;
+//        }
+
+        if (values.containsKey("order_no") && !values.get("order_no").isEmpty()) {
+            String  orderId = (String) values.get("order_no").iterator().next();
+            // 提取后4位并转换为long类型
+            String lastFourStr = orderId.substring(orderId.length() - 4);
+            return Long.parseLong(lastFourStr);
+        }
+
+
+        return null;
+    }
+
+    // 判断是否为1-6月
+    private boolean isFirstHalfYear(Date date) {
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(date);
+        return FIRST_HALF_MONTHS.contains(calendar.get(Calendar.MONTH) + 1);
+    }
+
+    // 判断是否为7-12月
+    private boolean isSecondHalfYear(Date date) {
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(date);
+        return SECOND_HALF_MONTHS.contains(calendar.get(Calendar.MONTH) + 1);
+    }
+
+    // 获取user_id后四位
+    private String getLastFourDigits(String value) {
+        if (value == null || value.isEmpty()) return "0";
+        return value.substring(Math.max(0, value.length() - 4));
+    }
+
+    // 无create_time时的全量库过滤
+    private Collection<String> filterAllDatabases(Collection<String> availableTargets, Long userId) {
+        if (userId != null) {
+            // 有user_id但无时间时,需扫描所有可能的库(mall_0/mall_1/mall_2)
+            return Arrays.asList("ds0", "ds1", "ds2","ds3");
+        }
+        // 无任何条件时扫描所有库
+        return availableTargets;
+    }
+
+
+
+
+
+
+}

+ 51 - 0
mall-service/src/main/java/com/txz/mall/configurer/StoreOrderInfoTableShardingAlgorithm.java

@@ -0,0 +1,51 @@
+package com.txz.mall.configurer;
+
+import org.apache.shardingsphere.api.sharding.complex.ComplexKeysShardingAlgorithm;
+import org.apache.shardingsphere.api.sharding.complex.ComplexKeysShardingValue;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+public class StoreOrderInfoTableShardingAlgorithm implements ComplexKeysShardingAlgorithm<Comparable<?>> {
+
+    @Override
+    public Collection<String> doSharding(Collection<String> availableTargets, ComplexKeysShardingValue<Comparable<?>> shardingValue) {
+        Long userId = getUserId(shardingValue);
+        // 查询时无create_time:扫描所有符合条件的库
+        return filterAllTable(availableTargets, userId);
+    }
+
+
+    private Long getUserId(ComplexKeysShardingValue<Comparable<?>> shardingValue) {
+        Map<String, Collection<Comparable<?>>> values = shardingValue.getColumnNameAndShardingValuesMap();
+//        if (values.containsKey("uid") && !values.get("uid").isEmpty()) {
+//            Long uid = (Long) values.get("uid").iterator().next();
+//            return uid % 10000;
+//        }
+
+        if (values.containsKey("order_no") && !values.get("order_no").isEmpty()) {
+            String  orderId = (String) values.get("order_no").iterator().next();
+            // 提取后4位并转换为long类型
+            String lastFourStr = orderId.substring(orderId.length() - 4);
+            return Long.parseLong(lastFourStr);
+        }
+
+        return null;
+    }
+
+    private Collection<String> filterAllTable(Collection<String> availableTargets, Long userId) {
+        //这个模树要拎出去形成配置项
+        long mod = userId % 5;
+        for (String tableName : availableTargets) {
+            if (tableName.endsWith(String.valueOf(mod))) {
+                List<String> list = Arrays.asList(tableName);
+                return list;
+            }
+        }
+        throw new IllegalArgumentException("未找到匹配的表: " + availableTargets + ", 分片值: " + userId);
+
+    }
+
+}

+ 168 - 0
mall-service/src/main/java/com/txz/mall/configurer/StoreOrderStatusDatabaseShardingAlgorithm.java

@@ -0,0 +1,168 @@
+package com.txz.mall.configurer;
+
+import org.apache.shardingsphere.api.sharding.complex.ComplexKeysShardingAlgorithm;
+import org.apache.shardingsphere.api.sharding.complex.ComplexKeysShardingValue;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+public class StoreOrderStatusDatabaseShardingAlgorithm implements ComplexKeysShardingAlgorithm<Comparable<?>> {
+
+
+    private static final SimpleDateFormat SDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+    private static final SimpleDateFormat SDFORDERNO = new SimpleDateFormat("yyyyMMdd");
+    private static final Set<Integer> FIRST_HALF_MONTHS = new HashSet<>(Arrays.asList(1, 2, 3, 4, 5, 6));
+    private static final Set<Integer> SECOND_HALF_MONTHS = new HashSet<>(Arrays.asList(7, 8, 9, 10, 11, 12));
+
+    @Override
+    public Collection<String> doSharding(Collection<String> availableTargets, ComplexKeysShardingValue<Comparable<?>> shardingValue) {
+        // 判断操作类型
+        boolean isInsert = isInsertOperation(shardingValue);
+
+        // 提取分片键
+        Date createTime = getCreateTime(shardingValue);
+        Long userId = getUserId(shardingValue);
+
+
+
+        // 插入操作必须包含create_time和user_id
+        if (isInsert && (createTime == null || userId == null)) {
+          //  throw new IllegalArgumentException("插入数据必须包含create_time和user_id");
+        }
+
+        // 1-6月数据处理(维持原逻辑)
+        if (createTime != null && isFirstHalfYear(createTime)) {
+            return routeFirstHalf(availableTargets, userId);
+        }
+
+        // 7-12月数据处理
+        if (createTime != null && isSecondHalfYear(createTime)) {
+            return routeSecondHalf(availableTargets, userId);
+        }
+
+        // 查询时无create_time:扫描所有符合条件的库
+        return filterAllDatabases(availableTargets, userId);
+    }
+
+    // 1-6月路由逻辑(维持原逻辑:mall_0/mall_1)
+    private Collection<String> routeFirstHalf(Collection<String> availableTargets, Long userId) {
+        if (userId != null) {
+           // String lastFour = getLastFourDigits(userId);
+            long dbIndex = userId % 2; // 0→mall_0,1→mall_1
+            String targetDb = "ds" + dbIndex;
+            if (availableTargets.contains(targetDb)) {
+                return Collections.singleton(targetDb);
+            }
+        }
+        // 查询时无user_id:扫描1-6月的库
+        return Arrays.asList("ds0", "ds1");
+    }
+
+    // 7-12月路由逻辑(mall_1/mall_2)
+    private Collection<String> routeSecondHalf(Collection<String> availableTargets, Long userId) {
+        if (userId != null) {
+            //String lastFour = getLastFourDigits(userId);
+            long dbIndex = 1 + (userId % 2); // 1→mall_1,2→mall_2
+            String targetDb = "ds" + dbIndex;
+            if (availableTargets.contains(targetDb)) {
+                return Collections.singleton(targetDb);
+            }
+        }
+        // 查询时无user_id:扫描7-12月的库
+        return Arrays.asList("ds1", "ds2");
+    }
+
+    // 判断是否为插入操作
+    private boolean isInsertOperation(ComplexKeysShardingValue<?> shardingValue) {
+        //return shardingValue.getSqlType() != null && shardingValue.getSqlType().name().startsWith("INSERT");
+
+        //shardingValue
+        return true;
+    }
+
+    // 提取并解析create_time
+    private Date getCreateTime(ComplexKeysShardingValue<Comparable<?>> shardingValue) {
+        Map<String, Collection<Comparable<?>>> values = shardingValue.getColumnNameAndShardingValuesMap();
+//        if (values.containsKey("create_time") && !values.get("create_time").isEmpty()) {
+//            Object value = values.get("create_time").iterator().next();
+//            if (value instanceof Date) return (Date) value;
+//            try {
+//                return SDF.parse(value.toString());
+//            } catch (ParseException e) {
+//                throw new RuntimeException("create_time格式错误,应为yyyy-MM-dd HH:mm:ss");
+//            }
+//        }
+
+
+        if (values.containsKey("order_id") && !values.get("order_id").isEmpty()) {
+            String  orderId = (String) values.get("order_id").iterator().next();
+            // 提取日期位并转换为Date类型
+            String dateStr = "20"+orderId.substring(2, 8);
+            try {
+                return SDFORDERNO.parse(dateStr);
+            } catch (ParseException e) {
+                throw new RuntimeException("StoreOrderStatusDatabaseShardingAlgorithm从订单号中提取日期错误"+dateStr);
+            }
+
+        }
+
+
+        return null;
+    }
+
+    // 提取user_id
+    private Long getUserId(ComplexKeysShardingValue<Comparable<?>> shardingValue) {
+        Map<String, Collection<Comparable<?>>> values = shardingValue.getColumnNameAndShardingValuesMap();
+//        if (values.containsKey("uid") && !values.get("uid").isEmpty()) {
+//            Long uid = (Long) values.get("uid").iterator().next();
+//            return uid % 10000;
+//        }
+
+        if (values.containsKey("order_id") && !values.get("order_id").isEmpty()) {
+            String  orderId = (String) values.get("order_id").iterator().next();
+            // 提取后4位并转换为long类型
+            String lastFourStr = orderId.substring(orderId.length() - 4);
+            return Long.parseLong(lastFourStr);
+        }
+
+
+        return null;
+    }
+
+    // 判断是否为1-6月
+    private boolean isFirstHalfYear(Date date) {
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(date);
+        return FIRST_HALF_MONTHS.contains(calendar.get(Calendar.MONTH) + 1);
+    }
+
+    // 判断是否为7-12月
+    private boolean isSecondHalfYear(Date date) {
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(date);
+        return SECOND_HALF_MONTHS.contains(calendar.get(Calendar.MONTH) + 1);
+    }
+
+    // 获取user_id后四位
+    private String getLastFourDigits(String value) {
+        if (value == null || value.isEmpty()) return "0";
+        return value.substring(Math.max(0, value.length() - 4));
+    }
+
+    // 无create_time时的全量库过滤
+    private Collection<String> filterAllDatabases(Collection<String> availableTargets, Long userId) {
+        if (userId != null) {
+            // 有user_id但无时间时,需扫描所有可能的库(mall_0/mall_1/mall_2)
+            return Arrays.asList("ds0", "ds1", "ds2","ds3");
+        }
+        // 无任何条件时扫描所有库
+        return availableTargets;
+    }
+
+
+
+
+
+
+}

+ 51 - 0
mall-service/src/main/java/com/txz/mall/configurer/StoreOrderStatusTableShardingAlgorithm.java

@@ -0,0 +1,51 @@
+package com.txz.mall.configurer;
+
+import org.apache.shardingsphere.api.sharding.complex.ComplexKeysShardingAlgorithm;
+import org.apache.shardingsphere.api.sharding.complex.ComplexKeysShardingValue;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+public class StoreOrderStatusTableShardingAlgorithm implements ComplexKeysShardingAlgorithm<Comparable<?>> {
+
+    @Override
+    public Collection<String> doSharding(Collection<String> availableTargets, ComplexKeysShardingValue<Comparable<?>> shardingValue) {
+        Long userId = getUserId(shardingValue);
+        // 查询时无create_time:扫描所有符合条件的库
+        return filterAllTable(availableTargets, userId);
+    }
+
+
+    private Long getUserId(ComplexKeysShardingValue<Comparable<?>> shardingValue) {
+        Map<String, Collection<Comparable<?>>> values = shardingValue.getColumnNameAndShardingValuesMap();
+//        if (values.containsKey("uid") && !values.get("uid").isEmpty()) {
+//            Long uid = (Long) values.get("uid").iterator().next();
+//            return uid % 10000;
+//        }
+
+        if (values.containsKey("order_id") && !values.get("order_id").isEmpty()) {
+            String  orderId = (String) values.get("order_id").iterator().next();
+            // 提取后4位并转换为long类型
+            String lastFourStr = orderId.substring(orderId.length() - 4);
+            return Long.parseLong(lastFourStr);
+        }
+
+        return null;
+    }
+
+    private Collection<String> filterAllTable(Collection<String> availableTargets, Long userId) {
+        //这个模树要拎出去形成配置项
+        long mod = userId % 5;
+        for (String tableName : availableTargets) {
+            if (tableName.endsWith(String.valueOf(mod))) {
+                List<String> list = Arrays.asList(tableName);
+                return list;
+            }
+        }
+        throw new IllegalArgumentException("未找到匹配的表: " + availableTargets + ", 分片值: " + userId);
+
+    }
+
+}

+ 168 - 0
mall-service/src/main/java/com/txz/mall/configurer/StorePinkSummaryDatabaseShardingAlgorithm.java

@@ -0,0 +1,168 @@
+package com.txz.mall.configurer;
+
+import org.apache.shardingsphere.api.sharding.complex.ComplexKeysShardingAlgorithm;
+import org.apache.shardingsphere.api.sharding.complex.ComplexKeysShardingValue;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+public class StorePinkSummaryDatabaseShardingAlgorithm implements ComplexKeysShardingAlgorithm<Comparable<?>> {
+
+
+    private static final SimpleDateFormat SDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+    private static final SimpleDateFormat SDFORDERNO = new SimpleDateFormat("yyyyMMdd");
+    private static final Set<Integer> FIRST_HALF_MONTHS = new HashSet<>(Arrays.asList(1, 2, 3, 4, 5, 6));
+    private static final Set<Integer> SECOND_HALF_MONTHS = new HashSet<>(Arrays.asList(7, 8, 9, 10, 11, 12));
+
+    @Override
+    public Collection<String> doSharding(Collection<String> availableTargets, ComplexKeysShardingValue<Comparable<?>> shardingValue) {
+        // 判断操作类型
+        boolean isInsert = isInsertOperation(shardingValue);
+
+        // 提取分片键
+        Date createTime = getCreateTime(shardingValue);
+        Long userId = getUserId(shardingValue);
+
+
+
+        // 插入操作必须包含create_time和user_id
+        if (isInsert && (createTime == null || userId == null)) {
+          //  throw new IllegalArgumentException("插入数据必须包含create_time和user_id");
+        }
+
+        // 1-6月数据处理(维持原逻辑)
+        if (createTime != null && isFirstHalfYear(createTime)) {
+            return routeFirstHalf(availableTargets, userId);
+        }
+
+        // 7-12月数据处理
+        if (createTime != null && isSecondHalfYear(createTime)) {
+            return routeSecondHalf(availableTargets, userId);
+        }
+
+        // 查询时无create_time:扫描所有符合条件的库
+        return filterAllDatabases(availableTargets, userId);
+    }
+
+    // 1-6月路由逻辑(维持原逻辑:mall_0/mall_1)
+    private Collection<String> routeFirstHalf(Collection<String> availableTargets, Long userId) {
+        if (userId != null) {
+           // String lastFour = getLastFourDigits(userId);
+            long dbIndex = userId % 2; // 0→mall_0,1→mall_1
+            String targetDb = "ds" + dbIndex;
+            if (availableTargets.contains(targetDb)) {
+                return Collections.singleton(targetDb);
+            }
+        }
+        // 查询时无user_id:扫描1-6月的库
+        return Arrays.asList("ds0", "ds1");
+    }
+
+    // 7-12月路由逻辑(mall_1/mall_2)
+    private Collection<String> routeSecondHalf(Collection<String> availableTargets, Long userId) {
+        if (userId != null) {
+            //String lastFour = getLastFourDigits(userId);
+            long dbIndex = 1 + (userId % 2); // 1→mall_1,2→mall_2
+            String targetDb = "ds" + dbIndex;
+            if (availableTargets.contains(targetDb)) {
+                return Collections.singleton(targetDb);
+            }
+        }
+        // 查询时无user_id:扫描7-12月的库
+        return Arrays.asList("ds1", "ds2");
+    }
+
+    // 判断是否为插入操作
+    private boolean isInsertOperation(ComplexKeysShardingValue<?> shardingValue) {
+        //return shardingValue.getSqlType() != null && shardingValue.getSqlType().name().startsWith("INSERT");
+
+        //shardingValue
+        return true;
+    }
+
+    // 提取并解析create_time
+    private Date getCreateTime(ComplexKeysShardingValue<Comparable<?>> shardingValue) {
+        Map<String, Collection<Comparable<?>>> values = shardingValue.getColumnNameAndShardingValuesMap();
+//        if (values.containsKey("create_time") && !values.get("create_time").isEmpty()) {
+//            Object value = values.get("create_time").iterator().next();
+//            if (value instanceof Date) return (Date) value;
+//            try {
+//                return SDF.parse(value.toString());
+//            } catch (ParseException e) {
+//                throw new RuntimeException("create_time格式错误,应为yyyy-MM-dd HH:mm:ss");
+//            }
+//        }
+
+
+        if (values.containsKey("code") && !values.get("code").isEmpty()) {
+            String  orderId = (String) values.get("code").iterator().next();
+            // 提取日期位并转换为Date类型
+            String dateStr = "20"+orderId.substring(2, 8);
+            try {
+                return SDFORDERNO.parse(dateStr);
+            } catch (ParseException e) {
+                throw new RuntimeException("StoreOrderStatusDatabaseShardingAlgorithm从订单号中提取日期错误"+dateStr);
+            }
+
+        }
+
+
+        return null;
+    }
+
+    // 提取user_id
+    private Long getUserId(ComplexKeysShardingValue<Comparable<?>> shardingValue) {
+        Map<String, Collection<Comparable<?>>> values = shardingValue.getColumnNameAndShardingValuesMap();
+//        if (values.containsKey("uid") && !values.get("uid").isEmpty()) {
+//            Long uid = (Long) values.get("uid").iterator().next();
+//            return uid % 10000;
+//        }
+
+        if (values.containsKey("code") && !values.get("code").isEmpty()) {
+            String  orderId = (String) values.get("code").iterator().next();
+            // 提取后4位并转换为long类型
+            String lastFourStr = orderId.substring(orderId.length() - 4);
+            return Long.parseLong(lastFourStr);
+        }
+
+
+        return null;
+    }
+
+    // 判断是否为1-6月
+    private boolean isFirstHalfYear(Date date) {
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(date);
+        return FIRST_HALF_MONTHS.contains(calendar.get(Calendar.MONTH) + 1);
+    }
+
+    // 判断是否为7-12月
+    private boolean isSecondHalfYear(Date date) {
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(date);
+        return SECOND_HALF_MONTHS.contains(calendar.get(Calendar.MONTH) + 1);
+    }
+
+    // 获取user_id后四位
+    private String getLastFourDigits(String value) {
+        if (value == null || value.isEmpty()) return "0";
+        return value.substring(Math.max(0, value.length() - 4));
+    }
+
+    // 无create_time时的全量库过滤
+    private Collection<String> filterAllDatabases(Collection<String> availableTargets, Long userId) {
+        if (userId != null) {
+            // 有user_id但无时间时,需扫描所有可能的库(mall_0/mall_1/mall_2)
+            return Arrays.asList("ds0", "ds1", "ds2","ds3");
+        }
+        // 无任何条件时扫描所有库
+        return availableTargets;
+    }
+
+
+
+
+
+
+}

+ 51 - 0
mall-service/src/main/java/com/txz/mall/configurer/StorePinkSummaryTableShardingAlgorithm.java

@@ -0,0 +1,51 @@
+package com.txz.mall.configurer;
+
+import org.apache.shardingsphere.api.sharding.complex.ComplexKeysShardingAlgorithm;
+import org.apache.shardingsphere.api.sharding.complex.ComplexKeysShardingValue;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+public class StorePinkSummaryTableShardingAlgorithm implements ComplexKeysShardingAlgorithm<Comparable<?>> {
+
+    @Override
+    public Collection<String> doSharding(Collection<String> availableTargets, ComplexKeysShardingValue<Comparable<?>> shardingValue) {
+        Long userId = getUserId(shardingValue);
+        // 查询时无create_time:扫描所有符合条件的库
+        return filterAllTable(availableTargets, userId);
+    }
+
+
+    private Long getUserId(ComplexKeysShardingValue<Comparable<?>> shardingValue) {
+        Map<String, Collection<Comparable<?>>> values = shardingValue.getColumnNameAndShardingValuesMap();
+//        if (values.containsKey("uid") && !values.get("uid").isEmpty()) {
+//            Long uid = (Long) values.get("uid").iterator().next();
+//            return uid % 10000;
+//        }
+
+        if (values.containsKey("code") && !values.get("code").isEmpty()) {
+            String  orderId = (String) values.get("code").iterator().next();
+            // 提取后4位并转换为long类型
+            String lastFourStr = orderId.substring(orderId.length() - 4);
+            return Long.parseLong(lastFourStr);
+        }
+
+        return null;
+    }
+
+    private Collection<String> filterAllTable(Collection<String> availableTargets, Long userId) {
+        //这个模树要拎出去形成配置项
+        long mod = userId % 5;
+        for (String tableName : availableTargets) {
+            if (tableName.endsWith(String.valueOf(mod))) {
+                List<String> list = Arrays.asList(tableName);
+                return list;
+            }
+        }
+        throw new IllegalArgumentException("未找到匹配的表: " + availableTargets + ", 分片值: " + userId);
+
+    }
+
+}

+ 50 - 0
mall-service/src/main/java/com/txz/mall/configurer/TableShardingAlgorithm.java

@@ -0,0 +1,50 @@
+package com.txz.mall.configurer;
+
+import org.apache.shardingsphere.api.sharding.complex.ComplexKeysShardingAlgorithm;
+import org.apache.shardingsphere.api.sharding.complex.ComplexKeysShardingValue;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+public class TableShardingAlgorithm implements ComplexKeysShardingAlgorithm<Comparable<?>> {
+
+    @Override
+    public Collection<String> doSharding(Collection<String> availableTargets, ComplexKeysShardingValue<Comparable<?>> shardingValue) {
+        Long userId = getUserId(shardingValue);
+        // 查询时无create_time:扫描所有符合条件的库
+        return filterAllTable(availableTargets, userId);
+    }
+
+
+    private Long getUserId(ComplexKeysShardingValue<Comparable<?>> shardingValue) {
+        Map<String, Collection<Comparable<?>>> values = shardingValue.getColumnNameAndShardingValuesMap();
+        if (values.containsKey("uid") && !values.get("uid").isEmpty()) {
+            Long uid = (Long) values.get("uid").iterator().next();
+            return uid % 10000;
+        }
+
+        if (values.containsKey("order_id") && !values.get("order_id").isEmpty()) {
+            String  orderId = (String) values.get("order_id").iterator().next();
+            // 提取后4位并转换为long类型
+            String lastFourStr = orderId.substring(orderId.length() - 4);
+            return Long.parseLong(lastFourStr);
+        }
+
+        return null;
+    }
+
+    private Collection<String> filterAllTable(Collection<String> availableTargets, Long userId) {
+        //这个模树要拎出去形成配置项
+        long mod = userId % 5;
+        for (String tableName : availableTargets) {
+            if (tableName.endsWith(String.valueOf(mod))) {
+                List<String> list = Arrays.asList(tableName);
+                return list;
+            }
+        }
+        throw new IllegalArgumentException("未找到匹配的表: " + availableTargets + ", 分片值: " + userId);
+
+    }
+
+}

+ 27 - 0
mall-service/src/main/java/com/txz/mall/configurer/UidModuloDatabaseShardingAlgorithm.java

@@ -0,0 +1,27 @@
+package com.txz.mall.configurer;
+
+import org.apache.shardingsphere.api.sharding.standard.PreciseShardingAlgorithm;
+import org.apache.shardingsphere.api.sharding.standard.PreciseShardingValue;
+
+import java.util.Collection;
+
+public class UidModuloDatabaseShardingAlgorithm implements PreciseShardingAlgorithm<Long> {
+
+    @Override
+    public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<Long> shardingValue) {
+        // 获取uid值
+        Long uid = shardingValue.getValue();
+        // 取uid后四位
+        long lastFourDigits = uid % 10000;
+        // 对2取模,确定库索引
+        long dbIndex = lastFourDigits % 2;
+
+        // 匹配对应的数据库
+        for (String targetName : availableTargetNames) {
+            if (targetName.endsWith(String.valueOf(dbIndex))) {
+                return targetName;
+            }
+        }
+        throw new IllegalArgumentException("未找到匹配的数据库: " + availableTargetNames + ", uid: " + uid);
+    }
+}

+ 23 - 0
mall-service/src/main/java/com/txz/mall/configurer/UidModuloTableShardingAlgorithm.java

@@ -0,0 +1,23 @@
+package com.txz.mall.configurer;
+
+import org.apache.shardingsphere.api.sharding.standard.PreciseShardingAlgorithm;
+import org.apache.shardingsphere.api.sharding.standard.PreciseShardingValue;
+
+import java.util.Collection;
+
+public class UidModuloTableShardingAlgorithm implements PreciseShardingAlgorithm<Long> {
+
+    @Override
+    public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<Long> shardingValue) {
+        // 获取uid值
+        Long uid = shardingValue.getValue();
+        // 取uid后四位
+        long lastFourDigits = uid % 10000;
+        // 对2取模,确定表索引
+        long tableIndex = lastFourDigits % 2;
+
+        // 匹配对应的表
+        String logicTableName = shardingValue.getLogicTableName();
+        return logicTableName + "_" + tableIndex;
+    }
+}

+ 0 - 32
mall-service/src/main/java/com/txz/mall/configurer/UserIdShardingAlg.java

@@ -1,32 +0,0 @@
-package com.txz.mall.configurer;
-
-import org.apache.shardingsphere.api.sharding.standard.PreciseShardingAlgorithm;
-import org.apache.shardingsphere.api.sharding.standard.PreciseShardingValue;
-
-import java.util.Collection;
-
-public class UserIdShardingAlg implements PreciseShardingAlgorithm<String> {
-    
-    @Override
-    public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<String> shardingValue) {
-        String userId = String.valueOf(shardingValue.getValue());
-        String last4Digits = userId;
-        if (userId.length() >= 4) {
-            last4Digits = userId.substring(userId.length() - 4);
-        }
-        
-        long shardValue = Long.parseLong(last4Digits);
-        
-        String logicTableName = shardingValue.getLogicTableName();
-        if ("c_account_flow".equals(logicTableName) || "c_flow".equals(logicTableName) || "c_red_envelope".equals(logicTableName)) {
-            String dataSource = "ds" + (shardValue % 2);
-            if (availableTargetNames.contains(dataSource)) {
-                return dataSource;
-            }
-            // 兜底
-            return availableTargetNames.iterator().next();
-        } else {
-            return "dsdefault";
-        }
-    }
-}

+ 31 - 0
mall-service/src/main/java/com/txz/mall/configurer/UserIdTableShardingAlgorithm.java

@@ -0,0 +1,31 @@
+package com.txz.mall.configurer;
+
+import org.apache.shardingsphere.api.sharding.standard.PreciseShardingAlgorithm;
+import org.apache.shardingsphere.api.sharding.standard.PreciseShardingValue;
+
+import java.util.Collection;
+
+public class UserIdTableShardingAlgorithm implements PreciseShardingAlgorithm<Long> {
+
+    @Override
+    public String doSharding(Collection<String> availableTargetNames, PreciseShardingValue<Long> shardingValue) {
+
+        long lastFourDigits = getLastFourDigits(shardingValue.getValue());
+        // 用户ID取模5,分配到0-4表
+        long mod = lastFourDigits % 5;
+        for (String tableName : availableTargetNames) {
+            if (tableName.endsWith(String.valueOf(mod))) {
+                return tableName;
+            }
+        }
+        throw new IllegalArgumentException("未找到匹配的表: " + availableTargetNames + ", 分片值: " + shardingValue);
+    }
+
+
+    // 获取user_id后四位
+    private long getLastFourDigits(Long value) {
+        if (value == null ) return 0L;
+        return value % 10000 ;
+    }
+
+}

+ 148 - 0
mall-service/src/main/java/com/txz/mall/configurer/UserSignDatabaseShardingAlgorithm.java

@@ -0,0 +1,148 @@
+package com.txz.mall.configurer;
+
+import org.apache.shardingsphere.api.sharding.complex.ComplexKeysShardingAlgorithm;
+import org.apache.shardingsphere.api.sharding.complex.ComplexKeysShardingValue;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+public class UserSignDatabaseShardingAlgorithm implements ComplexKeysShardingAlgorithm<Comparable<?>> {
+
+
+    private static final SimpleDateFormat SDF = new SimpleDateFormat("yyyy-MM-dd");
+
+    private static final Set<Integer> FIRST_HALF_MONTHS = new HashSet<>(Arrays.asList(1, 2, 3, 4, 5, 6));
+    private static final Set<Integer> SECOND_HALF_MONTHS = new HashSet<>(Arrays.asList(7, 8, 9, 10, 11, 12));
+
+    @Override
+    public Collection<String> doSharding(Collection<String> availableTargets, ComplexKeysShardingValue<Comparable<?>> shardingValue) {
+        // 判断操作类型
+     //   boolean isInsert = isInsertOperation(shardingValue);
+
+        // 提取分片键
+        Date createTime = getCreateTime(shardingValue);
+        Long userId = getUserId(shardingValue);
+
+
+
+        // 插入操作必须包含create_time和user_id
+     //   if (isInsert && (createTime == null || userId == null)) {
+          //  throw new IllegalArgumentException("插入数据必须包含create_time和user_id");
+     //   }
+
+        // 1-6月数据处理(维持原逻辑)
+        if (createTime != null && isFirstHalfYear(createTime)) {
+            return routeFirstHalf(availableTargets, userId);
+        }
+
+        // 7-12月数据处理
+        if (createTime != null && isSecondHalfYear(createTime)) {
+            return routeSecondHalf(availableTargets, userId);
+        }
+
+        // 查询时无create_time:扫描所有符合条件的库
+        return filterAllDatabases(availableTargets, userId);
+    }
+
+    // 1-6月路由逻辑(维持原逻辑:mall_0/mall_1)
+    private Collection<String> routeFirstHalf(Collection<String> availableTargets, Long userId) {
+        if (userId != null) {
+           // String lastFour = getLastFourDigits(userId);
+            long dbIndex = userId % 2; // 0→mall_0,1→mall_1
+            String targetDb = "ds" + dbIndex;
+            if (availableTargets.contains(targetDb)) {
+                return Collections.singleton(targetDb);
+            }
+        }
+        // 查询时无user_id:扫描1-6月的库
+        return Arrays.asList("ds0", "ds1");
+    }
+
+    // 7-12月路由逻辑(mall_1/mall_2)
+    private Collection<String> routeSecondHalf(Collection<String> availableTargets, Long userId) {
+        if (userId != null) {
+            //String lastFour = getLastFourDigits(userId);
+            long dbIndex = 1 + (userId % 2); // 1→mall_1,2→mall_2
+            String targetDb = "ds" + dbIndex;
+            if (availableTargets.contains(targetDb)) {
+                return Collections.singleton(targetDb);
+            }
+        }
+        // 查询时无user_id:扫描7-12月的库
+        return Arrays.asList("ds1", "ds2");
+    }
+
+    // 判断是否为插入操作
+    private boolean isInsertOperation(ComplexKeysShardingValue<?> shardingValue) {
+        //return shardingValue.getSqlType() != null && shardingValue.getSqlType().name().startsWith("INSERT");
+
+        //shardingValue
+        return true;
+    }
+
+    // 提取并解析create_time
+    private Date getCreateTime(ComplexKeysShardingValue<Comparable<?>> shardingValue) {
+        Map<String, Collection<Comparable<?>>> values = shardingValue.getColumnNameAndShardingValuesMap();
+        if (values.containsKey("create_day") && !values.get("create_day").isEmpty()) {
+            Object value = values.get("create_day").iterator().next();
+            if (value instanceof Date) return (Date) value;
+            try {
+                return SDF.parse(value.toString());
+            } catch (ParseException e) {
+                throw new RuntimeException("UserSignDatabaseShardingAlgorithm create_day格式错误,应为yyyy-MM-dd");
+            }
+        }
+
+
+        return null;
+    }
+
+    // 提取user_id
+    private Long getUserId(ComplexKeysShardingValue<Comparable<?>> shardingValue) {
+        Map<String, Collection<Comparable<?>>> values = shardingValue.getColumnNameAndShardingValuesMap();
+        if (values.containsKey("uid") && !values.get("uid").isEmpty()) {
+            Long uid = (Long) values.get("uid").iterator().next();
+            return uid % 10000;
+        }
+
+
+        return null;
+    }
+
+    // 判断是否为1-6月
+    private boolean isFirstHalfYear(Date date) {
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(date);
+        return FIRST_HALF_MONTHS.contains(calendar.get(Calendar.MONTH) + 1);
+    }
+
+    // 判断是否为7-12月
+    private boolean isSecondHalfYear(Date date) {
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(date);
+        return SECOND_HALF_MONTHS.contains(calendar.get(Calendar.MONTH) + 1);
+    }
+
+    // 获取user_id后四位
+    private String getLastFourDigits(String value) {
+        if (value == null || value.isEmpty()) return "0";
+        return value.substring(Math.max(0, value.length() - 4));
+    }
+
+    // 无create_time时的全量库过滤
+    private Collection<String> filterAllDatabases(Collection<String> availableTargets, Long userId) {
+        if (userId != null) {
+            // 有user_id但无时间时,需扫描所有可能的库(mall_0/mall_1/mall_2)
+            return Arrays.asList("ds0", "ds1", "ds2","ds3");
+        }
+        // 无任何条件时扫描所有库
+        return availableTargets;
+    }
+
+
+
+
+
+
+}

+ 44 - 0
mall-service/src/main/java/com/txz/mall/configurer/UserSignTableShardingAlgorithm.java

@@ -0,0 +1,44 @@
+package com.txz.mall.configurer;
+
+import org.apache.shardingsphere.api.sharding.complex.ComplexKeysShardingAlgorithm;
+import org.apache.shardingsphere.api.sharding.complex.ComplexKeysShardingValue;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+public class UserSignTableShardingAlgorithm implements ComplexKeysShardingAlgorithm<Comparable<?>> {
+
+    @Override
+    public Collection<String> doSharding(Collection<String> availableTargets, ComplexKeysShardingValue<Comparable<?>> shardingValue) {
+        Long userId = getUserId(shardingValue);
+        // 查询时无create_time:扫描所有符合条件的库
+        return filterAllTable(availableTargets, userId);
+    }
+
+
+    private Long getUserId(ComplexKeysShardingValue<Comparable<?>> shardingValue) {
+        Map<String, Collection<Comparable<?>>> values = shardingValue.getColumnNameAndShardingValuesMap();
+        if (values.containsKey("uid") && !values.get("uid").isEmpty()) {
+            Long uid = (Long) values.get("uid").iterator().next();
+            return uid % 10000;
+        }
+
+        return null;
+    }
+
+    private Collection<String> filterAllTable(Collection<String> availableTargets, Long userId) {
+        //这个模树要拎出去形成配置项
+        long mod = userId % 5;
+        for (String tableName : availableTargets) {
+            if (tableName.endsWith(String.valueOf(mod))) {
+                List<String> list = Arrays.asList(tableName);
+                return list;
+            }
+        }
+        throw new IllegalArgumentException("未找到匹配的表: " + availableTargets + ", 分片值: " + userId);
+
+    }
+
+}

+ 2 - 2
mall-service/src/main/java/com/txz/mall/controller/OrderController.java

@@ -102,8 +102,8 @@ public class OrderController {
     public Result<StoreOrderVO> detail(@RequestParam(value = "id", required = false) Long id
             ,@RequestParam(value = "orderNo", required = false) String orderNo) {
 
-        if (ObjectUtils.isEmpty(id) && ObjectUtils.isEmpty(orderNo) ) {
-            return Result.fail(ResultCode.ID_IS_NULL);
+        if (ObjectUtils.isEmpty(orderNo) ) {
+            return Result.fail(ResultCode.CODE_IS_NULL);
         }
         StoreOrderVO vo = orderServiceBusiness.orderDetail(id,orderNo);
         return Result.success(vo);

+ 2 - 2
mall-service/src/main/java/com/txz/mall/controller/PinkController.java

@@ -166,8 +166,8 @@ public class PinkController {
      */
     @ApiOperation(value = "拼团订单列表")
     @GetMapping(value = "/orderPink")
-    public Result<List<StorePinkDetailVO>> getPinkList(@RequestParam("id") Long id) {
-        return Result.success(pinkServiceBusiness.getAdminList(id,"pc"));
+    public Result<List<StorePinkDetailVO>> getPinkList(@RequestParam("orderNo") String orderNo) {
+        return Result.success(pinkServiceBusiness.getAdminList(orderNo,"pc"));
     }
 
     /**

+ 2 - 2
mall-service/src/main/java/com/txz/mall/controller/appcontroller/AppOrderController.java

@@ -137,8 +137,8 @@ public class AppOrderController {
     public Result<StoreOrderVO> detail(@RequestParam(value = "id", required = false) Long id
             , @RequestParam(value = "orderNo", required = false) String orderNo) {
         
-        if (ObjectUtils.isEmpty(id) && ObjectUtils.isEmpty(orderNo)) {
-            return Result.fail(ResultCode.ID_IS_NULL);
+        if (ObjectUtils.isEmpty(orderNo)) {
+            return Result.fail(ResultCode.CODE_IS_NULL);
         }
         StoreOrderVO vo = orderServiceBusiness.orderDetail(id, orderNo);
         return Result.success(vo);

+ 2 - 2
mall-service/src/main/java/com/txz/mall/controller/appcontroller/AppPinkController.java

@@ -152,8 +152,8 @@ public class AppPinkController {
      */
     @ApiOperation(value = "拼团订单列表")
     @GetMapping(value = "/orderPink")
-    public Result<List<StorePinkDetailVO>> getPinkList(@RequestParam("id") Long id) {
-        return Result.success(pinkServiceBusiness.getAdminList(id,"app"));
+    public Result<List<StorePinkDetailVO>> getPinkList(@RequestParam("orderNo") String orderNo) {
+        return Result.success(pinkServiceBusiness.getAdminList(orderNo,"app"));
     }
 
     /**

+ 5 - 0
mall-service/src/main/java/com/txz/mall/model/StoreOrderStatus.java

@@ -36,5 +36,10 @@ public class StoreOrderStatus {
     @Column(name = "create_time")
     private Date createTime;
 
+    /**
+     * 订单编码
+     */
+    @Column(name = "order_id")
+    private String orderId;
 
 }

+ 5 - 0
mall-service/src/main/java/com/txz/mall/model/StorePink.java

@@ -183,4 +183,9 @@ public class StorePink {
     @Column(name = "order_status")
     private Integer orderStatus;
 
+
+    @ApiModelProperty(value = "拼团汇总编码")
+    @Column(name = "sps_code")
+    private String spsCode;
+
 }

+ 11 - 1
mall-service/src/main/java/com/txz/mall/model/StorePinkSummary.java

@@ -137,7 +137,11 @@ public class StorePinkSummary {
     @Column(name = "version")
     private Integer version;
 
-
+    /**
+     * 订单编码集合
+     */
+    @Column(name = "order_no_set")
+    private String orderNoSet;
 
     public Integer getVersion() {
         return version;
@@ -506,5 +510,11 @@ public class StorePinkSummary {
         this.code = code;
     }
 
+    public String getOrderNoSet() {
+        return orderNoSet;
+    }
 
+    public void setOrderNoSet(String orderNoSet) {
+        this.orderNoSet = orderNoSet;
+    }
 }

+ 3 - 0
mall-service/src/main/java/com/txz/mall/service/StoreOrderService.java

@@ -174,4 +174,7 @@ public interface StoreOrderService extends Service<StoreOrder> {
 
     List<StoreCombinationRankVO> getRank();
 
+
+
+
 }

+ 2 - 2
mall-service/src/main/java/com/txz/mall/service/StoreOrderStatusService.java

@@ -19,7 +19,7 @@ public interface StoreOrderStatusService extends Service<StoreOrderStatus> {
      * @param message 备注
      * @return Boolean
      */
-    void createLog(Long orderId, String type, String message);
+    void createLog(Long orderId,String orderCode, String type, String message);
 
     /**
      * 获取订单日志
@@ -27,5 +27,5 @@ public interface StoreOrderStatusService extends Service<StoreOrderStatus> {
      * @param orderId 订单id
      * @return List<StoreOrderStatus>
      */
-    List<StoreOrderStatus> getLogList(Long orderId);
+    List<StoreOrderStatus> getLogList(String orderId);
 }

+ 1 - 1
mall-service/src/main/java/com/txz/mall/service/StorePinkSummaryService.java

@@ -12,6 +12,6 @@ public interface StorePinkSummaryService extends Service<StorePinkSummary> {
 
     Boolean maintainQuantityStatusOfTheStorePinkSummary(Long id);
 
-
+    Boolean maintainOrderNoSetOfTheStorePinkSummary(String spsCode,String orderNo);
 
 }

+ 63 - 12
mall-service/src/main/java/com/txz/mall/service/impl/StoreOrderServiceImpl.java

@@ -3,6 +3,7 @@ package com.txz.mall.service.impl;
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.util.IdUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.poi.excel.ExcelUtil;
@@ -39,6 +40,8 @@ import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang.time.DateUtils;
 import org.apache.commons.lang3.StringEscapeUtils;
 import org.apache.commons.lang3.StringUtils;
+import org.apache.ibatis.annotations.SelectKey;
+import org.apache.ibatis.session.ExecutorType;
 import org.springframework.beans.BeanUtils;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Propagation;
@@ -86,6 +89,8 @@ public class StoreOrderServiceImpl extends AbstractService<StoreOrder> implement
     private final StoreOrderStatusService storeOrderStatusService;
     private RedisUtil redisUtil;
     private final CifAccountDubboServiceClient accountDubboServiceClient;
+    @Resource
+    private StoreOrderMapper storeOrderMapper;
 
     @Override
     public StoreOrderCountItemVO getOrderStatusNum() {
@@ -179,7 +184,7 @@ public class StoreOrderServiceImpl extends AbstractService<StoreOrder> implement
         StoreOrder storeOrder = findBy("orderId", orderId);
         if (storeOrder == null) {
             String s = I18nUtil.get("order.does.not.exist");
-            throw new ServiceException(s);
+            throw new ServiceException(s+orderId);
         }
         UserDTO user = userDubboServiceClient.getUser(storeOrder.getUid());
         StorePink storePink = new StorePink();
@@ -210,11 +215,16 @@ public class StoreOrderServiceImpl extends AbstractService<StoreOrder> implement
 
         // 插入拼团汇总表
         StorePinkSummary storePinkSummary = new StorePinkSummary();
+        long storePinkSummaryId = IdUtil.getSnowflake(1, 1).nextId();
+        storePinkSummary.setId(storePinkSummaryId);
         storePinkSummary.setTotalPrice(storeOrder.getTotalPrice());
         storePinkSummary.setCid(storeCombination.getId());
         storePinkSummary.setPid(storeCombination.getProductId());
 
-        String tgCode = OrderUtils.getTGCode();
+        SimpleDateFormat sdf = new SimpleDateFormat("yyMMdd");
+        String formatted = sdf.format(date);
+        String tgCode = OrderUtils.getTGCode(formatted);
+
         storePinkSummary.setCode(tgCode);
         storePinkSummary.setPeople(storeCombination.getPeople());
         storePinkSummary.setAddTime(date);
@@ -225,18 +235,33 @@ public class StoreOrderServiceImpl extends AbstractService<StoreOrder> implement
         storePinkSummary.setIsVirtual(Boolean.TRUE);  // 初始化时直接锁定,防止团长还没支付这个团就暴露出来了。等团长支付时会重新计算是否锁定
         storePinkSummary.setPeopleCount(1);
         storePinkSummary.setStatus(1);
-
-
+        List<String> orderNoSet = new ArrayList<>();
+        orderNoSet.add(orderId);
+        String orderNoSetStr = JSONObject.toJSONString(orderNoSet);
+        storePinkSummary.setOrderNoSet(orderNoSetStr);
         EasyToUseUtil.appCreateAssignment(date, storePinkSummary);
         storePinkSummaryService.save(storePinkSummary);
 
         // 插入拼团详情表
         storePink.setSpsId(storePinkSummary.getId());
+        storePink.setSpsCode(storePinkSummary.getCode());
         storePinkService.save(storePink);
 
         // 如果是开团,需要更新订单数据
         storeOrder.setPinkId(storePink.getId());
-        update(storeOrder);
+
+
+        Example exampleStoreOrder = new Example(StoreOrder.class);
+        exampleStoreOrder.createCriteria().andEqualTo("orderId", orderId);
+        storeOrder.setOrderId(null);
+        storeOrder.setCreateTime(null);
+        storeOrder.setUid(null);
+
+        storeOrderMapper.updateByConditionSelective(storeOrder,exampleStoreOrder);
+        //先清空分片建再设置回去传递到后面,因为分片建不允许更新
+        storeOrder.setOrderId(orderId);
+      //分库分表后下面的修改方式已经不合适了换上上面的方式
+     //   update(storeOrder);
     }
 
     //    @Override
@@ -353,6 +378,7 @@ public class StoreOrderServiceImpl extends AbstractService<StoreOrder> implement
         storePink.setOrderStatus(PinkOrderStatusEnum.GROUP_ORDER_TO_PAY.getKey());
         storePink.setIsRefund(0);
         storePink.setKId(1);
+        storePink.setSpsCode(dto.getSpsCode());
         UserDTO user = userDubboServiceClient.getUser(dto.getUserId());
         if (!ObjectUtils.isEmpty(user)) {
             storePink.setUid(dto.getUserId());
@@ -459,6 +485,7 @@ public class StoreOrderServiceImpl extends AbstractService<StoreOrder> implement
                 log.info("count:" + count);
                 if (count > 0) {
                     dto.setSpsId(pink.getSpsId()); // 拼团汇总表id
+                    dto.setSpsCode(pink.getSpsCode()); //拼团汇总表code
                     joinGroup(pink, dto, count, pinkList.size());
                 } else {
                     throw new ServiceException(I18nUtil.get("the.number.of.group.buying.participants.exceeds.the.limit.please.initiate.group.buying.again.pinkid") + pink.getId());
@@ -575,7 +602,7 @@ public class StoreOrderServiceImpl extends AbstractService<StoreOrder> implement
             Example example = new Example(StoreOrder.class);
             example.createCriteria().andEqualTo("orderId", storeOrder.getOrderId());
             storeOrderMapper.updateByConditionSelective(storeOrderForUpdate, example);
-            storeOrderStatusService.createLog(storeOrder.getId(), Constants.ORDER_STATUS_DELIVERY_ORDER, "订单发货");
+            storeOrderStatusService.createLog(storeOrder.getId(),storeOrder.getOrderId(), Constants.ORDER_STATUS_DELIVERY_ORDER, "订单发货");
 
             // 维护拼团订单状态
             StorePink storePinkForUpdate = new StorePink();
@@ -1500,7 +1527,21 @@ public class StoreOrderServiceImpl extends AbstractService<StoreOrder> implement
     @Resource
     private CreateSequenceService createSequenceService;
 
+    private String getLastFourDigitsOfTheUserId(Long userId){
+        String result = "0000";
+        if(!ObjectUtils.isEmpty(userId)){
+            String userIdStr = userId.toString();
+            if(userIdStr.length()<4){
+                String aa = "0000"+userIdStr;
+                result = aa.substring(aa.length() - 4);
+
+            }
+        }
+        return result;
+    }
+
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public MyRecord createOrder(CreateOrderRequest request) {
         UserDTO user = userDubboServiceClient.getUser(request.getUserId());
         // 通过缓存获取预下单对象
@@ -1555,11 +1596,13 @@ public class StoreOrderServiceImpl extends AbstractService<StoreOrder> implement
         CreateSequence createSequence = new CreateSequence();
         createSequenceService.save(createSequence);
 
+        Long userId = request.getUserId();
+        String lastFourDigitsOfTheUserId = getLastFourDigitsOfTheUserId(userId);
 
         Long id = createSequence.getId();
 
         // 生成订单号
-         String orderNo = OrderUtils.getOrderCode()+ id;
+         String orderNo = OrderUtils.getOrderCode()+ id +lastFourDigitsOfTheUserId;
 
         // 购买赠送的积分
         List<StoreOrderInfo> storeOrderInfos = new ArrayList<>();
@@ -1661,8 +1704,11 @@ public class StoreOrderServiceImpl extends AbstractService<StoreOrder> implement
                 //**   productAttrValueService.operationStock(skuRecord.getInt("attrValueId"), skuRecord.getInt("num"), "sub", Constants.PRODUCT_TYPE_NORMAL);
             }
         }
-
+        Long snowflakeId = IdUtil.getSnowflake(1,1).nextId();
+        storeOrder.setId(snowflakeId);
         save(storeOrder);
+        //SELECT LAST_INSERT_ID() 被路由到默认库去了,只能通过下面到方式解决
+       // storeOrder = findBy("orderId", storeOrder.getOrderId());
         for (StoreOrderInfo storeOrderInfo : storeOrderInfos) {
             storeOrderInfo.setOrderId(storeOrder.getId());
             storeOrderInfo.setIsDelete(0);
@@ -1692,7 +1738,7 @@ public class StoreOrderServiceImpl extends AbstractService<StoreOrder> implement
 
 
         //        // 生成订单日志
-        storeOrderStatusService.createLog(storeOrder.getId(), Constants.ORDER_STATUS_CREATE_ORDER, "订单生成");
+        storeOrderStatusService.createLog(storeOrder.getId(),storeOrder.getOrderId(), Constants.ORDER_STATUS_CREATE_ORDER, "订单生成");
         //
         //        // 清除购物车数据
         //        if (CollUtil.isNotEmpty(orderInfoVo.getCartIdList())) {
@@ -1714,6 +1760,10 @@ public class StoreOrderServiceImpl extends AbstractService<StoreOrder> implement
         return record;
     }
 
+
+
+
+
     @Override
     @Transactional(propagation = Propagation.REQUIRED)
     public com.txz.mall.core.Result goPay(GoPinkDTO dto) {
@@ -2327,8 +2377,7 @@ public class StoreOrderServiceImpl extends AbstractService<StoreOrder> implement
         return recordList;
     }
 
-    @Resource
-    private StoreOrderMapper storeOrderMapper;
+
 
 
     @Override
@@ -2410,7 +2459,7 @@ public class StoreOrderServiceImpl extends AbstractService<StoreOrder> implement
                     storeOrderMapper.updateByConditionSelective(storeOrderForUpdate, example);
 
 
-                    storeOrderStatusService.createLog(storeOrder.getId(), Constants.ORDER_STATUS_RECEIVE_ORDER, I18nUtil.get("automatic.order.receipt.confirmation"));
+                    storeOrderStatusService.createLog(storeOrder.getId(),storeOrder.getOrderId(), Constants.ORDER_STATUS_RECEIVE_ORDER, I18nUtil.get("automatic.order.receipt.confirmation"));
 
                     //维护拼团订单状态
                     StorePink storePinkForUpdate = new StorePink();
@@ -2490,4 +2539,6 @@ public class StoreOrderServiceImpl extends AbstractService<StoreOrder> implement
 
         return null;
     }
+
+
 }

+ 4 - 3
mall-service/src/main/java/com/txz/mall/service/impl/StoreOrderStatusServiceImpl.java

@@ -24,20 +24,21 @@ public class StoreOrderStatusServiceImpl extends AbstractService<StoreOrderStatu
     private StoreOrderStatusMapper storeOrderStatusMapper;
 
     @Override
-    public void createLog(Long orderId, String type, String message) {
+    public void createLog(Long orderId, String orderCode,String type, String message) {
         StoreOrderStatus storeOrderStatus = new StoreOrderStatus();
         storeOrderStatus.setOid(orderId);
         storeOrderStatus.setChangeType(type);
         storeOrderStatus.setChangeMessage(message);
         storeOrderStatus.setCreateTime(new Date());
+        storeOrderStatus.setOrderId(orderCode);
         save(storeOrderStatus);
     }
 
     @Override
-    public List<StoreOrderStatus> getLogList(Long orderId) {
+    public List<StoreOrderStatus> getLogList(String orderId) {
         Condition statusCondition = new Condition(StoreOrderStatus.class);
         Example.Criteria statusCriteria = statusCondition.createCriteria();
-        statusCriteria.andEqualTo("oid", orderId);
+        statusCriteria.andEqualTo("orderId", orderId);
         return findByCondition(statusCondition);
     }
 }

+ 3 - 3
mall-service/src/main/java/com/txz/mall/service/impl/StorePinkServiceImpl.java

@@ -104,7 +104,7 @@ public class StorePinkServiceImpl extends AbstractService<StorePink> implements
         log.info("storePink2:"+storePink2);
         update(storePink2);
 
-        storeOrderStatusService.createLog(storeOrder.getId(), Constants.ORDER_LOG_PAY_SUCCESS, "支付成功");
+        storeOrderStatusService.createLog(storeOrder.getId(), storeOrder.getOrderId(),Constants.ORDER_LOG_PAY_SUCCESS, "支付成功");
         noticeService.addOrderNotice(NoticeEnum.ORDER_GROUP_BUY_PAYMENT_SUCCESS,storeOrder.getOrderId(),storeOrder.getUid());
 
         //累计虚拟销量,虚拟销量和下单数挂钩,和是否退款或者成团或者是否中奖都无关  只累加不扣减
@@ -261,7 +261,7 @@ public class StorePinkServiceImpl extends AbstractService<StorePink> implements
             update(luckPink);
             //推进订单状态到待发货状态
 
-            storeOrderStatusService.createLog(storeOrder.getId(), Constants.ORDER_STATUS_PINK_SUCCESS_ORDER, "拼团成功");
+            storeOrderStatusService.createLog(storeOrder.getId(), storeOrder.getOrderId(),Constants.ORDER_STATUS_PINK_SUCCESS_ORDER, "拼团成功");
             noticeService.addOrderNotice(NoticeEnum.ORDER_GROUP_BUY_SUCCESS_WIN,storeOrder.getOrderId(),storeOrder.getUid());
             //中奖者
             param.setWinnerOrderNo(storeOrder.getOrderId());
@@ -299,7 +299,7 @@ public class StorePinkServiceImpl extends AbstractService<StorePink> implements
             log.info("storeOrderService.updateOrderStatus"+JSONObject.toJSONString(a));
 
             storeOrderService.updateOrderStatus(a.getOrderIdKey(),pinkOrderStatusEnum.getKey());
-            storeOrderStatusService.createLog(storeOrder.getId(), Constants.ORDER_STATUS_PINK_SUCCESS_ORDER, "拼团成功");
+            storeOrderStatusService.createLog(storeOrder.getId(),storeOrder.getOrderId(),Constants.ORDER_STATUS_PINK_SUCCESS_ORDER, "拼团成功");
             noticeService.addOrderNotice(NoticeEnum.ORDER_GROUP_BUY_SUCCESS_LOSE,storeOrder.getOrderId(),storeOrder.getUid());
 
             //库存回退

+ 34 - 0
mall-service/src/main/java/com/txz/mall/service/impl/StorePinkSummaryServiceImpl.java

@@ -1,5 +1,6 @@
 package com.txz.mall.service.impl;
 
+import com.alibaba.fastjson.JSONObject;
 import com.txz.mall.core.ServiceException;
 import com.txz.mall.dao.StorePinkMapper;
 import com.txz.mall.dao.StorePinkSummaryMapper;
@@ -18,7 +19,9 @@ import tk.mybatis.mapper.entity.Condition;
 import tk.mybatis.mapper.entity.Example;
 
 import javax.annotation.Resource;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 
 /**
@@ -148,4 +151,35 @@ public class StorePinkSummaryServiceImpl extends AbstractService<StorePinkSummar
 
        return successFlag;
     }
+
+
+    @Override
+    public Boolean maintainOrderNoSetOfTheStorePinkSummary(String spsCode, String orderNo) {
+
+        Condition storePinkSummarycCondition = new Condition(StorePinkSummary.class);
+        storePinkSummarycCondition.createCriteria().andEqualTo("spsCode",spsCode);
+        List<StorePinkSummary> storePinkSummaries = mStorePinkSummaryMapper.selectByCondition(storePinkSummarycCondition);
+        if(CollectionUtils.isEmpty(storePinkSummaries)){
+            throw new ServiceException(I18nUtil.get("group.buying.summary.does.not.exist.id")+spsCode);
+        }
+        StorePinkSummary storePinkSummary = storePinkSummaries.get(0);
+
+        String orderNoSet = storePinkSummary.getOrderNoSet();
+        Set<String> resultSet = new HashSet<>();
+
+        if(!ObjectUtils.isEmpty(orderNoSet)){
+            List<String> orderNoSetList = JSONObject.parseArray(orderNoSet, String.class);
+            boolean b = resultSet.addAll(orderNoSetList);
+            resultSet.add(orderNo);
+        }
+        if(!ObjectUtils.isEmpty(resultSet)){
+            StorePinkSummary storePinkSummaryForUpdate = new StorePinkSummary();
+            storePinkSummaryForUpdate.setOrderNoSet(JSONObject.toJSONString(resultSet));
+            mStorePinkSummaryMapper.updateByConditionSelective(storePinkSummaryForUpdate,storePinkSummarycCondition);
+        }else{
+            throw new ServiceException(I18nUtil.get("store.pink.summary.order.no.set.not.exist")+spsCode);
+        }
+
+        return true;
+    }
 }

+ 8 - 4
mall-service/src/main/java/com/txz/mall/service/impl/UserSignServiceImpl.java

@@ -111,7 +111,8 @@ public class UserSignServiceImpl extends AbstractService<UserSign> implements Us
         Condition condition = new Condition(UserSign.class);
         Example.Criteria criteria = condition.createCriteria();
         criteria.andEqualTo("uid", uid);
-        criteria.andLike("createDay", new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + "%");
+        criteria.andEqualTo("createDay", new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
+       // criteria.andLike("createDay", new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + "%");
         return !userSignMapper.selectByCondition(condition).isEmpty();
     }
 
@@ -121,7 +122,8 @@ public class UserSignServiceImpl extends AbstractService<UserSign> implements Us
         Condition condition = new Condition(UserSign.class);
         Example.Criteria criteria = condition.createCriteria();
         criteria.andEqualTo("uid", uid);
-        criteria.andLike("createDay", new SimpleDateFormat("yyyy-MM-dd").format(yesterday) + "%");
+        criteria.andEqualTo("createDay", new SimpleDateFormat("yyyy-MM-dd").format(yesterday));
+       // criteria.andLike("createDay", new SimpleDateFormat("yyyy-MM-dd").format(yesterday) + "%");
         condition.setOrderByClause("id desc");
         List<UserSign> list = userSignMapper.selectByCondition(condition);
         return list.isEmpty() ? null : list.get(0);
@@ -148,10 +150,12 @@ public class UserSignServiceImpl extends AbstractService<UserSign> implements Us
         criteria.andEqualTo("uid", userId);
         Date date = new Date();
         if(hasSignedToday) {
-            criteria.andLike("createDay", new SimpleDateFormat("yyyy-MM-dd").format(date) + "%");
+            //criteria.andLike("createDay", new SimpleDateFormat("yyyy-MM-dd").format(date) + "%");
+            criteria.andEqualTo("createDay", new SimpleDateFormat("yyyy-MM-dd").format(date));
         }else{
             DateTime dateTime = DateUtil.offsetDay(date, -1);
-            criteria.andLike("createDay", new SimpleDateFormat("yyyy-MM-dd").format(dateTime) + "%");
+           // criteria.andLike("createDay", new SimpleDateFormat("yyyy-MM-dd").format(dateTime) + "%");
+            criteria.andEqualTo("createDay", new SimpleDateFormat("yyyy-MM-dd").format(dateTime));
         }
         condition.orderBy("id").desc();
 

+ 2 - 3
mall-service/src/main/java/com/txz/mall/util/OrderUtils.java

@@ -110,8 +110,8 @@ public class OrderUtils {
      * 团购编码
      * @return
      */
-    public static String getTGCode() {
-        return TG_CODE + getCode();
+    public static String getTGCode(String prefix) {
+        return TG_CODE + prefix + getCode() % 10000;
     }
 
 
@@ -119,7 +119,6 @@ public class OrderUtils {
     /**
      * 生成订单单号编码(调用方法)
      */
-
     public static String getOrderCode() {
 
         DateFormat sdf = new SimpleDateFormat("yyMMdd");

+ 4 - 0
mall-service/src/main/java/dto/GoPinkDTO.java

@@ -37,4 +37,8 @@ public class GoPinkDTO implements Serializable {
     @ApiModelProperty(value = "m_store_order.id")
     private Long orderIdKey;
 
+    //这个变量作为后端数据传递的变量前端无需感知
+    @ApiModelProperty(value = "m_store_pink.sps_code")
+    private String spsCode;
+
 }

+ 2 - 0
mall-service/src/main/java/vo/StorePinkDetailVO.java

@@ -69,4 +69,6 @@ public class StorePinkDetailVO implements Serializable {
     private Long spsId;
     @ApiModelProperty(value = "团长id 0为团长")
     private Integer kId;
+    @ApiModelProperty(value = "拼团汇总表编码")
+    private String spsCode;
 }

+ 1 - 14
mall-service/src/main/resources/bootstrap.properties

@@ -127,19 +127,6 @@ spring.datasource.hikari.pool-name=DatebookHikariCP
 spring.datasource.hikari.max-lifetime=28740000
 spring.datasource.hikari.connection-test-query=SELECT 1
 
+spring.main.allow-bean-definition-overriding=true
 
 
-sharding.datasource.ds0.driver-class-name=com.mysql.jdbc.Driver
-sharding.datasource.ds0.jdbc-url=jdbc:mysql://124.222.152.234:3306/cif_0?serverTimezone=GMT%2b8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false
-sharding.datasource.ds0.username=root
-sharding.datasource.ds0.password=hy123456
-
-sharding.datasource.ds1.driver-class-name=com.mysql.jdbc.Driver
-sharding.datasource.ds1.jdbc-url=jdbc:mysql://124.222.152.234:3306/cif_1?serverTimezone=GMT%2b8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false
-sharding.datasource.ds1.username=root
-sharding.datasource.ds1.password=hy123456
-
-sharding.datasource.dsdefault.driver-class-name=com.mysql.jdbc.Driver
-sharding.datasource.dsdefault.jdbc-url=jdbc:mysql://124.222.152.234:3306/cif?serverTimezone=GMT%2b8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false
-sharding.datasource.dsdefault.username=root
-sharding.datasource.dsdefault.password=hy123456

+ 4 - 1
mall-service/src/main/resources/i18n/messages_en_US.properties

@@ -166,4 +166,7 @@ does.not.exist=does not exist
 internal.error.please.contact.the.administrator=internal error please contact the administrator
 exception.occurred=exception occurred
 method=method
-exception.summary=exception summary:
+exception.summary=exception summary:
+yixiashixinzengshuju
+the.group.buying.summary.data.does.not.exist=the group buying summary data does not exist
+store.pink.summary.order.no.set.not.exist=store pink summary order no set not exist

+ 2 - 1
mall-service/src/main/resources/i18n/messages_zh_CN.properties

@@ -164,5 +164,6 @@ internal.error.please.contact.the.administrator=\u5185\u90E8\u5F02\u5E38\uFF0C\u
 exception.occurred=\u53D1\u751F\u5F02\u5E38
 method=\u65B9\u6CD5
 exception.summary=\u5F02\u5E38\u6982\u8981:
-
+the.group.buying.summary.data.does.not.exist=\u62FC\u56E2\u6C47\u603B\u6570\u636E\u4E0D\u5B58\u5728
+store.pink.summary.order.no.set.not.exist=\u62FC\u56E2\u6C47\u603B\u8868\u65E0\u8BA2\u5355\u7F16\u7801\u96C6