From b09e3bae766504987270418d793909bb326a1a1c Mon Sep 17 00:00:00 2001 From: zhangsan <646228430@qq.com> Date: Fri, 27 Jun 2025 13:19:13 +0800 Subject: [PATCH] =?UTF-8?q?6.27=20=E6=8B=86=E5=88=86=E6=B4=BB=E5=8A=A8?= =?UTF-8?q?=E8=A1=A8=EF=BC=8C=E8=A7=A3=E8=80=A6=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mysql/sql/0626group_buying_sys.sql | 304 +++++++++--------- .../mapper/group_buy_activity_mapper.xml | 16 +- .../mybatis/mapper/sc_sku_activity_mapper.xml | 21 ++ .../IIndexGroupBuyMarketServiceTest.java | 12 + .../repository/IActivityRepository.java | 5 +- .../model/valobj/SCSkuActivityVO.java | 26 ++ .../activity/service/trial/node/EndNode.java | 2 +- .../service/trial/node/ErrorNode.java | 38 +++ .../service/trial/node/MarketNode.java | 41 ++- ...yGroupBuyActivityDiscountVOThreadTask.java | 20 +- .../repository/ActivityRepository.java | 50 ++- .../dao/IGroupBuyActivityDao.java | 2 + .../infrastructure/dao/ISCSkuActivityDao.java | 13 + .../dao/po/GroupBuyActivity.java | 6 - .../infrastructure/dao/po/SCSkuActivity.java | 34 ++ .../infrastructure/redis/IRedisService.java | 61 ++-- .../AbstractMultiThreadStrategyRouter.java | 18 +- .../edu/whut/types/enums/ResponseCode.java | 1 + 18 files changed, 455 insertions(+), 215 deletions(-) create mode 100644 group-buying-sys-app/src/main/resources/mybatis/mapper/sc_sku_activity_mapper.xml create mode 100644 group-buying-sys-domain/src/main/java/edu/whut/domain/activity/model/valobj/SCSkuActivityVO.java create mode 100644 group-buying-sys-domain/src/main/java/edu/whut/domain/activity/service/trial/node/ErrorNode.java create mode 100644 group-buying-sys-infrastructure/src/main/java/edu/whut/infrastructure/dao/ISCSkuActivityDao.java create mode 100644 group-buying-sys-infrastructure/src/main/java/edu/whut/infrastructure/dao/po/SCSkuActivity.java diff --git a/docs/dev-ops/mysql/sql/0626group_buying_sys.sql b/docs/dev-ops/mysql/sql/0626group_buying_sys.sql index 61e4004..90689f0 100644 --- a/docs/dev-ops/mysql/sql/0626group_buying_sys.sql +++ b/docs/dev-ops/mysql/sql/0626group_buying_sys.sql @@ -3,163 +3,169 @@ SET NAMES utf8mb4; CREATE database if NOT EXISTS `group_buying_sys` default character set utf8mb4 collate utf8mb4_0900_ai_ci; use `group_buying_sys`; - -DROP TABLE IF EXISTS `group_buy_activity`; - ---拼团活动表 -CREATE TABLE `group_buy_activity` ( - `id` bigint(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增', - `activity_id` bigint(8) NOT NULL COMMENT '活动ID', - `activity_name` varchar(128) NOT NULL COMMENT '活动名称', - `source` varchar(8) NOT NULL COMMENT '来源', - `channel` varchar(8) NOT NULL COMMENT '渠道', - `goods_id` varchar(12) NOT NULL COMMENT '商品ID', - `discount_id` varchar(8) NOT NULL COMMENT '折扣ID', - `group_type` tinyint(1) NOT NULL DEFAULT '0' COMMENT '拼团方式(0自动成团、1达成目标拼团)', - `take_limit_count` int(4) NOT NULL DEFAULT '1' COMMENT '拼团次数限制', - `target` int(5) NOT NULL DEFAULT '1' COMMENT '拼团目标', - `valid_time` int(4) NOT NULL DEFAULT '15' COMMENT '拼团时长(分钟)', - `status` tinyint(1) NOT NULL DEFAULT '0' COMMENT '活动状态(0创建、1生效、2过期、3废弃)', - `start_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '活动开始时间', - `end_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '活动结束时间', - `tag_id` varchar(32) DEFAULT NULL COMMENT '人群标签规则标识', - `tag_scope` varchar(4) DEFAULT NULL COMMENT '人群标签规则范围(多选;1可见限制、2参与限制)', - `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', - PRIMARY KEY (`id`), - UNIQUE KEY `uq_activity_id` (`activity_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='拼团活动'; - -LOCK TABLES `group_buy_activity` WRITE; - -INSERT INTO `group_buy_activity` (`id`, `activity_id`, `activity_name`, `source`, `channel`, `goods_id`, `discount_id`, `group_type`, `take_limit_count`, `target`, `valid_time`, `status`, `start_time`, `end_time`, `tag_id`, `tag_scope`, `create_time`, `update_time`) -VALUES - (1,100123,'测试活动','s01','c01','9890001','25120207',0,1,1,15,0,'2025-06-19 10:19:40','2025-06-19 10:19:40','1','1','2025-06-19 10:19:40','2025-06-19 11:47:27'); - -UNLOCK TABLES; - - -DROP TABLE IF EXISTS `group_buy_discount`; ---折扣配置表 -CREATE TABLE `group_buy_discount` ( - `id` bigint(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增ID', - `discount_id` int(8) NOT NULL COMMENT '折扣ID', - `discount_name` varchar(64) NOT NULL COMMENT '折扣标题', - `discount_desc` varchar(256) NOT NULL COMMENT '折扣描述', - `discount_type` tinyint(1) NOT NULL DEFAULT '0' COMMENT '折扣类型(0:base、1:tag)', - `market_plan` varchar(4) NOT NULL DEFAULT 'ZJ' COMMENT '营销优惠计划(ZJ:直减、MJ:满减、ZK:折扣、N元购)', - `market_expr` varchar(32) NOT NULL COMMENT '营销优惠表达式', - `tag_id` varchar(8) DEFAULT NULL COMMENT '人群标签,特定优惠限定', - `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', - PRIMARY KEY (`id`), - UNIQUE KEY `uq_discount_id` (`discount_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; - -LOCK TABLES `group_buy_discount` WRITE; - -INSERT INTO `group_buy_discount` (`id`, `discount_id`, `discount_name`, `discount_desc`, `discount_type`, `market_plan`, `market_expr`, `tag_id`, `create_time`, `update_time`) -VALUES - (1,'25120207','直减优惠20元','直减优惠20元',0,'ZJ','20',NULL,'2025-06-25 14:02:13','2025-06-25 14:02:13'), - (2,'25120208','满减优惠100-10元','满减优惠100-10元',0,'MJ','100,10',NULL,'2025-06-25 14:02:13','2025-06-25 14:02:13'), - (4,'25120209','折扣优惠8折','折扣优惠8折',0,'ZK','0.8',NULL,'2025-06-25 14:02:13','2025-06-25 14:02:13'), - (5,'25120210','N元购买优惠','N元购买优惠',0,'N','1.99',NULL,'2025-06-25 14:02:13','2025-06-25 14:02:13'); - -UNLOCK TABLES; - - -DROP TABLE IF EXISTS `sku`; - -CREATE TABLE `sku` ( - `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增ID', - `source` varchar(8) NOT NULL COMMENT '渠道', - `channel` varchar(8) NOT NULL COMMENT '来源', - `goods_id` varchar(16) NOT NULL COMMENT '商品ID', - `goods_name` varchar(128) NOT NULL COMMENT '商品名称', - `original_price` decimal(10,2) NOT NULL COMMENT '商品价格', - `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', - PRIMARY KEY (`id`), - UNIQUE KEY `uq_goods_id` (`goods_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商品信息'; - -LOCK TABLES `sku` WRITE; - -INSERT INTO `sku` (`id`, `source`, `channel`, `goods_id`, `goods_name`, `original_price`, `create_time`, `update_time`) -VALUES - (1,'s01','c01','9890001','《手写MyBatis:渐进式源码实践》',100.00,'2025-06-22 11:10:06','2025-06-22 11:10:06'); - -UNLOCK TABLES; - - --- 人群标签表 +-- ---------------------------- +-- Table structure for crowd_tags +-- ---------------------------- DROP TABLE IF EXISTS `crowd_tags`; +CREATE TABLE `crowd_tags` ( + `id` int UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '自增ID', + `tag_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '人群ID', + `tag_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '人群名称', + `tag_desc` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '人群描述', + `statistics` int NOT NULL COMMENT '人群标签统计量', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `uq_tag_id`(`tag_id` ASC) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '人群标签' ROW_FORMAT = Dynamic; -CREATE TABLE `crowd_tags` ( - `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增ID', - `tag_id` varchar(32) NOT NULL COMMENT '人群ID', - `tag_name` varchar(64) NOT NULL COMMENT '人群名称', - `tag_desc` varchar(256) NOT NULL COMMENT '人群描述', - `statistics` int(8) NOT NULL COMMENT '人群标签统计量', - `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', - PRIMARY KEY (`id`), - UNIQUE KEY `uq_tag_id` (`tag_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='人群标签'; +-- ---------------------------- +-- Records of crowd_tags +-- ---------------------------- +INSERT INTO `crowd_tags` VALUES (1, 'RQ_KJHKL98UU78H66554GFDV', '潜在消费用户', '潜在消费用户', 8, '2025-06-26 09:12:22', '2025-06-26 11:47:01'); -LOCK TABLES `crowd_tags` WRITE; - -INSERT INTO `crowd_tags` (`id`, `tag_id`, `tag_name`, `tag_desc`, `statistics`, `create_time`, `update_time`) -VALUES - (1,'RQ_KJHKL98UU78H66554GFDV','潜在消费用户','潜在消费用户',6,'2025-06-26 09:12:22','2025-06-26 09:12:22'); - -UNLOCK TABLES; - - --- 人群标签明细表 +-- ---------------------------- +-- Table structure for crowd_tags_detail +-- ---------------------------- DROP TABLE IF EXISTS `crowd_tags_detail`; +CREATE TABLE `crowd_tags_detail` ( + `id` int UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '自增ID', + `tag_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '人群ID', + `user_id` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '用户ID', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `uq_tag_user`(`tag_id` ASC, `user_id` ASC) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 6 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '人群标签明细' ROW_FORMAT = Dynamic; -CREATE TABLE `crowd_tags_detail` ( - `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增ID', - `tag_id` varchar(32) NOT NULL COMMENT '人群ID', - `user_id` varchar(16) NOT NULL COMMENT '用户ID', - `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', - PRIMARY KEY (`id`), - UNIQUE KEY `uq_tag_user` (`tag_id`,`user_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='人群标签明细'; - -LOCK TABLES `crowd_tags_detail` WRITE; - -INSERT INTO `crowd_tags_detail` (`id`, `tag_id`, `user_id`, `create_time`, `update_time`) -VALUES - (4,'RQ_KJHKL98UU78H66554GFDV','zy123','2025-06-26 09:08:31','2025-06-26 09:08:31'), - (5,'RQ_KJHKL98UU78H66554GFDV','smile','2025-06-26 09:09:54','2025-06-26 09:09:54'); - -UNLOCK TABLES; +-- ---------------------------- +-- Records of crowd_tags_detail +-- ---------------------------- +INSERT INTO `crowd_tags_detail` VALUES (4, 'RQ_KJHKL98UU78H66554GFDV', 'zy123', '2025-06-26 09:08:31', '2025-06-26 09:08:31'); +INSERT INTO `crowd_tags_detail` VALUES (5, 'RQ_KJHKL98UU78H66554GFDV', 'smile', '2025-06-26 09:09:54', '2025-06-26 09:09:54'); +-- ---------------------------- +-- Table structure for crowd_tags_job +-- ---------------------------- DROP TABLE IF EXISTS `crowd_tags_job`; +CREATE TABLE `crowd_tags_job` ( + `id` int UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '自增ID', + `tag_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '标签ID', + `batch_id` varchar(8) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '批次ID', + `tag_type` tinyint(1) NOT NULL DEFAULT 1 COMMENT '标签类型(参与量、消费金额)', + `tag_rule` varchar(8) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '标签规则(限定类型 N次)', + `stat_start_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '统计数据,开始时间', + `stat_end_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '统计数据,结束时间', + `status` tinyint(1) NOT NULL DEFAULT 0 COMMENT '状态;0初始、1计划(进入执行阶段)、2重置、3完成', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `uq_batch_id`(`batch_id` ASC) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '人群标签任务' ROW_FORMAT = Dynamic; --- 人群标签任务表 -CREATE TABLE `crowd_tags_job` ( - `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增ID', - `tag_id` varchar(32) NOT NULL COMMENT '标签ID', - `batch_id` varchar(8) NOT NULL COMMENT '批次ID', - `tag_type` tinyint(1) NOT NULL DEFAULT '1' COMMENT '标签类型(参与量、消费金额)', - `tag_rule` varchar(8) NOT NULL COMMENT '标签规则(限定类型 N次)', - `stat_start_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '统计数据,开始时间', - `stat_end_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '统计数据,结束时间', - `status` tinyint(1) NOT NULL DEFAULT '0' COMMENT '状态;0初始、1计划(进入执行阶段)、2重置、3完成', - `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', - `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', - PRIMARY KEY (`id`), - UNIQUE KEY `uq_batch_id` (`batch_id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='人群标签任务'; +-- ---------------------------- +-- Records of crowd_tags_job +-- ---------------------------- +INSERT INTO `crowd_tags_job` VALUES (1, 'RQ_KJHKL98UU78H66554GFDV', '10001', 0, '100', '2025-06-26 09:13:31', '2025-06-26 09:13:31', 0, '2025-06-26 09:13:31', '2025-06-26 09:13:31'); -LOCK TABLES `crowd_tags_job` WRITE; +-- ---------------------------- +-- Table structure for group_buy_activity +-- ---------------------------- +DROP TABLE IF EXISTS `group_buy_activity`; +CREATE TABLE `group_buy_activity` ( + `id` bigint UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '自增', + `activity_id` bigint NOT NULL COMMENT '活动ID', + `activity_name` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '活动名称', + `discount_id` varchar(8) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '折扣ID', + `group_type` tinyint(1) NOT NULL DEFAULT 0 COMMENT '拼团方式(0自动成团、1达成目标拼团)', + `take_limit_count` int NOT NULL DEFAULT 1 COMMENT '拼团次数限制', + `target` int NOT NULL DEFAULT 1 COMMENT '拼团目标', + `valid_time` int NOT NULL DEFAULT 15 COMMENT '拼团时长(分钟)', + `status` tinyint(1) NOT NULL DEFAULT 0 COMMENT '活动状态(0创建、1生效、2过期、3废弃)', + `start_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '活动开始时间', + `end_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '活动结束时间', + `tag_id` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '人群标签规则标识', + `tag_scope` varchar(4) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '人群标签规则范围(多选;1可见限制、2参与限制)', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `uq_activity_id`(`activity_id` ASC) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '拼团活动' ROW_FORMAT = Dynamic; -INSERT INTO `crowd_tags_job` (`id`, `tag_id`, `batch_id`, `tag_type`, `tag_rule`, `stat_start_time`, `stat_end_time`, `status`, `create_time`, `update_time`) -VALUES - (1,'RQ_KJHKL98UU78H66554GFDV','10001',0,'100','2025-06-26 09:13:31','2025-06-26 09:13:31',0,'2025-06-26 09:13:31','2025-06-26 09:13:31'); +-- ---------------------------- +-- Records of group_buy_activity +-- ---------------------------- +INSERT INTO `group_buy_activity` VALUES (1, 100123, '测试活动', '25120207', 0, 1, 1, 15, 1, '2025-06-19 10:19:40', '2025-06-19 10:19:40', '1', '1', '2025-06-19 10:19:40', '2025-06-26 15:27:48'); + +-- ---------------------------- +-- Table structure for group_buy_discount +-- ---------------------------- +DROP TABLE IF EXISTS `group_buy_discount`; +CREATE TABLE `group_buy_discount` ( + `id` bigint UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '自增ID', + `discount_id` int NOT NULL COMMENT '折扣ID', + `discount_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '折扣标题', + `discount_desc` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '折扣描述', + `discount_type` tinyint(1) NOT NULL DEFAULT 0 COMMENT '折扣类型(0:base、1:tag)', + `market_plan` varchar(4) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT 'ZJ' COMMENT '营销优惠计划(ZJ:直减、MJ:满减、ZK:折扣、N元购)', + `market_expr` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '营销优惠表达式', + `tag_id` varchar(8) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '人群标签,特定优惠限定', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `uq_discount_id`(`discount_id` ASC) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 6 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '折扣配置' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of group_buy_discount +-- ---------------------------- +INSERT INTO `group_buy_discount` VALUES (1, 25120207, '直减优惠20元', '直减优惠20元', 0, 'ZJ', '20', NULL, '2025-06-25 14:02:13', '2025-06-25 14:02:13'); +INSERT INTO `group_buy_discount` VALUES (2, 25120208, '满减优惠100-10元', '满减优惠100-10元', 0, 'MJ', '100,10', NULL, '2025-06-25 14:02:13', '2025-06-25 14:02:13'); +INSERT INTO `group_buy_discount` VALUES (4, 25120209, '折扣优惠8折', '折扣优惠8折', 0, 'ZK', '0.8', NULL, '2025-06-25 14:02:13', '2025-06-25 14:02:13'); +INSERT INTO `group_buy_discount` VALUES (5, 25120210, 'N元购买优惠', 'N元购买优惠', 0, 'N', '1.99', NULL, '2025-06-25 14:02:13', '2025-06-25 14:02:13'); + +-- ---------------------------- +-- Table structure for sc_sku_activity +-- ---------------------------- +DROP TABLE IF EXISTS `sc_sku_activity`; +CREATE TABLE `sc_sku_activity` ( + `id` int UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '自增ID', + `source` varchar(8) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '渠道', + `channel` varchar(8) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '来源', + `activity_id` bigint NOT NULL COMMENT '活动ID', + `goods_id` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '商品ID', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `uq_sc_goodsid`(`source` ASC, `channel` ASC, `goods_id` ASC) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '渠道商品活动配置关联表' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sc_sku_activity +-- ---------------------------- +INSERT INTO `sc_sku_activity` VALUES (1, 's01', 'c01', 100123, '9890001', '2025-06-26 17:15:54', '2025-06-26 17:15:54'); + +-- ---------------------------- +-- Table structure for sku +-- ---------------------------- +DROP TABLE IF EXISTS `sku`; +CREATE TABLE `sku` ( + `id` int UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '自增ID', + `source` varchar(8) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '渠道', + `channel` varchar(8) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '来源', + `goods_id` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '商品ID', + `goods_name` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '商品名称', + `original_price` decimal(10, 2) NOT NULL COMMENT '商品价格', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + PRIMARY KEY (`id`) USING BTREE, + UNIQUE INDEX `uq_goods_id`(`goods_id` ASC) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '商品信息' ROW_FORMAT = Dynamic; + +-- ---------------------------- +-- Records of sku +-- ---------------------------- +INSERT INTO `sku` VALUES (1, 's01', 'c01', '9890001', '《手写MyBatis:渐进式源码实践》', 100.00, '2025-06-22 11:10:06', '2025-06-22 11:10:06'); + +SET FOREIGN_KEY_CHECKS = 1; -UNLOCK TABLES; diff --git a/group-buying-sys-app/src/main/resources/mybatis/mapper/group_buy_activity_mapper.xml b/group-buying-sys-app/src/main/resources/mybatis/mapper/group_buy_activity_mapper.xml index ee6ccf4..d55e266 100644 --- a/group-buying-sys-app/src/main/resources/mybatis/mapper/group_buy_activity_mapper.xml +++ b/group-buying-sys-app/src/main/resources/mybatis/mapper/group_buy_activity_mapper.xml @@ -6,9 +6,6 @@ - - - @@ -29,13 +26,20 @@ + + diff --git a/group-buying-sys-app/src/main/resources/mybatis/mapper/sc_sku_activity_mapper.xml b/group-buying-sys-app/src/main/resources/mybatis/mapper/sc_sku_activity_mapper.xml new file mode 100644 index 0000000..bf469df --- /dev/null +++ b/group-buying-sys-app/src/main/resources/mybatis/mapper/sc_sku_activity_mapper.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + diff --git a/group-buying-sys-app/src/test/java/edu/whut/test/domain/activity/IIndexGroupBuyMarketServiceTest.java b/group-buying-sys-app/src/test/java/edu/whut/test/domain/activity/IIndexGroupBuyMarketServiceTest.java index 72210b9..2a6a23a 100644 --- a/group-buying-sys-app/src/test/java/edu/whut/test/domain/activity/IIndexGroupBuyMarketServiceTest.java +++ b/group-buying-sys-app/src/test/java/edu/whut/test/domain/activity/IIndexGroupBuyMarketServiceTest.java @@ -36,4 +36,16 @@ public class IIndexGroupBuyMarketServiceTest { log.info("返回结果:{}", JSON.toJSONString(trialBalanceEntity)); } + @Test + public void test_indexMarketTrial_error() throws Exception { + MarketProductEntity marketProductEntity = new MarketProductEntity(); + marketProductEntity.setUserId("smile"); + marketProductEntity.setSource("s01"); + marketProductEntity.setChannel("c01"); + marketProductEntity.setGoodsId("9890002"); + + TrialBalanceEntity trialBalanceEntity = indexGroupBuyMarketService.indexMarketTrial(marketProductEntity); + log.info("请求参数:{}", JSON.toJSONString(marketProductEntity)); + log.info("返回结果:{}", JSON.toJSONString(trialBalanceEntity)); + } } diff --git a/group-buying-sys-domain/src/main/java/edu/whut/domain/activity/adapter/repository/IActivityRepository.java b/group-buying-sys-domain/src/main/java/edu/whut/domain/activity/adapter/repository/IActivityRepository.java index 183ad90..d19e310 100644 --- a/group-buying-sys-domain/src/main/java/edu/whut/domain/activity/adapter/repository/IActivityRepository.java +++ b/group-buying-sys-domain/src/main/java/edu/whut/domain/activity/adapter/repository/IActivityRepository.java @@ -1,5 +1,6 @@ package edu.whut.domain.activity.adapter.repository; import edu.whut.domain.activity.model.valobj.GroupBuyActivityDiscountVO; +import edu.whut.domain.activity.model.valobj.SCSkuActivityVO; import edu.whut.domain.activity.model.valobj.SkuVO; /** @@ -7,8 +8,10 @@ import edu.whut.domain.activity.model.valobj.SkuVO; */ public interface IActivityRepository { - GroupBuyActivityDiscountVO queryGroupBuyActivityDiscountVO(String source, String channel); + GroupBuyActivityDiscountVO queryGroupBuyActivityDiscountVO(Long activityId); SkuVO querySkuByGoodsId(String goodsId); + SCSkuActivityVO querySCSkuActivityBySCGoodsId(String source, String channel, String goodsId); + } diff --git a/group-buying-sys-domain/src/main/java/edu/whut/domain/activity/model/valobj/SCSkuActivityVO.java b/group-buying-sys-domain/src/main/java/edu/whut/domain/activity/model/valobj/SCSkuActivityVO.java new file mode 100644 index 0000000..4796e1f --- /dev/null +++ b/group-buying-sys-domain/src/main/java/edu/whut/domain/activity/model/valobj/SCSkuActivityVO.java @@ -0,0 +1,26 @@ +package edu.whut.domain.activity.model.valobj; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +/** + * 渠道商品活动配置值对象 + */ +@Getter +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class SCSkuActivityVO { + + /** 渠道 */ + private String source; + /** 来源 */ + private String chanel; + /** 活动ID */ + private Long activityId; + /** 商品ID */ + private String goodsId; + +} diff --git a/group-buying-sys-domain/src/main/java/edu/whut/domain/activity/service/trial/node/EndNode.java b/group-buying-sys-domain/src/main/java/edu/whut/domain/activity/service/trial/node/EndNode.java index 0df3abe..2625e44 100644 --- a/group-buying-sys-domain/src/main/java/edu/whut/domain/activity/service/trial/node/EndNode.java +++ b/group-buying-sys-domain/src/main/java/edu/whut/domain/activity/service/trial/node/EndNode.java @@ -15,7 +15,7 @@ import org.springframework.stereotype.Service; import java.math.BigDecimal; /** - * 结束节点 + * 正常结束节点 */ @Slf4j @Service diff --git a/group-buying-sys-domain/src/main/java/edu/whut/domain/activity/service/trial/node/ErrorNode.java b/group-buying-sys-domain/src/main/java/edu/whut/domain/activity/service/trial/node/ErrorNode.java new file mode 100644 index 0000000..8938c82 --- /dev/null +++ b/group-buying-sys-domain/src/main/java/edu/whut/domain/activity/service/trial/node/ErrorNode.java @@ -0,0 +1,38 @@ +package edu.whut.domain.activity.service.trial.node; +import com.alibaba.fastjson.JSON; +import edu.whut.domain.activity.model.entity.MarketProductEntity; +import edu.whut.domain.activity.model.entity.TrialBalanceEntity; +import edu.whut.domain.activity.service.trial.AbstractGroupBuyMarketSupport; +import edu.whut.domain.activity.service.trial.factory.DefaultActivityStrategyFactory; +import edu.whut.types.design.framework.tree.StrategyHandler; +import edu.whut.types.enums.ResponseCode; +import edu.whut.types.exception.AppException; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +/** + * 异常节点处理;无营销、流程降级、超时调用等,都可以路由到 ErrorNode 节点统一处理 + */ +@Slf4j +@Service +public class ErrorNode extends AbstractGroupBuyMarketSupport { + + @Override + protected TrialBalanceEntity doApply(MarketProductEntity requestParameter, DefaultActivityStrategyFactory.DynamicContext dynamicContext) throws Exception { + log.info("拼团商品查询试算服务-NoMarketNode userId:{} requestParameter:{}", requestParameter.getUserId(), JSON.toJSONString(requestParameter)); + + // 无营销配置 + if (null == dynamicContext.getGroupBuyActivityDiscountVO() || null == dynamicContext.getSkuVO()) { + log.info("商品无拼团营销配置 {}", requestParameter.getGoodsId()); + throw new AppException(ResponseCode.E0002.getCode(), ResponseCode.E0002.getInfo()); + } + + return TrialBalanceEntity.builder().build(); + } + + @Override + public StrategyHandler get(MarketProductEntity requestParameter, DefaultActivityStrategyFactory.DynamicContext dynamicContext) throws Exception { + return defaultStrategyHandler; + } + +} diff --git a/group-buying-sys-domain/src/main/java/edu/whut/domain/activity/service/trial/node/MarketNode.java b/group-buying-sys-domain/src/main/java/edu/whut/domain/activity/service/trial/node/MarketNode.java index 5bd77fb..1fb6036 100644 --- a/group-buying-sys-domain/src/main/java/edu/whut/domain/activity/service/trial/node/MarketNode.java +++ b/group-buying-sys-domain/src/main/java/edu/whut/domain/activity/service/trial/node/MarketNode.java @@ -33,13 +33,22 @@ public class MarketNode extends AbstractGroupBuyMarketSupport discountCalculateServiceMap; - // 异步加载数据 + /** + * 异步加载数据 + * @param requestParameter + * @param dynamicContext + * @throws ExecutionException + * @throws InterruptedException + * @throws TimeoutException + */ @Override protected void multiThread(MarketProductEntity requestParameter, DefaultActivityStrategyFactory.DynamicContext dynamicContext) throws ExecutionException, InterruptedException, TimeoutException { // 异步查询活动配置 - QueryGroupBuyActivityDiscountVOThreadTask queryGroupBuyActivityDiscountVOThreadTask = new QueryGroupBuyActivityDiscountVOThreadTask(requestParameter.getSource(), requestParameter.getChannel(), repository); + QueryGroupBuyActivityDiscountVOThreadTask queryGroupBuyActivityDiscountVOThreadTask = new QueryGroupBuyActivityDiscountVOThreadTask(requestParameter.getSource(), requestParameter.getChannel(),requestParameter.getGoodsId(), repository); FutureTask groupBuyActivityDiscountVOFutureTask = new FutureTask<>(queryGroupBuyActivityDiscountVOThreadTask); threadPoolExecutor.execute(groupBuyActivityDiscountVOFutureTask); @@ -55,15 +64,30 @@ public class MarketNode extends AbstractGroupBuyMarketSupport get(MarketProductEntity requestParameter, DefaultActivityStrategyFactory.DynamicContext dynamicContext) throws Exception { + // 不存在配置的拼团活动,走异常节点 + if (null == dynamicContext.getGroupBuyActivityDiscountVO() || null == dynamicContext.getSkuVO() || null == dynamicContext.getDeductionPrice()) { + return errorNode; + } return endNode; } diff --git a/group-buying-sys-domain/src/main/java/edu/whut/domain/activity/service/trial/thread/QueryGroupBuyActivityDiscountVOThreadTask.java b/group-buying-sys-domain/src/main/java/edu/whut/domain/activity/service/trial/thread/QueryGroupBuyActivityDiscountVOThreadTask.java index 607efcc..6696643 100644 --- a/group-buying-sys-domain/src/main/java/edu/whut/domain/activity/service/trial/thread/QueryGroupBuyActivityDiscountVOThreadTask.java +++ b/group-buying-sys-domain/src/main/java/edu/whut/domain/activity/service/trial/thread/QueryGroupBuyActivityDiscountVOThreadTask.java @@ -2,12 +2,15 @@ package edu.whut.domain.activity.service.trial.thread; import edu.whut.domain.activity.adapter.repository.IActivityRepository; import edu.whut.domain.activity.model.valobj.GroupBuyActivityDiscountVO; +import edu.whut.domain.activity.model.valobj.SCSkuActivityVO; +import lombok.RequiredArgsConstructor; import java.util.concurrent.Callable; /** * 查询营销配置任务 */ +@RequiredArgsConstructor public class QueryGroupBuyActivityDiscountVOThreadTask implements Callable { /** @@ -20,20 +23,25 @@ public class QueryGroupBuyActivityDiscountVOThreadTask implements Callable T getValue(String key); /** - * 获取队列 + * 移除指定 key 的值 + * + * @param key 键 + */ + void remove(String key); + + /** + * 判断指定 key 的值是否存在 + * + * @param key 键 + * @return true/false + */ + boolean isExists(String key); + + //队列 + /** + * 获取普通队列 非阻塞的先进先出队列 * * @param key 键 * @param 泛型 @@ -48,7 +65,7 @@ public interface IRedisService { RQueue getQueue(String key); /** - * 加锁队列 + * 加锁队列 消费者可以阻塞等待队列元素。 * * @param key 键 * @param 泛型 @@ -57,7 +74,7 @@ public interface IRedisService { RBlockingQueue getBlockingQueue(String key); /** - * 延迟队列 + * 延迟队列 把消息延后放到阻塞队列中,适合定时任务、重试机制。 * * @param rBlockingQueue 加锁队列 * @param 泛型 @@ -65,6 +82,7 @@ public interface IRedisService { */ RDelayedQueue getDelayedQueue(RBlockingQueue rBlockingQueue); + //数值计数器,原子自增/自减计数器,适合做分布式编号、PV/UV 统计、限流计数等。 /** * 设置值 * @@ -112,22 +130,7 @@ public interface IRedisService { */ long decrBy(String key, long delta); - - /** - * 移除指定 key 的值 - * - * @param key 键 - */ - void remove(String key); - - /** - * 判断指定 key 的值是否存在 - * - * @param key 键 - * @return true/false - */ - boolean isExists(String key); - + //集合 /** * 将指定的值添加到集合中 * @@ -145,6 +148,7 @@ public interface IRedisService { */ boolean isSetMember(String key, String value); + //列表 /** * 将指定的值添加到列表中 * @@ -162,6 +166,8 @@ public interface IRedisService { */ String getFromList(String key, int index); + + //映射/哈希 /** * 获取Map * @@ -197,6 +203,7 @@ public interface IRedisService { */ V getFromMap(String key, K field); + //有序集合 /** * 将指定的值添加到有序集合中 * @@ -205,6 +212,8 @@ public interface IRedisService { */ void addToSortedSet(String key, String value); + + //分布式同步原语 /** * 获取 Redis 锁(可重入锁) * @@ -256,8 +265,14 @@ public interface IRedisService { */ RCountDownLatch getCountDownLatch(String key); + //实现分布式锁 + Boolean setNx(String key); + + Boolean setNx(String key, long expired, TimeUnit timeUnit); + + //布隆过滤器 /** - * 布隆过滤器 + * 布隆过滤器 ,海量元素去重或判定“可能存在” * * @param key 键 * @param 存放对象 @@ -265,10 +280,7 @@ public interface IRedisService { */ RBloomFilter getBloomFilter(String key); - Boolean setNx(String key); - - Boolean setNx(String key, long expired, TimeUnit timeUnit); - + //位图 RBitSet getBitSet(String key); default int getIndexFromUserId(String userId) { @@ -283,5 +295,4 @@ public interface IRedisService { throw new RuntimeException("MD5 algorithm not found", e); } } - } diff --git a/group-buying-sys-types/src/main/java/edu/whut/types/design/framework/tree/AbstractMultiThreadStrategyRouter.java b/group-buying-sys-types/src/main/java/edu/whut/types/design/framework/tree/AbstractMultiThreadStrategyRouter.java index 41327a5..7654b75 100644 --- a/group-buying-sys-types/src/main/java/edu/whut/types/design/framework/tree/AbstractMultiThreadStrategyRouter.java +++ b/group-buying-sys-types/src/main/java/edu/whut/types/design/framework/tree/AbstractMultiThreadStrategyRouter.java @@ -15,14 +15,26 @@ public abstract class AbstractMultiThreadStrategyRouter implements Stra @Setter protected StrategyHandler defaultStrategyHandler = StrategyHandler.DEFAULT; - //实现自己的普通方法router + /** + * 实现自己的普通方法router,规定执行顺序:先获取handler,再执行handler + * @param requestParameter + * @param dynamicContext + * @return + * @throws Exception + */ public R router(T requestParameter, D dynamicContext) throws Exception { StrategyHandler strategyHandler = get(requestParameter, dynamicContext); if(null != strategyHandler) return strategyHandler.apply(requestParameter, dynamicContext); return defaultStrategyHandler.apply(requestParameter, dynamicContext); } - //实现了接口中的apply方法。 + /** + * 实现了接口中的apply方法。先执行异步加载数据,再执行业务流程受理 + * @param requestParameter + * @param dynamicContext + * @return + * @throws Exception + */ @Override public R apply(T requestParameter, D dynamicContext) throws Exception { // 异步加载数据 @@ -37,7 +49,7 @@ public abstract class AbstractMultiThreadStrategyRouter implements Stra protected abstract void multiThread(T requestParameter, D dynamicContext) throws ExecutionException, InterruptedException, TimeoutException; /** - * 业务流程受理 + * 真正的业务流程,由子类实现 */ protected abstract R doApply(T requestParameter, D dynamicContext) throws Exception; diff --git a/group-buying-sys-types/src/main/java/edu/whut/types/enums/ResponseCode.java b/group-buying-sys-types/src/main/java/edu/whut/types/enums/ResponseCode.java index 96dc557..237a9fe 100644 --- a/group-buying-sys-types/src/main/java/edu/whut/types/enums/ResponseCode.java +++ b/group-buying-sys-types/src/main/java/edu/whut/types/enums/ResponseCode.java @@ -13,6 +13,7 @@ public enum ResponseCode { UN_ERROR("0001", "未知失败"), ILLEGAL_PARAMETER("0002", "非法参数"), E0001("E0001", "不存在对应的折扣计算服务"), + E0002("E0002", "无拼团营销配置"), ; private String code;