fs_store_promotion_init.sql 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. -- ============================================================
  2. -- 多店铺阶梯满减活动 - 初始化 / 增量升级 SQL
  3. -- 文档: docs/multi-store-tiered-promotion-design.md v1.2
  4. -- 执行前请备份数据库;菜单 parent_id 请按实际 hisStore 父菜单 ID 调整
  5. --
  6. -- 使用说明:
  7. -- 1. 全新环境:从「一、建表」起顺序执行即可
  8. -- 2. 已建活动表、仅缺订单字段:执行「二、订单表扩展字段(增量)」
  9. -- 3. 增量语句可重复执行,字段/索引已存在时自动跳过
  10. -- ============================================================
  11. -- ============================================================
  12. -- 一、建表(CREATE TABLE IF NOT EXISTS,可重复执行)
  13. -- ============================================================
  14. -- 1. 活动主表
  15. CREATE TABLE IF NOT EXISTS `fs_store_promotion_activity` (
  16. `id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  17. `title` VARCHAR(100) NOT NULL COMMENT '活动名称',
  18. `store_id` BIGINT(20) NOT NULL COMMENT '店铺ID',
  19. `start_time` DATETIME NOT NULL COMMENT '活动开始时间',
  20. `end_time` DATETIME NOT NULL COMMENT '活动结束时间',
  21. `scope_type` TINYINT(2) NOT NULL DEFAULT 1 COMMENT '适用范围:1全场 2指定分类 3指定商品',
  22. `tier_type` TINYINT(2) NOT NULL DEFAULT 1 COMMENT '阶梯类型:1金额 2折扣',
  23. `is_stackable` TINYINT(1) NOT NULL DEFAULT 1 COMMENT '是否可叠加优惠券:0否 1是',
  24. `is_capped` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否上不封顶:0否 1是',
  25. `limit_per_user` INT(11) NOT NULL DEFAULT 0 COMMENT '每人限参与次数,0=不限',
  26. `status` TINYINT(2) NOT NULL DEFAULT 0 COMMENT '状态:0草稿 1启用 3已结束',
  27. `manual_status` TINYINT(1) DEFAULT NULL COMMENT '手动开关:NULL未操作 1启用 0关闭',
  28. `version` INT(11) NOT NULL DEFAULT 0 COMMENT '乐观锁版本号',
  29. `remark` VARCHAR(500) DEFAULT NULL COMMENT '备注',
  30. `is_del` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '逻辑删除:0正常 1删除',
  31. `create_by` VARCHAR(64) DEFAULT NULL COMMENT '创建者',
  32. `create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  33. `update_by` VARCHAR(64) DEFAULT NULL COMMENT '更新者',
  34. `update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  35. PRIMARY KEY (`id`),
  36. KEY `idx_store_id` (`store_id`),
  37. KEY `idx_status_time` (`status`, `manual_status`, `start_time`, `end_time`),
  38. KEY `idx_store_status` (`store_id`, `status`, `manual_status`, `is_del`)
  39. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='店铺阶梯满减活动主表';
  40. -- 2. 满减档位表
  41. CREATE TABLE IF NOT EXISTS `fs_store_promotion_tier` (
  42. `id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  43. `activity_id` BIGINT(20) NOT NULL COMMENT '活动ID',
  44. `sort_order` INT(11) NOT NULL DEFAULT 1 COMMENT '档位序号',
  45. `threshold_amount` DECIMAL(10,2) NOT NULL COMMENT '门槛金额(元)',
  46. `discount_amount` DECIMAL(10,2) NOT NULL COMMENT '减扣金额(元)/折扣(折),含义由活动 tier_type 决定',
  47. `create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  48. `update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  49. PRIMARY KEY (`id`),
  50. KEY `idx_activity_id` (`activity_id`)
  51. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='阶梯满减档位表';
  52. -- 3. 适用范围表(指定分类/指定商品写入此表,全场通用不写记录)
  53. CREATE TABLE IF NOT EXISTS `fs_store_promotion_scope` (
  54. `id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  55. `activity_id` BIGINT(20) NOT NULL COMMENT '活动ID',
  56. `scope_type` TINYINT(2) NOT NULL COMMENT '范围类型:2分类 3商品',
  57. `target_id` BIGINT(20) NOT NULL COMMENT '分类ID或商品ID',
  58. `create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  59. PRIMARY KEY (`id`),
  60. KEY `idx_activity_id` (`activity_id`),
  61. KEY `idx_target` (`scope_type`, `target_id`)
  62. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='活动适用范围明细表';
  63. -- 4. 用户参与记录表
  64. CREATE TABLE IF NOT EXISTS `fs_store_promotion_usage` (
  65. `id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  66. `activity_id` BIGINT(20) NOT NULL COMMENT '活动ID',
  67. `user_id` BIGINT(20) NOT NULL COMMENT '用户ID',
  68. `order_id` BIGINT(20) NOT NULL COMMENT '订单ID',
  69. `order_amount` DECIMAL(10,2) NOT NULL DEFAULT 0.00 COMMENT '订单原金额',
  70. `discount_amount` DECIMAL(10,2) NOT NULL DEFAULT 0.00 COMMENT '优惠金额',
  71. `tier_id` BIGINT(20) DEFAULT NULL COMMENT '命中档位ID',
  72. `usage_status` TINYINT(1) NOT NULL DEFAULT 0 COMMENT '0待支付 1已生效 2已回滚',
  73. `usage_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '参与时间',
  74. `create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  75. PRIMARY KEY (`id`),
  76. UNIQUE KEY `uk_activity_order` (`activity_id`, `order_id`),
  77. KEY `idx_activity_user` (`activity_id`, `user_id`),
  78. KEY `idx_order_id` (`order_id`),
  79. KEY `idx_usage_time` (`usage_time`)
  80. ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户活动参与记录表';
  81. -- ============================================================
  82. -- 二、订单表扩展字段(增量,可重复执行)
  83. -- 表:fs_store_order_scrm
  84. -- ============================================================
  85. SET @db_name = DATABASE();
  86. -- promotion_activity_id
  87. SET @sql_add_promotion_activity_id = (
  88. SELECT IF(
  89. EXISTS(
  90. SELECT 1 FROM information_schema.COLUMNS
  91. WHERE TABLE_SCHEMA = @db_name
  92. AND TABLE_NAME = 'fs_store_order_scrm'
  93. AND COLUMN_NAME = 'promotion_activity_id'
  94. ),
  95. 'SELECT ''skip: promotion_activity_id exists'' AS msg',
  96. 'ALTER TABLE `fs_store_order_scrm` ADD COLUMN `promotion_activity_id` BIGINT(20) DEFAULT NULL COMMENT ''阶梯满减活动ID'' AFTER `user_coupon_id`'
  97. )
  98. );
  99. PREPARE stmt FROM @sql_add_promotion_activity_id;
  100. EXECUTE stmt;
  101. DEALLOCATE PREPARE stmt;
  102. -- promotion_tier_id
  103. SET @sql_add_promotion_tier_id = (
  104. SELECT IF(
  105. EXISTS(
  106. SELECT 1 FROM information_schema.COLUMNS
  107. WHERE TABLE_SCHEMA = @db_name
  108. AND TABLE_NAME = 'fs_store_order_scrm'
  109. AND COLUMN_NAME = 'promotion_tier_id'
  110. ),
  111. 'SELECT ''skip: promotion_tier_id exists'' AS msg',
  112. 'ALTER TABLE `fs_store_order_scrm` ADD COLUMN `promotion_tier_id` BIGINT(20) DEFAULT NULL COMMENT ''命中档位ID'' AFTER `promotion_activity_id`'
  113. )
  114. );
  115. PREPARE stmt FROM @sql_add_promotion_tier_id;
  116. EXECUTE stmt;
  117. DEALLOCATE PREPARE stmt;
  118. -- promotion_discount_amount
  119. SET @sql_add_promotion_discount_amount = (
  120. SELECT IF(
  121. EXISTS(
  122. SELECT 1 FROM information_schema.COLUMNS
  123. WHERE TABLE_SCHEMA = @db_name
  124. AND TABLE_NAME = 'fs_store_order_scrm'
  125. AND COLUMN_NAME = 'promotion_discount_amount'
  126. ),
  127. 'SELECT ''skip: promotion_discount_amount exists'' AS msg',
  128. 'ALTER TABLE `fs_store_order_scrm` ADD COLUMN `promotion_discount_amount` DECIMAL(10,2) DEFAULT NULL COMMENT ''满减优惠金额'' AFTER `promotion_tier_id`'
  129. )
  130. );
  131. PREPARE stmt FROM @sql_add_promotion_discount_amount;
  132. EXECUTE stmt;
  133. DEALLOCATE PREPARE stmt;
  134. -- ============================================================
  135. -- 二点五、活动主表 tier_type 字段(旧库增量,可重复执行)
  136. -- 说明:CREATE TABLE IF NOT EXISTS 不会给已存在的表加新字段,旧环境必须执行本段
  137. -- ============================================================
  138. SET @sql_add_tier_type = (
  139. SELECT IF(
  140. EXISTS(
  141. SELECT 1 FROM information_schema.COLUMNS
  142. WHERE TABLE_SCHEMA = @db_name
  143. AND TABLE_NAME = 'fs_store_promotion_activity'
  144. AND COLUMN_NAME = 'tier_type'
  145. ),
  146. 'SELECT ''skip: tier_type exists'' AS msg',
  147. 'ALTER TABLE `fs_store_promotion_activity` ADD COLUMN `tier_type` TINYINT(2) NOT NULL DEFAULT 1 COMMENT ''阶梯类型:1金额 2折扣'' AFTER `scope_type`'
  148. )
  149. );
  150. PREPARE stmt FROM @sql_add_tier_type;
  151. EXECUTE stmt;
  152. DEALLOCATE PREPARE stmt;
  153. UPDATE `fs_store_promotion_activity`
  154. SET `tier_type` = 1
  155. WHERE `tier_type` IS NULL OR `tier_type` = 0;
  156. -- ============================================================
  157. -- 三、参与记录表索引补全(旧库若已建表但缺 idx_usage_time 可执行)
  158. -- ============================================================
  159. SET @sql_add_idx_usage_time = (
  160. SELECT IF(
  161. EXISTS(
  162. SELECT 1 FROM information_schema.STATISTICS
  163. WHERE TABLE_SCHEMA = @db_name
  164. AND TABLE_NAME = 'fs_store_promotion_usage'
  165. AND INDEX_NAME = 'idx_usage_time'
  166. ),
  167. 'SELECT ''skip: idx_usage_time exists'' AS msg',
  168. 'ALTER TABLE `fs_store_promotion_usage` ADD INDEX `idx_usage_time` (`usage_time`)'
  169. )
  170. );
  171. PREPARE stmt FROM @sql_add_idx_usage_time;
  172. EXECUTE stmt;
  173. DEALLOCATE PREPARE stmt;
  174. -- ============================================================
  175. -- 四、菜单与按钮权限(parent_id 请替换为商城/hisStore 父菜单 ID)
  176. -- 注意:菜单 INSERT 仅首次执行,重复执行会插入重复菜单
  177. -- ============================================================
  178. -- SET @parent_menu_id = (SELECT menu_id FROM sys_menu WHERE menu_name = '商城管理' LIMIT 1);
  179. INSERT INTO `sys_menu` (`menu_name`, `parent_id`, `order_num`, `path`, `component`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`)
  180. VALUES ('阶梯满减', 0, 1, 'storePromotion', 'hisStore/storePromotion/index', 1, 0, 'C', '0', '0', 'store:storePromotion:list', 'money', 'admin', NOW(), '', NULL, '阶梯满减活动');
  181. SET @promotion_menu_id = LAST_INSERT_ID();
  182. INSERT INTO `sys_menu` (`menu_name`, `parent_id`, `order_num`, `path`, `component`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_by`, `create_time`, `remark`) VALUES
  183. ('阶梯满减查询', @promotion_menu_id, 1, '#', '', 1, 0, 'F', '0', '0', 'store:storePromotion:query', '#', 'admin', NOW(), ''),
  184. ('阶梯满减新增', @promotion_menu_id, 2, '#', '', 1, 0, 'F', '0', '0', 'store:storePromotion:add', '#', 'admin', NOW(), ''),
  185. ('阶梯满减修改', @promotion_menu_id, 3, '#', '', 1, 0, 'F', '0', '0', 'store:storePromotion:edit', '#', 'admin', NOW(), ''),
  186. ('阶梯满减删除', @promotion_menu_id, 4, '#', '', 1, 0, 'F', '0', '0', 'store:storePromotion:remove', '#', 'admin', NOW(), ''),
  187. ('阶梯满减导出', @promotion_menu_id, 5, '#', '', 1, 0, 'F', '0', '0', 'store:storePromotion:export', '#', 'admin', NOW(), ''),
  188. ('阶梯满减启用', @promotion_menu_id, 6, '#', '', 1, 0, 'F', '0', '0', 'store:storePromotion:enable', '#', 'admin', NOW(), ''),
  189. ('阶梯满减停用', @promotion_menu_id, 7, '#', '', 1, 0, 'F', '0', '0', 'store:storePromotion:disable', '#', 'admin', NOW(), '');