不管是正常支付还是拼团支付,都需要在pay表有记录,pay表type字段新增:课程拼团,type用来区分购买的商品类型,status字段新增:拼团中,成团后status就变为支付成功,微信支付、支付宝支付等会有回调,pay_order表记录回调信息。pay、pay_order用订单id关联。需求上未成团,用户不能访问已购买商品内容,比如课程

拼团活动表。目前只有课程有拼团,考虑到以后可能有其他商品拼团,加入一个product_type字段。金额单位用分,各种计算会方便很多。成团人数一定要加上,之前产品说3人成团,后面新产品上线,希望早点成团,需求是2人成团,成团人数会影响到定时任务自动成团,后面再说。另外可以加一个开团后多久自动成团,目前是24小时,这点需求还没变过

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
CREATE TABLE `group_buying` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `product_id` int(11) NOT NULL COMMENT '拼团商品id',
  `product_type` tinyint(2) NOT NULL COMMENT '商品类型 1-课程',
  `condition_num` int(10) NOT NULL DEFAULT '3' COMMENT '成团人数条件 默认为3人成团',
  `cost_price` int(11) NOT NULL COMMENT '原价 单位: 分',
  `discount_price` int(11) NOT NULL COMMENT '折扣价 单位: 分',
  `group_buying_price` int(11) NOT NULL COMMENT '拼团价 单位: 分',
  `create_time` int(11) NOT NULL COMMENT '创建时间',
  `update_time` int(11) NOT NULL COMMENT '更新时间',
  `state` tinyint(2) NOT NULL COMMENT '上下架状态 1-上架 0-下架',
  `del_flag` tinyint(2) NOT NULL COMMENT '是否删除 1-是 0-否',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='拼团活动商品表';

拼团团表。主要用于获取团id

1
2
3
4
5
6
7
8
CREATE TABLE `group_buying_group` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '团id',
  `group_buying_id` int(11) NOT NULL COMMENT '拼团表关联id',
  `create_time` int(11) NOT NULL COMMENT '创建时间',
  `update_time` int(11) NOT NULL COMMENT '更新时间',
  `del_flag` tinyint(2) NOT NULL COMMENT '是否删除 1-是 0-否',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='拼团活动团表';

拼团用户表。 由于存在自动成团,会有合并团的情况,需要记录老团id。比如,分享出去的拼团详情页链接包含group_id,需要接口根据参数返回当前团的信息。status是为了更加方便计算是否成团。robot_info用于存放机器人头像、昵称,其实机器人就是现有用户表里用代码随机取两个(千万不要用sql的rand,这种方式会每行算rand,然后排序,还跟sort buffer等有关,要是内存不够,会用到磁盘,性能很差,explain看看就知道了),分别取头像、昵称,确保不重复,不会出现相同用户参团,最好用用户id,如果有其他变动也方便改动。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
CREATE TABLE `group_buying_customer_rela` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `group_id` int(11) NOT NULL COMMENT '团id',
  `old_group_id` int(11) DEFAULT '0' COMMENT '自动合团前的groupId',
  `group_buying_id` int(11) NOT NULL COMMENT '拼团表关联id',
  `customer_id` int(11) NOT NULL COMMENT '用户id',
  `is_robot` tinyint(2) NOT NULL COMMENT '是否为机器人 1-是 0-否',
  `robot_info` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '机器人头像、昵称以","分隔',
  `participate_time` int(11) NOT NULL COMMENT '参团时间(支付时间)',
  `status` tinyint(2) NOT NULL COMMENT '支付状态 1-成功 0-未成功',
  `create_time` int(11) NOT NULL COMMENT '创建时间',
  `update_time` int(11) NOT NULL COMMENT '更新时间',
  `del_flag` tinyint(2) NOT NULL COMMENT '是否删除 1-是 0-否',
  PRIMARY KEY (`id`),
  UNIQUE KEY `group_buying_customer_index` (`group_buying_id`,`customer_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='拼团活动关联表';

每隔半小时启动的定时任务,检查有没有半小时内成团的,如果有,优先考虑真实用户自动合团,根据成团人数,需要留意的是如果是3人成团,组合2个人和1个人的团,不考虑3个1个人的团,避免拆散可能相互认识的2人团。从开团到截止是24小时,开团时间以团内第一个付费的为准。

拼团自动合团规则:
(1)、只有同一个拼团活动才能合团
(2)、先找半小时内拼团到期的2人团,如果有,再找半小时内到期的1人团,如果有就合团,如果没有就机器人补上
(3)、再找半小时内拼团到期的1人团,如果有,再找半小时内到期的1人团,如果有就合团,最后不够3人就机器人补上
(4)、为显得机器人真实,用户信息在一定范围内,随机获取,时间是当前时间+25分钟内随机时间

因为最后有机器人,拼团默认会成功,但会有个别退款操作,pay、group_buying_customer_rela表都需要做记录修改。 为确保一个用户只能购买或拼团购买一次课程,拼团用户表需要用户id、课程id一起创建的唯一索引,捕获到mysql的1062 error code,再做对应处理

存在一种情况,就是3人成团,可能超卖,比如最后4个人在一个团,极短的时间内2个人买就会出现这种情况。在返回给前端的拼团详情接口,就需要判断当前登录的用户是否已经在团里,如果不在,就根据时间选3人,如果在,就根据时间选2人

其实还有另一种拼团,用户在购买前可以选择是否可以用机器人成团