Commit c8cc3a57f7db2728b366cfa76b731681667d3ce1

Authored by 芋道源码
Committed by Gitee
2 parents dd6dc2ac 67d36547

!265 商品模块 60%

Merge pull request !265 from 芋道源码/feature/1.8.0-uniapp
Showing 268 changed files with 10948 additions and 4544 deletions

Too many changes.

To preserve performance only 100 of 268 files are displayed.

sql/optional/mall/coupon.sql 0 → 100644
  1 +DROP TABLE IF EXISTS `coupon`;
  2 +CREATE TABLE `coupon`
  3 +(
  4 + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '用户ID',
  5 + `type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '优惠券类型 reward-满减 discount-折扣 random-随机',
  6 + `name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '优惠券名称',
  7 + `coupon_type_id` bigint UNSIGNED DEFAULT 0 COMMENT '优惠券类型id',
  8 + `coupon_code` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '优惠券编码',
  9 + `member_id` bigint UNSIGNED NOT NULL DEFAULT 0 COMMENT '领用人',
  10 + `use_order_id` bigint UNSIGNED NOT NULL DEFAULT 0 COMMENT '优惠券使用订单id',
  11 + `goods_type` tinyint(1) UNSIGNED NOT NULL DEFAULT 0 COMMENT '适用商品类型1-全部商品可用;2-指定商品可用;3-指定商品不可用',
  12 + `goods_ids` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '适用商品id',
  13 + `at_least` decimal(10, 2) UNSIGNED NOT NULL DEFAULT 0 COMMENT '最小金额',
  14 + `money` decimal(10, 2) UNSIGNED NOT NULL DEFAULT 0 COMMENT '面额',
  15 + `discount` decimal(10, 2) UNSIGNED NOT NULL DEFAULT 0 COMMENT '1 =< 折扣 <= 9.9 当type为discount时需要添加',
  16 + `discount_limit` decimal(10, 2) UNSIGNED NOT NULL DEFAULT 0 COMMENT '最多折扣金额 当type为discount时可选择性添加',
  17 + `whether_forbid_preference` tinyint(1) UNSIGNED NOT NULL DEFAULT 0 COMMENT '优惠叠加 0-不限制 1- 优惠券仅原价购买商品时可用',
  18 + `whether_expire_notice` tinyint(1) UNSIGNED NOT NULL DEFAULT 0 COMMENT '是否开启过期提醒0-不开启 1-开启',
  19 + `expire_notice_fixed_term` int(11) UNSIGNED NOT NULL DEFAULT 0 COMMENT '过期前N天提醒',
  20 + `whether_noticed` tinyint(1) UNSIGNED NOT NULL DEFAULT 0 COMMENT '是否已提醒',
  21 + `state` tinyint(4) UNSIGNED NOT NULL DEFAULT 0 COMMENT '优惠券状态 1已领用(未使用) 2已使用 3已过期',
  22 + `get_type` tinyint(1) UNSIGNED NOT NULL DEFAULT 0 COMMENT '获取方式1订单2.直接领取3.活动领取 4转赠 5分享获取',
  23 + `fetch_time` datetime NOT NULL DEFAULT 0 COMMENT '领取时间',
  24 + `use_time` datetime NOT NULL DEFAULT 0 COMMENT '使用时间',
  25 + `start_time` datetime NOT NULL DEFAULT 0 COMMENT '可使用的开始时间',
  26 + `end_time` datetime NOT NULL DEFAULT 0 COMMENT '有效期结束时间',
  27 + `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者',
  28 + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  29 + `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者',
  30 + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  31 + `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
  32 + `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
  33 + PRIMARY KEY (`id`) USING BTREE
  34 +) ENGINE = InnoDB
  35 + AUTO_INCREMENT = 119
  36 + CHARACTER SET = utf8mb4
  37 + COLLATE = utf8mb4_unicode_ci COMMENT = '优惠券';
  38 +
  39 +DROP TABLE IF EXISTS `coupon_templete`;
  40 +CREATE TABLE `coupon_templete`
  41 +(
  42 + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '用户ID',
  43 + `type` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '优惠券类型 reward-满减 discount-折扣 random-随机',
  44 + `name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '优惠券名称',
  45 + `coupon_name_remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci COMMENT '名称备注',
  46 + `image` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci COMMENT '优惠券图片',
  47 + `count` int(11) NOT NULL DEFAULT 0 COMMENT '发放数量',
  48 + `lead_count` int(11) NOT NULL DEFAULT 0 COMMENT '已领取数量',
  49 + `used_count` int(11) UNSIGNED NOT NULL DEFAULT 0 COMMENT '已使用数量',
  50 + `goods_type` tinyint(1) UNSIGNED NOT NULL DEFAULT 1 COMMENT '适用商品类型1-全部商品可用;2-指定商品可用;3-指定商品不可用',
  51 + `product_ids` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci COMMENT '适用商品id',
  52 + `has_use_limit` tinyint(1) UNSIGNED NOT NULL DEFAULT 0 COMMENT '使用门槛0-无门槛 1-有门槛',
  53 + `at_least` decimal(10, 2) NOT NULL DEFAULT 0 COMMENT '满多少元使用 0代表无限制',
  54 + `money` decimal(10, 2) NOT NULL DEFAULT 0 COMMENT '发放面额 当type为reward时需要添加',
  55 + `discount` decimal(10, 2) UNSIGNED NOT NULL DEFAULT 0 COMMENT '1 =< 折扣 <= 9.9 当type为discount时需要添加',
  56 + `discount_limit` decimal(10, 2) NOT NULL DEFAULT 0 COMMENT '最多折扣金额 当type为discount时可选择性添加',
  57 + `min_money` decimal(10, 2) UNSIGNED NOT NULL DEFAULT 0 COMMENT '最低金额 当type为radom时需要添加',
  58 + `max_money` decimal(10, 2) UNSIGNED NOT NULL DEFAULT 0 COMMENT '最大金额 当type为radom时需要添加',
  59 + `validity_type` tinyint(1) UNSIGNED NOT NULL DEFAULT 0 COMMENT '过期类型1-时间范围过期 2-领取之日固定日期后过期 3-领取次日固定日期后过期',
  60 + `start_use_time` datetime COMMENT '使用开始日期 过期类型1时必填',
  61 + `end_use_time` datetime COMMENT '使用结束日期 过期类型1时必填',
  62 + `fixed_term` int(11) UNSIGNED NOT NULL DEFAULT 0 COMMENT '当validity_type为2或者3时需要添加 领取之日起或者次日N天内有效',
  63 + `whether_limitless` tinyint(1) UNSIGNED NOT NULL DEFAULT 0 COMMENT '是否无限制0-否 1是',
  64 + `max_fetch` int(11) UNSIGNED NOT NULL DEFAULT 0 COMMENT '每人最大领取个数',
  65 + `whether_expire_notice` tinyint(1) UNSIGNED NOT NULL DEFAULT 0 COMMENT '是否开启过期提醒0-不开启 1-开启',
  66 + `expire_notice_fixed_term` int(11) UNSIGNED NOT NULL DEFAULT 0 COMMENT '过期前N天提醒',
  67 + `whether_forbid_preference` tinyint(1) UNSIGNED NOT NULL DEFAULT 0 COMMENT '优惠叠加 0-不限制 1- 优惠券仅原价购买商品时可用',
  68 + `whether_show` int(11) UNSIGNED NOT NULL DEFAULT 0 COMMENT '是否显示',
  69 + `discount_order_money` decimal(10, 2) UNSIGNED NOT NULL DEFAULT 0 COMMENT '订单的优惠总金额',
  70 + `order_money` decimal(10, 2) UNSIGNED NOT NULL DEFAULT 0 COMMENT '用券总成交额',
  71 + `whether_forbidden` tinyint(1) UNSIGNED NOT NULL DEFAULT 0 COMMENT '是否禁止发放0-否 1-是',
  72 + `order_goods_num` int(11) UNSIGNED NOT NULL DEFAULT 0 COMMENT '使用优惠券购买的商品数量',
  73 + `status` tinyint(11) NOT NULL DEFAULT 0 COMMENT '状态(1进行中2已结束-1已关闭)',
  74 + `end_time` datetime COMMENT '有效日期结束时间',
  75 + `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者',
  76 + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  77 + `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者',
  78 + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  79 + `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
  80 + `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
  81 + PRIMARY KEY (`id`) USING BTREE
  82 +) ENGINE = InnoDB
  83 + AUTO_INCREMENT = 119
  84 + CHARACTER SET = utf8mb4
  85 + COLLATE = utf8mb4_unicode_ci COMMENT = '优惠券模板';
0 \ No newline at end of file 86 \ No newline at end of file
sql/optional/mall/mall.sql
1 /* 1 /*
2 Navicat Premium Data Transfer 2 Navicat Premium Data Transfer
3 3
4 - Source Server : 127.0.0.1 4 + Source Server : 127.0.0.1 MySQL
5 Source Server Type : MySQL 5 Source Server Type : MySQL
6 Source Server Version : 80026 6 Source Server Version : 80026
7 Source Host : localhost:3306 7 Source Host : localhost:3306
@@ -11,277 +11,305 @@ @@ -11,277 +11,305 @@
11 Target Server Version : 80026 11 Target Server Version : 80026
12 File Encoding : 65001 12 File Encoding : 65001
13 13
14 - Date: 05/02/2022 00:50:30 14 + Date: 01/08/2022 23:01:36
15 */ 15 */
16 -SET  
17 -FOREIGN_KEY_CHECKS = 0; 16 +
18 SET NAMES utf8mb4; 17 SET NAMES utf8mb4;
  18 +SET FOREIGN_KEY_CHECKS = 0;
19 19
20 -- ---------------------------- 20 -- ----------------------------
21 --- Table structure for product_category 21 +-- Table structure for market_activity
22 -- ---------------------------- 22 -- ----------------------------
23 -DROP TABLE IF EXISTS `product_category`;  
24 -CREATE TABLE `product_category`  
25 -(  
26 - `id` bigint NOT NULL AUTO_INCREMENT COMMENT '分类编号',  
27 - `parent_id` bigint NOT NULL COMMENT '父分类编号',  
28 - `name` varchar(255) NOT NULL COMMENT '分类名称',  
29 - `icon` varchar(100) NOT NULL DEFAULT '#' COMMENT '分类图标',  
30 - `banner_url` varchar(255) NOT NULL COMMENT '分类图片',  
31 - `sort` int DEFAULT '0' COMMENT '分类排序',  
32 - `description` varchar(1024) DEFAULT NULL COMMENT '分类描述',  
33 - `status` tinyint NOT NULL COMMENT '开启状态',  
34 - `creator` varchar(64) DEFAULT '' COMMENT '创建者',  
35 - `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',  
36 - `updater` varchar(64) DEFAULT '' COMMENT '更新者',  
37 - `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',  
38 - `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',  
39 - `tenant_id` bigint NOT NULL DEFAULT '0' COMMENT '租户编号',  
40 - PRIMARY KEY (`id`) USING BTREE  
41 -) ENGINE=InnoDB COMMENT='商品分类'; 23 +DROP TABLE IF EXISTS `market_activity`;
  24 +CREATE TABLE `market_activity` (
  25 + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '活动编号',
  26 + `title` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '活动标题',
  27 + `activity_type` tinyint NOT NULL COMMENT '活动类型',
  28 + `status` tinyint NOT NULL DEFAULT -1 COMMENT '活动状态',
  29 + `start_time` datetime NOT NULL COMMENT '开始时间',
  30 + `end_time` datetime NOT NULL COMMENT '结束时间',
  31 + `invalid_time` datetime NULL DEFAULT NULL COMMENT '失效时间',
  32 + `delete_time` datetime NULL DEFAULT NULL COMMENT '删除时间',
  33 + `time_limited_discount` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '限制折扣字符串,使用 JSON 序列化成字符串存储',
  34 + `full_privilege` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '限制折扣字符串,使用 JSON 序列化成字符串存储',
  35 + `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者',
  36 + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  37 + `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者',
  38 + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  39 + `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
  40 + `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
  41 + PRIMARY KEY (`id`) USING BTREE
  42 +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '促销活动';
42 43
43 -- ---------------------------- 44 -- ----------------------------
44 --- Table structure for product_brand 45 +-- Records of market_activity
45 -- ---------------------------- 46 -- ----------------------------
46 -DROP TABLE IF EXISTS `product_brand`;  
47 -CREATE TABLE `product_brand`  
48 -(  
49 - `id` bigint NOT NULL AUTO_INCREMENT COMMENT '品牌编号',  
50 - `category_id` bigint NOT NULL COMMENT '分类编号',  
51 - `name` varchar(255) NOT NULL COMMENT '品牌名称',  
52 - `banner_url` varchar(255) NOT NULL COMMENT '品牌图片',  
53 - `sort` int DEFAULT '0' COMMENT '品牌排序',  
54 - `description` varchar(1024) DEFAULT NULL COMMENT '品牌描述',  
55 - `status` tinyint NOT NULL COMMENT '状态',  
56 - `creator` varchar(64) DEFAULT '' COMMENT '创建者',  
57 - `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',  
58 - `updater` varchar(64) DEFAULT '' COMMENT '更新者',  
59 - `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',  
60 - `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',  
61 - `tenant_id` bigint NOT NULL DEFAULT '0' COMMENT '租户编号',  
62 - PRIMARY KEY (`id`) USING BTREE  
63 -) ENGINE=InnoDB COMMENT='品牌'; 47 +BEGIN;
  48 +COMMIT;
64 49
65 --- TODO 父级菜单的 id 处理: 2000 、 2001  
66 -INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`)  
67 -VALUES (2000, '商城', '', 1, 1, 0, '/mall', 'merchant', NULL, 0);  
68 -INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`)  
69 -VALUES (2001, '商品', '', 1, 1, 2000, 'product', 'dict', NULL, 0);  
70 --- 商品分类 菜单 SQL  
71 -INSERT INTO `system_menu`(`name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`)  
72 -VALUES ('分类管理', '', 2, 0, 2001, 'category', '', 'mall/product/category/index', 0);  
73 --- 按钮父菜单ID  
74 -SELECT @parentId := LAST_INSERT_ID();  
75 --- 按钮 SQL  
76 -INSERT INTO `system_menu`(`name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`)  
77 -VALUES ('分类查询', 'product:category:query', 3, 1, @parentId, '', '', '', 0);  
78 -INSERT INTO `system_menu`(`name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`)  
79 -VALUES ('分类创建', 'product:category:create', 3, 2, @parentId, '', '', '', 0);  
80 -INSERT INTO `system_menu`(`name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`)  
81 -VALUES ('分类更新', 'product:category:update', 3, 3, @parentId, '', '', '', 0);  
82 -INSERT INTO `system_menu`(`name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`)  
83 -VALUES ('分类删除', 'product:category:delete', 3, 4, @parentId, '', '', '', 0);  
84 -INSERT INTO `system_menu`(`name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`)  
85 -VALUES ('分类导出', 'product:category:export', 3, 5, @parentId, '', '', '', 0);  
86 --- 品牌管理 菜单 SQL  
87 -INSERT INTO `system_menu`(`name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`)  
88 -VALUES ('品牌管理', '', 2, 1, 2001, 'brand', '', 'mall/product/brand/index', 0);  
89 --- 按钮父菜单ID  
90 -SELECT @parentId := LAST_INSERT_ID();  
91 --- 按钮 SQL  
92 -INSERT INTO `system_menu`(`name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`)  
93 -VALUES ('品牌查询', 'product:brand:query', 3, 1, @parentId, '', '', '', 0);  
94 -INSERT INTO `system_menu`(`name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`)  
95 -VALUES ('品牌创建', 'product:brand:create', 3, 2, @parentId, '', '', '', 0);  
96 -INSERT INTO `system_menu`(`name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`)  
97 -VALUES ('品牌更新', 'product:brand:update', 3, 3, @parentId, '', '', '', 0);  
98 -INSERT INTO `system_menu`(`name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`)  
99 -VALUES ('品牌删除', 'product:brand:delete', 3, 4, @parentId, '', '', '', 0);  
100 -INSERT INTO `system_menu`(`name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`)  
101 -VALUES ('品牌导出', 'product:brand:export', 3, 5, @parentId, '', '', '', 0); 50 +-- ----------------------------
  51 +-- Table structure for market_banner
  52 +-- ----------------------------
  53 +DROP TABLE IF EXISTS `market_banner`;
  54 +CREATE TABLE `market_banner` (
  55 + `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'Banner编号',
  56 + `title` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT 'Banner标题',
  57 + `pic_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '图片URL',
  58 + `status` tinyint NOT NULL DEFAULT -1 COMMENT '活动状态',
  59 + `url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '跳转地址',
  60 + `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '创建者',
  61 + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  62 + `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '' COMMENT '更新者',
  63 + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  64 + `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
  65 + `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
  66 + `sort` tinyint NULL DEFAULT NULL COMMENT '排序',
  67 + `memo` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '描述',
  68 + PRIMARY KEY (`id`) USING BTREE
  69 +) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'Banner管理';
102 70
  71 +-- ----------------------------
  72 +-- Records of market_banner
  73 +-- ----------------------------
  74 +BEGIN;
  75 +COMMIT;
103 76
104 -- ---------------------------- 77 -- ----------------------------
105 --- Table structure for market_activity 78 +-- Table structure for member_address
106 -- ---------------------------- 79 -- ----------------------------
107 -DROP TABLE IF EXISTS `market_activity`;  
108 -CREATE TABLE `market_activity`  
109 -(  
110 - `id` bigint NOT NULL AUTO_INCREMENT COMMENT '活动编号',  
111 - `title` varchar(50) NOT NULL DEFAULT '' COMMENT '活动标题',  
112 - `activity_type` tinyint(4) NOT NULL COMMENT '活动类型',  
113 - `status` tinyint(4) NOT NULL DEFAULT '-1' COMMENT '活动状态',  
114 - `start_time` datetime NOT NULL COMMENT '开始时间',  
115 - `end_time` datetime NOT NULL COMMENT '结束时间',  
116 - `invalid_time` datetime DEFAULT NULL COMMENT '失效时间',  
117 - `delete_time` datetime DEFAULT NULL COMMENT '删除时间',  
118 - `time_limited_discount` varchar(2000) DEFAULT NULL COMMENT '限制折扣字符串,使用 JSON 序列化成字符串存储',  
119 - `full_privilege` varchar(2000) DEFAULT NULL COMMENT '限制折扣字符串,使用 JSON 序列化成字符串存储',  
120 - `creator` varchar(64) DEFAULT '' COMMENT '创建者',  
121 - `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',  
122 - `updater` varchar(64) DEFAULT '' COMMENT '更新者',  
123 - `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',  
124 - `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',  
125 - `tenant_id` bigint NOT NULL DEFAULT '0' COMMENT '租户编号',  
126 - PRIMARY KEY (`id`) USING BTREE  
127 -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='促销活动'; 80 +DROP TABLE IF EXISTS `member_address`;
  81 +CREATE TABLE `member_address` (
  82 + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '收件地址编号',
  83 + `user_id` bigint NOT NULL COMMENT '用户编号',
  84 + `name` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT '收件人名称',
  85 + `mobile` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT '手机号',
  86 + `area_id` bigint NOT NULL COMMENT '地区编码',
  87 + `post_code` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT '邮编',
  88 + `detail_address` varchar(250) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT '收件详细地址',
  89 + `defaulted` bit(1) NOT NULL COMMENT '是否默认',
  90 + `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者',
  91 + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  92 + `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者',
  93 + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  94 + `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
  95 + `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
  96 + PRIMARY KEY (`id`) USING BTREE,
  97 + INDEX `idx_userId`(`user_id` ASC) USING BTREE
  98 +) ENGINE = InnoDB AUTO_INCREMENT = 21 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin COMMENT = '用户收件地址';
128 99
  100 +-- ----------------------------
  101 +-- Records of member_address
  102 +-- ----------------------------
  103 +BEGIN;
  104 +INSERT INTO `member_address` (`id`, `user_id`, `name`, `mobile`, `area_id`, `post_code`, `detail_address`, `defaulted`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (21, 1, 'yunai', '15601691300', 610632, '200000', '芋道源码 233 号 666 室', b'1', '1', '2022-08-01 22:46:35', '1', '2022-08-01 22:46:35', b'0', 1);
  105 +COMMIT;
129 106
130 --- 规格菜单 SQL  
131 -INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status)  
132 -VALUES ('规格管理', '', 2, 3, 2001, 'property', '', 'mall/product/property/index', 0); 107 +-- ----------------------------
  108 +-- Table structure for product_brand
  109 +-- ----------------------------
  110 +DROP TABLE IF EXISTS `product_brand`;
  111 +CREATE TABLE `product_brand` (
  112 + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '品牌编号',
  113 + `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '品牌名称',
  114 + `pic_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '品牌图片',
  115 + `sort` int NULL DEFAULT 0 COMMENT '品牌排序',
  116 + `description` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '品牌描述',
  117 + `status` tinyint NOT NULL COMMENT '状态',
  118 + `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者',
  119 + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  120 + `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者',
  121 + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  122 + `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
  123 + `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
  124 + PRIMARY KEY (`id`) USING BTREE
  125 +) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '商品品牌';
133 126
134 --- 按钮父菜单ID  
135 -SELECT @parentId := LAST_INSERT_ID(); 127 +-- ----------------------------
  128 +-- Records of product_brand
  129 +-- ----------------------------
  130 +BEGIN;
  131 +INSERT INTO `product_brand` (`id`, `name`, `pic_url`, `sort`, `description`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1, '苹果', 'http://test.yudao.iocoder.cn/e3726713fa56db5717c78c011762fcc7a251db12735c3581470638b8e1fa17e2.jpeg', 0, '是上市', 0, '1', '2022-07-30 22:12:18', '1', '2022-07-30 22:13:55', b'0', 1);
  132 +COMMIT;
136 133
137 --- 按钮 SQL  
138 -INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status)  
139 -VALUES ('规格查询', 'product:property:query', 3, 1, @parentId, '', '', '', 0);  
140 -INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status)  
141 -VALUES ('规格创建', 'product:property:create', 3, 2, @parentId, '', '', '', 0);  
142 -INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status)  
143 -VALUES ('规格更新', 'product:property:update', 3, 3, @parentId, '', '', '', 0);  
144 -INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status)  
145 -VALUES ('规格删除', 'product:property:delete', 3, 4, @parentId, '', '', '', 0);  
146 -INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status)  
147 -VALUES ('规格导出', 'product:property:export', 3, 5, @parentId, '', '', '', 0); 134 +-- ----------------------------
  135 +-- Table structure for product_category
  136 +-- ----------------------------
  137 +DROP TABLE IF EXISTS `product_category`;
  138 +CREATE TABLE `product_category` (
  139 + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '分类编号',
  140 + `parent_id` bigint NOT NULL COMMENT '父分类编号',
  141 + `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '分类名称',
  142 + `pic_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '分类图片',
  143 + `sort` int NULL DEFAULT 0 COMMENT '分类排序',
  144 + `description` varchar(1024) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '分类描述',
  145 + `status` tinyint NOT NULL COMMENT '开启状态',
  146 + `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者',
  147 + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  148 + `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者',
  149 + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  150 + `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
  151 + `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
  152 + PRIMARY KEY (`id`) USING BTREE
  153 +) ENGINE = InnoDB AUTO_INCREMENT = 8 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '商品分类';
148 154
  155 +-- ----------------------------
  156 +-- Records of product_category
  157 +-- ----------------------------
  158 +BEGIN;
  159 +INSERT INTO `product_category` (`id`, `parent_id`, `name`, `pic_url`, `sort`, `description`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1, 0, '电脑办公', 'http://test.yudao.iocoder.cn/122d548e1b3cd5dec72fe8075c6977a70f9cc13541a684ab3685f1b5df42f6bd.jpeg', 1, '1234', 0, '1', '2022-07-30 16:36:35', '1', '2022-07-30 20:27:16', b'0', 1), (2, 1, '笔记本', 'http://test.yudao.iocoder.cn/72713ac7b947600a019a18786ed0e6562e8692e253dbd35110a0a85c2469bbec.jpg', 1, '<p>测试一下</p>', 0, '1', '2022-07-30 16:38:09', '1', '2022-07-30 16:38:09', b'0', 1), (3, 1, '游戏本', 'http://test.yudao.iocoder.cn/287c50dd9f5f575f57329a0c57b2095be6d1aeba83867b905fe549f54a296feb.jpg', 2, '<p>测试一下</p>', 0, '1', '2022-07-30 16:39:09', '1', '2022-07-30 20:26:59', b'0', 1), (4, 0, '手机', 'http://test.yudao.iocoder.cn/e1b63900c78dbb661b3e383960cee5cfea7e1dd2fb22cff2e317ff025faaf8b2.jpeg', 2, '<p>123</p>', 0, '1', '2022-07-30 16:40:00', '1', '2022-07-30 16:40:09', b'0', 1), (5, 4, '5G手机', 'http://test.yudao.iocoder.cn/3af6557ac7def6423f046f5b2e920b644793420b466959aaa996a2e19068bbde.jpeg', 1, '<p><br></p>', 0, '1', '2022-07-30 16:43:00', '1', '2022-07-30 16:43:00', b'0', 1), (6, 4, '游戏手机', 'http://test.yudao.iocoder.cn/964fe9ccd1710d64ede261dc36d231918a017641986c15293c367f9f66d94d05.jpeg', 2, NULL, 0, '1', '2022-07-30 16:43:44', '1', '2022-07-30 16:43:44', b'0', 1), (7, 5, '厉害的 5G 手机', 'http://test.yudao.iocoder.cn/b287122f277838e8de368769b96217918605743bc45f3a29bda3cc7359dc66e1.png', 0, '123', 0, '1', '2022-07-30 20:38:09', '1', '2022-07-30 20:38:09', b'0', 1);
  160 +COMMIT;
149 161
150 --- 商品菜单 SQL  
151 -INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status)  
152 -VALUES ('商品管理', '', 2, 2, 2001, 'spu', '', 'mall/product/spu/index', 0); 162 +-- ----------------------------
  163 +-- Table structure for product_property
  164 +-- ----------------------------
  165 +DROP TABLE IF EXISTS `product_property`;
  166 +CREATE TABLE `product_property` (
  167 + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
  168 + `name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '规格名称',
  169 + `status` tinyint NULL DEFAULT NULL COMMENT '状态: 0 开启 ,1 禁用',
  170 + `create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  171 + `update_time` datetime NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  172 + `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '创建人',
  173 + `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '更新人',
  174 + `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
  175 + `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
  176 + PRIMARY KEY (`id`) USING BTREE,
  177 + INDEX `idx_name`(`name`(32) ASC) USING BTREE COMMENT '规格名称索引'
  178 +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '规格名称';
153 179
154 --- 按钮父菜单ID  
155 -SELECT @parentId := LAST_INSERT_ID(); 180 +-- ----------------------------
  181 +-- Records of product_property
  182 +-- ----------------------------
  183 +BEGIN;
  184 +COMMIT;
156 185
157 --- 按钮 SQL  
158 -INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status)  
159 -VALUES ('商品查询', 'product:spu:query', 3, 1, @parentId, '', '', '', 0);  
160 -INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status)  
161 -VALUES ('商品创建', 'product:spu:create', 3, 2, @parentId, '', '', '', 0);  
162 -INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status)  
163 -VALUES ('商品更新', 'product:spu:update', 3, 3, @parentId, '', '', '', 0);  
164 -INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status)  
165 -VALUES ('商品删除', 'product:spu:delete', 3, 4, @parentId, '', '', '', 0);  
166 -INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status)  
167 -VALUES ('商品导出', 'product:spu:export', 3, 5, @parentId, '', '', '', 0); 186 +-- ----------------------------
  187 +-- Table structure for product_property_value
  188 +-- ----------------------------
  189 +DROP TABLE IF EXISTS `product_property_value`;
  190 +CREATE TABLE `product_property_value` (
  191 + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
  192 + `property_id` bigint NULL DEFAULT NULL COMMENT '规格键id',
  193 + `name` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '规格值名字',
  194 + `status` tinyint NULL DEFAULT NULL COMMENT '状态: 1 开启 ,2 禁用',
  195 + `create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  196 + `update_time` datetime NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  197 + `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '创建人',
  198 + `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '更新人',
  199 + `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
  200 + `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
  201 + PRIMARY KEY (`id`) USING BTREE
  202 +) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '规格值';
168 203
  204 +-- ----------------------------
  205 +-- Records of product_property_value
  206 +-- ----------------------------
  207 +BEGIN;
  208 +COMMIT;
169 209
170 --- 规格名称表  
171 -drop table if exists product_property;  
172 -create table product_property  
173 -(  
174 - id bigint NOT NULL AUTO_INCREMENT comment '主键',  
175 - name varchar(64) comment '规格名称',  
176 - status tinyint comment '状态: 0 开启 ,1 禁用',  
177 - create_time datetime default current_timestamp comment '创建时间',  
178 - update_time datetime default current_timestamp on update current_timestamp comment '更新时间',  
179 - creator varchar(64) comment '创建人',  
180 - updater varchar(64) comment '更新人',  
181 - tenant_id bigint NOT NULL DEFAULT '0' COMMENT '租户编号',  
182 - deleted bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',  
183 - primary key (id),  
184 - key idx_name ( name (32)) comment '规格名称索引'  
185 -) comment '规格名称' character set utf8mb4  
186 - collate utf8mb4_general_ci; 210 +-- ----------------------------
  211 +-- Table structure for product_sku
  212 +-- ----------------------------
  213 +DROP TABLE IF EXISTS `product_sku`;
  214 +CREATE TABLE `product_sku` (
  215 + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
  216 + `spu_id` bigint NOT NULL COMMENT 'spu编号',
  217 + `tenant_id` bigint NOT NULL DEFAULT '0' COMMENT '租户编号',
  218 + `name` varchar(128) DEFAULT NULL COMMENT '商品 SKU 名字',
  219 + `properties` varchar(128) DEFAULT NULL COMMENT '规格值数组-json格式, [{propertId: , valueId: }, {propertId: , valueId: }]',
  220 + `price` int NOT NULL DEFAULT '-1' COMMENT '销售价格,单位:分',
  221 + `market_price` int DEFAULT NULL COMMENT '市场价',
  222 + `cost_price` int NOT NULL DEFAULT '-1' COMMENT '成本价,单位: 分',
  223 + `pic_url` varchar(128) NOT NULL COMMENT '图片地址',
  224 + `stock` int DEFAULT NULL COMMENT '库存',
  225 + `warn_stock` int DEFAULT NULL COMMENT '预警库存',
  226 + `volume` double DEFAULT NULL COMMENT '商品体积',
  227 + `weight` double DEFAULT NULL COMMENT '商品重量',
  228 + `bar_code` varchar(64) DEFAULT NULL COMMENT '条形码',
  229 + `status` tinyint DEFAULT NULL COMMENT '状态: 0-正常 1-禁用',
  230 + `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  231 + `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  232 + `creator` varchar(64) DEFAULT NULL COMMENT '创建人',
  233 + `updater` double(64,0) DEFAULT NULL COMMENT '更新人',
  234 +`deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
  235 +PRIMARY KEY (`id`) USING BTREE
  236 +) ENGINE=InnoDB COMMENT='商品sku';
187 237
188 --- 规格值表  
189 -drop table if exists product_property_value;  
190 -create table product_property_value  
191 -(  
192 - id bigint NOT NULL AUTO_INCREMENT COMMENT '主键',  
193 - property_id bigint comment '规格键id',  
194 - name varchar(128) comment '规格值名字',  
195 - status tinyint comment '状态: 1 开启 ,2 禁用',  
196 - create_time datetime default current_timestamp comment '创建时间',  
197 - update_time datetime default current_timestamp on update current_timestamp comment '更新时间',  
198 - creator varchar(64) comment '创建人',  
199 - updater varchar(64) comment '更新人',  
200 - tenant_id bigint NOT NULL DEFAULT '0' COMMENT '租户编号',  
201 - deleted bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',  
202 - primary key (id)  
203 -) comment '规格值' character set utf8mb4  
204 - collate utf8mb4_general_ci; 238 +-- ----------------------------
  239 +-- Records of product_sku
  240 +-- ----------------------------
  241 +BEGIN;
  242 +COMMIT;
205 243
206 --- spu  
207 -drop table if exists product_spu;  
208 -create table product_spu  
209 -(  
210 - id bigint NOT NULL AUTO_INCREMENT COMMENT '主键',  
211 - name varchar(128) comment '商品名称',  
212 - sell_point varchar(128) not null comment '卖点',  
213 - description text not null comment '描述',  
214 - category_id bigint not null comment '分类id',  
215 - pic_urls varchar(1024) not null default '' comment '商品主图地址\n *\n * 数组,以逗号分隔\n 最多上传15张',  
216 - sort int not null default 0 comment '排序字段',  
217 - like_count int comment '点赞初始人数',  
218 - price int comment '价格 单位使用:分',  
219 - quantity int comment '库存数量',  
220 - status bit(1) comment '上下架状态: 0 上架(开启) 1 下架(禁用)',  
221 - create_time datetime default current_timestamp comment '创建时间',  
222 - update_time datetime default current_timestamp on update current_timestamp comment '更新时间',  
223 - creator varchar(64) comment '创建人',  
224 - updater varchar(64) comment '更新人',  
225 - tenant_id bigint NOT NULL DEFAULT '0' COMMENT '租户编号',  
226 - deleted bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',  
227 - primary key (id)  
228 -) comment '商品spu' character set utf8mb4  
229 - collate utf8mb4_general_ci; 244 +-- ----------------------------
  245 +-- Table structure for product_spu
  246 +-- ----------------------------
  247 +DROP TABLE IF EXISTS `product_spu`;
  248 +CREATE TABLE `product_spu` (
  249 + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
  250 + `tenant_id` bigint NOT NULL DEFAULT '0' COMMENT '租户编号',
  251 + `brand_id` int DEFAULT NULL COMMENT '商品品牌编号',
  252 + `category_id` bigint NOT NULL COMMENT '分类id',
  253 + `spec_type` int NOT NULL COMMENT '规格类型:0 单规格 1 多规格',
  254 + `code` varchar(128) DEFAULT NULL COMMENT '商品编码',
  255 + `name` varchar(128) NOT NULL COMMENT '商品名称',
  256 + `sell_point` varchar(128) DEFAULT NULL COMMENT '卖点',
  257 + `description` text COMMENT '描述',
  258 + `pic_urls` varchar(1024) DEFAULT '' COMMENT '商品轮播图地址\n 数组,以逗号分隔\n 最多上传15张',
  259 + `video_url` varchar(128) DEFAULT NULL COMMENT '商品视频',
  260 + `market_price` int DEFAULT NULL COMMENT '市场价,单位使用:分',
  261 + `min_price` int DEFAULT NULL COMMENT '最小价格,单位使用:分',
  262 + `max_price` int DEFAULT NULL COMMENT '最大价格,单位使用:分',
  263 + `total_stock` int NOT NULL DEFAULT '0' COMMENT '总库存',
  264 + `show_stock` int DEFAULT '0' COMMENT '是否展示库存',
  265 + `sales_count` int DEFAULT '0' COMMENT '商品销量',
  266 + `virtual_sales_count` int DEFAULT '0' COMMENT '虚拟销量',
  267 + `click_count` int DEFAULT '0' COMMENT '商品点击量',
  268 + `status` bit(1) DEFAULT NULL COMMENT '上下架状态: 0 上架(开启) 1 下架(禁用)-1 回收',
  269 + `sort` int NOT NULL DEFAULT '0' COMMENT '排序字段',
  270 + `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  271 + `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  272 + `creator` varchar(64) DEFAULT NULL COMMENT '创建人',
  273 + `updater` varchar(64) DEFAULT NULL COMMENT '更新人',
  274 + `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
  275 + PRIMARY KEY (`id`) USING BTREE
  276 +) ENGINE=InnoDB COMMENT='商品spu';
230 277
  278 +-- ----------------------------
  279 +-- Records of product_spu
  280 +-- ----------------------------
  281 +BEGIN;
  282 +COMMIT;
231 283
232 --- sku  
233 -drop table if exists product_sku;  
234 -create table product_sku  
235 -(  
236 - id bigint NOT NULL AUTO_INCREMENT COMMENT '主键',  
237 - spu_id bigint not null comment 'spu编号',  
238 - properties varchar(64) not null comment '规格值数组-json格式, [{propertId: , valueId: }, {propertId: , valueId: }]',  
239 - price int not null DEFAULT -1 comment '销售价格,单位:分',  
240 - original_price int not null DEFAULT -1 comment '原价, 单位: 分',  
241 - cost_price int not null DEFAULT -1 comment '成本价,单位: 分',  
242 - bar_code varchar(64) not null comment '条形码',  
243 - pic_url VARCHAR(128) not null comment '图片地址',  
244 - status tinyint comment '状态: 0-正常 1-禁用',  
245 - create_time datetime default current_timestamp comment '创建时间',  
246 - update_time datetime default current_timestamp on update current_timestamp comment '更新时间',  
247 - creator varchar(64) comment '创建人',  
248 - updater varchar(64) comment '更新人',  
249 - tenant_id bigint NOT NULL DEFAULT '0' COMMENT '租户编号',  
250 - deleted bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',  
251 - primary key (id)  
252 -) comment '商品sku' character set utf8mb4  
253 - collate utf8mb4_general_ci; 284 +SET FOREIGN_KEY_CHECKS = 1;
254 285
  286 +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2000, '商品中心', '', 1, 60, 0, '/product', 'merchant', NULL, 0, b'1', b'1', '', '2022-07-29 15:53:53', '1', '2022-07-30 22:26:19', b'0');
  287 +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2002, '商品分类', '', 2, 2, 2000, 'category', 'dict', 'mall/product/category/index', 0, b'1', b'1', '', '2022-07-29 15:53:53', '1', '2022-07-30 22:23:37', b'0');
  288 +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2003, '分类查询', 'product:category:query', 3, 1, 2002, '', '', '', 0, b'1', b'1', '', '2022-07-29 15:53:53', '', '2022-07-29 15:53:53', b'0');
  289 +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2004, '分类创建', 'product:category:create', 3, 2, 2002, '', '', '', 0, b'1', b'1', '', '2022-07-29 15:53:53', '', '2022-07-29 15:53:53', b'0');
  290 +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2005, '分类更新', 'product:category:update', 3, 3, 2002, '', '', '', 0, b'1', b'1', '', '2022-07-29 15:53:53', '', '2022-07-29 15:53:53', b'0');
  291 +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2006, '分类删除', 'product:category:delete', 3, 4, 2002, '', '', '', 0, b'1', b'1', '', '2022-07-29 15:53:53', '', '2022-07-29 15:53:53', b'0');
  292 +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2007, '分类导出', 'product:category:export', 3, 5, 2002, '', '', '', 0, b'1', b'1', '', '2022-07-29 15:53:53', '', '2022-07-30 13:52:13', b'1');
  293 +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2008, '商品品牌', '', 2, 1, 2000, 'brand', 'dashboard', 'mall/product/brand/index', 0, b'1', b'1', '', '2022-07-30 13:52:44', '1', '2022-07-30 22:23:43', b'0');
  294 +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2009, '品牌查询', 'product:brand:query', 3, 1, 2008, '', '', '', 0, b'1', b'1', '', '2022-07-30 13:52:44', '', '2022-07-30 13:52:44', b'0');
  295 +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2010, '品牌创建', 'product:brand:create', 3, 2, 2008, '', '', '', 0, b'1', b'1', '', '2022-07-30 13:52:44', '', '2022-07-30 13:52:44', b'0');
  296 +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2011, '品牌更新', 'product:brand:update', 3, 3, 2008, '', '', '', 0, b'1', b'1', '', '2022-07-30 13:52:44', '', '2022-07-30 13:52:44', b'0');
  297 +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2012, '品牌删除', 'product:brand:delete', 3, 4, 2008, '', '', '', 0, b'1', b'1', '', '2022-07-30 13:52:44', '', '2022-07-30 13:52:44', b'0');
  298 +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2013, '品牌导出', 'product:brand:export', 3, 5, 2008, '', '', '', 0, b'1', b'1', '', '2022-07-30 13:52:44', '', '2022-07-30 14:15:00', b'1');
  299 +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2014, '商品管理', '', 2, 0, 2000, 'spu', 'link', 'mall/product/spu/index', 0, b'1', b'1', '', '2022-07-30 14:22:58', '1', '2022-07-30 22:26:35', b'0');
  300 +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2015, '商品查询', 'product:spu:query', 3, 1, 2014, '', '', '', 0, b'1', b'1', '', '2022-07-30 14:22:58', '', '2022-07-30 14:22:58', b'0');
  301 +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2016, '商品创建', 'product:spu:create', 3, 2, 2014, '', '', '', 0, b'1', b'1', '', '2022-07-30 14:22:58', '', '2022-07-30 14:22:58', b'0');
  302 +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2017, '商品更新', 'product:spu:update', 3, 3, 2014, '', '', '', 0, b'1', b'1', '', '2022-07-30 14:22:58', '', '2022-07-30 14:22:58', b'0');
  303 +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2018, '商品删除', 'product:spu:delete', 3, 4, 2014, '', '', '', 0, b'1', b'1', '', '2022-07-30 14:22:58', '', '2022-07-30 14:22:58', b'0');
  304 +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2019, '规格管理', '', 2, 3, 2000, 'property', '', 'mall/product/property/index', 0, b'1', b'1', '', '2022-08-01 14:55:35', '', '2022-08-01 14:55:35', b'0');
  305 +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2020, '规格查询', 'product:property:query', 3, 1, 2019, '', '', '', 0, b'1', b'1', '', '2022-08-01 14:55:35', '', '2022-08-01 14:55:35', b'0');
  306 +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2021, '规格创建', 'product:property:create', 3, 2, 2019, '', '', '', 0, b'1', b'1', '', '2022-08-01 14:55:35', '', '2022-08-01 14:55:35', b'0');
  307 +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2022, '规格更新', 'product:property:update', 3, 3, 2019, '', '', '', 0, b'1', b'1', '', '2022-08-01 14:55:35', '', '2022-08-01 14:55:35', b'0');
  308 +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2023, '规格删除', 'product:property:delete', 3, 4, 2019, '', '', '', 0, b'1', b'1', '', '2022-08-01 14:55:35', '', '2022-08-01 14:55:35', b'0');
  309 +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2024, '规格导出', 'product:property:export', 3, 5, 2019, '', '', '', 0, b'1', b'1', '', '2022-08-01 14:55:35', '', '2022-08-01 14:55:35', b'0');
  310 +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2025, 'Banner管理', '', 2, 1, 2000, 'brand', '', 'mall/market/banner/index', 0, b'1', b'1', '', '2022-08-01 14:56:14', '', '2022-08-01 14:56:14', b'0');
  311 +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2026, 'Banner查询', 'market:banner:query', 3, 1, 2025, '', '', '', 0, b'1', b'1', '', '2022-08-01 14:56:14', '', '2022-08-01 14:56:14', b'0');
  312 +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2027, 'Banner创建', 'market:banner:create', 3, 2, 2025, '', '', '', 0, b'1', b'1', '', '2022-08-01 14:56:14', '', '2022-08-01 14:56:14', b'0');
  313 +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2028, 'Banner更新', 'market:banner:update', 3, 3, 2025, '', '', '', 0, b'1', b'1', '', '2022-08-01 14:56:14', '', '2022-08-01 14:56:14', b'0');
  314 +INSERT INTO `ruoyi-vue-pro`.`system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`, `visible`, `keep_alive`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2029, 'Banner删除', 'market:banner:delete', 3, 4, 2025, '', '', '', 0, b'1', b'1', '', '2022-08-01 14:56:14', '', '2022-08-01 14:56:14', b'0');
255 315
256 --- Market-Banner管理SQL  
257 -drop table if exists market_banner;  
258 -CREATE TABLE `market_banner` (  
259 - `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'Banner编号',  
260 - `title` varchar(64) NOT NULL DEFAULT '' COMMENT 'Banner标题',  
261 - `pic_url` varchar(255) NOT NULL COMMENT '图片URL',  
262 - `status` tinyint(4) NOT NULL DEFAULT '-1' COMMENT '活动状态',  
263 - `url` varchar(255) NOT NULL COMMENT '跳转地址',  
264 - `creator` varchar(64) DEFAULT '' COMMENT '创建者',  
265 - `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',  
266 - `updater` varchar(64) DEFAULT '' COMMENT '更新者',  
267 - `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',  
268 - `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',  
269 - `tenant_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '租户编号',  
270 - `sort` tinyint(4) DEFAULT NULL COMMENT '排序',  
271 - `memo` varchar(255) DEFAULT NULL COMMENT '描述',  
272 - PRIMARY KEY (`id`) USING BTREE  
273 -) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COMMENT='Banner管理';  
274 --- 菜单 SQL  
275 -INSERT INTO `system_menu`(`id`,`name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`)  
276 -VALUES (2026, 'Banner管理', '', 2, 1, 2000, 'brand', '', 'mall/market/banner/index', 0);  
277 --- 按钮父菜单ID  
278 -SELECT @parentId := LAST_INSERT_ID();  
279 --- 按钮 SQL  
280 -INSERT INTO `system_menu`(`name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`)  
281 -VALUES ('Banner查询', 'market:banner:query', 3, 1, @parentId, '', '', '', 0);  
282 -INSERT INTO `system_menu`(`name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`)  
283 -VALUES ('Banner创建', 'market:banner:create', 3, 2, @parentId, '', '', '', 0);  
284 -INSERT INTO `system_menu`(`name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`)  
285 -VALUES ('Banner更新', 'market:banner:update', 3, 3, @parentId, '', '', '', 0);  
286 -INSERT INTO `system_menu`(`name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `status`)  
287 -VALUES ('Banner删除', 'market:banner:delete', 3, 4, @parentId, '', '', '', 0);  
sql/optional/mall/order.sql 0 → 100644
  1 +/**todo cancelType 设置默认值 0?*/
  2 +CREATE TABLE `trade_order`
  3 +(
  4 + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '用户ID',
  5 + `sn` varchar(32) NOT NULL COMMENT '订单流水号',
  6 + `type` int NOT NULL DEFAULT '0' COMMENT '订单类型:[0:普通订单 1:秒杀订单 2:拼团订单 3:砍价订单]',
  7 + `terminal` int NOT NULL COMMENT '订单来源终端:[1:小程序 2:H5 3:iOS 4:安卓]',
  8 + `user_id` bigint unsigned NOT NULL COMMENT '用户编号',
  9 + `user_ip` varchar(30) NOT NULL DEFAULT '' COMMENT '用户 IP',
  10 + `user_remark` varchar(200) DEFAULT NULL COMMENT '用户备注',
  11 + `status` int NOT NULL DEFAULT '0' COMMENT '订单状态:[0:待付款 1:待发货 2:待收货 3:已完成 4:已关闭]',
  12 + `product_count` int NOT NULL COMMENT '购买的商品数量',
  13 + `cancel_type` int NOT NULL COMMENT '取消类型:[10:超时未支付 20:退款关闭 30:买家取消 40:已通过货到付款交易]',
  14 + `remark` varchar(200) DEFAULT NULL COMMENT '商家备注',
  15 + `payed` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否已支付:[0:未支付 1:已经支付过]',
  16 + `finish_time` datetime DEFAULT NULL COMMENT '订单完成时间',
  17 + `cancel_time` datetime DEFAULT NULL COMMENT '订单取消时间',
  18 + `sku_original_price` int NOT NULL DEFAULT '0' COMMENT '商品原价(总),单位:分',
  19 + `sku_promotion_price` int NOT NULL DEFAULT '0' COMMENT '商品优惠(总),单位:分',
  20 + `order_promotion_price` int NOT NULL DEFAULT '0' COMMENT '订单优惠(总),单位:分',
  21 + `delivery_price` int NOT NULL DEFAULT '0' COMMENT '运费金额,单位:分',
  22 + `pay_price` int NOT NULL DEFAULT '0' COMMENT '应付金额(总),单位:分',
  23 + `pay_order_id` int NOT NULL COMMENT '支付订单编号',
  24 + `pay_channel` int NOT NULL COMMENT '支付成功的支付渠道',
  25 + `delivery_type` int NOT NULL DEFAULT '1' COMMENT '配送方式:[1:快递发货 2:自提]',
  26 + `actual_delivery_type` int NOT NULL DEFAULT '1' COMMENT '实际的配送方式:[1:快递发货 2:自提]',
  27 + `delivery_templateid` int DEFAULT NULL COMMENT '配置模板的编号',
  28 + `express_no` int DEFAULT NULL COMMENT '物流公司单号',
  29 + `delivery_status` bit(1) NOT NULL DEFAULT b'0' COMMENT '发货状态[0:未发货 1:已发货]',
  30 + `delivery_time` datetime DEFAULT NULL COMMENT '发货时间',
  31 + `receive_time` datetime DEFAULT NULL COMMENT '收货时间',
  32 + `receiver_name` varchar(20) NOT NULL COMMENT '收件人名称',
  33 + `receiver_mobile` varchar(20) NOT NULL COMMENT '收件人手机',
  34 + `receiver_area_id` int NOT NULL COMMENT '收件人地区编号',
  35 + `receiver_post_code` int DEFAULT NULL COMMENT '收件人邮编',
  36 + `receiver_detail_address` varchar(255) NOT NULL COMMENT '收件人详细地址',
  37 + `refund_status` int NOT NULL DEFAULT '0' COMMENT '订单状态:[0:未退款 1:部分退款 2:全部退款]',
  38 + `refund_price` int NOT NULL DEFAULT '0' COMMENT '退款金额,单位:分',
  39 + `coupon_id` bigint unsigned NOT NULL COMMENT '优惠劵编号',
  40 + `creator` varchar(64) DEFAULT '' COMMENT '创建者',
  41 + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  42 + `updater` varchar(64) DEFAULT '' COMMENT '更新者',
  43 + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  44 + `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
  45 + PRIMARY KEY (`id`) USING BTREE
  46 +) ENGINE = InnoDB COMMENT ='交易订单表';
  47 +
  48 +
  49 +DROP TABLE IF EXISTS `trade_order_item`;
  50 +CREATE TABLE `trade_order_item`
  51 +(
  52 + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '用户ID',
  53 + `user_id` bigint unsigned NOT NULL COMMENT '用户编号',
  54 + `order_Id` bigint unsigned NOT NULL COMMENT '订单编号',
  55 + `spu_id` bigint unsigned NOT NULL COMMENT '商品 SPU 编号',
  56 + `sku_id` bigint unsigned NOT NULL COMMENT '商品 SKU 编号',
  57 + `properties` json DEFAULT NULL COMMENT '规格值数组,JSON 格式',
  58 + `name` varchar(128) NOT NULL DEFAULT '' COMMENT '商品名称',
  59 + `pic_url` varchar(200) DEFAULT NULL COMMENT '商品图片',
  60 + `count` int NOT NULL COMMENT '购买数量',
  61 + `commented` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否评论:[0:未评论 1:已评论]',
  62 + `original_price` int NOT NULL DEFAULT '0' COMMENT '商品原价(单),单位:分',
  63 + `total_original_price` int NOT NULL DEFAULT '0' COMMENT '商品原价(总),单位:分',
  64 + `total_promotion_price` int NOT NULL DEFAULT '0' COMMENT '商品级优惠(总),单位:分',
  65 + `present_price` int NOT NULL DEFAULT '0' COMMENT '最终购买金额(单),单位:分。',
  66 + `total_present_price` int NOT NULL DEFAULT '0' COMMENT '最终购买金额(总),单位:分。',
  67 + `total_pay_price` int NOT NULL DEFAULT '0' COMMENT '应付金额(总),单位:分',
  68 + `refund_status` int NOT NULL DEFAULT '0' COMMENT '退款状态:[0:未申请退款 1:申请退款 2:等待退款 3:退款成功]',
  69 + `refund_total` int NOT NULL DEFAULT '0' COMMENT '退款总金额,单位:分',
  70 + `creator` varchar(64) DEFAULT '' COMMENT '创建者',
  71 + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  72 + `updater` varchar(64) DEFAULT '' COMMENT '更新者',
  73 + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  74 + `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
  75 + PRIMARY KEY (`id`) USING BTREE
  76 +) ENGINE = InnoDB COMMENT ='交易订单明细表';
0 \ No newline at end of file 77 \ No newline at end of file
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/enums/TerminalEnum.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.common.enums;
  2 +
  3 +import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
  4 +import lombok.Getter;
  5 +import lombok.RequiredArgsConstructor;
  6 +
  7 +import java.util.Arrays;
  8 +
  9 +/**
  10 + * 终端的枚举
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +@RequiredArgsConstructor
  15 +@Getter
  16 +public enum TerminalEnum implements IntArrayValuable {
  17 +
  18 + //TODO terminal 重复,请参考 '订单来源终端:[1:小程序 2:H5 3:iOS 4:安卓]'
  19 + MINI_PROGRAM(1, "小程序"),
  20 + H5(2, "H5"),
  21 + IOS(3, "iOS"),
  22 + ANDROID(3, "安卓"),;
  23 +
  24 + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(TerminalEnum::getTerminal).toArray();
  25 +
  26 + /**
  27 + * 终端
  28 + */
  29 + private final Integer terminal;
  30 + /**
  31 + * 终端名
  32 + */
  33 + private final String name;
  34 +
  35 + @Override
  36 + public int[] array() {
  37 + return ARRAYS;
  38 + }
  39 +}
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/collection/CollectionUtils.java
@@ -173,6 +173,23 @@ public class CollectionUtils { @@ -173,6 +173,23 @@ public class CollectionUtils {
173 return valueFunc.apply(t); 173 return valueFunc.apply(t);
174 } 174 }
175 175
  176 + public static <T, V extends Comparable<? super V>> V getMinValue(List<T> from, Function<T, V> valueFunc) {
  177 + if (CollUtil.isEmpty(from)) {
  178 + return null;
  179 + }
  180 + assert from.size() > 0; // 断言,避免告警
  181 + T t = from.stream().min(Comparator.comparing(valueFunc)).get();
  182 + return valueFunc.apply(t);
  183 + }
  184 +
  185 + public static <T, V extends Comparable<? super V>> V getSumValue(List<T> from, Function<T, V> valueFunc, BinaryOperator<V> accumulator) {
  186 + if (CollUtil.isEmpty(from)) {
  187 + return null;
  188 + }
  189 + assert from.size() > 0; // 断言,避免告警
  190 + return from.stream().map(valueFunc).reduce(accumulator).get();
  191 + }
  192 +
176 public static <T> void addIfNotNull(Collection<T> coll, T item) { 193 public static <T> void addIfNotNull(Collection<T> coll, T item) {
177 if (item == null) { 194 if (item == null) {
178 return; 195 return;
yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/core/db/DataPermissionDatabaseInterceptor.java
@@ -18,7 +18,6 @@ import net.sf.jsqlparser.expression.operators.conditional.OrExpression; @@ -18,7 +18,6 @@ import net.sf.jsqlparser.expression.operators.conditional.OrExpression;
18 import net.sf.jsqlparser.expression.operators.relational.ExistsExpression; 18 import net.sf.jsqlparser.expression.operators.relational.ExistsExpression;
19 import net.sf.jsqlparser.expression.operators.relational.ExpressionList; 19 import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
20 import net.sf.jsqlparser.expression.operators.relational.InExpression; 20 import net.sf.jsqlparser.expression.operators.relational.InExpression;
21 -import net.sf.jsqlparser.expression.operators.relational.ItemsList;  
22 import net.sf.jsqlparser.schema.Table; 21 import net.sf.jsqlparser.schema.Table;
23 import net.sf.jsqlparser.statement.delete.Delete; 22 import net.sf.jsqlparser.statement.delete.Delete;
24 import net.sf.jsqlparser.statement.select.*; 23 import net.sf.jsqlparser.statement.select.*;
@@ -37,7 +36,7 @@ import java.util.concurrent.ConcurrentHashMap; @@ -37,7 +36,7 @@ import java.util.concurrent.ConcurrentHashMap;
37 36
38 /** 37 /**
39 * 数据权限拦截器,通过 {@link DataPermissionRule} 数据权限规则,重写 SQL 的方式来实现 38 * 数据权限拦截器,通过 {@link DataPermissionRule} 数据权限规则,重写 SQL 的方式来实现
40 - * 主要的 SQL 重写方法,可见 {@link #builderExpression(Expression, Table)} 方法 39 + * 主要的 SQL 重写方法,可见 {@link #builderExpression(Expression, List)} 方法
41 * 40 *
42 * 整体的代码实现上,参考 {@link com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor} 实现。 41 * 整体的代码实现上,参考 {@link com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor} 实现。
43 * 所以每次 MyBatis Plus 升级时,需要 Review 下其具体的实现是否有变更! 42 * 所以每次 MyBatis Plus 升级时,需要 Review 下其具体的实现是否有变更!
@@ -53,8 +52,7 @@ public class DataPermissionDatabaseInterceptor extends JsqlParserSupport impleme @@ -53,8 +52,7 @@ public class DataPermissionDatabaseInterceptor extends JsqlParserSupport impleme
53 private final MappedStatementCache mappedStatementCache = new MappedStatementCache(); 52 private final MappedStatementCache mappedStatementCache = new MappedStatementCache();
54 53
55 @Override // SELECT 场景 54 @Override // SELECT 场景
56 - public void beforeQuery(Executor executor, MappedStatement ms, Object parameter,  
57 - RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) { 55 + public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
58 // 获得 Mapper 对应的数据权限的规则 56 // 获得 Mapper 对应的数据权限的规则
59 List<DataPermissionRule> rules = ruleFactory.getDataPermissionRule(ms.getId()); 57 List<DataPermissionRule> rules = ruleFactory.getDataPermissionRule(ms.getId());
60 if (mappedStatementCache.noRewritable(ms, rules)) { // 如果无需重写,则跳过 58 if (mappedStatementCache.noRewritable(ms, rules)) { // 如果无需重写,则跳过
@@ -68,12 +66,14 @@ public class DataPermissionDatabaseInterceptor extends JsqlParserSupport impleme @@ -68,12 +66,14 @@ public class DataPermissionDatabaseInterceptor extends JsqlParserSupport impleme
68 // 处理 SQL 66 // 处理 SQL
69 mpBs.sql(parserSingle(mpBs.sql(), null)); 67 mpBs.sql(parserSingle(mpBs.sql(), null));
70 } finally { 68 } finally {
  69 + // 添加是否需要重写的缓存
71 addMappedStatementCache(ms); 70 addMappedStatementCache(ms);
  71 + // 清空上下文
72 ContextHolder.clear(); 72 ContextHolder.clear();
73 } 73 }
74 } 74 }
75 75
76 - @Override // 只处理 UPDATE / DELETE 场景,不处理 INSERT 场景 76 + @Override // 只处理 UPDATE / DELETE 场景,不处理 INSERT 场景(因为 INSERT 不需要数据权限)
77 public void beforePrepare(StatementHandler sh, Connection connection, Integer transactionTimeout) { 77 public void beforePrepare(StatementHandler sh, Connection connection, Integer transactionTimeout) {
78 PluginUtils.MPStatementHandler mpSh = PluginUtils.mpStatementHandler(sh); 78 PluginUtils.MPStatementHandler mpSh = PluginUtils.mpStatementHandler(sh);
79 MappedStatement ms = mpSh.mappedStatement(); 79 MappedStatement ms = mpSh.mappedStatement();
@@ -92,7 +92,9 @@ public class DataPermissionDatabaseInterceptor extends JsqlParserSupport impleme @@ -92,7 +92,9 @@ public class DataPermissionDatabaseInterceptor extends JsqlParserSupport impleme
92 // 处理 SQL 92 // 处理 SQL
93 mpBs.sql(parserMulti(mpBs.sql(), null)); 93 mpBs.sql(parserMulti(mpBs.sql(), null));
94 } finally { 94 } finally {
  95 + // 添加是否需要重写的缓存
95 addMappedStatementCache(ms); 96 addMappedStatementCache(ms);
  97 + // 清空上下文
96 ContextHolder.clear(); 98 ContextHolder.clear();
97 } 99 }
98 } 100 }
@@ -107,24 +109,6 @@ public class DataPermissionDatabaseInterceptor extends JsqlParserSupport impleme @@ -107,24 +109,6 @@ public class DataPermissionDatabaseInterceptor extends JsqlParserSupport impleme
107 } 109 }
108 } 110 }
109 111
110 - protected void processSelectBody(SelectBody selectBody) {  
111 - if (selectBody == null) {  
112 - return;  
113 - }  
114 - if (selectBody instanceof PlainSelect) {  
115 - processPlainSelect((PlainSelect) selectBody);  
116 - } else if (selectBody instanceof WithItem) {  
117 - WithItem withItem = (WithItem) selectBody;  
118 - processSelectBody(withItem.getSubSelect().getSelectBody());  
119 - } else {  
120 - SetOperationList operationList = (SetOperationList) selectBody;  
121 - List<SelectBody> selectBodys = operationList.getSelects();  
122 - if (CollectionUtils.isNotEmpty(selectBodys)) {  
123 - selectBodys.forEach(this::processSelectBody);  
124 - }  
125 - }  
126 - }  
127 -  
128 /** 112 /**
129 * update 语句处理 113 * update 语句处理
130 */ 114 */
@@ -142,28 +126,77 @@ public class DataPermissionDatabaseInterceptor extends JsqlParserSupport impleme @@ -142,28 +126,77 @@ public class DataPermissionDatabaseInterceptor extends JsqlParserSupport impleme
142 delete.setWhere(this.builderExpression(delete.getWhere(), delete.getTable())); 126 delete.setWhere(this.builderExpression(delete.getWhere(), delete.getTable()));
143 } 127 }
144 128
  129 + // ========== 和 TenantLineInnerInterceptor 一致的逻辑 ==========
  130 +
  131 + protected void processSelectBody(SelectBody selectBody) {
  132 + if (selectBody == null) {
  133 + return;
  134 + }
  135 + if (selectBody instanceof PlainSelect) {
  136 + processPlainSelect((PlainSelect) selectBody);
  137 + } else if (selectBody instanceof WithItem) {
  138 + WithItem withItem = (WithItem) selectBody;
  139 + processSelectBody(withItem.getSubSelect().getSelectBody());
  140 + } else {
  141 + SetOperationList operationList = (SetOperationList) selectBody;
  142 + List<SelectBody> selectBodyList = operationList.getSelects();
  143 + if (CollectionUtils.isNotEmpty(selectBodyList)) {
  144 + selectBodyList.forEach(this::processSelectBody);
  145 + }
  146 + }
  147 + }
  148 +
145 /** 149 /**
146 * 处理 PlainSelect 150 * 处理 PlainSelect
147 */ 151 */
148 protected void processPlainSelect(PlainSelect plainSelect) { 152 protected void processPlainSelect(PlainSelect plainSelect) {
149 - FromItem fromItem = plainSelect.getFromItem();  
150 - Expression where = plainSelect.getWhere();  
151 - processWhereSubSelect(where);  
152 - if (fromItem instanceof Table) {  
153 - Table fromTable = (Table) fromItem;  
154 - plainSelect.setWhere(builderExpression(where, fromTable));  
155 - } else {  
156 - processFromItem(fromItem);  
157 - }  
158 //#3087 github 153 //#3087 github
159 List<SelectItem> selectItems = plainSelect.getSelectItems(); 154 List<SelectItem> selectItems = plainSelect.getSelectItems();
160 if (CollectionUtils.isNotEmpty(selectItems)) { 155 if (CollectionUtils.isNotEmpty(selectItems)) {
161 selectItems.forEach(this::processSelectItem); 156 selectItems.forEach(this::processSelectItem);
162 } 157 }
  158 +
  159 + // 处理 where 中的子查询
  160 + Expression where = plainSelect.getWhere();
  161 + processWhereSubSelect(where);
  162 +
  163 + // 处理 fromItem
  164 + FromItem fromItem = plainSelect.getFromItem();
  165 + List<Table> list = processFromItem(fromItem);
  166 + List<Table> mainTables = new ArrayList<>(list);
  167 +
  168 + // 处理 join
163 List<Join> joins = plainSelect.getJoins(); 169 List<Join> joins = plainSelect.getJoins();
164 if (CollectionUtils.isNotEmpty(joins)) { 170 if (CollectionUtils.isNotEmpty(joins)) {
165 - processJoins(joins); 171 + mainTables = processJoins(mainTables, joins);
  172 + }
  173 +
  174 + // 当有 mainTable 时,进行 where 条件追加
  175 + if (CollectionUtils.isNotEmpty(mainTables)) {
  176 + plainSelect.setWhere(builderExpression(where, mainTables));
  177 + }
  178 + }
  179 +
  180 + private List<Table> processFromItem(FromItem fromItem) {
  181 + // 处理括号括起来的表达式
  182 + while (fromItem instanceof ParenthesisFromItem) {
  183 + fromItem = ((ParenthesisFromItem) fromItem).getFromItem();
  184 + }
  185 +
  186 + List<Table> mainTables = new ArrayList<>();
  187 + // 无 join 时的处理逻辑
  188 + if (fromItem instanceof Table) {
  189 + Table fromTable = (Table) fromItem;
  190 + mainTables.add(fromTable);
  191 + } else if (fromItem instanceof SubJoin) {
  192 + // SubJoin 类型则还需要添加上 where 条件
  193 + List<Table> tables = processSubJoin((SubJoin) fromItem);
  194 + mainTables.addAll(tables);
  195 + } else {
  196 + // 处理下 fromItem
  197 + processOtherFromItem(fromItem);
166 } 198 }
  199 + return mainTables;
167 } 200 }
168 201
169 /** 202 /**
@@ -191,7 +224,7 @@ public class DataPermissionDatabaseInterceptor extends JsqlParserSupport impleme @@ -191,7 +224,7 @@ public class DataPermissionDatabaseInterceptor extends JsqlParserSupport impleme
191 return; 224 return;
192 } 225 }
193 if (where instanceof FromItem) { 226 if (where instanceof FromItem) {
194 - processFromItem((FromItem) where); 227 + processOtherFromItem((FromItem) where);
195 return; 228 return;
196 } 229 }
197 if (where.toString().indexOf("SELECT") > 0) { 230 if (where.toString().indexOf("SELECT") > 0) {
@@ -204,9 +237,9 @@ public class DataPermissionDatabaseInterceptor extends JsqlParserSupport impleme @@ -204,9 +237,9 @@ public class DataPermissionDatabaseInterceptor extends JsqlParserSupport impleme
204 } else if (where instanceof InExpression) { 237 } else if (where instanceof InExpression) {
205 // in 238 // in
206 InExpression expression = (InExpression) where; 239 InExpression expression = (InExpression) where;
207 - ItemsList itemsList = expression.getRightItemsList();  
208 - if (itemsList instanceof SubSelect) {  
209 - processSelectBody(((SubSelect) itemsList).getSelectBody()); 240 + Expression inExpression = expression.getRightExpression();
  241 + if (inExpression instanceof SubSelect) {
  242 + processSelectBody(((SubSelect) inExpression).getSelectBody());
210 } 243 }
211 } else if (where instanceof ExistsExpression) { 244 } else if (where instanceof ExistsExpression) {
212 // exists 245 // exists
@@ -239,7 +272,7 @@ public class DataPermissionDatabaseInterceptor extends JsqlParserSupport impleme @@ -239,7 +272,7 @@ public class DataPermissionDatabaseInterceptor extends JsqlParserSupport impleme
239 * <p>支持: 1. select fun(args..) 2. select fun1(fun2(args..),args..)<p> 272 * <p>支持: 1. select fun(args..) 2. select fun1(fun2(args..),args..)<p>
240 * <p> fixed gitee pulls/141</p> 273 * <p> fixed gitee pulls/141</p>
241 * 274 *
242 - * @param function 函数 275 + * @param function
243 */ 276 */
244 protected void processFunction(Function function) { 277 protected void processFunction(Function function) {
245 ExpressionList parameters = function.getParameters(); 278 ExpressionList parameters = function.getParameters();
@@ -257,22 +290,19 @@ public class DataPermissionDatabaseInterceptor extends JsqlParserSupport impleme @@ -257,22 +290,19 @@ public class DataPermissionDatabaseInterceptor extends JsqlParserSupport impleme
257 /** 290 /**
258 * 处理子查询等 291 * 处理子查询等
259 */ 292 */
260 - protected void processFromItem(FromItem fromItem) {  
261 - if (fromItem instanceof SubJoin) {  
262 - SubJoin subJoin = (SubJoin) fromItem;  
263 - if (subJoin.getJoinList() != null) {  
264 - processJoins(subJoin.getJoinList());  
265 - }  
266 - if (subJoin.getLeft() != null) {  
267 - processFromItem(subJoin.getLeft());  
268 - }  
269 - } else if (fromItem instanceof SubSelect) { 293 + protected void processOtherFromItem(FromItem fromItem) {
  294 + // 去除括号
  295 + while (fromItem instanceof ParenthesisFromItem) {
  296 + fromItem = ((ParenthesisFromItem) fromItem).getFromItem();
  297 + }
  298 +
  299 + if (fromItem instanceof SubSelect) {
270 SubSelect subSelect = (SubSelect) fromItem; 300 SubSelect subSelect = (SubSelect) fromItem;
271 if (subSelect.getSelectBody() != null) { 301 if (subSelect.getSelectBody() != null) {
272 processSelectBody(subSelect.getSelectBody()); 302 processSelectBody(subSelect.getSelectBody());
273 } 303 }
274 } else if (fromItem instanceof ValuesList) { 304 } else if (fromItem instanceof ValuesList) {
275 - logger.debug("Perform a subquery, if you do not give us feedback"); 305 + logger.debug("Perform a subQuery, if you do not give us feedback");
276 } else if (fromItem instanceof LateralSubSelect) { 306 } else if (fromItem instanceof LateralSubSelect) {
277 LateralSubSelect lateralSubSelect = (LateralSubSelect) fromItem; 307 LateralSubSelect lateralSubSelect = (LateralSubSelect) fromItem;
278 if (lateralSubSelect.getSubSelect() != null) { 308 if (lateralSubSelect.getSubSelect() != null) {
@@ -285,74 +315,175 @@ public class DataPermissionDatabaseInterceptor extends JsqlParserSupport impleme @@ -285,74 +315,175 @@ public class DataPermissionDatabaseInterceptor extends JsqlParserSupport impleme
285 } 315 }
286 316
287 /** 317 /**
  318 + * 处理 sub join
  319 + *
  320 + * @param subJoin subJoin
  321 + * @return Table subJoin 中的主表
  322 + */
  323 + private List<Table> processSubJoin(SubJoin subJoin) {
  324 + List<Table> mainTables = new ArrayList<>();
  325 + if (subJoin.getJoinList() != null) {
  326 + List<Table> list = processFromItem(subJoin.getLeft());
  327 + mainTables.addAll(list);
  328 + mainTables = processJoins(mainTables, subJoin.getJoinList());
  329 + }
  330 + return mainTables;
  331 + }
  332 +
  333 + /**
288 * 处理 joins 334 * 处理 joins
289 * 335 *
290 - * @param joins join 集合 336 + * @param mainTables 可以为 null
  337 + * @param joins join 集合
  338 + * @return List<Table> 右连接查询的 Table 列表
291 */ 339 */
292 - private void processJoins(List<Join> joins) { 340 + private List<Table> processJoins(List<Table> mainTables, List<Join> joins) {
  341 + // join 表达式中最终的主表
  342 + Table mainTable = null;
  343 + // 当前 join 的左表
  344 + Table leftTable = null;
  345 +
  346 + if (mainTables == null) {
  347 + mainTables = new ArrayList<>();
  348 + } else if (mainTables.size() == 1) {
  349 + mainTable = mainTables.get(0);
  350 + leftTable = mainTable;
  351 + }
  352 +
293 //对于 on 表达式写在最后的 join,需要记录下前面多个 on 的表名 353 //对于 on 表达式写在最后的 join,需要记录下前面多个 on 的表名
294 - Deque<Table> tables = new LinkedList<>(); 354 + Deque<List<Table>> onTableDeque = new LinkedList<>();
295 for (Join join : joins) { 355 for (Join join : joins) {
296 // 处理 on 表达式 356 // 处理 on 表达式
297 - FromItem fromItem = join.getRightItem();  
298 - if (fromItem instanceof Table) {  
299 - Table fromTable = (Table) fromItem; 357 + FromItem joinItem = join.getRightItem();
  358 +
  359 + // 获取当前 join 的表,subJoint 可以看作是一张表
  360 + List<Table> joinTables = null;
  361 + if (joinItem instanceof Table) {
  362 + joinTables = new ArrayList<>();
  363 + joinTables.add((Table) joinItem);
  364 + } else if (joinItem instanceof SubJoin) {
  365 + joinTables = processSubJoin((SubJoin) joinItem);
  366 + }
  367 +
  368 + if (joinTables != null) {
  369 +
  370 + // 如果是隐式内连接
  371 + if (join.isSimple()) {
  372 + mainTables.addAll(joinTables);
  373 + continue;
  374 + }
  375 +
  376 + // 当前表是否忽略
  377 + Table joinTable = joinTables.get(0);
  378 +
  379 + List<Table> onTables = null;
  380 + // 如果不要忽略,且是右连接,则记录下当前表
  381 + if (join.isRight()) {
  382 + mainTable = joinTable;
  383 + if (leftTable != null) {
  384 + onTables = Collections.singletonList(leftTable);
  385 + }
  386 + } else if (join.isLeft()) {
  387 + onTables = Collections.singletonList(joinTable);
  388 + } else if (join.isInner()) {
  389 + if (mainTable == null) {
  390 + onTables = Collections.singletonList(joinTable);
  391 + } else {
  392 + onTables = Arrays.asList(mainTable, joinTable);
  393 + }
  394 + mainTable = null;
  395 + }
  396 +
  397 + mainTables = new ArrayList<>();
  398 + if (mainTable != null) {
  399 + mainTables.add(mainTable);
  400 + }
  401 +
300 // 获取 join 尾缀的 on 表达式列表 402 // 获取 join 尾缀的 on 表达式列表
301 Collection<Expression> originOnExpressions = join.getOnExpressions(); 403 Collection<Expression> originOnExpressions = join.getOnExpressions();
302 // 正常 join on 表达式只有一个,立刻处理 404 // 正常 join on 表达式只有一个,立刻处理
303 - if (originOnExpressions.size() == 1) {  
304 - processJoin(join); 405 + if (originOnExpressions.size() == 1 && onTables != null) {
  406 + List<Expression> onExpressions = new LinkedList<>();
  407 + onExpressions.add(builderExpression(originOnExpressions.iterator().next(), onTables));
  408 + join.setOnExpressions(onExpressions);
  409 + leftTable = joinTable;
305 continue; 410 continue;
306 } 411 }
307 - tables.push(fromTable); 412 + // 表名压栈,忽略的表压入 null,以便后续不处理
  413 + onTableDeque.push(onTables);
308 // 尾缀多个 on 表达式的时候统一处理 414 // 尾缀多个 on 表达式的时候统一处理
309 if (originOnExpressions.size() > 1) { 415 if (originOnExpressions.size() > 1) {
310 Collection<Expression> onExpressions = new LinkedList<>(); 416 Collection<Expression> onExpressions = new LinkedList<>();
311 for (Expression originOnExpression : originOnExpressions) { 417 for (Expression originOnExpression : originOnExpressions) {
312 - Table currentTable = tables.poll();  
313 - onExpressions.add(builderExpression(originOnExpression, currentTable)); 418 + List<Table> currentTableList = onTableDeque.poll();
  419 + if (CollectionUtils.isEmpty(currentTableList)) {
  420 + onExpressions.add(originOnExpression);
  421 + } else {
  422 + onExpressions.add(builderExpression(originOnExpression, currentTableList));
  423 + }
314 } 424 }
315 join.setOnExpressions(onExpressions); 425 join.setOnExpressions(onExpressions);
316 } 426 }
  427 + leftTable = joinTable;
317 } else { 428 } else {
318 - // 处理右边连接的子表达式  
319 - processFromItem(fromItem); 429 + processOtherFromItem(joinItem);
  430 + leftTable = null;
320 } 431 }
321 } 432 }
  433 +
  434 + return mainTables;
322 } 435 }
323 436
  437 + // ========== 和 TenantLineInnerInterceptor 存在差异的逻辑:关键,实现权限条件的拼接 ==========
  438 +
324 /** 439 /**
325 - * 处理联接语句 440 + * 处理条件
  441 + *
  442 + * @param currentExpression 当前 where 条件
  443 + * @param table 单个表
326 */ 444 */
327 - protected void processJoin(Join join) {  
328 - if (join.getRightItem() instanceof Table) {  
329 - Table fromTable = (Table) join.getRightItem();  
330 - Expression originOnExpression = CollUtil.getFirst(join.getOnExpressions());  
331 - originOnExpression = builderExpression(originOnExpression, fromTable);  
332 - join.setOnExpressions(CollUtil.newArrayList(originOnExpression));  
333 - } 445 + protected Expression builderExpression(Expression currentExpression, Table table) {
  446 + return this.builderExpression(currentExpression, Collections.singletonList(table));
334 } 447 }
335 448
336 /** 449 /**
337 * 处理条件 450 * 处理条件
  451 + *
  452 + * @param currentExpression 当前 where 条件
  453 + * @param tables 多个表
338 */ 454 */
339 - protected Expression builderExpression(Expression currentExpression, Table table) {  
340 - // 获得 Table 对应的数据权限条件  
341 - Expression equalsTo = buildDataPermissionExpression(table);  
342 - if (equalsTo == null) { // 如果没条件,则返回 currentExpression 默认 455 + protected Expression builderExpression(Expression currentExpression, List<Table> tables) {
  456 + // 没有表需要处理直接返回
  457 + if (CollectionUtils.isEmpty(tables)) {
343 return currentExpression; 458 return currentExpression;
344 } 459 }
345 460
346 - // 表达式为空,则直接返回 equalsTo 461 + // 第一步,获得 Table 对应的数据权限条件
  462 + Expression dataPermissionExpression = null;
  463 + for (Table table : tables) {
  464 + // 构建每个表的权限 Expression 条件
  465 + Expression expression = buildDataPermissionExpression(table);
  466 + if (expression == null) {
  467 + continue;
  468 + }
  469 + // 合并到 dataPermissionExpression 中
  470 + dataPermissionExpression = dataPermissionExpression == null ? expression
  471 + : new AndExpression(dataPermissionExpression, expression);
  472 + }
  473 +
  474 + // 第二步,合并多个 Expression 条件
  475 + if (dataPermissionExpression == null) {
  476 + return currentExpression;
  477 + }
347 if (currentExpression == null) { 478 if (currentExpression == null) {
348 - return equalsTo; 479 + return dataPermissionExpression;
349 } 480 }
350 - // 如果表达式为 Or,则需要 (currentExpression) AND equalsTo 481 + // ① 如果表达式为 Or,则需要 (currentExpression) AND dataPermissionExpression
351 if (currentExpression instanceof OrExpression) { 482 if (currentExpression instanceof OrExpression) {
352 - return new AndExpression(new Parenthesis(currentExpression), equalsTo); 483 + return new AndExpression(new Parenthesis(currentExpression), dataPermissionExpression);
353 } 484 }
354 - // 如果表达式为 And,则直接返回 currentExpression AND equalsTo  
355 - return new AndExpression(currentExpression, equalsTo); 485 + // ② 如果表达式为 And,则直接返回 where AND dataPermissionExpression
  486 + return new AndExpression(currentExpression, dataPermissionExpression);
356 } 487 }
357 488
358 /** 489 /**
yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/test/java/cn/iocoder/yudao/framework/datapermission/core/db/DataPermissionDatabaseInterceptorTest2.java
@@ -46,7 +46,7 @@ public class DataPermissionDatabaseInterceptorTest2 extends BaseMockitoUnitTest @@ -46,7 +46,7 @@ public class DataPermissionDatabaseInterceptorTest2 extends BaseMockitoUnitTest
46 46
47 @Override 47 @Override
48 public Set<String> getTableNames() { 48 public Set<String> getTableNames() {
49 - return asSet("entity", "entity1", "entity2", "t1", "t2", // 支持 MyBatis Plus 的单元测试 49 + return asSet("entity", "entity1", "entity2", "entity3", "t1", "t2", "sys_dict_item", // 支持 MyBatis Plus 的单元测试
50 "t_user", "t_role"); // 满足自己的单元测试 50 "t_user", "t_role"); // 满足自己的单元测试
51 } 51 }
52 52
@@ -84,30 +84,30 @@ public class DataPermissionDatabaseInterceptorTest2 extends BaseMockitoUnitTest @@ -84,30 +84,30 @@ public class DataPermissionDatabaseInterceptorTest2 extends BaseMockitoUnitTest
84 @Test 84 @Test
85 void delete() { 85 void delete() {
86 assertSql("delete from entity where id = ?", 86 assertSql("delete from entity where id = ?",
87 - "DELETE FROM entity WHERE id = ? AND tenant_id = 1"); 87 + "DELETE FROM entity WHERE id = ? AND entity.tenant_id = 1");
88 } 88 }
89 89
90 @Test 90 @Test
91 void update() { 91 void update() {
92 assertSql("update entity set name = ? where id = ?", 92 assertSql("update entity set name = ? where id = ?",
93 - "UPDATE entity SET name = ? WHERE id = ? AND tenant_id = 1"); 93 + "UPDATE entity SET name = ? WHERE id = ? AND entity.tenant_id = 1");
94 } 94 }
95 95
96 @Test 96 @Test
97 void selectSingle() { 97 void selectSingle() {
98 // 单表 98 // 单表
99 assertSql("select * from entity where id = ?", 99 assertSql("select * from entity where id = ?",
100 - "SELECT * FROM entity WHERE id = ? AND tenant_id = 1"); 100 + "SELECT * FROM entity WHERE id = ? AND entity.tenant_id = 1");
101 101
102 assertSql("select * from entity where id = ? or name = ?", 102 assertSql("select * from entity where id = ? or name = ?",
103 - "SELECT * FROM entity WHERE (id = ? OR name = ?) AND tenant_id = 1"); 103 + "SELECT * FROM entity WHERE (id = ? OR name = ?) AND entity.tenant_id = 1");
104 104
105 assertSql("SELECT * FROM entity WHERE (id = ? OR name = ?)", 105 assertSql("SELECT * FROM entity WHERE (id = ? OR name = ?)",
106 - "SELECT * FROM entity WHERE (id = ? OR name = ?) AND tenant_id = 1"); 106 + "SELECT * FROM entity WHERE (id = ? OR name = ?) AND entity.tenant_id = 1");
107 107
108 /* not */ 108 /* not */
109 assertSql("SELECT * FROM entity WHERE not (id = ? OR name = ?)", 109 assertSql("SELECT * FROM entity WHERE not (id = ? OR name = ?)",
110 - "SELECT * FROM entity WHERE NOT (id = ? OR name = ?) AND tenant_id = 1"); 110 + "SELECT * FROM entity WHERE NOT (id = ? OR name = ?) AND entity.tenant_id = 1");
111 } 111 }
112 112
113 @Test 113 @Test
@@ -167,10 +167,12 @@ public class DataPermissionDatabaseInterceptorTest2 extends BaseMockitoUnitTest @@ -167,10 +167,12 @@ public class DataPermissionDatabaseInterceptorTest2 extends BaseMockitoUnitTest
167 assertSql("SELECT * FROM entity e WHERE e.id >= (select e1.id from entity1 e1 where e1.id = ?)", 167 assertSql("SELECT * FROM entity e WHERE e.id >= (select e1.id from entity1 e1 where e1.id = ?)",
168 "SELECT * FROM entity e WHERE e.id >= (SELECT e1.id FROM entity1 e1 WHERE e1.id = ? AND e1.tenant_id = 1) AND e.tenant_id = 1"); 168 "SELECT * FROM entity e WHERE e.id >= (SELECT e1.id FROM entity1 e1 WHERE e1.id = ? AND e1.tenant_id = 1) AND e.tenant_id = 1");
169 169
  170 +
170 /* <= */ 171 /* <= */
171 assertSql("SELECT * FROM entity e WHERE e.id <= (select e1.id from entity1 e1 where e1.id = ?)", 172 assertSql("SELECT * FROM entity e WHERE e.id <= (select e1.id from entity1 e1 where e1.id = ?)",
172 "SELECT * FROM entity e WHERE e.id <= (SELECT e1.id FROM entity1 e1 WHERE e1.id = ? AND e1.tenant_id = 1) AND e.tenant_id = 1"); 173 "SELECT * FROM entity e WHERE e.id <= (SELECT e1.id FROM entity1 e1 WHERE e1.id = ? AND e1.tenant_id = 1) AND e.tenant_id = 1");
173 174
  175 +
174 /* <> */ 176 /* <> */
175 assertSql("SELECT * FROM entity e WHERE e.id <> (select e1.id from entity1 e1 where e1.id = ?)", 177 assertSql("SELECT * FROM entity e WHERE e.id <> (select e1.id from entity1 e1 where e1.id = ?)",
176 "SELECT * FROM entity e WHERE e.id <> (SELECT e1.id FROM entity1 e1 WHERE e1.id = ? AND e1.tenant_id = 1) AND e.tenant_id = 1"); 178 "SELECT * FROM entity e WHERE e.id <> (SELECT e1.id FROM entity1 e1 WHERE e1.id = ? AND e1.tenant_id = 1) AND e.tenant_id = 1");
@@ -204,6 +206,14 @@ public class DataPermissionDatabaseInterceptorTest2 extends BaseMockitoUnitTest @@ -204,6 +206,14 @@ public class DataPermissionDatabaseInterceptorTest2 extends BaseMockitoUnitTest
204 "SELECT * FROM entity e " + 206 "SELECT * FROM entity e " +
205 "LEFT JOIN entity1 e1 ON e1.id = e.id AND e1.tenant_id = 1 " + 207 "LEFT JOIN entity1 e1 ON e1.id = e.id AND e1.tenant_id = 1 " +
206 "WHERE (e.id = ? OR e.name = ?) AND e.tenant_id = 1"); 208 "WHERE (e.id = ? OR e.name = ?) AND e.tenant_id = 1");
  209 +
  210 + assertSql("SELECT * FROM entity e " +
  211 + "left join entity1 e1 on e1.id = e.id " +
  212 + "left join entity2 e2 on e1.id = e2.id",
  213 + "SELECT * FROM entity e " +
  214 + "LEFT JOIN entity1 e1 ON e1.id = e.id AND e1.tenant_id = 1 " +
  215 + "LEFT JOIN entity2 e2 ON e1.id = e2.id AND e2.tenant_id = 1 " +
  216 + "WHERE e.tenant_id = 1");
207 } 217 }
208 218
209 @Test 219 @Test
@@ -212,17 +222,125 @@ public class DataPermissionDatabaseInterceptorTest2 extends BaseMockitoUnitTest @@ -212,17 +222,125 @@ public class DataPermissionDatabaseInterceptorTest2 extends BaseMockitoUnitTest
212 assertSql("SELECT * FROM entity e " + 222 assertSql("SELECT * FROM entity e " +
213 "right join entity1 e1 on e1.id = e.id", 223 "right join entity1 e1 on e1.id = e.id",
214 "SELECT * FROM entity e " + 224 "SELECT * FROM entity e " +
215 - "RIGHT JOIN entity1 e1 ON e1.id = e.id AND e1.tenant_id = 1 " +  
216 - "WHERE e.tenant_id = 1"); 225 + "RIGHT JOIN entity1 e1 ON e1.id = e.id AND e.tenant_id = 1 " +
  226 + "WHERE e1.tenant_id = 1");
  227 +
  228 + assertSql("SELECT * FROM with_as_1 e " +
  229 + "right join entity1 e1 on e1.id = e.id",
  230 + "SELECT * FROM with_as_1 e " +
  231 + "RIGHT JOIN entity1 e1 ON e1.id = e.id " +
  232 + "WHERE e1.tenant_id = 1");
217 233
218 assertSql("SELECT * FROM entity e " + 234 assertSql("SELECT * FROM entity e " +
219 "right join entity1 e1 on e1.id = e.id " + 235 "right join entity1 e1 on e1.id = e.id " +
220 "WHERE e.id = ? OR e.name = ?", 236 "WHERE e.id = ? OR e.name = ?",
221 "SELECT * FROM entity e " + 237 "SELECT * FROM entity e " +
222 - "RIGHT JOIN entity1 e1 ON e1.id = e.id AND e1.tenant_id = 1 " +  
223 - "WHERE (e.id = ? OR e.name = ?) AND e.tenant_id = 1"); 238 + "RIGHT JOIN entity1 e1 ON e1.id = e.id AND e.tenant_id = 1 " +
  239 + "WHERE (e.id = ? OR e.name = ?) AND e1.tenant_id = 1");
  240 +
  241 + assertSql("SELECT * FROM entity e " +
  242 + "right join entity1 e1 on e1.id = e.id " +
  243 + "right join entity2 e2 on e1.id = e2.id ",
  244 + "SELECT * FROM entity e " +
  245 + "RIGHT JOIN entity1 e1 ON e1.id = e.id AND e.tenant_id = 1 " +
  246 + "RIGHT JOIN entity2 e2 ON e1.id = e2.id AND e1.tenant_id = 1 " +
  247 + "WHERE e2.tenant_id = 1");
  248 + }
  249 +
  250 + @Test
  251 + void selectMixJoin() {
  252 + assertSql("SELECT * FROM entity e " +
  253 + "right join entity1 e1 on e1.id = e.id " +
  254 + "left join entity2 e2 on e1.id = e2.id",
  255 + "SELECT * FROM entity e " +
  256 + "RIGHT JOIN entity1 e1 ON e1.id = e.id AND e.tenant_id = 1 " +
  257 + "LEFT JOIN entity2 e2 ON e1.id = e2.id AND e2.tenant_id = 1 " +
  258 + "WHERE e1.tenant_id = 1");
  259 +
  260 + assertSql("SELECT * FROM entity e " +
  261 + "left join entity1 e1 on e1.id = e.id " +
  262 + "right join entity2 e2 on e1.id = e2.id",
  263 + "SELECT * FROM entity e " +
  264 + "LEFT JOIN entity1 e1 ON e1.id = e.id AND e1.tenant_id = 1 " +
  265 + "RIGHT JOIN entity2 e2 ON e1.id = e2.id AND e1.tenant_id = 1 " +
  266 + "WHERE e2.tenant_id = 1");
  267 +
  268 + assertSql("SELECT * FROM entity e " +
  269 + "left join entity1 e1 on e1.id = e.id " +
  270 + "inner join entity2 e2 on e1.id = e2.id",
  271 + "SELECT * FROM entity e " +
  272 + "LEFT JOIN entity1 e1 ON e1.id = e.id AND e1.tenant_id = 1 " +
  273 + "INNER JOIN entity2 e2 ON e1.id = e2.id AND e.tenant_id = 1 AND e2.tenant_id = 1");
224 } 274 }
225 275
  276 +
  277 + @Test
  278 + void selectJoinSubSelect() {
  279 + assertSql("select * from (select * from entity) e1 " +
  280 + "left join entity2 e2 on e1.id = e2.id",
  281 + "SELECT * FROM (SELECT * FROM entity WHERE entity.tenant_id = 1) e1 " +
  282 + "LEFT JOIN entity2 e2 ON e1.id = e2.id AND e2.tenant_id = 1");
  283 +
  284 + assertSql("select * from entity1 e1 " +
  285 + "left join (select * from entity2) e2 " +
  286 + "on e1.id = e2.id",
  287 + "SELECT * FROM entity1 e1 " +
  288 + "LEFT JOIN (SELECT * FROM entity2 WHERE entity2.tenant_id = 1) e2 " +
  289 + "ON e1.id = e2.id " +
  290 + "WHERE e1.tenant_id = 1");
  291 + }
  292 +
  293 + @Test
  294 + void selectSubJoin() {
  295 +
  296 + assertSql("select * FROM " +
  297 + "(entity1 e1 right JOIN entity2 e2 ON e1.id = e2.id)",
  298 + "SELECT * FROM " +
  299 + "(entity1 e1 RIGHT JOIN entity2 e2 ON e1.id = e2.id AND e1.tenant_id = 1) " +
  300 + "WHERE e2.tenant_id = 1");
  301 +
  302 + assertSql("select * FROM " +
  303 + "(entity1 e1 LEFT JOIN entity2 e2 ON e1.id = e2.id)",
  304 + "SELECT * FROM " +
  305 + "(entity1 e1 LEFT JOIN entity2 e2 ON e1.id = e2.id AND e2.tenant_id = 1) " +
  306 + "WHERE e1.tenant_id = 1");
  307 +
  308 +
  309 + assertSql("select * FROM " +
  310 + "(entity1 e1 LEFT JOIN entity2 e2 ON e1.id = e2.id) " +
  311 + "right join entity3 e3 on e1.id = e3.id",
  312 + "SELECT * FROM " +
  313 + "(entity1 e1 LEFT JOIN entity2 e2 ON e1.id = e2.id AND e2.tenant_id = 1) " +
  314 + "RIGHT JOIN entity3 e3 ON e1.id = e3.id AND e1.tenant_id = 1 " +
  315 + "WHERE e3.tenant_id = 1");
  316 +
  317 +
  318 + assertSql("select * FROM entity e " +
  319 + "LEFT JOIN (entity1 e1 right join entity2 e2 ON e1.id = e2.id) " +
  320 + "on e.id = e2.id",
  321 + "SELECT * FROM entity e " +
  322 + "LEFT JOIN (entity1 e1 RIGHT JOIN entity2 e2 ON e1.id = e2.id AND e1.tenant_id = 1) " +
  323 + "ON e.id = e2.id AND e2.tenant_id = 1 " +
  324 + "WHERE e.tenant_id = 1");
  325 +
  326 + assertSql("select * FROM entity e " +
  327 + "LEFT JOIN (entity1 e1 left join entity2 e2 ON e1.id = e2.id) " +
  328 + "on e.id = e2.id",
  329 + "SELECT * FROM entity e " +
  330 + "LEFT JOIN (entity1 e1 LEFT JOIN entity2 e2 ON e1.id = e2.id AND e2.tenant_id = 1) " +
  331 + "ON e.id = e2.id AND e1.tenant_id = 1 " +
  332 + "WHERE e.tenant_id = 1");
  333 +
  334 + assertSql("select * FROM entity e " +
  335 + "RIGHT JOIN (entity1 e1 left join entity2 e2 ON e1.id = e2.id) " +
  336 + "on e.id = e2.id",
  337 + "SELECT * FROM entity e " +
  338 + "RIGHT JOIN (entity1 e1 LEFT JOIN entity2 e2 ON e1.id = e2.id AND e2.tenant_id = 1) " +
  339 + "ON e.id = e2.id AND e.tenant_id = 1 " +
  340 + "WHERE e1.tenant_id = 1");
  341 + }
  342 +
  343 +
226 @Test 344 @Test
227 void selectLeftJoinMultipleTrailingOn() { 345 void selectLeftJoinMultipleTrailingOn() {
228 // 多个 on 尾缀的 346 // 多个 on 尾缀的
@@ -256,51 +374,97 @@ public class DataPermissionDatabaseInterceptorTest2 extends BaseMockitoUnitTest @@ -256,51 +374,97 @@ public class DataPermissionDatabaseInterceptorTest2 extends BaseMockitoUnitTest
256 "inner join entity1 e1 on e1.id = e.id " + 374 "inner join entity1 e1 on e1.id = e.id " +
257 "WHERE e.id = ? OR e.name = ?", 375 "WHERE e.id = ? OR e.name = ?",
258 "SELECT * FROM entity e " + 376 "SELECT * FROM entity e " +
259 - "INNER JOIN entity1 e1 ON e1.id = e.id AND e1.tenant_id = 1 " +  
260 - "WHERE (e.id = ? OR e.name = ?) AND e.tenant_id = 1"); 377 + "INNER JOIN entity1 e1 ON e1.id = e.id AND e.tenant_id = 1 AND e1.tenant_id = 1 " +
  378 + "WHERE e.id = ? OR e.name = ?");
261 379
262 assertSql("SELECT * FROM entity e " + 380 assertSql("SELECT * FROM entity e " +
263 "inner join entity1 e1 on e1.id = e.id " + 381 "inner join entity1 e1 on e1.id = e.id " +
264 "WHERE (e.id = ? OR e.name = ?)", 382 "WHERE (e.id = ? OR e.name = ?)",
265 "SELECT * FROM entity e " + 383 "SELECT * FROM entity e " +
266 - "INNER JOIN entity1 e1 ON e1.id = e.id AND e1.tenant_id = 1 " +  
267 - "WHERE (e.id = ? OR e.name = ?) AND e.tenant_id = 1"); 384 + "INNER JOIN entity1 e1 ON e1.id = e.id AND e.tenant_id = 1 AND e1.tenant_id = 1 " +
  385 + "WHERE (e.id = ? OR e.name = ?)");
  386 +
  387 + // 隐式内连接
  388 + assertSql("SELECT * FROM entity,entity1 " +
  389 + "WHERE entity.id = entity1.id",
  390 + "SELECT * FROM entity, entity1 " +
  391 + "WHERE entity.id = entity1.id AND entity.tenant_id = 1 AND entity1.tenant_id = 1");
  392 +
  393 + // 隐式内连接
  394 + assertSql("SELECT * FROM entity a, with_as_entity1 b " +
  395 + "WHERE a.id = b.id",
  396 + "SELECT * FROM entity a, with_as_entity1 b " +
  397 + "WHERE a.id = b.id AND a.tenant_id = 1");
  398 +
  399 + assertSql("SELECT * FROM with_as_entity a, with_as_entity1 b " +
  400 + "WHERE a.id = b.id",
  401 + "SELECT * FROM with_as_entity a, with_as_entity1 b " +
  402 + "WHERE a.id = b.id");
  403 +
  404 + // SubJoin with 隐式内连接
  405 + assertSql("SELECT * FROM (entity,entity1) " +
  406 + "WHERE entity.id = entity1.id",
  407 + "SELECT * FROM (entity, entity1) " +
  408 + "WHERE entity.id = entity1.id " +
  409 + "AND entity.tenant_id = 1 AND entity1.tenant_id = 1");
  410 +
  411 + assertSql("SELECT * FROM ((entity,entity1),entity2) " +
  412 + "WHERE entity.id = entity1.id and entity.id = entity2.id",
  413 + "SELECT * FROM ((entity, entity1), entity2) " +
  414 + "WHERE entity.id = entity1.id AND entity.id = entity2.id " +
  415 + "AND entity.tenant_id = 1 AND entity1.tenant_id = 1 AND entity2.tenant_id = 1");
  416 +
  417 + assertSql("SELECT * FROM (entity,(entity1,entity2)) " +
  418 + "WHERE entity.id = entity1.id and entity.id = entity2.id",
  419 + "SELECT * FROM (entity, (entity1, entity2)) " +
  420 + "WHERE entity.id = entity1.id AND entity.id = entity2.id " +
  421 + "AND entity.tenant_id = 1 AND entity1.tenant_id = 1 AND entity2.tenant_id = 1");
  422 +
  423 + // 沙雕的括号写法
  424 + assertSql("SELECT * FROM (((entity,entity1))) " +
  425 + "WHERE entity.id = entity1.id",
  426 + "SELECT * FROM (((entity, entity1))) " +
  427 + "WHERE entity.id = entity1.id " +
  428 + "AND entity.tenant_id = 1 AND entity1.tenant_id = 1");
268 429
269 - // 垃圾 inner join todo  
270 -// assertSql("SELECT * FROM entity,entity1 " +  
271 -// "WHERE entity.id = entity1.id",  
272 -// "SELECT * FROM entity e " +  
273 -// "INNER JOIN entity1 e1 ON e1.id = e.id AND e1.tenant_id = 1 " +  
274 -// "WHERE (e.id = ? OR e.name = ?) AND e.tenant_id = 1");  
275 } 430 }
276 431
  432 +
277 @Test 433 @Test
278 void selectWithAs() { 434 void selectWithAs() {
279 assertSql("with with_as_A as (select * from entity) select * from with_as_A", 435 assertSql("with with_as_A as (select * from entity) select * from with_as_A",
280 - "WITH with_as_A AS (SELECT * FROM entity WHERE tenant_id = 1) SELECT * FROM with_as_A"); 436 + "WITH with_as_A AS (SELECT * FROM entity WHERE entity.tenant_id = 1) SELECT * FROM with_as_A");
  437 + }
  438 +
  439 +
  440 + @Test
  441 + void selectIgnoreTable() {
  442 + assertSql(" SELECT dict.dict_code, item.item_text AS \"text\", item.item_value AS \"value\" FROM sys_dict_item item INNER JOIN sys_dict dict ON dict.id = item.dict_id WHERE dict.dict_code IN (1, 2, 3) AND item.item_value IN (1, 2, 3)",
  443 + "SELECT dict.dict_code, item.item_text AS \"text\", item.item_value AS \"value\" FROM sys_dict_item item INNER JOIN sys_dict dict ON dict.id = item.dict_id AND item.tenant_id = 1 WHERE dict.dict_code IN (1, 2, 3) AND item.item_value IN (1, 2, 3)");
281 } 444 }
282 445
283 private void assertSql(String sql, String targetSql) { 446 private void assertSql(String sql, String targetSql) {
284 assertEquals(targetSql, interceptor.parserSingle(sql, null)); 447 assertEquals(targetSql, interceptor.parserSingle(sql, null));
285 } 448 }
286 449
  450 +
287 // ========== 额外的测试 ========== 451 // ========== 额外的测试 ==========
288 452
289 @Test 453 @Test
290 public void testSelectSingle() { 454 public void testSelectSingle() {
291 // 单表 455 // 单表
292 assertSql("select * from t_user where id = ?", 456 assertSql("select * from t_user where id = ?",
293 - "SELECT * FROM t_user WHERE id = ? AND tenant_id = 1 AND dept_id IN (10, 20)"); 457 + "SELECT * FROM t_user WHERE id = ? AND t_user.tenant_id = 1 AND t_user.dept_id IN (10, 20)");
294 458
295 assertSql("select * from t_user where id = ? or name = ?", 459 assertSql("select * from t_user where id = ? or name = ?",
296 - "SELECT * FROM t_user WHERE (id = ? OR name = ?) AND tenant_id = 1 AND dept_id IN (10, 20)"); 460 + "SELECT * FROM t_user WHERE (id = ? OR name = ?) AND t_user.tenant_id = 1 AND t_user.dept_id IN (10, 20)");
297 461
298 assertSql("SELECT * FROM t_user WHERE (id = ? OR name = ?)", 462 assertSql("SELECT * FROM t_user WHERE (id = ? OR name = ?)",
299 - "SELECT * FROM t_user WHERE (id = ? OR name = ?) AND tenant_id = 1 AND dept_id IN (10, 20)"); 463 + "SELECT * FROM t_user WHERE (id = ? OR name = ?) AND t_user.tenant_id = 1 AND t_user.dept_id IN (10, 20)");
300 464
301 /* not */ 465 /* not */
302 assertSql("SELECT * FROM t_user WHERE not (id = ? OR name = ?)", 466 assertSql("SELECT * FROM t_user WHERE not (id = ? OR name = ?)",
303 - "SELECT * FROM t_user WHERE NOT (id = ? OR name = ?) AND tenant_id = 1 AND dept_id IN (10, 20)"); 467 + "SELECT * FROM t_user WHERE NOT (id = ? OR name = ?) AND t_user.tenant_id = 1 AND t_user.dept_id IN (10, 20)");
304 } 468 }
305 469
306 @Test 470 @Test
@@ -329,16 +493,16 @@ public class DataPermissionDatabaseInterceptorTest2 extends BaseMockitoUnitTest @@ -329,16 +493,16 @@ public class DataPermissionDatabaseInterceptorTest2 extends BaseMockitoUnitTest
329 "right join t_role e1 on e1.id = e.id " + 493 "right join t_role e1 on e1.id = e.id " +
330 "WHERE e.id = ? OR e.name = ?", 494 "WHERE e.id = ? OR e.name = ?",
331 "SELECT * FROM t_user e " + 495 "SELECT * FROM t_user e " +
332 - "RIGHT JOIN t_role e1 ON e1.id = e.id AND e1.tenant_id = 1 " +  
333 - "WHERE (e.id = ? OR e.name = ?) AND e.tenant_id = 1 AND e.dept_id IN (10, 20)"); 496 + "RIGHT JOIN t_role e1 ON e1.id = e.id AND e.tenant_id = 1 AND e.dept_id IN (10, 20) " +
  497 + "WHERE (e.id = ? OR e.name = ?) AND e1.tenant_id = 1");
334 498
335 // 条件 e.id = ? OR e.name = ? 带括号 499 // 条件 e.id = ? OR e.name = ? 带括号
336 assertSql("SELECT * FROM t_user e " + 500 assertSql("SELECT * FROM t_user e " +
337 "right join t_role e1 on e1.id = e.id " + 501 "right join t_role e1 on e1.id = e.id " +
338 "WHERE (e.id = ? OR e.name = ?)", 502 "WHERE (e.id = ? OR e.name = ?)",
339 "SELECT * FROM t_user e " + 503 "SELECT * FROM t_user e " +
340 - "RIGHT JOIN t_role e1 ON e1.id = e.id AND e1.tenant_id = 1 " +  
341 - "WHERE (e.id = ? OR e.name = ?) AND e.tenant_id = 1 AND e.dept_id IN (10, 20)"); 504 + "RIGHT JOIN t_role e1 ON e1.id = e.id AND e.tenant_id = 1 AND e.dept_id IN (10, 20) " +
  505 + "WHERE (e.id = ? OR e.name = ?) AND e1.tenant_id = 1");
342 } 506 }
343 507
344 @Test 508 @Test
@@ -348,23 +512,22 @@ public class DataPermissionDatabaseInterceptorTest2 extends BaseMockitoUnitTest @@ -348,23 +512,22 @@ public class DataPermissionDatabaseInterceptorTest2 extends BaseMockitoUnitTest
348 "inner join entity1 e1 on e1.id = e.id " + 512 "inner join entity1 e1 on e1.id = e.id " +
349 "WHERE e.id = ? OR e.name = ?", 513 "WHERE e.id = ? OR e.name = ?",
350 "SELECT * FROM t_user e " + 514 "SELECT * FROM t_user e " +
351 - "INNER JOIN entity1 e1 ON e1.id = e.id AND e1.tenant_id = 1 " +  
352 - "WHERE (e.id = ? OR e.name = ?) AND e.tenant_id = 1 AND e.dept_id IN (10, 20)"); 515 + "INNER JOIN entity1 e1 ON e1.id = e.id AND e.tenant_id = 1 AND e.dept_id IN (10, 20) AND e1.tenant_id = 1 " +
  516 + "WHERE e.id = ? OR e.name = ?");
353 517
354 // 条件 e.id = ? OR e.name = ? 带括号 518 // 条件 e.id = ? OR e.name = ? 带括号
355 assertSql("SELECT * FROM t_user e " + 519 assertSql("SELECT * FROM t_user e " +
356 - "inner join t_role e1 on e1.id = e.id " + 520 + "inner join entity1 e1 on e1.id = e.id " +
357 "WHERE (e.id = ? OR e.name = ?)", 521 "WHERE (e.id = ? OR e.name = ?)",
358 "SELECT * FROM t_user e " + 522 "SELECT * FROM t_user e " +
359 - "INNER JOIN t_role e1 ON e1.id = e.id AND e1.tenant_id = 1 " +  
360 - "WHERE (e.id = ? OR e.name = ?) AND e.tenant_id = 1 AND e.dept_id IN (10, 20)");  
361 -  
362 - // 垃圾 inner join todo  
363 -// assertSql("SELECT * FROM entity,entity1 " +  
364 -// "WHERE entity.id = entity1.id",  
365 -// "SELECT * FROM entity e " +  
366 -// "INNER JOIN entity1 e1 ON e1.id = e.id AND e1.tenant_id = 1 " +  
367 -// "WHERE (e.id = ? OR e.name = ?) AND e.tenant_id = 1"); 523 + "INNER JOIN entity1 e1 ON e1.id = e.id AND e.tenant_id = 1 AND e.dept_id IN (10, 20) AND e1.tenant_id = 1 " +
  524 + "WHERE (e.id = ? OR e.name = ?)");
  525 +
  526 + // 没有 On 的 inner join
  527 + assertSql("SELECT * FROM entity,entity1 " +
  528 + "WHERE entity.id = entity1.id",
  529 + "SELECT * FROM entity, entity1 " +
  530 + "WHERE entity.id = entity1.id AND entity.tenant_id = 1 AND entity1.tenant_id = 1");
368 } 531 }
369 532
370 } 533 }
yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/util/MyBatisUtils.java
@@ -4,6 +4,7 @@ import cn.hutool.core.collection.CollectionUtil; @@ -4,6 +4,7 @@ import cn.hutool.core.collection.CollectionUtil;
4 import cn.iocoder.yudao.framework.common.pojo.PageParam; 4 import cn.iocoder.yudao.framework.common.pojo.PageParam;
5 import cn.iocoder.yudao.framework.common.pojo.SortingField; 5 import cn.iocoder.yudao.framework.common.pojo.SortingField;
6 import com.baomidou.mybatisplus.core.metadata.OrderItem; 6 import com.baomidou.mybatisplus.core.metadata.OrderItem;
  7 +import com.baomidou.mybatisplus.core.toolkit.StringPool;
7 import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; 8 import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
8 import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor; 9 import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
9 import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 10 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -78,7 +79,10 @@ public class MyBatisUtils { @@ -78,7 +79,10 @@ public class MyBatisUtils {
78 * @return Column 对象 79 * @return Column 对象
79 */ 80 */
80 public static Column buildColumn(String tableName, Alias tableAlias, String column) { 81 public static Column buildColumn(String tableName, Alias tableAlias, String column) {
81 - return new Column(tableAlias != null ? tableAlias.getName() + "." + column : column); 82 + if (tableAlias != null) {
  83 + tableName = tableAlias.getName();
  84 + }
  85 + return new Column(tableName + StringPool.DOT + column);
82 } 86 }
83 87
84 } 88 }
yudao-module-mall/pom.xml
@@ -15,14 +15,18 @@ @@ -15,14 +15,18 @@
15 <name>${project.artifactId}</name> 15 <name>${project.artifactId}</name>
16 16
17 <description> 17 <description>
18 - market模块,主要实现营销相关功能  
19 - 例如:营销活动、banner广告、优惠券、优惠码等功能。 18 + 商城大模块,由 product 商品、market 营销、trade 交易 coupon等组成
20 </description> 19 </description>
21 <modules> 20 <modules>
  21 + <module>yudao-module-coupon-api</module>
  22 + <module>yudao-module-coupon-biz</module>
22 <module>yudao-module-market-api</module> 23 <module>yudao-module-market-api</module>
23 <module>yudao-module-market-biz</module> 24 <module>yudao-module-market-biz</module>
24 <module>yudao-module-product-api</module> 25 <module>yudao-module-product-api</module>
25 <module>yudao-module-product-biz</module> 26 <module>yudao-module-product-biz</module>
  27 + <module>yudao-module-trade-api</module>
  28 + <module>yudao-module-trade-biz</module>
  29 +
26 </modules> 30 </modules>
27 31
28 </project> 32 </project>
yudao-module-mall/yudao-module-coupon-api/pom.xml 0 → 100644
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<project xmlns="http://maven.apache.org/POM/4.0.0"
  3 + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5 + <parent>
  6 + <groupId>cn.iocoder.boot</groupId>
  7 + <artifactId>yudao-module-mall</artifactId>
  8 + <version>${revision}</version>
  9 + </parent>
  10 +
  11 + <modelVersion>4.0.0</modelVersion>
  12 + <artifactId>yudao-module-coupon-api</artifactId>
  13 + <packaging>jar</packaging>
  14 +
  15 +
  16 + <name>${project.artifactId}</name>
  17 + <description>
  18 + coupon 模块 API,暴露给其它模块调用
  19 + </description>
  20 +
  21 + <dependencies>
  22 + <dependency>
  23 + <groupId>cn.iocoder.boot</groupId>
  24 + <artifactId>yudao-common</artifactId>
  25 + </dependency>
  26 +
  27 + <!-- 参数校验 -->
  28 + <dependency>
  29 + <groupId>org.springframework.boot</groupId>
  30 + <artifactId>spring-boot-starter-validation</artifactId>
  31 + <optional>true</optional>
  32 + </dependency>
  33 + </dependencies>
  34 +
  35 +</project>
0 \ No newline at end of file 36 \ No newline at end of file
yudao-module-mall/yudao-module-coupon-api/src/main/java/cn/iocoder/yudao/module/CouponTemplete/enums/CouponExpireTimeTypeEnum.java 0 → 100644
  1 +package cn.iocoder.yudao.module.CouponTemplete.enums;
  2 +
  3 +
  4 +import lombok.Getter;
  5 +import lombok.RequiredArgsConstructor;
  6 +
  7 +
  8 +/**
  9 + * 优惠券 - 是否开启过期提醒
  10 + *
  11 + * @author Sin
  12 + */
  13 +@RequiredArgsConstructor
  14 +@Getter
  15 +public enum CouponExpireTimeTypeEnum {
  16 +
  17 + OPEN(1,"不开启"),
  18 + CLOSE(0,"开启"),;
  19 +
  20 + /**
  21 + * 是否开启过期提醒
  22 + */
  23 + private final Integer type;
  24 + /**
  25 + * 是否开启过期提醒
  26 + */
  27 + private final String name;
  28 +
  29 +}
yudao-module-mall/yudao-module-coupon-api/src/main/java/cn/iocoder/yudao/module/CouponTemplete/enums/CouponFetchTypeEnum.java 0 → 100644
  1 +package cn.iocoder.yudao.module.CouponTemplete.enums;
  2 +
  3 +
  4 +import lombok.Getter;
  5 +import lombok.RequiredArgsConstructor;
  6 +
  7 +
  8 +/**
  9 + * 优惠券 - 领取是否无限制 0
  10 + *
  11 + * @author Sin
  12 + */
  13 +@RequiredArgsConstructor
  14 +@Getter
  15 +public enum CouponFetchTypeEnum {
  16 +
  17 + LIMIT(1,"限制"),
  18 + NOT_LIMIT(0,"不限制"),;
  19 +
  20 + /**
  21 + * 是否开启过期提醒
  22 + */
  23 + private final Integer type;
  24 + /**
  25 + * 是否开启过期提醒
  26 + */
  27 + private final String name;
  28 +
  29 +}
yudao-module-mall/yudao-module-coupon-api/src/main/java/cn/iocoder/yudao/module/CouponTemplete/enums/CouponForbidPreferenceEnum.java 0 → 100644
  1 +package cn.iocoder.yudao.module.CouponTemplete.enums;
  2 +
  3 +
  4 +import lombok.Getter;
  5 +import lombok.RequiredArgsConstructor;
  6 +
  7 +
  8 +/**
  9 + * 优惠券 - 优惠叠加类型
  10 + *
  11 + * @author Sin
  12 + */
  13 +@RequiredArgsConstructor
  14 +@Getter
  15 +public enum CouponForbidPreferenceEnum {
  16 +
  17 + UN_FORBID(0,"不限制"),
  18 + FORBID(1,"优惠券仅原价购买商品时可用");
  19 +
  20 + /**
  21 + * 优惠券类型
  22 + */
  23 + private final Integer type;
  24 + /**
  25 + * 优惠券类型名
  26 + */
  27 + private final String name;
  28 +
  29 +}
yudao-module-mall/yudao-module-coupon-api/src/main/java/cn/iocoder/yudao/module/CouponTemplete/enums/CouponGoodsTypeEnum.java 0 → 100644
  1 +package cn.iocoder.yudao.module.CouponTemplete.enums;
  2 +
  3 +
  4 +import lombok.Getter;
  5 +import lombok.RequiredArgsConstructor;
  6 +
  7 +
  8 +/**
  9 + * 优惠券 - 优惠券商品使用类型
  10 + *
  11 + * @author Sin
  12 + */
  13 +@RequiredArgsConstructor
  14 +@Getter
  15 +public enum CouponGoodsTypeEnum {
  16 +
  17 + ALL(1,"全部商品可用"),
  18 + POINT_PRODUCT(2,"指定商品可用"),
  19 + POINT_PRODUCT_NOT(3,"指定商品不可用"),;
  20 +
  21 + /**
  22 + * 优惠券商品使用类型
  23 + */
  24 + private final Integer type;
  25 + /**
  26 + * 优惠券商品使用类型名
  27 + */
  28 + private final String name;
  29 +
  30 +}
yudao-module-mall/yudao-module-coupon-api/src/main/java/cn/iocoder/yudao/module/CouponTemplete/enums/CouponStatusTypeEnum.java 0 → 100644
  1 +package cn.iocoder.yudao.module.CouponTemplete.enums;
  2 +
  3 +
  4 +import lombok.Getter;
  5 +import lombok.RequiredArgsConstructor;
  6 +
  7 +
  8 +/**
  9 + * 优惠券 - 优惠券状态类型
  10 + *
  11 + * @author Sin
  12 + */
  13 +@RequiredArgsConstructor
  14 +@Getter
  15 +public enum CouponStatusTypeEnum {
  16 +
  17 + PROCESSING(1,"进行中"),
  18 + END(2,"已结束"),
  19 + CLOSE(3,"已关闭"),;
  20 +
  21 + /**
  22 + * 优惠券类型
  23 + */
  24 + private final Integer type;
  25 + /**
  26 + * 优惠券类型名
  27 + */
  28 + private final String name;
  29 +
  30 +}
yudao-module-mall/yudao-module-coupon-api/src/main/java/cn/iocoder/yudao/module/CouponTemplete/enums/CouponTypeEnum.java 0 → 100644
  1 +package cn.iocoder.yudao.module.CouponTemplete.enums;
  2 +
  3 +
  4 +import lombok.Getter;
  5 +import lombok.RequiredArgsConstructor;
  6 +
  7 +
  8 +/**
  9 + * 优惠券 - 优惠券类型
  10 + *
  11 + * @author Sin
  12 + */
  13 +@RequiredArgsConstructor
  14 +@Getter
  15 +public enum CouponTypeEnum {
  16 +
  17 + REWARD(1,"满减"),
  18 + DISCOUNT(2,"折扣"),
  19 + RANDOW(3,"随机"),;
  20 +
  21 + /**
  22 + * 优惠券类型
  23 + */
  24 + private final Integer type;
  25 + /**
  26 + * 优惠券类型名
  27 + */
  28 + private final String name;
  29 +
  30 +}
yudao-module-mall/yudao-module-coupon-api/src/main/java/cn/iocoder/yudao/module/CouponTemplete/enums/CouponUseLimitEnum.java 0 → 100644
  1 +package cn.iocoder.yudao.module.CouponTemplete.enums;
  2 +
  3 +
  4 +import lombok.Getter;
  5 +import lombok.RequiredArgsConstructor;
  6 +
  7 +
  8 +/**
  9 + * 优惠券使用类型 - 优惠券使用类型类型
  10 + *
  11 + * @author Sin
  12 + */
  13 +@RequiredArgsConstructor
  14 +@Getter
  15 +public enum CouponUseLimitEnum {
  16 +
  17 + HAS_LIMIT(1,"无门槛"),
  18 + NO_LIMIT(2,"有门槛"),;
  19 +
  20 + /**
  21 + * 优惠券使用类型
  22 + */
  23 + private final Integer type;
  24 + /**
  25 + * 优惠券使用类型名
  26 + */
  27 + private final String name;
  28 +
  29 +}
yudao-module-mall/yudao-module-coupon-api/src/main/java/cn/iocoder/yudao/module/CouponTemplete/enums/CouponValidityTypeEnum.java 0 → 100644
  1 +package cn.iocoder.yudao.module.CouponTemplete.enums;
  2 +
  3 +import lombok.Getter;
  4 +import lombok.RequiredArgsConstructor;
  5 +
  6 +/**
  7 + * 过期类型 - 状态
  8 + *
  9 + * @author Sin
  10 + */
  11 +@RequiredArgsConstructor
  12 +@Getter
  13 +public enum CouponValidityTypeEnum {
  14 +
  15 + TIME_RANGE_EXPIRTED(1,"时间范围过期"),
  16 + EXPIRES_AFTER_FIXED_DATE(2,"领取之日固定日期后过期"),
  17 + EXPIRES_DATE_NEXT_FIEXD_DATE(3,"领取次日固定日期后过期"),;
  18 +
  19 +
  20 + /**
  21 + * 状态值
  22 + */
  23 + private final Integer status;
  24 + /**
  25 + * 状态名
  26 + */
  27 + private final String name;
  28 +
  29 +}
yudao-module-mall/yudao-module-coupon-api/src/main/java/cn/iocoder/yudao/module/CouponTemplete/enums/ErrorCodeConstants.java 0 → 100644
  1 +package cn.iocoder.yudao.module.CouponTemplete.enums;
  2 +
  3 +import cn.iocoder.yudao.framework.common.exception.ErrorCode;
  4 +
  5 +/**
  6 + * coupon 优惠券错误码枚举类
  7 + *
  8 + * coupon 优惠券系统,使用 1-010-000-000 段
  9 + */
  10 +public interface ErrorCodeConstants {
  11 + // ========== COUPON分类相关 1010001000 ============
  12 +
  13 + ErrorCode COUPON_TEMPLETE_NOT_EXISTS = new ErrorCode(1010001000, "优惠券模板不存在");
  14 + ErrorCode MONEY_NOT_NULL = new ErrorCode(1010001001, "当type为reward时需要添加发放面额不能为空");
  15 + ErrorCode DISCOUNT_NOT_NULL = new ErrorCode(1010001001, "当type为discount时需要添加折扣不能为空");
  16 + ErrorCode DISCOUNT_LIMIT_NOT_NULL = new ErrorCode(1010001001, "当type为discount时可选择性添加最多折扣金额不能为空");
  17 + ErrorCode MIN_MAX_NOT_NULL = new ErrorCode(1010001001, "当type为radom时需要添加最低金额");
  18 + ErrorCode START_END_TIME_NOT_NULL = new ErrorCode(1010001001, "使用开始日期,使用结束日期不能为空");
  19 + ErrorCode FIXED_TERM_NOT_NULL = new ErrorCode(1010001001, "领取之日起或者次日N天内有效不能为空");
  20 +
  21 +
  22 + // ========== COUPON分类相关 1010002000 ============
  23 + ErrorCode COUPON_NOT_EXISTS = new ErrorCode(1010001000, "优惠券模板不存在");
  24 +
  25 +
  26 +}
  27 +
yudao-module-mall/yudao-module-coupon-biz/pom.xml 0 → 100644
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<project xmlns="http://maven.apache.org/POM/4.0.0"
  3 + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5 + <parent>
  6 + <groupId>cn.iocoder.boot</groupId>
  7 + <artifactId>yudao-module-mall</artifactId>
  8 + <version>${revision}</version>
  9 + </parent>
  10 + <modelVersion>4.0.0</modelVersion>
  11 + <packaging>jar</packaging>
  12 + <artifactId>yudao-module-coupon-biz</artifactId>
  13 +
  14 + <name>${project.artifactId}</name>
  15 +
  16 + <description>
  17 + coupon模块,主要负责优惠券的一些业务,含发布优惠券模板,分发优惠券等
  18 + </description>
  19 +
  20 + <dependencies>
  21 +
  22 + <dependency>
  23 + <groupId>cn.iocoder.boot</groupId>
  24 + <artifactId>yudao-module-coupon-api</artifactId>
  25 + <version>${revision}</version>
  26 + </dependency>
  27 +
  28 + <!-- 业务组件 -->
  29 + <dependency>
  30 + <groupId>cn.iocoder.boot</groupId>
  31 + <artifactId>yudao-spring-boot-starter-biz-operatelog</artifactId>
  32 + </dependency>
  33 + <dependency>
  34 + <groupId>cn.iocoder.boot</groupId>
  35 + <artifactId>yudao-spring-boot-starter-biz-tenant</artifactId>
  36 + </dependency>
  37 +
  38 + <!-- Web 相关 -->
  39 + <dependency>
  40 + <groupId>cn.iocoder.boot</groupId>
  41 + <artifactId>yudao-spring-boot-starter-web</artifactId>
  42 + </dependency>
  43 + <dependency>
  44 + <groupId>cn.iocoder.boot</groupId>
  45 + <artifactId>yudao-spring-boot-starter-excel</artifactId>
  46 + </dependency>
  47 +
  48 + <!-- DB 相关 -->
  49 + <dependency>
  50 + <groupId>cn.iocoder.boot</groupId>
  51 + <artifactId>yudao-spring-boot-starter-mybatis</artifactId>
  52 + </dependency>
  53 +
  54 + <!-- Test 测试相关 -->
  55 + <dependency>
  56 + <groupId>cn.iocoder.boot</groupId>
  57 + <artifactId>yudao-spring-boot-starter-test</artifactId>
  58 + </dependency>
  59 +
  60 + </dependencies>
  61 +
  62 +</project>
0 \ No newline at end of file 63 \ No newline at end of file
yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/coupon/CouponController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.coupon.controller.admin.coupon;
  2 +
  3 +import org.springframework.web.bind.annotation.*;
  4 +import javax.annotation.Resource;
  5 +import org.springframework.validation.annotation.Validated;
  6 +import org.springframework.security.access.prepost.PreAuthorize;
  7 +import io.swagger.annotations.*;
  8 +
  9 +import javax.validation.*;
  10 +import java.util.*;
  11 +
  12 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  13 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  14 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  15 +
  16 +
  17 +import cn.iocoder.yudao.module.coupon.controller.admin.coupon.vo.*;
  18 +import cn.iocoder.yudao.module.coupon.dal.dataobject.coupon.CouponDO;
  19 +import cn.iocoder.yudao.module.coupon.convert.coupon.CouponConvert;
  20 +import cn.iocoder.yudao.module.coupon.service.coupon.CouponService;
  21 +
  22 +@Api(tags = "管理后台 - 优惠券")
  23 +@RestController
  24 +@RequestMapping("/coupon/item")
  25 +@Validated
  26 +public class CouponController {
  27 +
  28 + @Resource
  29 + private CouponService couponService;
  30 +
  31 +
  32 + //todo 用户优惠券
  33 + @PostMapping("/create")
  34 + @ApiOperation("用户领取优惠券")
  35 + @PreAuthorize("@ss.hasPermission('coupon::create')")
  36 + public CommonResult<Long> create(@RequestParam("couponTemplateId") Long couponTemplateId) {
  37 +
  38 + return success(couponService.create(couponTemplateId));
  39 + }
  40 +
  41 +
  42 + @PutMapping("/update")
  43 + @ApiOperation("更新优惠券")
  44 + @PreAuthorize("@ss.hasPermission('coupon::update')")
  45 + public CommonResult<Boolean> update(@Valid @RequestBody CouponUpdateReqVO updateReqVO) {
  46 + couponService.update(updateReqVO);
  47 + return success(true);
  48 + }
  49 +
  50 + @DeleteMapping("/delete")
  51 + @ApiOperation("删除优惠券")
  52 + @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class)
  53 + @PreAuthorize("@ss.hasPermission('coupon::delete')")
  54 + public CommonResult<Boolean> delete(@RequestParam("id") Long id) {
  55 + couponService.delete(id);
  56 + return success(true);
  57 + }
  58 +
  59 + @GetMapping("/get")
  60 + @ApiOperation("获得优惠券")
  61 + @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
  62 + @PreAuthorize("@ss.hasPermission('coupon::query')")
  63 + public CommonResult<CouponRespVO> get(@RequestParam("id") Long id) {
  64 + CouponDO couponDO = couponService.get(id);
  65 + return success(CouponConvert.INSTANCE.convert(couponDO));
  66 + }
  67 +
  68 +
  69 +
  70 + @GetMapping("/list")
  71 + @ApiOperation("获得优惠券列表")
  72 + @ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class)
  73 + @PreAuthorize("@ss.hasPermission('coupon::query')")
  74 + public CommonResult<List<CouponRespVO>> getList(@RequestParam("ids") Collection<Long> ids) {
  75 + List<CouponDO> list = couponService.getList(ids);
  76 + return success(CouponConvert.INSTANCE.convertList(list));
  77 + }
  78 +
  79 + @GetMapping("/page")
  80 + @ApiOperation("获得优惠券分页")
  81 + @PreAuthorize("@ss.hasPermission('coupon::query')")
  82 + public CommonResult<PageResult<CouponRespVO>> getPage(@Valid CouponPageReqVO pageVO) {
  83 + PageResult<CouponDO> pageResult = couponService.getPage(pageVO);
  84 + return success(CouponConvert.INSTANCE.convertPage(pageResult));
  85 + }
  86 +
  87 +
  88 +}
yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/coupon/vo/CouponBaseVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.coupon.controller.admin.coupon.vo;
  2 +
  3 +import lombok.*;
  4 +import java.util.*;
  5 +import java.math.BigDecimal;
  6 +import io.swagger.annotations.*;
  7 +import javax.validation.constraints.*;
  8 +import org.springframework.format.annotation.DateTimeFormat;
  9 +
  10 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  11 +
  12 +/**
  13 +* 优惠券 Base VO,提供给添加、修改、详细的子 VO 使用
  14 +* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
  15 +*/
  16 +@Data
  17 +public class CouponBaseVO {
  18 +
  19 + @ApiModelProperty(value = "优惠券类型 reward-满减 discount-折扣 random-随机", required = true)
  20 + @NotNull(message = "优惠券类型 reward-满减 discount-折扣 random-随机不能为空")
  21 + private String type;
  22 +
  23 + @ApiModelProperty(value = "优惠券名称", required = true)
  24 + @NotNull(message = "优惠券名称不能为空")
  25 + private String name;
  26 +
  27 + @ApiModelProperty(value = "优惠券类型id")
  28 + private Long couponTypeId;
  29 +
  30 + @ApiModelProperty(value = "优惠券编码", required = true)
  31 + @NotNull(message = "优惠券编码不能为空")
  32 + private String couponCode;
  33 +
  34 + @ApiModelProperty(value = "领用人", required = true)
  35 + @NotNull(message = "领用人不能为空")
  36 + private Long memberId;
  37 +
  38 + @ApiModelProperty(value = "优惠券使用订单id", required = true)
  39 + @NotNull(message = "优惠券使用订单id不能为空")
  40 + private Long useOrderId;
  41 +
  42 + @ApiModelProperty(value = "适用商品类型1-全部商品可用;2-指定商品可用;3-指定商品不可用", required = true)
  43 + @NotNull(message = "适用商品类型1-全部商品可用;2-指定商品可用;3-指定商品不可用不能为空")
  44 + private Boolean goodsType;
  45 +
  46 + @ApiModelProperty(value = "适用商品id", required = true)
  47 + @NotNull(message = "适用商品id不能为空")
  48 + private String goodsIds;
  49 +
  50 + @ApiModelProperty(value = "最小金额", required = true)
  51 + @NotNull(message = "最小金额不能为空")
  52 + private BigDecimal atLeast;
  53 +
  54 + @ApiModelProperty(value = "面额", required = true)
  55 + @NotNull(message = "面额不能为空")
  56 + private BigDecimal money;
  57 +
  58 + @ApiModelProperty(value = "1 =< 折扣 <= 9.9 当type为discount时需要添加", required = true)
  59 + @NotNull(message = "1 =< 折扣 <= 9.9 当type为discount时需要添加不能为空")
  60 + private BigDecimal discount;
  61 +
  62 + @ApiModelProperty(value = "最多折扣金额 当type为discount时可选择性添加", required = true)
  63 + @NotNull(message = "最多折扣金额 当type为discount时可选择性添加不能为空")
  64 + private BigDecimal discountLimit;
  65 +
  66 + @ApiModelProperty(value = "优惠叠加 0-不限制 1- 优惠券仅原价购买商品时可用", required = true)
  67 + @NotNull(message = "优惠叠加 0-不限制 1- 优惠券仅原价购买商品时可用不能为空")
  68 + private Boolean whetherForbidPreference;
  69 +
  70 + @ApiModelProperty(value = "是否开启过期提醒0-不开启 1-开启", required = true)
  71 + @NotNull(message = "是否开启过期提醒0-不开启 1-开启")
  72 + private Boolean whetherExpireNotice;
  73 +
  74 + @ApiModelProperty(value = "过期前N天提醒", required = true)
  75 + @NotNull(message = "过期前N天提醒不能为空")
  76 + private Integer expireNoticeFixedTerm;
  77 +
  78 + @ApiModelProperty(value = "是否已提醒", required = true)
  79 + @NotNull(message = "是否已提醒不能为空")
  80 + private Boolean whetherNoticed;
  81 +
  82 + @ApiModelProperty(value = "优惠券状态 1已领用(未使用) 2已使用 3已过期", required = true)
  83 + @NotNull(message = "优惠券状态 1已领用(未使用) 2已使用 3已过期不能为空")
  84 + private Integer state;
  85 +
  86 + @ApiModelProperty(value = "获取方式1订单2.直接领取3.活动领取 4转赠 5分享获取", required = true)
  87 + @NotNull(message = "获取方式1订单2.直接领取3.活动领取 4转赠 5分享获取不能为空")
  88 + private Boolean getType;
  89 +
  90 + @ApiModelProperty(value = "领取时间", required = true)
  91 + @NotNull(message = "领取时间不能为空")
  92 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  93 + private Date fetchTime;
  94 +
  95 + @ApiModelProperty(value = "使用时间", required = true)
  96 + @NotNull(message = "使用时间不能为空")
  97 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  98 + private Date useTime;
  99 +
  100 + @ApiModelProperty(value = "可使用的开始时间", required = true)
  101 + @NotNull(message = "可使用的开始时间不能为空")
  102 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  103 + private Date startTime;
  104 +
  105 + @ApiModelProperty(value = "有效期结束时间", required = true)
  106 + @NotNull(message = "有效期结束时间不能为空")
  107 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  108 + private Date endTime;
  109 +
  110 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/BrandCreateReqVO.java renamed to yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/coupon/vo/CouponCreateReqVO.java
1 -package cn.iocoder.yudao.module.product.controller.admin.brand.vo; 1 +package cn.iocoder.yudao.module.coupon.controller.admin.coupon.vo;
2 2
3 import lombok.*; 3 import lombok.*;
4 import java.util.*; 4 import java.util.*;
5 import io.swagger.annotations.*; 5 import io.swagger.annotations.*;
6 import javax.validation.constraints.*; 6 import javax.validation.constraints.*;
7 7
8 -@ApiModel("管理后台 - 品牌创建 Request VO") 8 +@ApiModel("管理后台 - 优惠券创建 Request VO")
9 @Data 9 @Data
10 @EqualsAndHashCode(callSuper = true) 10 @EqualsAndHashCode(callSuper = true)
11 @ToString(callSuper = true) 11 @ToString(callSuper = true)
12 -public class BrandCreateReqVO extends BrandBaseVO { 12 +public class CouponCreateReqVO extends CouponBaseVO {
13 13
14 } 14 }
yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/coupon/vo/CouponExcelVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.coupon.controller.admin.coupon.vo;
  2 +
  3 +import lombok.*;
  4 +import java.util.*;
  5 +import java.math.BigDecimal;
  6 +import io.swagger.annotations.*;
  7 +
  8 +import com.alibaba.excel.annotation.ExcelProperty;
  9 +
  10 +/**
  11 + * 优惠券 Excel VO
  12 + *
  13 + * @author wxr
  14 + */
  15 +@Data
  16 +public class CouponExcelVO {
  17 +
  18 + @ExcelProperty("用户ID")
  19 + private Long id;
  20 +
  21 + @ExcelProperty("优惠券类型 reward-满减 discount-折扣 random-随机")
  22 + private String type;
  23 +
  24 + @ExcelProperty("优惠券名称")
  25 + private String name;
  26 +
  27 + @ExcelProperty("优惠券类型id")
  28 + private Long couponTypeId;
  29 +
  30 + @ExcelProperty("优惠券编码")
  31 + private String couponCode;
  32 +
  33 + @ExcelProperty("领用人")
  34 + private Long memberId;
  35 +
  36 + @ExcelProperty("优惠券使用订单id")
  37 + private Long useOrderId;
  38 +
  39 + @ExcelProperty("适用商品类型1-全部商品可用;2-指定商品可用;3-指定商品不可用")
  40 + private Boolean goodsType;
  41 +
  42 + @ExcelProperty("适用商品id")
  43 + private String goodsIds;
  44 +
  45 + @ExcelProperty("最小金额")
  46 + private BigDecimal atLeast;
  47 +
  48 + @ExcelProperty("面额")
  49 + private BigDecimal money;
  50 +
  51 + @ExcelProperty("1 =< 折扣 <= 9.9 当type为discount时需要添加")
  52 + private BigDecimal discount;
  53 +
  54 + @ExcelProperty("最多折扣金额 当type为discount时可选择性添加")
  55 + private BigDecimal discountLimit;
  56 +
  57 + @ExcelProperty("优惠叠加 0-不限制 1- 优惠券仅原价购买商品时可用")
  58 + private Boolean whetherForbidPreference;
  59 +
  60 + @ExcelProperty("是否开启过期提醒0-不开启 1-开启")
  61 + private Boolean whetherExpireNotice;
  62 +
  63 + @ExcelProperty("过期前N天提醒")
  64 + private Integer expireNoticeFixedTerm;
  65 +
  66 + @ExcelProperty("是否已提醒")
  67 + private Boolean whetherNoticed;
  68 +
  69 + @ExcelProperty("优惠券状态 1已领用(未使用) 2已使用 3已过期")
  70 + private Integer state;
  71 +
  72 + @ExcelProperty("获取方式1订单2.直接领取3.活动领取 4转赠 5分享获取")
  73 + private Boolean getType;
  74 +
  75 + @ExcelProperty("领取时间")
  76 + private Date fetchTime;
  77 +
  78 + @ExcelProperty("使用时间")
  79 + private Date useTime;
  80 +
  81 + @ExcelProperty("可使用的开始时间")
  82 + private Date startTime;
  83 +
  84 + @ExcelProperty("有效期结束时间")
  85 + private Date endTime;
  86 +
  87 + @ExcelProperty("创建时间")
  88 + private Date createTime;
  89 +
  90 +}
yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/coupon/vo/CouponExportReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.coupon.controller.admin.coupon.vo;
  2 +
  3 +import lombok.*;
  4 +
  5 +import java.math.BigDecimal;
  6 +import java.util.*;
  7 +import io.swagger.annotations.*;
  8 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  9 +import org.springframework.format.annotation.DateTimeFormat;
  10 +
  11 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  12 +
  13 +@ApiModel(value = "管理后台 - 优惠券 Excel 导出 Request VO", description = "参数和 CouponPageReqVO 是一致的")
  14 +@Data
  15 +public class CouponExportReqVO {
  16 +
  17 + @ApiModelProperty(value = "优惠券类型 reward-满减 discount-折扣 random-随机")
  18 + private String type;
  19 +
  20 + @ApiModelProperty(value = "优惠券名称")
  21 + private String name;
  22 +
  23 + @ApiModelProperty(value = "优惠券类型id")
  24 + private Long couponTypeId;
  25 +
  26 + @ApiModelProperty(value = "优惠券编码")
  27 + private String couponCode;
  28 +
  29 + @ApiModelProperty(value = "领用人")
  30 + private Long memberId;
  31 +
  32 + @ApiModelProperty(value = "优惠券使用订单id")
  33 + private Long useOrderId;
  34 +
  35 + @ApiModelProperty(value = "适用商品类型1-全部商品可用;2-指定商品可用;3-指定商品不可用")
  36 + private Boolean goodsType;
  37 +
  38 + @ApiModelProperty(value = "适用商品id")
  39 + private String goodsIds;
  40 +
  41 + @ApiModelProperty(value = "最小金额")
  42 + private BigDecimal atLeast;
  43 +
  44 + @ApiModelProperty(value = "面额")
  45 + private BigDecimal money;
  46 +
  47 + @ApiModelProperty(value = "1 =< 折扣 <= 9.9 当type为discount时需要添加")
  48 + private BigDecimal discount;
  49 +
  50 + @ApiModelProperty(value = "最多折扣金额 当type为discount时可选择性添加")
  51 + private BigDecimal discountLimit;
  52 +
  53 + @ApiModelProperty(value = "优惠叠加 0-不限制 1- 优惠券仅原价购买商品时可用")
  54 + private Boolean whetherForbidPreference;
  55 +
  56 + @ApiModelProperty(value = "是否开启过期提醒0-不开启 1-开启")
  57 + private Boolean whetherExpireNotice;
  58 +
  59 + @ApiModelProperty(value = "过期前N天提醒")
  60 + private Integer expireNoticeFixedTerm;
  61 +
  62 + @ApiModelProperty(value = "是否已提醒")
  63 + private Boolean whetherNoticed;
  64 +
  65 + @ApiModelProperty(value = "优惠券状态 1已领用(未使用) 2已使用 3已过期")
  66 + private Integer state;
  67 +
  68 + @ApiModelProperty(value = "获取方式1订单2.直接领取3.活动领取 4转赠 5分享获取")
  69 + private Boolean getType;
  70 +
  71 + @ApiModelProperty(value = "领取时间")
  72 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  73 + private Date[] fetchTime;
  74 +
  75 + @ApiModelProperty(value = "使用时间")
  76 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  77 + private Date[] useTime;
  78 +
  79 + @ApiModelProperty(value = "可使用的开始时间")
  80 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  81 + private Date[] startTime;
  82 +
  83 + @ApiModelProperty(value = "有效期结束时间")
  84 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  85 + private Date[] endTime;
  86 +
  87 + @ApiModelProperty(value = "创建时间")
  88 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  89 + private Date[] createTime;
  90 +
  91 +}
yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/coupon/vo/CouponPageReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.coupon.controller.admin.coupon.vo;
  2 +
  3 +import lombok.*;
  4 +
  5 +import java.math.BigDecimal;
  6 +import java.util.*;
  7 +import io.swagger.annotations.*;
  8 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  9 +import org.springframework.format.annotation.DateTimeFormat;
  10 +
  11 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  12 +
  13 +@ApiModel("管理后台 - 优惠券分页 Request VO")
  14 +@Data
  15 +@EqualsAndHashCode(callSuper = true)
  16 +@ToString(callSuper = true)
  17 +public class CouponPageReqVO extends PageParam {
  18 +
  19 + @ApiModelProperty(value = "优惠券类型 reward-满减 discount-折扣 random-随机")
  20 + private String type;
  21 +
  22 + @ApiModelProperty(value = "优惠券名称")
  23 + private String name;
  24 +
  25 + @ApiModelProperty(value = "优惠券类型id")
  26 + private Long couponTypeId;
  27 +
  28 + @ApiModelProperty(value = "优惠券编码")
  29 + private String couponCode;
  30 +
  31 + @ApiModelProperty(value = "领用人")
  32 + private Long memberId;
  33 +
  34 + @ApiModelProperty(value = "优惠券使用订单id")
  35 + private Long useOrderId;
  36 +
  37 + @ApiModelProperty(value = "适用商品类型1-全部商品可用;2-指定商品可用;3-指定商品不可用")
  38 + private Boolean goodsType;
  39 +
  40 + @ApiModelProperty(value = "适用商品id")
  41 + private String goodsIds;
  42 +
  43 + @ApiModelProperty(value = "最小金额")
  44 + private BigDecimal atLeast;
  45 +
  46 + @ApiModelProperty(value = "面额")
  47 + private BigDecimal money;
  48 +
  49 + @ApiModelProperty(value = "1 =< 折扣 <= 9.9 当type为discount时需要添加")
  50 + private BigDecimal discount;
  51 +
  52 + @ApiModelProperty(value = "最多折扣金额 当type为discount时可选择性添加")
  53 + private BigDecimal discountLimit;
  54 +
  55 + @ApiModelProperty(value = "优惠叠加 0-不限制 1- 优惠券仅原价购买商品时可用")
  56 + private Boolean whetherForbidPreference;
  57 +
  58 + @ApiModelProperty(value = "是否开启过期提醒0-不开启 1-开启")
  59 + private Boolean whetherExpireNotice;
  60 +
  61 + @ApiModelProperty(value = "过期前N天提醒")
  62 + private Integer expireNoticeFixedTerm;
  63 +
  64 + @ApiModelProperty(value = "是否已提醒")
  65 + private Boolean whetherNoticed;
  66 +
  67 + @ApiModelProperty(value = "优惠券状态 1已领用(未使用) 2已使用 3已过期")
  68 + private Integer state;
  69 +
  70 + @ApiModelProperty(value = "获取方式1订单2.直接领取3.活动领取 4转赠 5分享获取")
  71 + private Boolean getType;
  72 +
  73 + @ApiModelProperty(value = "领取时间")
  74 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  75 + private Date[] fetchTime;
  76 +
  77 + @ApiModelProperty(value = "使用时间")
  78 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  79 + private Date[] useTime;
  80 +
  81 + @ApiModelProperty(value = "可使用的开始时间")
  82 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  83 + private Date[] startTime;
  84 +
  85 + @ApiModelProperty(value = "有效期结束时间")
  86 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  87 + private Date[] endTime;
  88 +
  89 + @ApiModelProperty(value = "创建时间")
  90 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  91 + private Date[] createTime;
  92 +
  93 +}
yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/activity/vo/ActivityRespVO.java renamed to yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/coupon/vo/CouponRespVO.java
1 -package cn.iocoder.yudao.module.market.controller.admin.activity.vo; 1 +package cn.iocoder.yudao.module.coupon.controller.admin.coupon.vo;
2 2
3 import lombok.*; 3 import lombok.*;
4 import java.util.*; 4 import java.util.*;
5 import io.swagger.annotations.*; 5 import io.swagger.annotations.*;
6 6
7 -@ApiModel("管理后台 - 促销活动 Response VO") 7 +@ApiModel("管理后台 - 优惠券 Response VO")
8 @Data 8 @Data
9 @EqualsAndHashCode(callSuper = true) 9 @EqualsAndHashCode(callSuper = true)
10 @ToString(callSuper = true) 10 @ToString(callSuper = true)
11 -public class ActivityRespVO extends ActivityBaseVO { 11 +public class CouponRespVO extends CouponBaseVO {
12 12
13 - @ApiModelProperty(value = "活动编号", required = true) 13 + @ApiModelProperty(value = "用户ID", required = true)
14 private Long id; 14 private Long id;
15 15
16 @ApiModelProperty(value = "创建时间", required = true) 16 @ApiModelProperty(value = "创建时间", required = true)
yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/activity/vo/ActivityUpdateReqVO.java renamed to yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/coupon/vo/CouponUpdateReqVO.java
1 -package cn.iocoder.yudao.module.market.controller.admin.activity.vo; 1 +package cn.iocoder.yudao.module.coupon.controller.admin.coupon.vo;
2 2
3 import lombok.*; 3 import lombok.*;
4 import java.util.*; 4 import java.util.*;
5 import io.swagger.annotations.*; 5 import io.swagger.annotations.*;
6 import javax.validation.constraints.*; 6 import javax.validation.constraints.*;
7 7
8 -@ApiModel("管理后台 - 促销活动更新 Request VO") 8 +@ApiModel("管理后台 - 优惠券更新 Request VO")
9 @Data 9 @Data
10 @EqualsAndHashCode(callSuper = true) 10 @EqualsAndHashCode(callSuper = true)
11 @ToString(callSuper = true) 11 @ToString(callSuper = true)
12 -public class ActivityUpdateReqVO extends ActivityBaseVO { 12 +public class CouponUpdateReqVO extends CouponBaseVO {
13 13
14 - @ApiModelProperty(value = "活动编号", required = true)  
15 - @NotNull(message = "活动编号不能为空") 14 + @ApiModelProperty(value = "用户ID", required = true)
  15 + @NotNull(message = "用户ID不能为空")
16 private Long id; 16 private Long id;
17 17
18 } 18 }
yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/templete/CouponTempleteController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.coupon.controller.admin.templete;
  2 +
  3 +import cn.iocoder.yudao.module.coupon.controller.admin.templete.vo.*;
  4 +import cn.iocoder.yudao.module.coupon.convert.CouponTemplete.CouponTempleteConvert;
  5 +import cn.iocoder.yudao.module.coupon.dal.dataobject.CouponTemplete.CouponTempleteDO;
  6 +import cn.iocoder.yudao.module.coupon.service.CouponTemplete.CouponTempleteService;
  7 +import org.springframework.web.bind.annotation.*;
  8 +import javax.annotation.Resource;
  9 +import org.springframework.validation.annotation.Validated;
  10 +import org.springframework.security.access.prepost.PreAuthorize;
  11 +import io.swagger.annotations.*;
  12 +
  13 +import javax.validation.*;
  14 +import java.util.*;
  15 +
  16 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  17 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  18 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  19 +
  20 +@Api(tags = "管理后台 - 优惠券模板")
  21 +@RestController
  22 +@RequestMapping("/coupon/template")
  23 +@Validated
  24 +public class CouponTempleteController {
  25 +
  26 + @Resource
  27 + private CouponTempleteService couponTempleteServiceService;
  28 +
  29 + @PostMapping("/create")
  30 + @ApiOperation("创建优惠券模板")
  31 + @PreAuthorize("@ss.hasPermission('CouponTemplete::create')")
  32 + public CommonResult<Long> create(@Valid @RequestBody CouponTempleteCreateReqVO createReqVO) {
  33 + return success(couponTempleteServiceService.create(createReqVO));
  34 + }
  35 +
  36 +// @PutMapping("/update")
  37 +// @ApiOperation("更新优惠券模板")
  38 +// @PreAuthorize("@ss.hasPermission('CouponTemplete::update')")
  39 +// public CommonResult<Boolean> update(@Valid @RequestBody CouponTempleteUpdateReqVO updateReqVO) {
  40 +// couponTempleteServiceService.update(updateReqVO);
  41 +// return success(true);
  42 +// }
  43 +//
  44 +// @DeleteMapping("/delete")
  45 +// @ApiOperation("删除优惠券模板")
  46 +// @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class)
  47 +// @PreAuthorize("@ss.hasPermission('CouponTemplete::delete')")
  48 +// public CommonResult<Boolean> delete(@RequestParam("id") Long id) {
  49 +// couponTempleteServiceService.delete(id);
  50 +// return success(true);
  51 +// }
  52 +//
  53 +// @GetMapping("/get")
  54 +// @ApiOperation("获得优惠券模板")
  55 +// @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
  56 +// @PreAuthorize("@ss.hasPermission('CouponTemplete::query')")
  57 +// public CommonResult<CouponTempleteRespVO> get(@RequestParam("id") Long id) {
  58 +// CouponTempleteDO couponTempleteDO = couponTempleteServiceService.get(id);
  59 +// return success(CouponTempleteConvert.INSTANCE.convert(couponTempleteDO));
  60 +// }
  61 +//
  62 +// @GetMapping("/list")
  63 +// @ApiOperation("获得优惠券模板列表")
  64 +// @ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class)
  65 +// @PreAuthorize("@ss.hasPermission('CouponTemplete::query')")
  66 +// public CommonResult<List<CouponTempleteRespVO>> getList(@RequestParam("ids") Collection<Long> ids) {
  67 +// List<CouponTempleteDO> list = couponTempleteServiceService.getList(ids);
  68 +// return success(CouponTempleteConvert.INSTANCE.convertList(list));
  69 +// }
  70 +//
  71 + @GetMapping("/page")
  72 + @ApiOperation("获得优惠券模板分页")
  73 + @PreAuthorize("@ss.hasPermission('CouponTemplete::query')")
  74 + public CommonResult<PageResult<CouponTempleteRespVO>> getPage(@Valid CouponTempletePageReqVO pageVO) {
  75 + PageResult<CouponTempleteDO> pageResult = couponTempleteServiceService.getPage(pageVO);
  76 + return success(CouponTempleteConvert.INSTANCE.convertPage(pageResult));
  77 + }
  78 +
  79 +
  80 +
  81 +}
yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/templete/vo/CouponTempleteBaseVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.coupon.controller.admin.templete.vo;
  2 +
  3 +import lombok.*;
  4 +import java.util.*;
  5 +import java.math.BigDecimal;
  6 +import io.swagger.annotations.*;
  7 +import javax.validation.constraints.*;
  8 +import org.springframework.format.annotation.DateTimeFormat;
  9 +
  10 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  11 +
  12 +/**
  13 +* 优惠券模板 Base VO,提供给添加、修改、详细的子 VO 使用
  14 +* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
  15 +*/
  16 +@Data
  17 +public class CouponTempleteBaseVO {
  18 +
  19 +
  20 + //基本信息
  21 +
  22 + @ApiModelProperty(value = "优惠券名称", required = true)
  23 + @NotNull(message = "优惠券名称不能为空")
  24 + private String name;
  25 +
  26 + @ApiModelProperty(value = "名称备注")
  27 + private String couponNameRemark;
  28 +
  29 + @ApiModelProperty(value = "优惠券图片")
  30 + private String image;
  31 +
  32 + /* ============判断适用商品——开始============= */
  33 +
  34 +
  35 + @ApiModelProperty(value = "适用商品类型1-全部商品可用;2-指定商品可用;3-指定商品不可用", required = true)
  36 + @NotNull(message = "适用商品类型1-全部商品可用;2-指定商品可用;3-指定商品不可用不能为空")
  37 + private Integer goodsType;
  38 +
  39 + @ApiModelProperty(value = "适用商品id")
  40 + private String productIds;
  41 +
  42 + @ApiModelProperty(value = "使用门槛0-无门槛 1-有门槛", required = true)
  43 + @NotNull(message = "使用门槛0-无门槛 1-有门槛不能为空")
  44 + private Boolean hasUseLimit;
  45 +
  46 + @ApiModelProperty(value = "满多少元使用 0代表无限制", required = true)
  47 + @NotNull(message = "满多少元使用 0代表无限制不能为空")
  48 + private BigDecimal atLeast;
  49 +
  50 +
  51 + /* ============折扣类型——开始============= */
  52 +
  53 + @ApiModelProperty(value = "优惠券类型 reward-满减 discount-折扣 random-随机", required = true)
  54 + @NotNull(message = "优惠券类型 reward-满减 discount-折扣 random-随机不能为空")
  55 + private String type;
  56 +
  57 + @ApiModelProperty(value = "发放面额 当type为reward时需要添加")
  58 + @NotNull(message = "发放面额 当type为reward时需要添加不能为空")
  59 + private BigDecimal money;
  60 +
  61 + @ApiModelProperty(value = "1 =< 折扣 <= 9.9 当type为discount时需要添加")
  62 + @NotNull(message = "1 =< 折扣 <= 9.9 当type为discount时需要添加不能为空")
  63 + private BigDecimal discount;
  64 +
  65 + @ApiModelProperty(value = "最多折扣金额 当type为discount时可选择性添加")
  66 + @NotNull(message = "最多折扣金额 当type为discount时可选择性添加不能为空")
  67 + private BigDecimal discountLimit;
  68 +
  69 + @ApiModelProperty(value = "最低金额 当type为radom时需要添加", required = true)
  70 + @NotNull(message = "最低金额 当type为radom时需要添加不能为空")
  71 + private BigDecimal minMoney;
  72 +
  73 + @ApiModelProperty(value = "最大金额 当type为radom时需要添加", required = true)
  74 + @NotNull(message = "最大金额 当type为radom时需要添加不能为空")
  75 + private BigDecimal maxMoney;
  76 +
  77 + /* ============折扣类型——结束============= */
  78 +
  79 +
  80 + /* ============过期类型——开始============= */
  81 +
  82 +
  83 + @ApiModelProperty(value = "过期类型1-时间范围过期 2-领取之日固定日期后过期 3-领取次日固定日期后过期", required = true)
  84 + @NotNull(message = "过期类型1-时间范围过期 2-领取之日固定日期后过期 3-领取次日固定日期后过期 不能为空")
  85 + private Integer validityType;
  86 +
  87 + @ApiModelProperty(value = "使用开始日期 过期类型1时必填")
  88 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  89 + private Date startUseTime;
  90 +
  91 + @ApiModelProperty(value = "使用结束日期 过期类型1时必填")
  92 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  93 + private Date endUseTime;
  94 +
  95 + @ApiModelProperty(value = "当validity_type为2或者3时需要添加 领取之日起或者次日N天内有效")
  96 + @NotNull(message = "当validity_type为2或者3时需要添加 领取之日起或者次日N天内有效不能为空")
  97 + private Integer fixedTerm;
  98 +
  99 + @ApiModelProperty(value = "有效日期结束时间")
  100 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  101 + private Date endTime;
  102 +
  103 + /* ============过期类型——结束============= */
  104 +
  105 +
  106 + @ApiModelProperty(value = "领取是否无限制0-否 1是", required = true)
  107 + @NotNull(message = "是否无限制0-否 1是")
  108 + private Boolean whetherLimitless;
  109 +
  110 + @ApiModelProperty(value = "每人最大领取个数", required = true)
  111 + @NotNull(message = "每人最大领取个数不能为空")
  112 + private Integer maxFetch;
  113 +
  114 + @ApiModelProperty(value = "是否开启过期提醒 0-不开启 1-开启", required = true)
  115 + @NotNull(message = "是否开启过期提醒0-不开启 1-开启不能为空")
  116 + private Boolean whetherExpireNotice;
  117 +
  118 + @ApiModelProperty(value = "过期前N天提醒", required = true)
  119 + @NotNull(message = "过期前N天提醒不能为空")
  120 + private Integer expireNoticeFixedTerm;
  121 +
  122 + @ApiModelProperty(value = "优惠叠加 0-不限制 1- 优惠券仅原价购买商品时可用", required = true)
  123 + @NotNull(message = "优惠叠加 0-不限制 1- 优惠券仅原价购买商品时可用不能为空")
  124 + private Boolean whetherForbidPreference;
  125 +
  126 + @ApiModelProperty(value = "是否显示", required = true)
  127 + @NotNull(message = "是否显示不能为空")
  128 + private Integer whetherShow;
  129 +
  130 + @ApiModelProperty(value = "是否禁止发放0-否 1-是", required = true)
  131 + @NotNull(message = "是否禁止发放0-否 1-是不能为空")
  132 + private Boolean whetherForbidden;
  133 +
  134 + /* ============汇总计算——开始============= */
  135 +
  136 +
  137 +
  138 + @ApiModelProperty(value = "使用优惠券购买的商品数量", required = true)
  139 + @NotNull(message = "使用优惠券购买的商品数量不能为空")
  140 + private Integer orderGoodsNum;
  141 +
  142 + @ApiModelProperty(value = "订单的优惠总金额", required = true)
  143 + @NotNull(message = "订单的优惠总金额不能为空")
  144 + private BigDecimal discountOrderMoney;
  145 +
  146 + @ApiModelProperty(value = "用券总成交额", required = true)
  147 + @NotNull(message = "用券总成交额不能为空")
  148 + private BigDecimal orderMoney;
  149 +
  150 + @ApiModelProperty(value = "发放数量", required = true)
  151 + @NotNull(message = "发放数量不能为空")
  152 + private Integer count;
  153 +
  154 + @ApiModelProperty(value = "已领取数量", required = true)
  155 + @NotNull(message = "已领取数量不能为空")
  156 + private Integer leadCount;
  157 +
  158 + @ApiModelProperty(value = "已使用数量", required = true)
  159 + @NotNull(message = "已使用数量不能为空")
  160 + private Integer usedCount;
  161 +
  162 +
  163 + /* ============汇总计算——结束============= */
  164 +
  165 +
  166 + @ApiModelProperty(value = "状态(1进行中2已结束3已关闭)", required = true)
  167 + @NotNull(message = "状态(1进行中2已结束-1已关闭)不能为空")
  168 + private Integer status;
  169 +
  170 +
  171 +
  172 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuCreateReqVO.java renamed to yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/templete/vo/CouponTempleteCreateReqVO.java 100755 → 100644
1 -package cn.iocoder.yudao.module.product.controller.admin.sku.vo; 1 +package cn.iocoder.yudao.module.coupon.controller.admin.templete.vo;
2 2
3 import lombok.*; 3 import lombok.*;
4 -import java.util.*;  
5 import io.swagger.annotations.*; 4 import io.swagger.annotations.*;
6 -import javax.validation.constraints.*;  
7 5
8 -@ApiModel("管理后台 - 商品sku创建 Request VO") 6 +@ApiModel("管理后台 - 优惠券模板创建 Request VO")
9 @Data 7 @Data
10 @EqualsAndHashCode(callSuper = true) 8 @EqualsAndHashCode(callSuper = true)
11 @ToString(callSuper = true) 9 @ToString(callSuper = true)
12 -public class ProductSkuCreateReqVO extends ProductSkuBaseVO { 10 +public class CouponTempleteCreateReqVO extends CouponTempleteBaseVO {
13 11
14 } 12 }
yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/templete/vo/CouponTempleteExcelVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.coupon.controller.admin.templete.vo;
  2 +
  3 +import lombok.*;
  4 +import java.util.*;
  5 +import java.math.BigDecimal;
  6 +
  7 +import com.alibaba.excel.annotation.ExcelProperty;
  8 +
  9 +/**
  10 + * 优惠券模板 Excel VO
  11 + *
  12 + * @author wxr
  13 + */
  14 +@Data
  15 +public class CouponTempleteExcelVO {
  16 +
  17 + @ExcelProperty("用户ID")
  18 + private Long id;
  19 +
  20 + @ExcelProperty("优惠券类型 reward-满减 discount-折扣 random-随机")
  21 + private String type;
  22 +
  23 + @ExcelProperty("优惠券名称")
  24 + private String name;
  25 +
  26 + @ExcelProperty("名称备注")
  27 + private String couponNameRemark;
  28 +
  29 + @ExcelProperty("优惠券图片")
  30 + private String image;
  31 +
  32 + @ExcelProperty("发放数量")
  33 + private Integer count;
  34 +
  35 + @ExcelProperty("已领取数量")
  36 + private Integer leadCount;
  37 +
  38 + @ExcelProperty("已使用数量")
  39 + private Integer usedCount;
  40 +
  41 + @ExcelProperty("适用商品类型1-全部商品可用;2-指定商品可用;3-指定商品不可用")
  42 + private Integer goodsType;
  43 +
  44 + @ExcelProperty("适用商品id")
  45 + private String productIds;
  46 +
  47 + @ExcelProperty("使用门槛0-无门槛 1-有门槛")
  48 + private Boolean hasUseLimit;
  49 +
  50 + @ExcelProperty("满多少元使用 0代表无限制")
  51 + private BigDecimal atLeast;
  52 +
  53 + @ExcelProperty("发放面额 当type为reward时需要添加")
  54 + private BigDecimal money;
  55 +
  56 + @ExcelProperty("1 =< 折扣 <= 9.9 当type为discount时需要添加")
  57 + private BigDecimal discount;
  58 +
  59 + @ExcelProperty("最多折扣金额 当type为discount时可选择性添加")
  60 + private BigDecimal discountLimit;
  61 +
  62 + @ExcelProperty("最低金额 当type为radom时需要添加")
  63 + private BigDecimal minMoney;
  64 +
  65 + @ExcelProperty("最大金额 当type为radom时需要添加")
  66 + private BigDecimal maxMoney;
  67 +
  68 + @ExcelProperty("过期类型1-时间范围过期 2-领取之日固定日期后过期 3-领取次日固定日期后过期")
  69 + private Integer validityType;
  70 +
  71 + @ExcelProperty("使用开始日期 过期类型1时必填")
  72 + private Date startUseTime;
  73 +
  74 + @ExcelProperty("使用结束日期 过期类型1时必填")
  75 + private Date endUseTime;
  76 +
  77 + @ExcelProperty("当validity_type为2或者3时需要添加 领取之日起或者次日N天内有效")
  78 + private Integer fixedTerm;
  79 +
  80 + @ExcelProperty("是否无限制0-否 1是")
  81 + private Boolean whetherLimitless;
  82 +
  83 + @ExcelProperty("每人最大领取个数")
  84 + private Integer maxFetch;
  85 +
  86 + @ExcelProperty("是否开启过期提醒0-不开启 1-开启")
  87 + private Boolean whetherExpireNotice;
  88 +
  89 + @ExcelProperty("过期前N天提醒")
  90 + private Integer expireNoticeFixedTerm;
  91 +
  92 + @ExcelProperty("优惠叠加 0-不限制 1- 优惠券仅原价购买商品时可用")
  93 + private Boolean whetherForbidPreference;
  94 +
  95 + @ExcelProperty("是否显示")
  96 + private Integer whetherShow;
  97 +
  98 + @ExcelProperty("订单的优惠总金额")
  99 + private BigDecimal discountOrderMoney;
  100 +
  101 + @ExcelProperty("用券总成交额")
  102 + private BigDecimal orderMoney;
  103 +
  104 + @ExcelProperty("是否禁止发放0-否 1-是")
  105 + private Boolean whetherForbidden;
  106 +
  107 + @ExcelProperty("使用优惠券购买的商品数量")
  108 + private Integer orderGoodsNum;
  109 +
  110 + @ExcelProperty("状态(1进行中2已结束-1已关闭)")
  111 + private Integer status;
  112 +
  113 + @ExcelProperty("有效日期结束时间")
  114 + private Date endTime;
  115 +
  116 + @ExcelProperty("创建时间")
  117 + private Date createTime;
  118 +
  119 +}
yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/templete/vo/CouponTempleteExportReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.coupon.controller.admin.templete.vo;
  2 +
  3 +import lombok.*;
  4 +
  5 +import java.math.BigDecimal;
  6 +import java.util.*;
  7 +import io.swagger.annotations.*;
  8 +import org.springframework.format.annotation.DateTimeFormat;
  9 +
  10 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  11 +
  12 +@ApiModel(value = "管理后台 - 优惠券模板 Excel 导出 Request VO", description = "参数和 CouponTempletePageReqVO 是一致的")
  13 +@Data
  14 +public class CouponTempleteExportReqVO {
  15 +
  16 + @ApiModelProperty(value = "优惠券类型 reward-满减 discount-折扣 random-随机")
  17 + private String type;
  18 +
  19 + @ApiModelProperty(value = "优惠券名称")
  20 + private String name;
  21 +
  22 + @ApiModelProperty(value = "名称备注")
  23 + private String couponNameRemark;
  24 +
  25 + @ApiModelProperty(value = "优惠券图片")
  26 + private String image;
  27 +
  28 + @ApiModelProperty(value = "发放数量")
  29 + private Integer count;
  30 +
  31 + @ApiModelProperty(value = "已领取数量")
  32 + private Integer leadCount;
  33 +
  34 + @ApiModelProperty(value = "已使用数量")
  35 + private Integer usedCount;
  36 +
  37 + @ApiModelProperty(value = "适用商品类型1-全部商品可用;2-指定商品可用;3-指定商品不可用")
  38 + private Boolean goodsType;
  39 +
  40 + @ApiModelProperty(value = "适用商品id")
  41 + private String productIds;
  42 +
  43 + @ApiModelProperty(value = "使用门槛0-无门槛 1-有门槛")
  44 + private Boolean hasUseLimit;
  45 +
  46 + @ApiModelProperty(value = "满多少元使用 0代表无限制")
  47 + private BigDecimal atLeast;
  48 +
  49 + @ApiModelProperty(value = "发放面额 当type为reward时需要添加")
  50 + private BigDecimal money;
  51 +
  52 + @ApiModelProperty(value = "1 =< 折扣 <= 9.9 当type为discount时需要添加")
  53 + private BigDecimal discount;
  54 +
  55 + @ApiModelProperty(value = "最多折扣金额 当type为discount时可选择性添加")
  56 + private BigDecimal discountLimit;
  57 +
  58 + @ApiModelProperty(value = "最低金额 当type为radom时需要添加")
  59 + private BigDecimal minMoney;
  60 +
  61 + @ApiModelProperty(value = "最大金额 当type为radom时需要添加")
  62 + private BigDecimal maxMoney;
  63 +
  64 + @ApiModelProperty(value = "过期类型1-时间范围过期 2-领取之日固定日期后过期 3-领取次日固定日期后过期")
  65 + private Boolean validityType;
  66 +
  67 + @ApiModelProperty(value = "使用开始日期 过期类型1时必填")
  68 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  69 + private Date[] startUseTime;
  70 +
  71 + @ApiModelProperty(value = "使用结束日期 过期类型1时必填")
  72 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  73 + private Date[] endUseTime;
  74 +
  75 + @ApiModelProperty(value = "当validity_type为2或者3时需要添加 领取之日起或者次日N天内有效")
  76 + private Integer fixedTerm;
  77 +
  78 + @ApiModelProperty(value = "是否无限制0-否 1是")
  79 + private Boolean whetherLimitless;
  80 +
  81 + @ApiModelProperty(value = "每人最大领取个数")
  82 + private Integer maxFetch;
  83 +
  84 + @ApiModelProperty(value = "是否开启过期提醒0-不开启 1-开启")
  85 + private Boolean whetherExpireNotice;
  86 +
  87 + @ApiModelProperty(value = "过期前N天提醒")
  88 + private Integer expireNoticeFixedTerm;
  89 +
  90 + @ApiModelProperty(value = "优惠叠加 0-不限制 1- 优惠券仅原价购买商品时可用")
  91 + private Boolean whetherForbidPreference;
  92 +
  93 + @ApiModelProperty(value = "是否显示")
  94 + private Integer whetherShow;
  95 +
  96 + @ApiModelProperty(value = "订单的优惠总金额")
  97 + private BigDecimal discountOrderMoney;
  98 +
  99 + @ApiModelProperty(value = "用券总成交额")
  100 + private BigDecimal orderMoney;
  101 +
  102 + @ApiModelProperty(value = "是否禁止发放0-否 1-是")
  103 + private Boolean whetherForbidden;
  104 +
  105 + @ApiModelProperty(value = "使用优惠券购买的商品数量")
  106 + private Integer orderGoodsNum;
  107 +
  108 + @ApiModelProperty(value = "状态(1进行中2已结束-1已关闭)")
  109 + private Integer status;
  110 +
  111 + @ApiModelProperty(value = "有效日期结束时间")
  112 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  113 + private Date[] endTime;
  114 +
  115 + @ApiModelProperty(value = "创建时间")
  116 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  117 + private Date[] createTime;
  118 +
  119 +}
yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/templete/vo/CouponTempletePageReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.coupon.controller.admin.templete.vo;
  2 +
  3 +import lombok.*;
  4 +
  5 +import java.math.BigDecimal;
  6 +import java.util.*;
  7 +import io.swagger.annotations.*;
  8 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  9 +import org.springframework.format.annotation.DateTimeFormat;
  10 +
  11 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  12 +
  13 +@ApiModel("管理后台 - 优惠券模板分页 Request VO")
  14 +@Data
  15 +@EqualsAndHashCode(callSuper = true)
  16 +@ToString(callSuper = true)
  17 +public class CouponTempletePageReqVO extends PageParam {
  18 +
  19 + @ApiModelProperty(value = "优惠券类型 reward-满减 discount-折扣 random-随机")
  20 + private String type;
  21 +
  22 + @ApiModelProperty(value = "优惠券名称")
  23 + private String name;
  24 +
  25 + @ApiModelProperty(value = "名称备注")
  26 + private String couponNameRemark;
  27 +
  28 + @ApiModelProperty(value = "优惠券图片")
  29 + private String image;
  30 +
  31 + @ApiModelProperty(value = "发放数量")
  32 + private Integer count;
  33 +
  34 + @ApiModelProperty(value = "已领取数量")
  35 + private Integer leadCount;
  36 +
  37 + @ApiModelProperty(value = "已使用数量")
  38 + private Integer usedCount;
  39 +
  40 + @ApiModelProperty(value = "适用商品类型1-全部商品可用;2-指定商品可用;3-指定商品不可用")
  41 + private Boolean goodsType;
  42 +
  43 + @ApiModelProperty(value = "适用商品id")
  44 + private String productIds;
  45 +
  46 + @ApiModelProperty(value = "使用门槛0-无门槛 1-有门槛")
  47 + private Boolean hasUseLimit;
  48 +
  49 + @ApiModelProperty(value = "满多少元使用 0代表无限制")
  50 + private BigDecimal atLeast;
  51 +
  52 + @ApiModelProperty(value = "发放面额 当type为reward时需要添加")
  53 + private BigDecimal money;
  54 +
  55 + @ApiModelProperty(value = "1 =< 折扣 <= 9.9 当type为discount时需要添加")
  56 + private BigDecimal discount;
  57 +
  58 + @ApiModelProperty(value = "最多折扣金额 当type为discount时可选择性添加")
  59 + private BigDecimal discountLimit;
  60 +
  61 + @ApiModelProperty(value = "最低金额 当type为radom时需要添加")
  62 + private BigDecimal minMoney;
  63 +
  64 + @ApiModelProperty(value = "最大金额 当type为radom时需要添加")
  65 + private BigDecimal maxMoney;
  66 +
  67 + @ApiModelProperty(value = "过期类型1-时间范围过期 2-领取之日固定日期后过期 3-领取次日固定日期后过期")
  68 + private Boolean validityType;
  69 +
  70 + @ApiModelProperty(value = "使用开始日期 过期类型1时必填")
  71 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  72 + private Date[] startUseTime;
  73 +
  74 + @ApiModelProperty(value = "使用结束日期 过期类型1时必填")
  75 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  76 + private Date[] endUseTime;
  77 +
  78 + @ApiModelProperty(value = "当validity_type为2或者3时需要添加 领取之日起或者次日N天内有效")
  79 + private Integer fixedTerm;
  80 +
  81 + @ApiModelProperty(value = "是否无限制0-否 1是")
  82 + private Boolean whetherLimitless;
  83 +
  84 + @ApiModelProperty(value = "每人最大领取个数")
  85 + private Integer maxFetch;
  86 +
  87 + @ApiModelProperty(value = "是否开启过期提醒0-不开启 1-开启")
  88 + private Boolean whetherExpireNotice;
  89 +
  90 + @ApiModelProperty(value = "过期前N天提醒")
  91 + private Integer expireNoticeFixedTerm;
  92 +
  93 + @ApiModelProperty(value = "优惠叠加 0-不限制 1- 优惠券仅原价购买商品时可用")
  94 + private Boolean whetherForbidPreference;
  95 +
  96 + @ApiModelProperty(value = "是否显示")
  97 + private Integer whetherShow;
  98 +
  99 + @ApiModelProperty(value = "订单的优惠总金额")
  100 + private BigDecimal discountOrderMoney;
  101 +
  102 + @ApiModelProperty(value = "用券总成交额")
  103 + private BigDecimal orderMoney;
  104 +
  105 + @ApiModelProperty(value = "是否禁止发放0-否 1-是")
  106 + private Boolean whetherForbidden;
  107 +
  108 + @ApiModelProperty(value = "使用优惠券购买的商品数量")
  109 + private Integer orderGoodsNum;
  110 +
  111 + @ApiModelProperty(value = "状态(1进行中2已结束-1已关闭)")
  112 + private Integer status;
  113 +
  114 + @ApiModelProperty(value = "有效日期结束时间")
  115 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  116 + private Date[] endTime;
  117 +
  118 + @ApiModelProperty(value = "创建时间")
  119 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  120 + private Date[] createTime;
  121 +
  122 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/BrandRespVO.java renamed to yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/templete/vo/CouponTempleteRespVO.java
1 -package cn.iocoder.yudao.module.product.controller.admin.brand.vo; 1 +package cn.iocoder.yudao.module.coupon.controller.admin.templete.vo;
2 2
3 import lombok.*; 3 import lombok.*;
4 import java.util.*; 4 import java.util.*;
5 import io.swagger.annotations.*; 5 import io.swagger.annotations.*;
6 6
7 -@ApiModel("管理后台 - 品牌 Response VO") 7 +@ApiModel("管理后台 - 优惠券模板 Response VO")
8 @Data 8 @Data
9 @EqualsAndHashCode(callSuper = true) 9 @EqualsAndHashCode(callSuper = true)
10 @ToString(callSuper = true) 10 @ToString(callSuper = true)
11 -public class BrandRespVO extends BrandBaseVO { 11 +public class CouponTempleteRespVO extends CouponTempleteBaseVO {
12 12
13 - @ApiModelProperty(value = "品牌编号", required = true, example = "1") 13 + @ApiModelProperty(value = "用户ID", required = true)
14 private Long id; 14 private Long id;
15 15
16 @ApiModelProperty(value = "创建时间", required = true) 16 @ApiModelProperty(value = "创建时间", required = true)
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuUpdateReqVO.java renamed to yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/controller/admin/templete/vo/CouponTempleteUpdateReqVO.java 100755 → 100644
1 -package cn.iocoder.yudao.module.product.controller.admin.sku.vo; 1 +package cn.iocoder.yudao.module.coupon.controller.admin.templete.vo;
2 2
3 import lombok.*; 3 import lombok.*;
4 -import java.util.*;  
5 import io.swagger.annotations.*; 4 import io.swagger.annotations.*;
6 import javax.validation.constraints.*; 5 import javax.validation.constraints.*;
7 6
8 -@ApiModel("管理后台 - 商品sku更新 Request VO") 7 +@ApiModel("管理后台 - 优惠券模板更新 Request VO")
9 @Data 8 @Data
10 @EqualsAndHashCode(callSuper = true) 9 @EqualsAndHashCode(callSuper = true)
11 @ToString(callSuper = true) 10 @ToString(callSuper = true)
12 -public class ProductSkuUpdateReqVO extends ProductSkuBaseVO { 11 +public class CouponTempleteUpdateReqVO extends CouponTempleteBaseVO {
13 12
14 - @ApiModelProperty(value = "主键", required = true)  
15 - @NotNull(message = "主键不能为空") 13 + @ApiModelProperty(value = "用户ID", required = true)
  14 + @NotNull(message = "用户ID不能为空")
16 private Long id; 15 private Long id;
17 16
18 } 17 }
yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/convert/CouponTemplete/CouponTempleteConvert.java 0 → 100644
  1 +package cn.iocoder.yudao.module.coupon.convert.CouponTemplete;
  2 +
  3 +import java.util.*;
  4 +
  5 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  6 +
  7 +import cn.iocoder.yudao.module.coupon.controller.admin.templete.vo.CouponTempleteCreateReqVO;
  8 +import cn.iocoder.yudao.module.coupon.controller.admin.templete.vo.CouponTempleteExcelVO;
  9 +import cn.iocoder.yudao.module.coupon.controller.admin.templete.vo.CouponTempleteRespVO;
  10 +import cn.iocoder.yudao.module.coupon.controller.admin.templete.vo.CouponTempleteUpdateReqVO;
  11 +import cn.iocoder.yudao.module.coupon.dal.dataobject.CouponTemplete.CouponTempleteDO;
  12 +import org.mapstruct.Mapper;
  13 +import org.mapstruct.factory.Mappers;
  14 +
  15 +
  16 +/**
  17 + * 优惠券模板 Convert
  18 + *
  19 + * @author wxr
  20 + */
  21 +@Mapper
  22 +public interface CouponTempleteConvert {
  23 +
  24 + CouponTempleteConvert INSTANCE = Mappers.getMapper(CouponTempleteConvert.class);
  25 +
  26 + CouponTempleteDO convert(CouponTempleteCreateReqVO bean);
  27 +
  28 + CouponTempleteDO convert(CouponTempleteUpdateReqVO bean);
  29 +
  30 + CouponTempleteRespVO convert(CouponTempleteDO bean);
  31 +
  32 + List<CouponTempleteRespVO> convertList(List<CouponTempleteDO> list);
  33 +
  34 + PageResult<CouponTempleteRespVO> convertPage(PageResult<CouponTempleteDO> page);
  35 +
  36 + List<CouponTempleteExcelVO> convertList02(List<CouponTempleteDO> list);
  37 +
  38 +}
yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/convert/coupon/CouponConvert.java 0 → 100644
  1 +package cn.iocoder.yudao.module.coupon.convert.coupon;
  2 +
  3 +import java.util.*;
  4 +
  5 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  6 +
  7 +import org.mapstruct.Mapper;
  8 +import org.mapstruct.factory.Mappers;
  9 +import cn.iocoder.yudao.module.coupon.controller.admin.coupon.vo.*;
  10 +import cn.iocoder.yudao.module.coupon.dal.dataobject.coupon.CouponDO;
  11 +
  12 +/**
  13 + * 优惠券 Convert
  14 + *
  15 + * @author wxr
  16 + */
  17 +@Mapper
  18 +public interface CouponConvert {
  19 +
  20 + CouponConvert INSTANCE = Mappers.getMapper(CouponConvert.class);
  21 +
  22 + CouponDO convert(CouponCreateReqVO bean);
  23 +
  24 + CouponDO convert(CouponUpdateReqVO bean);
  25 +
  26 + CouponRespVO convert(CouponDO bean);
  27 +
  28 + List<CouponRespVO> convertList(List<CouponDO> list);
  29 +
  30 + PageResult<CouponRespVO> convertPage(PageResult<CouponDO> page);
  31 +
  32 + List<CouponExcelVO> convertList02(List<CouponDO> list);
  33 +
  34 +}
yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/dal/dataobject/CouponTemplete/CouponTempleteDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.coupon.dal.dataobject.CouponTemplete;
  2 +
  3 +import lombok.*;
  4 +import java.util.*;
  5 +import java.math.BigDecimal;
  6 +import com.baomidou.mybatisplus.annotation.*;
  7 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  8 +
  9 +/**
  10 + * 优惠券模板 DO
  11 + *
  12 + * @author wxr
  13 + */
  14 +@TableName("coupon_templete")
  15 +@KeySequence("coupon_templete_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
  16 +@Data
  17 +@EqualsAndHashCode(callSuper = true)
  18 +@ToString(callSuper = true)
  19 +@Builder
  20 +@NoArgsConstructor
  21 +@AllArgsConstructor
  22 +public class CouponTempleteDO extends BaseDO {
  23 +
  24 + /**
  25 + * 用户ID
  26 + */
  27 + @TableId
  28 + private Long id;
  29 + /**
  30 + * 优惠券类型 reward-满减 discount-折扣 random-随机
  31 + */
  32 + private String type;
  33 + /**
  34 + * 优惠券名称
  35 + */
  36 + private String name;
  37 + /**
  38 + * 名称备注
  39 + */
  40 + private String couponNameRemark;
  41 + /**
  42 + * 优惠券图片
  43 + */
  44 + private String image;
  45 + /**
  46 + * 发放数量
  47 + */
  48 + private Integer count;
  49 + /**
  50 + * 已领取数量
  51 + */
  52 + private Integer leadCount;
  53 + /**
  54 + * 已使用数量
  55 + */
  56 + private Integer usedCount;
  57 + /**
  58 + * 适用商品类型1-全部商品可用;2-指定商品可用;3-指定商品不可用
  59 + */
  60 + private Integer goodsType;
  61 + /**
  62 + * 适用商品id
  63 + */
  64 + private String productIds;
  65 + /**
  66 + * 使用门槛0-无门槛 1-有门槛
  67 + */
  68 + private Boolean hasUseLimit;
  69 + /**
  70 + * 满多少元使用 0代表无限制
  71 + */
  72 + private BigDecimal atLeast;
  73 + /**
  74 + * 发放面额 当type为reward时需要添加
  75 + */
  76 + private BigDecimal money;
  77 + /**
  78 + * 1 =< 折扣 <= 9.9 当type为discount时需要添加
  79 + */
  80 + private BigDecimal discount;
  81 + /**
  82 + * 最多折扣金额 当type为discount时可选择性添加
  83 + */
  84 + private BigDecimal discountLimit;
  85 + /**
  86 + * 最低金额 当type为radom时需要添加
  87 + */
  88 + private BigDecimal minMoney;
  89 + /**
  90 + * 最大金额 当type为radom时需要添加
  91 + */
  92 + private BigDecimal maxMoney;
  93 + /**
  94 + * 过期类型1-时间范围过期 2-领取之日固定日期后过期 3-领取次日固定日期后过期
  95 + */
  96 + private Integer validityType;
  97 + /**
  98 + * 使用开始日期 过期类型1时必填
  99 + */
  100 + private Date startUseTime;
  101 + /**
  102 + * 使用结束日期 过期类型1时必填
  103 + */
  104 + private Date endUseTime;
  105 + /**
  106 + * 当validity_type为2或者3时需要添加 领取之日起或者次日N天内有效
  107 + */
  108 + private Integer fixedTerm;
  109 + /**
  110 + * 是否无限制0-否 1是
  111 + */
  112 + private Boolean whetherLimitless;
  113 + /**
  114 + * 每人最大领取个数
  115 + */
  116 + private Integer maxFetch;
  117 + /**
  118 + * 是否开启过期提醒0-不开启 1-开启
  119 + */
  120 + private Boolean whetherExpireNotice;
  121 + /**
  122 + * 过期前N天提醒
  123 + */
  124 + private Integer expireNoticeFixedTerm;
  125 + /**
  126 + * 优惠叠加 0-不限制 1- 优惠券仅原价购买商品时可用
  127 + */
  128 + private Boolean whetherForbidPreference;
  129 + /**
  130 + * 是否显示
  131 + */
  132 + private Integer whetherShow;
  133 + /**
  134 + * 订单的优惠总金额
  135 + */
  136 + private BigDecimal discountOrderMoney;
  137 + /**
  138 + * 用券总成交额
  139 + */
  140 + private BigDecimal orderMoney;
  141 + /**
  142 + * 是否禁止发放0-否 1-是
  143 + */
  144 + private Boolean whetherForbidden;
  145 + /**
  146 + * 使用优惠券购买的商品数量
  147 + */
  148 + private Integer orderGoodsNum;
  149 + /**
  150 + * 状态(1进行中2已结束-1已关闭)
  151 + */
  152 + private Integer status;
  153 + /**
  154 + * 有效日期结束时间
  155 + */
  156 + private Date endTime;
  157 +
  158 +}
yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/dal/dataobject/coupon/CouponDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.coupon.dal.dataobject.coupon;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import lombok.*;
  5 +import java.util.*;
  6 +import java.math.BigDecimal;
  7 +import com.baomidou.mybatisplus.annotation.*;
  8 +
  9 +/**
  10 + * 优惠券 DO
  11 + *
  12 + * @author wxr
  13 + */
  14 +@TableName("coupon")
  15 +@KeySequence("coupon_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
  16 +@Data
  17 +@EqualsAndHashCode(callSuper = true)
  18 +@ToString(callSuper = true)
  19 +@Builder
  20 +@NoArgsConstructor
  21 +@AllArgsConstructor
  22 +public class CouponDO extends BaseDO {
  23 +
  24 + /**
  25 + * 用户ID
  26 + */
  27 + @TableId
  28 + private Long id;
  29 + /**
  30 + * 优惠券类型 reward-满减 discount-折扣 random-随机
  31 + */
  32 + private String type;
  33 + /**
  34 + * 优惠券名称
  35 + */
  36 + private String name;
  37 + /**
  38 + * 优惠券类型id
  39 + */
  40 + private Long couponTypeId;
  41 + /**
  42 + * 优惠券编码
  43 + */
  44 + private String couponCode;
  45 + /**
  46 + * 领用人
  47 + */
  48 + private Long memberId;
  49 + /**
  50 + * 优惠券使用订单id
  51 + */
  52 + private Long useOrderId;
  53 + /**
  54 + * 适用商品类型1-全部商品可用;2-指定商品可用;3-指定商品不可用
  55 + */
  56 + private Boolean goodsType;
  57 + /**
  58 + * 适用商品id
  59 + */
  60 + private String goodsIds;
  61 + /**
  62 + * 最小金额
  63 + */
  64 + private BigDecimal atLeast;
  65 + /**
  66 + * 面额
  67 + */
  68 + private BigDecimal money;
  69 + /**
  70 + * 1 =< 折扣 <= 9.9 当type为discount时需要添加
  71 + */
  72 + private BigDecimal discount;
  73 + /**
  74 + * 最多折扣金额 当type为discount时可选择性添加
  75 + */
  76 + private BigDecimal discountLimit;
  77 + /**
  78 + * 优惠叠加 0-不限制 1- 优惠券仅原价购买商品时可用
  79 + */
  80 + private Boolean whetherForbidPreference;
  81 + /**
  82 + * 是否开启过期提醒0-不开启 1-开启
  83 + */
  84 + private Boolean whetherExpireNotice;
  85 + /**
  86 + * 过期前N天提醒
  87 + */
  88 + private Integer expireNoticeFixedTerm;
  89 + /**
  90 + * 是否已提醒
  91 + */
  92 + private Boolean whetherNoticed;
  93 + /**
  94 + * 优惠券状态 1已领用(未使用) 2已使用 3已过期
  95 + */
  96 + private Integer state;
  97 + /**
  98 + * 获取方式1订单2.直接领取3.活动领取 4转赠 5分享获取
  99 + */
  100 + private Boolean getType;
  101 + /**
  102 + * 领取时间
  103 + */
  104 + private Date fetchTime;
  105 + /**
  106 + * 使用时间
  107 + */
  108 + private Date useTime;
  109 + /**
  110 + * 可使用的开始时间
  111 + */
  112 + private Date startTime;
  113 + /**
  114 + * 有效期结束时间
  115 + */
  116 + private Date endTime;
  117 +
  118 +}
yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/dal/mysql/CouponTemplete/CouponTempleteMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.coupon.dal.mysql.CouponTemplete;
  2 +
  3 +import java.util.*;
  4 +
  5 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  6 +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
  7 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  8 +import cn.iocoder.yudao.module.coupon.controller.admin.templete.vo.CouponTempleteExportReqVO;
  9 +import cn.iocoder.yudao.module.coupon.controller.admin.templete.vo.CouponTempletePageReqVO;
  10 +import cn.iocoder.yudao.module.coupon.dal.dataobject.CouponTemplete.CouponTempleteDO;
  11 +import org.apache.ibatis.annotations.Mapper;
  12 +
  13 +
  14 +/**
  15 + * 优惠券模板 Mapper
  16 + *
  17 + * @author wxr
  18 + */
  19 +@Mapper
  20 +public interface CouponTempleteMapper extends BaseMapperX<CouponTempleteDO> {
  21 +
  22 + default PageResult<CouponTempleteDO> selectPage(CouponTempletePageReqVO reqVO) {
  23 + return selectPage(reqVO, new LambdaQueryWrapperX<CouponTempleteDO>()
  24 + .eqIfPresent(CouponTempleteDO::getType, reqVO.getType())
  25 + .likeIfPresent(CouponTempleteDO::getName, reqVO.getName())
  26 + .eqIfPresent(CouponTempleteDO::getCouponNameRemark, reqVO.getCouponNameRemark())
  27 + .eqIfPresent(CouponTempleteDO::getImage, reqVO.getImage())
  28 + .eqIfPresent(CouponTempleteDO::getCount, reqVO.getCount())
  29 + .eqIfPresent(CouponTempleteDO::getLeadCount, reqVO.getLeadCount())
  30 + .eqIfPresent(CouponTempleteDO::getUsedCount, reqVO.getUsedCount())
  31 + .eqIfPresent(CouponTempleteDO::getGoodsType, reqVO.getGoodsType())
  32 + .eqIfPresent(CouponTempleteDO::getProductIds, reqVO.getProductIds())
  33 + .eqIfPresent(CouponTempleteDO::getHasUseLimit, reqVO.getHasUseLimit())
  34 + .eqIfPresent(CouponTempleteDO::getAtLeast, reqVO.getAtLeast())
  35 + .eqIfPresent(CouponTempleteDO::getMoney, reqVO.getMoney())
  36 + .eqIfPresent(CouponTempleteDO::getDiscount, reqVO.getDiscount())
  37 + .eqIfPresent(CouponTempleteDO::getDiscountLimit, reqVO.getDiscountLimit())
  38 + .eqIfPresent(CouponTempleteDO::getMinMoney, reqVO.getMinMoney())
  39 + .eqIfPresent(CouponTempleteDO::getMaxMoney, reqVO.getMaxMoney())
  40 + .eqIfPresent(CouponTempleteDO::getValidityType, reqVO.getValidityType())
  41 + .betweenIfPresent(CouponTempleteDO::getStartUseTime, reqVO.getStartUseTime())
  42 + .betweenIfPresent(CouponTempleteDO::getEndUseTime, reqVO.getEndUseTime())
  43 + .eqIfPresent(CouponTempleteDO::getFixedTerm, reqVO.getFixedTerm())
  44 + .eqIfPresent(CouponTempleteDO::getWhetherLimitless, reqVO.getWhetherLimitless())
  45 + .eqIfPresent(CouponTempleteDO::getMaxFetch, reqVO.getMaxFetch())
  46 + .eqIfPresent(CouponTempleteDO::getWhetherExpireNotice, reqVO.getWhetherExpireNotice())
  47 + .eqIfPresent(CouponTempleteDO::getExpireNoticeFixedTerm, reqVO.getExpireNoticeFixedTerm())
  48 + .eqIfPresent(CouponTempleteDO::getWhetherForbidPreference, reqVO.getWhetherForbidPreference())
  49 + .eqIfPresent(CouponTempleteDO::getWhetherShow, reqVO.getWhetherShow())
  50 + .eqIfPresent(CouponTempleteDO::getDiscountOrderMoney, reqVO.getDiscountOrderMoney())
  51 + .eqIfPresent(CouponTempleteDO::getOrderMoney, reqVO.getOrderMoney())
  52 + .eqIfPresent(CouponTempleteDO::getWhetherForbidden, reqVO.getWhetherForbidden())
  53 + .eqIfPresent(CouponTempleteDO::getOrderGoodsNum, reqVO.getOrderGoodsNum())
  54 + .eqIfPresent(CouponTempleteDO::getStatus, reqVO.getStatus())
  55 + .betweenIfPresent(CouponTempleteDO::getEndTime, reqVO.getEndTime())
  56 + .betweenIfPresent(CouponTempleteDO::getCreateTime, reqVO.getCreateTime())
  57 + .orderByDesc(CouponTempleteDO::getId));
  58 + }
  59 +
  60 + default List<CouponTempleteDO> selectList(CouponTempleteExportReqVO reqVO) {
  61 + return selectList(new LambdaQueryWrapperX<CouponTempleteDO>()
  62 + .eqIfPresent(CouponTempleteDO::getType, reqVO.getType())
  63 + .likeIfPresent(CouponTempleteDO::getName, reqVO.getName())
  64 + .eqIfPresent(CouponTempleteDO::getCouponNameRemark, reqVO.getCouponNameRemark())
  65 + .eqIfPresent(CouponTempleteDO::getImage, reqVO.getImage())
  66 + .eqIfPresent(CouponTempleteDO::getCount, reqVO.getCount())
  67 + .eqIfPresent(CouponTempleteDO::getLeadCount, reqVO.getLeadCount())
  68 + .eqIfPresent(CouponTempleteDO::getUsedCount, reqVO.getUsedCount())
  69 + .eqIfPresent(CouponTempleteDO::getGoodsType, reqVO.getGoodsType())
  70 + .eqIfPresent(CouponTempleteDO::getProductIds, reqVO.getProductIds())
  71 + .eqIfPresent(CouponTempleteDO::getHasUseLimit, reqVO.getHasUseLimit())
  72 + .eqIfPresent(CouponTempleteDO::getAtLeast, reqVO.getAtLeast())
  73 + .eqIfPresent(CouponTempleteDO::getMoney, reqVO.getMoney())
  74 + .eqIfPresent(CouponTempleteDO::getDiscount, reqVO.getDiscount())
  75 + .eqIfPresent(CouponTempleteDO::getDiscountLimit, reqVO.getDiscountLimit())
  76 + .eqIfPresent(CouponTempleteDO::getMinMoney, reqVO.getMinMoney())
  77 + .eqIfPresent(CouponTempleteDO::getMaxMoney, reqVO.getMaxMoney())
  78 + .eqIfPresent(CouponTempleteDO::getValidityType, reqVO.getValidityType())
  79 + .betweenIfPresent(CouponTempleteDO::getStartUseTime, reqVO.getStartUseTime())
  80 + .betweenIfPresent(CouponTempleteDO::getEndUseTime, reqVO.getEndUseTime())
  81 + .eqIfPresent(CouponTempleteDO::getFixedTerm, reqVO.getFixedTerm())
  82 + .eqIfPresent(CouponTempleteDO::getWhetherLimitless, reqVO.getWhetherLimitless())
  83 + .eqIfPresent(CouponTempleteDO::getMaxFetch, reqVO.getMaxFetch())
  84 + .eqIfPresent(CouponTempleteDO::getWhetherExpireNotice, reqVO.getWhetherExpireNotice())
  85 + .eqIfPresent(CouponTempleteDO::getExpireNoticeFixedTerm, reqVO.getExpireNoticeFixedTerm())
  86 + .eqIfPresent(CouponTempleteDO::getWhetherForbidPreference, reqVO.getWhetherForbidPreference())
  87 + .eqIfPresent(CouponTempleteDO::getWhetherShow, reqVO.getWhetherShow())
  88 + .eqIfPresent(CouponTempleteDO::getDiscountOrderMoney, reqVO.getDiscountOrderMoney())
  89 + .eqIfPresent(CouponTempleteDO::getOrderMoney, reqVO.getOrderMoney())
  90 + .eqIfPresent(CouponTempleteDO::getWhetherForbidden, reqVO.getWhetherForbidden())
  91 + .eqIfPresent(CouponTempleteDO::getOrderGoodsNum, reqVO.getOrderGoodsNum())
  92 + .eqIfPresent(CouponTempleteDO::getStatus, reqVO.getStatus())
  93 + .betweenIfPresent(CouponTempleteDO::getEndTime, reqVO.getEndTime())
  94 + .betweenIfPresent(CouponTempleteDO::getCreateTime, reqVO.getCreateTime())
  95 + .orderByDesc(CouponTempleteDO::getId));
  96 + }
  97 +
  98 +}
yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/dal/mysql/coupon/CouponMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.coupon.dal.mysql.coupon;
  2 +
  3 +import java.util.*;
  4 +
  5 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  6 +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
  7 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  8 +import cn.iocoder.yudao.module.coupon.dal.dataobject.coupon.CouponDO;
  9 +import org.apache.ibatis.annotations.Mapper;
  10 +import cn.iocoder.yudao.module.coupon.controller.admin.coupon.vo.*;
  11 +
  12 +/**
  13 + * 优惠券 Mapper
  14 + *
  15 + * @author wxr
  16 + */
  17 +@Mapper
  18 +public interface CouponMapper extends BaseMapperX<CouponDO> {
  19 +
  20 + default PageResult<CouponDO> selectPage(CouponPageReqVO reqVO) {
  21 + return selectPage(reqVO, new LambdaQueryWrapperX<CouponDO>()
  22 + .eqIfPresent(CouponDO::getType, reqVO.getType())
  23 + .likeIfPresent(CouponDO::getName, reqVO.getName())
  24 + .eqIfPresent(CouponDO::getCouponTypeId, reqVO.getCouponTypeId())
  25 + .eqIfPresent(CouponDO::getCouponCode, reqVO.getCouponCode())
  26 + .eqIfPresent(CouponDO::getMemberId, reqVO.getMemberId())
  27 + .eqIfPresent(CouponDO::getUseOrderId, reqVO.getUseOrderId())
  28 + .eqIfPresent(CouponDO::getGoodsType, reqVO.getGoodsType())
  29 + .eqIfPresent(CouponDO::getGoodsIds, reqVO.getGoodsIds())
  30 + .eqIfPresent(CouponDO::getAtLeast, reqVO.getAtLeast())
  31 + .eqIfPresent(CouponDO::getMoney, reqVO.getMoney())
  32 + .eqIfPresent(CouponDO::getDiscount, reqVO.getDiscount())
  33 + .eqIfPresent(CouponDO::getDiscountLimit, reqVO.getDiscountLimit())
  34 + .eqIfPresent(CouponDO::getWhetherForbidPreference, reqVO.getWhetherForbidPreference())
  35 + .eqIfPresent(CouponDO::getWhetherExpireNotice, reqVO.getWhetherExpireNotice())
  36 + .eqIfPresent(CouponDO::getExpireNoticeFixedTerm, reqVO.getExpireNoticeFixedTerm())
  37 + .eqIfPresent(CouponDO::getWhetherNoticed, reqVO.getWhetherNoticed())
  38 + .eqIfPresent(CouponDO::getState, reqVO.getState())
  39 + .eqIfPresent(CouponDO::getGetType, reqVO.getGetType())
  40 + .betweenIfPresent(CouponDO::getFetchTime, reqVO.getFetchTime())
  41 + .betweenIfPresent(CouponDO::getUseTime, reqVO.getUseTime())
  42 + .betweenIfPresent(CouponDO::getStartTime, reqVO.getStartTime())
  43 + .betweenIfPresent(CouponDO::getEndTime, reqVO.getEndTime())
  44 + .betweenIfPresent(CouponDO::getCreateTime, reqVO.getCreateTime())
  45 + .orderByDesc(CouponDO::getId));
  46 + }
  47 +
  48 + default List<CouponDO> selectList(CouponExportReqVO reqVO) {
  49 + return selectList(new LambdaQueryWrapperX<CouponDO>()
  50 + .eqIfPresent(CouponDO::getType, reqVO.getType())
  51 + .likeIfPresent(CouponDO::getName, reqVO.getName())
  52 + .eqIfPresent(CouponDO::getCouponTypeId, reqVO.getCouponTypeId())
  53 + .eqIfPresent(CouponDO::getCouponCode, reqVO.getCouponCode())
  54 + .eqIfPresent(CouponDO::getMemberId, reqVO.getMemberId())
  55 + .eqIfPresent(CouponDO::getUseOrderId, reqVO.getUseOrderId())
  56 + .eqIfPresent(CouponDO::getGoodsType, reqVO.getGoodsType())
  57 + .eqIfPresent(CouponDO::getGoodsIds, reqVO.getGoodsIds())
  58 + .eqIfPresent(CouponDO::getAtLeast, reqVO.getAtLeast())
  59 + .eqIfPresent(CouponDO::getMoney, reqVO.getMoney())
  60 + .eqIfPresent(CouponDO::getDiscount, reqVO.getDiscount())
  61 + .eqIfPresent(CouponDO::getDiscountLimit, reqVO.getDiscountLimit())
  62 + .eqIfPresent(CouponDO::getWhetherForbidPreference, reqVO.getWhetherForbidPreference())
  63 + .eqIfPresent(CouponDO::getWhetherExpireNotice, reqVO.getWhetherExpireNotice())
  64 + .eqIfPresent(CouponDO::getExpireNoticeFixedTerm, reqVO.getExpireNoticeFixedTerm())
  65 + .eqIfPresent(CouponDO::getWhetherNoticed, reqVO.getWhetherNoticed())
  66 + .eqIfPresent(CouponDO::getState, reqVO.getState())
  67 + .eqIfPresent(CouponDO::getGetType, reqVO.getGetType())
  68 + .betweenIfPresent(CouponDO::getFetchTime, reqVO.getFetchTime())
  69 + .betweenIfPresent(CouponDO::getUseTime, reqVO.getUseTime())
  70 + .betweenIfPresent(CouponDO::getStartTime, reqVO.getStartTime())
  71 + .betweenIfPresent(CouponDO::getEndTime, reqVO.getEndTime())
  72 + .betweenIfPresent(CouponDO::getCreateTime, reqVO.getCreateTime())
  73 + .orderByDesc(CouponDO::getId));
  74 + }
  75 +
  76 +}
yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/package-info.java 0 → 100644
  1 +/**
  2 + * coupon模块,主要负责麦一些优惠券的额增删
  3 + *
  4 + * 1. Controller URL:以 /coumon/ 开头,避免和其它 Module 冲突
  5 + */
  6 +package cn.iocoder.yudao.module.coupon;
yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/service/activity/ActivityService.java renamed to yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/service/CouponTemplete/CouponTempleteService.java
1 -package cn.iocoder.yudao.module.market.service.activity; 1 +package cn.iocoder.yudao.module.coupon.service.CouponTemplete;
2 2
3 import java.util.*; 3 import java.util.*;
4 import javax.validation.*; 4 import javax.validation.*;
5 -import cn.iocoder.yudao.module.market.controller.admin.activity.vo.*;  
6 -import cn.iocoder.yudao.module.market.dal.dataobject.activity.ActivityDO; 5 +import cn.iocoder.yudao.module.coupon.controller.admin.templete.vo.*;
7 import cn.iocoder.yudao.framework.common.pojo.PageResult; 6 import cn.iocoder.yudao.framework.common.pojo.PageResult;
  7 +import cn.iocoder.yudao.module.coupon.dal.dataobject.CouponTemplete.CouponTempleteDO;
8 8
9 /** 9 /**
10 - * 促销活动 Service 接口 10 + * 优惠券模板 Service 接口
11 * 11 *
12 - * @author 芋道源码 12 + * @author wxr
13 */ 13 */
14 -public interface ActivityService { 14 +public interface CouponTempleteService {
15 15
16 /** 16 /**
17 - * 创建促销活动 17 + * 创建优惠券模板
18 * 18 *
19 * @param createReqVO 创建信息 19 * @param createReqVO 创建信息
20 * @return 编号 20 * @return 编号
21 */ 21 */
22 - Long createActivity(@Valid ActivityCreateReqVO createReqVO); 22 + Long create(@Valid CouponTempleteCreateReqVO createReqVO);
23 23
24 /** 24 /**
25 - * 更新促销活动 25 + * 更新优惠券模板
26 * 26 *
27 * @param updateReqVO 更新信息 27 * @param updateReqVO 更新信息
28 */ 28 */
29 - void updateActivity(@Valid ActivityUpdateReqVO updateReqVO); 29 + void update(@Valid CouponTempleteUpdateReqVO updateReqVO);
30 30
31 /** 31 /**
32 - * 删除促销活动 32 + * 删除优惠券模板
33 * 33 *
34 * @param id 编号 34 * @param id 编号
35 */ 35 */
36 - void deleteActivity(Long id); 36 + void delete(Long id);
37 37
38 /** 38 /**
39 - * 获得促销活动 39 + * 获得优惠券模板
40 * 40 *
41 * @param id 编号 41 * @param id 编号
42 - * @return 促销活动 42 + * @return 优惠券模板
43 */ 43 */
44 - ActivityDO getActivity(Long id); 44 + CouponTempleteDO get(Long id);
45 45
46 /** 46 /**
47 - * 获得促销活动列表 47 + * 获得优惠券模板列表
48 * 48 *
49 * @param ids 编号 49 * @param ids 编号
50 - * @return 促销活动列表 50 + * @return 优惠券模板列表
51 */ 51 */
52 - List<ActivityDO> getActivityList(Collection<Long> ids); 52 + List<CouponTempleteDO> getList(Collection<Long> ids);
53 53
54 /** 54 /**
55 - * 获得促销活动分页 55 + * 获得优惠券模板分页
56 * 56 *
57 * @param pageReqVO 分页查询 57 * @param pageReqVO 分页查询
58 - * @return 促销活动分页 58 + * @return 优惠券模板分页
59 */ 59 */
60 - PageResult<ActivityDO> getActivityPage(ActivityPageReqVO pageReqVO); 60 + PageResult<CouponTempleteDO> getPage(CouponTempletePageReqVO pageReqVO);
  61 +
  62 + /**
  63 + * 获得优惠券模板列表, 用于 Excel 导出
  64 + *
  65 + * @param exportReqVO 查询条件
  66 + * @return 优惠券模板列表
  67 + */
  68 + List<CouponTempleteDO> getList(CouponTempleteExportReqVO exportReqVO);
61 69
62 } 70 }
yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/service/CouponTemplete/CouponTempleteServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.coupon.service.CouponTemplete;
  2 +
  3 +import cn.iocoder.yudao.module.CouponTemplete.enums.CouponTypeEnum;
  4 +import cn.iocoder.yudao.module.CouponTemplete.enums.CouponValidityTypeEnum;
  5 +import cn.iocoder.yudao.module.coupon.controller.admin.templete.vo.CouponTempleteCreateReqVO;
  6 +import cn.iocoder.yudao.module.coupon.controller.admin.templete.vo.CouponTempleteExportReqVO;
  7 +import cn.iocoder.yudao.module.coupon.controller.admin.templete.vo.CouponTempletePageReqVO;
  8 +import cn.iocoder.yudao.module.coupon.controller.admin.templete.vo.CouponTempleteUpdateReqVO;
  9 +import cn.iocoder.yudao.module.coupon.convert.CouponTemplete.CouponTempleteConvert;
  10 +import cn.iocoder.yudao.module.coupon.dal.dataobject.CouponTemplete.CouponTempleteDO;
  11 +import cn.iocoder.yudao.module.coupon.dal.mysql.CouponTemplete.CouponTempleteMapper;
  12 +import org.springframework.stereotype.Service;
  13 +import javax.annotation.Resource;
  14 +import org.springframework.validation.annotation.Validated;
  15 +
  16 +import java.util.*;
  17 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  18 +
  19 +
  20 +
  21 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  22 +import static cn.iocoder.yudao.module.CouponTemplete.enums.ErrorCodeConstants.*;
  23 +
  24 +/**
  25 + * 优惠券模板 Service 实现类
  26 + *
  27 + * @author wxr
  28 + */
  29 +@Service
  30 +@Validated
  31 +public class CouponTempleteServiceImpl implements CouponTempleteService {
  32 +
  33 + @Resource
  34 + private CouponTempleteMapper couponTempleteMapper;
  35 +
  36 + @Override
  37 + public Long create(CouponTempleteCreateReqVO createReqVO) {
  38 + // 插入
  39 + CouponTempleteDO couponTempleteDO = CouponTempleteConvert.INSTANCE.convert(createReqVO);
  40 + /* 验证类型、判断必填*/
  41 + checkCouponType(createReqVO);
  42 +
  43 + /*验证过期类型、判断必填*/
  44 + checkValidityType(createReqVO);
  45 +
  46 +
  47 +
  48 + couponTempleteMapper.insert(couponTempleteDO);
  49 + // 返回
  50 + return couponTempleteDO.getId();
  51 + }
  52 +
  53 + /*确认优惠券类型*/
  54 + private void checkValidityType(CouponTempleteCreateReqVO createReqVO) {
  55 + Integer validtyType = createReqVO.getValidityType();
  56 +
  57 + if(CouponValidityTypeEnum.TIME_RANGE_EXPIRTED.getStatus().equals(validtyType)){
  58 + if(createReqVO.getStartUseTime() == null||createReqVO.getEndUseTime() == null){
  59 + throw exception(START_END_TIME_NOT_NULL);
  60 + }
  61 + }else{
  62 + if(createReqVO.getFixedTerm() == null){
  63 + throw exception(FIXED_TERM_NOT_NULL);
  64 + }
  65 + }
  66 + }
  67 +
  68 + private void checkCouponType(CouponTempleteCreateReqVO createReqVO) {
  69 +
  70 + String couponType = createReqVO.getType();
  71 + //当type=reward时候,需要添加
  72 + if(couponType.equals(CouponTypeEnum.REWARD.getName())){
  73 + if(createReqVO.getMoney()==null){
  74 + throw exception(MONEY_NOT_NULL);
  75 + }
  76 + }else if(couponType.equals(CouponTypeEnum.DISCOUNT.getName())){
  77 + if(createReqVO.getDiscount()==null){
  78 + throw exception(DISCOUNT_NOT_NULL);
  79 + }
  80 + if(createReqVO.getDiscountLimit()==null){
  81 + throw exception(DISCOUNT_LIMIT_NOT_NULL);
  82 + }
  83 + }else if (couponType.equals(CouponTypeEnum.RANDOW.getName())){
  84 + //当type为radom时需要添加不能为空
  85 + if(createReqVO.getMinMoney()==null||createReqVO.getMaxMoney()==null){
  86 + throw exception(MIN_MAX_NOT_NULL);
  87 + }
  88 + }
  89 + }
  90 +
  91 + @Override
  92 + public void update(CouponTempleteUpdateReqVO updateReqVO) {
  93 + // 校验存在
  94 + this.validateExists(updateReqVO.getId());
  95 + // 更新
  96 + CouponTempleteDO updateObj = CouponTempleteConvert.INSTANCE.convert(updateReqVO);
  97 + couponTempleteMapper.updateById(updateObj);
  98 + }
  99 +
  100 + @Override
  101 + public void delete(Long id) {
  102 + // 校验存在
  103 + this.validateExists(id);
  104 + // 删除
  105 + couponTempleteMapper.deleteById(id);
  106 + }
  107 +
  108 + private void validateExists(Long id) {
  109 + if (couponTempleteMapper.selectById(id) == null) {
  110 + throw exception(COUPON_TEMPLETE_NOT_EXISTS);
  111 + }
  112 + }
  113 +
  114 + @Override
  115 + public CouponTempleteDO get(Long id) {
  116 + return couponTempleteMapper.selectById(id);
  117 + }
  118 +
  119 + @Override
  120 + public List<CouponTempleteDO> getList(Collection<Long> ids) {
  121 + return couponTempleteMapper.selectBatchIds(ids);
  122 + }
  123 +
  124 + @Override
  125 + public PageResult<CouponTempleteDO> getPage(CouponTempletePageReqVO pageReqVO) {
  126 + return couponTempleteMapper.selectPage(pageReqVO);
  127 + }
  128 +
  129 + @Override
  130 + public List<CouponTempleteDO> getList(CouponTempleteExportReqVO exportReqVO) {
  131 + return couponTempleteMapper.selectList(exportReqVO);
  132 + }
  133 +
  134 +}
yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/service/coupon/CouponService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.coupon.service.coupon;
  2 +
  3 +import java.util.*;
  4 +import javax.validation.*;
  5 +import cn.iocoder.yudao.module.coupon.controller.admin.coupon.vo.*;
  6 +import cn.iocoder.yudao.module.coupon.dal.dataobject.coupon.CouponDO;
  7 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  8 +
  9 +/**
  10 + * 优惠券 Service 接口
  11 + *
  12 + * @author wxr
  13 + */
  14 +public interface CouponService {
  15 +
  16 + /**
  17 + * 创建优惠券
  18 + *
  19 + * @param templateId 优惠券模板id
  20 + * @return 编号
  21 + */
  22 + Long create(Long templateId);
  23 +
  24 + /**
  25 + * 更新优惠券
  26 + *
  27 + * @param updateReqVO 更新信息
  28 + */
  29 + void update(@Valid CouponUpdateReqVO updateReqVO);
  30 +
  31 + /**
  32 + * 删除优惠券
  33 + *
  34 + * @param id 编号
  35 + */
  36 + void delete(Long id);
  37 +
  38 + /**
  39 + * 获得优惠券
  40 + *
  41 + * @param id 编号
  42 + * @return 优惠券
  43 + */
  44 + CouponDO get(Long id);
  45 +
  46 + /**
  47 + * 获得优惠券列表
  48 + *
  49 + * @param ids 编号
  50 + * @return 优惠券列表
  51 + */
  52 + List<CouponDO> getList(Collection<Long> ids);
  53 +
  54 + /**
  55 + * 获得优惠券分页
  56 + *
  57 + * @param pageReqVO 分页查询
  58 + * @return 优惠券分页
  59 + */
  60 + PageResult<CouponDO> getPage(CouponPageReqVO pageReqVO);
  61 +
  62 + /**
  63 + * 获得优惠券列表, 用于 Excel 导出
  64 + *
  65 + * @param exportReqVO 查询条件
  66 + * @return 优惠券列表
  67 + */
  68 + List<CouponDO> getList(CouponExportReqVO exportReqVO);
  69 +
  70 +}
yudao-module-mall/yudao-module-coupon-biz/src/main/java/cn/iocoder/yudao/module/coupon/service/coupon/CouponServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.coupon.service.coupon;
  2 +
  3 +import cn.hutool.core.bean.BeanUtil;
  4 +import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
  5 +import cn.iocoder.yudao.module.coupon.dal.dataobject.CouponTemplete.CouponTempleteDO;
  6 +import cn.iocoder.yudao.module.coupon.dal.mysql.CouponTemplete.CouponTempleteMapper;
  7 +import io.micrometer.core.instrument.Counter;
  8 +import org.springframework.stereotype.Service;
  9 +import javax.annotation.Resource;
  10 +import org.springframework.validation.annotation.Validated;
  11 +
  12 +import java.util.*;
  13 +import cn.iocoder.yudao.module.coupon.controller.admin.coupon.vo.*;
  14 +import cn.iocoder.yudao.module.coupon.dal.dataobject.coupon.CouponDO;
  15 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  16 +
  17 +import cn.iocoder.yudao.module.coupon.convert.coupon.CouponConvert;
  18 +import cn.iocoder.yudao.module.coupon.dal.mysql.coupon.CouponMapper;
  19 +
  20 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  21 +import static cn.iocoder.yudao.module.CouponTemplete.enums.ErrorCodeConstants.COUPON_NOT_EXISTS;
  22 +
  23 +/**
  24 + * 优惠券 Service 实现类
  25 + *
  26 + * @author wxr
  27 + */
  28 +@Service
  29 +@Validated
  30 +public class CouponServiceImpl implements CouponService {
  31 +
  32 + @Resource
  33 + private CouponMapper couponMapper;
  34 +
  35 + @Resource
  36 + private CouponTempleteMapper couponTempleteMapper;
  37 +
  38 + public Long create(CouponCreateReqVO createReqVO) {
  39 + // 插入
  40 + CouponDO couponDO = CouponConvert.INSTANCE.convert(createReqVO);
  41 + couponMapper.insert(couponDO);
  42 + // 返回
  43 + return couponDO.getId();
  44 + }
  45 +
  46 +
  47 + /**
  48 + *todo 获取用户id收获优惠券
  49 + *@author:wxr
  50 + *@date:2022-08-13 3:11
  51 + *@Description
  52 + */
  53 + @Override
  54 + public Long create(Long templateId) {
  55 + Long userid = SecurityFrameworkUtils.getLoginUserId();
  56 + CouponDO couponDO = CouponDO.builder().memberId(userid).build();
  57 + CouponTempleteDO couponTempleteDO = couponTempleteMapper.selectById(templateId);
  58 + //todo 缺少判空
  59 + BeanUtil.copyProperties(couponTempleteDO,couponTempleteDO);
  60 + couponMapper.insert(couponDO);
  61 + return couponDO.getId();
  62 + }
  63 +
  64 + @Override
  65 + public void update(CouponUpdateReqVO updateReqVO) {
  66 + // 校验存在
  67 + this.validateExists(updateReqVO.getId());
  68 + // 更新
  69 + CouponDO updateObj = CouponConvert.INSTANCE.convert(updateReqVO);
  70 + couponMapper.updateById(updateObj);
  71 + }
  72 +
  73 + @Override
  74 + public void delete(Long id) {
  75 + // 校验存在
  76 + this.validateExists(id);
  77 + // 删除
  78 + couponMapper.deleteById(id);
  79 + }
  80 +
  81 + private void validateExists(Long id) {
  82 + if (couponMapper.selectById(id) == null) {
  83 + throw exception(COUPON_NOT_EXISTS);
  84 + }
  85 + }
  86 +
  87 + @Override
  88 + public CouponDO get(Long id) {
  89 + return couponMapper.selectById(id);
  90 + }
  91 +
  92 + @Override
  93 + public List<CouponDO> getList(Collection<Long> ids) {
  94 + return couponMapper.selectBatchIds(ids);
  95 + }
  96 +
  97 + @Override
  98 + public PageResult<CouponDO> getPage(CouponPageReqVO pageReqVO) {
  99 + return couponMapper.selectPage(pageReqVO);
  100 + }
  101 +
  102 + @Override
  103 + public List<CouponDO> getList(CouponExportReqVO exportReqVO) {
  104 + return couponMapper.selectList(exportReqVO);
  105 + }
  106 +
  107 +}
yudao-module-mall/yudao-module-coupon-biz/src/main/resources/mapper/CouponTemplete/CouponTempleteMapper.xml 0 → 100644
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  3 +<mapper namespace="cn.iocoder.yudao.module.coupon.dal.mysql.CouponTemplete.CouponTempleteMapper">
  4 +
  5 + <!--
  6 + 一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。
  7 + 无法满足的场景,例如说多表关联查询,才使用 XML 编写 SQL。
  8 + 代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。
  9 + 文档可见:https://www.iocoder.cn/MyBatis/x-plugins/
  10 + -->
  11 +
  12 +</mapper>
yudao-module-mall/yudao-module-coupon-biz/src/main/resources/mapper/coupon/CouponMapper.xml 0 → 100644
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  3 +<mapper namespace="cn.iocoder.yudao.module.coupon.dal.mysql.coupon.CouponMapper">
  4 +
  5 + <!--
  6 + 一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。
  7 + 无法满足的场景,例如说多表关联查询,才使用 XML 编写 SQL。
  8 + 代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。
  9 + 文档可见:https://www.iocoder.cn/MyBatis/x-plugins/
  10 + -->
  11 +
  12 +</mapper>
yudao-module-mall/yudao-module-market-api/pom.xml
@@ -21,6 +21,13 @@ @@ -21,6 +21,13 @@
21 <groupId>cn.iocoder.boot</groupId> 21 <groupId>cn.iocoder.boot</groupId>
22 <artifactId>yudao-common</artifactId> 22 <artifactId>yudao-common</artifactId>
23 </dependency> 23 </dependency>
  24 +
  25 + <!-- 参数校验 -->
  26 + <dependency>
  27 + <groupId>org.springframework.boot</groupId>
  28 + <artifactId>spring-boot-starter-validation</artifactId>
  29 + <optional>true</optional>
  30 + </dependency>
24 </dependencies> 31 </dependencies>
25 32
26 </project> 33 </project>
yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/api/price/PriceApi.java 0 → 100644
  1 +package cn.iocoder.yudao.module.market.api.price;
  2 +
  3 +import cn.iocoder.yudao.module.market.api.price.dto.PriceCalculateReqDTO;
  4 +import cn.iocoder.yudao.module.market.api.price.dto.PriceCalculateRespDTO;
  5 +
  6 +/**
  7 + * 价格 API 接口
  8 + *
  9 + * @author 芋道源码
  10 + */
  11 +public interface PriceApi {
  12 +
  13 + /**
  14 + * 计算商品的价格
  15 + *
  16 + * @param calculateReqDTO 价格请求
  17 + * @return 价格相应
  18 + */
  19 + PriceCalculateRespDTO calculatePrice(PriceCalculateReqDTO calculateReqDTO);
  20 +
  21 +}
yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/api/price/dto/PriceCalculateReqDTO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.market.api.price.dto;
  2 +
  3 +import lombok.Data;
  4 +
  5 +import javax.validation.constraints.Min;
  6 +import javax.validation.constraints.NotNull;
  7 +import java.util.List;
  8 +
  9 +/**
  10 + * 价格计算 Request DTO
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +@Data
  15 +public class PriceCalculateReqDTO {
  16 +
  17 + /**
  18 + * 用户编号
  19 + *
  20 + * 对应 MemberUserDO 的 id 编号
  21 + */
  22 + private Long userId;
  23 +
  24 + /**
  25 + * 优惠劵编号
  26 + */
  27 + private Long couponId;
  28 +
  29 + /**
  30 + * 商品 SKU 数组
  31 + */
  32 + @NotNull(message = "商品数组不能为空")
  33 + private List<Item> items;
  34 +
  35 + /**
  36 + * 商品 SKU
  37 + */
  38 + @Data
  39 + public static class Item {
  40 +
  41 + /**
  42 + * SKU 编号
  43 + */
  44 + @NotNull(message = "商品 SKU 编号不能为空")
  45 + private Long skuId;
  46 +
  47 + /**
  48 + * SKU 数量
  49 + */
  50 + @NotNull(message = "商品 SKU 数量不能为空")
  51 + @Min(value = 0L, message = "商品 SKU 数量必须大于等于 0") // 可传递 0 数量,用于购物车未选中的情况
  52 + private Integer count;
  53 +
  54 + }
  55 +
  56 +}
yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/api/price/dto/PriceCalculateRespDTO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.market.api.price.dto;
  2 +
  3 +import cn.iocoder.yudao.module.market.enums.common.PromotionLevelEnum;
  4 +import cn.iocoder.yudao.module.market.enums.common.PromotionTypeEnum;
  5 +import lombok.Data;
  6 +
  7 +import java.util.List;
  8 +
  9 +/**
  10 + * 价格计算 Response DTO
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +@Data
  15 +public class PriceCalculateRespDTO {
  16 +
  17 + /**
  18 + * 订单
  19 + */
  20 + private Order order;
  21 +
  22 + /**
  23 + * 商品 SKU 数组
  24 + */
  25 + private List<Item> items;
  26 +
  27 + /**
  28 + * 营销活动数组
  29 + *
  30 + * 只对应 {@link #items} 商品匹配的活动
  31 + */
  32 + private List<Promotion> promotions;
  33 +
  34 + /**
  35 + * 订单
  36 + */
  37 + @Data
  38 + public static class Order {
  39 +
  40 + /**
  41 + * 商品原价(总),单位:分
  42 + *
  43 + * 基于 {@link Item#getTotalOriginalPrice()} 求和
  44 + */
  45 + private Integer skuOriginalPrice;
  46 + /**
  47 + * 商品优惠(总),单位:分
  48 + *
  49 + * 基于 {@link Item#getTotalPromotionPrice()} 求和
  50 + */
  51 + private Integer skuPromotionPrice;
  52 + /**
  53 + * 订单优惠(总),单位:分
  54 + *
  55 + * 例如说:满减折扣;不包括优惠劵、商品优惠
  56 + */
  57 + private Integer orderPromotionPrice;
  58 + /**
  59 + * 运费金额,单位:分
  60 + */
  61 + private Integer deliveryPrice;
  62 + /**
  63 + * 应付金额(总),单位:分
  64 + *
  65 + * = {@link #skuOriginalPrice}
  66 + * + {@link #deliveryPrice}
  67 + * - {@link #skuPromotionPrice}
  68 + * - {@link #orderPromotionPrice}
  69 + */
  70 + // * - {@link #couponPrice} // TODO 芋艿:靠营销表记录
  71 + private Integer payPrice;
  72 +
  73 + // ========== 营销基本信息 ==========
  74 + /**
  75 + * 优惠劵编号
  76 + */
  77 + private Long couponId;
  78 +// /**
  79 +// * 优惠劵减免金额,单位:分
  80 +// *
  81 +// * // TODO 芋艿:靠营销表记录
  82 +// */
  83 +// private Integer couponPrice;
  84 +
  85 + }
  86 +
  87 + /**
  88 + * 商品 SKU
  89 + */
  90 + @Data
  91 + public static class Item extends PriceCalculateReqDTO.Item {
  92 +
  93 + /**
  94 + * 商品原价(单),单位:分
  95 + *
  96 + * 对应 ProductSkuDO 的 price 字段
  97 + */
  98 + private Integer originalPrice;
  99 + /**
  100 + * 商品原价(总),单位:分
  101 + *
  102 + * = {@link #originalPrice} * {@link #getCount()}
  103 + */
  104 + private Integer totalOriginalPrice;
  105 + /**
  106 + * 商品级优惠(总),单位:分
  107 + *
  108 + * 例如说“限时折扣”:商品原价的 8 折;商品原价的减 50 元
  109 + */
  110 + private Integer totalPromotionPrice;
  111 + /**
  112 + * 最终购买金额(总),单位:分。
  113 + *
  114 + * = {@link #totalOriginalPrice}
  115 + * - {@link #totalPromotionPrice}
  116 + */
  117 + private Integer totalPresentPrice;
  118 + /**
  119 + * 最终购买金额(单),单位:分。
  120 + *
  121 + * = {@link #totalPresentPrice} / {@link #getCount()}
  122 + */
  123 + private Integer presentPrice;
  124 + /**
  125 + * 应付金额(总),单位:分
  126 + */
  127 + private Integer totalPayPrice;
  128 +
  129 + }
  130 +
  131 + /**
  132 + * 营销活动
  133 + */
  134 + @Data
  135 + public static class Promotion {
  136 +
  137 + /**
  138 + * 营销编号
  139 + *
  140 + * 例如说:营销活动的编号、优惠劵的编号
  141 + */
  142 + private Long id;
  143 + /**
  144 + * 营销类型
  145 + *
  146 + * 枚举 {@link PromotionTypeEnum}
  147 + */
  148 + private Integer type;
  149 + /**
  150 + * 营销级别
  151 + *
  152 + * 枚举 {@link PromotionLevelEnum}
  153 + */
  154 + private Integer level;
  155 + /**
  156 + * 匹配的商品 SKU 数组
  157 + */
  158 + private List<Item> items;
  159 + /**
  160 + * 计算时的原价(总),单位:分
  161 + */
  162 + private Integer totalOriginalPrice;
  163 + /**
  164 + * 计算时的优惠(总),单位:分
  165 + */
  166 + private Integer totalPromotionPrice;
  167 + /**
  168 + * 是否满足优惠条件
  169 + */
  170 + private Boolean meet;
  171 + /**
  172 + * 满足条件的提示
  173 + *
  174 + * 如果 {@link #meet} = true 满足,则提示“圣诞价:省 150.00 元”
  175 + * 如果 {@link #meet} = false 不满足,则提示“购满 85 元,可减 40 元”
  176 + */
  177 + private String meetTip;
  178 +
  179 + /**
  180 + * 匹配的商品 SKU
  181 + */
  182 + @Data
  183 + public static class Item {
  184 +
  185 + /**
  186 + * 商品 SKU 编号
  187 + */
  188 + private Long skuId;
  189 + /**
  190 + * 计算时的原价(总),单位:分
  191 + */
  192 + private Integer totalOriginalPrice;
  193 + /**
  194 + * 计算时的优惠(总),单位:分
  195 + */
  196 + private Integer totalPromotionPrice;
  197 +
  198 + }
  199 +
  200 + }
  201 +
  202 +}
yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/enums/activity/MarketActivityTypeEnum.java deleted
1 -package cn.iocoder.yudao.module.market.enums.activity;  
2 -  
3 -import cn.iocoder.yudao.framework.common.core.IntArrayValuable;  
4 -  
5 -import java.util.Arrays;  
6 -  
7 -/**  
8 - * 促销活动类型枚举  
9 - */  
10 -public enum MarketActivityTypeEnum implements IntArrayValuable {  
11 -  
12 - TIME_LIMITED_DISCOUNT(1, "限时折扣"),  
13 - FULL_PRIVILEGE(2, "满减送"),  
14 - ;  
15 -  
16 - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(MarketActivityTypeEnum::getValue).toArray();  
17 -  
18 - /**  
19 - * 类型值  
20 - */  
21 - private final Integer value;  
22 - /**  
23 - * 类型名  
24 - */  
25 - private final String name;  
26 -  
27 - MarketActivityTypeEnum(Integer value, String name) {  
28 - this.value = value;  
29 - this.name = name;  
30 - }  
31 -  
32 - public Integer getValue() {  
33 - return value;  
34 - }  
35 -  
36 - public String getName() {  
37 - return name;  
38 - }  
39 -  
40 - @Override  
41 - public int[] array() {  
42 - return ARRAYS;  
43 - }  
44 -}  
yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/enums/activity/MarketActivityStatusEnum.java renamed to yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/enums/common/PromotionActivityStatusEnum.java
1 -package cn.iocoder.yudao.module.market.enums.activity; 1 +package cn.iocoder.yudao.module.market.enums.common;
2 2
3 import cn.iocoder.yudao.framework.common.core.IntArrayValuable; 3 import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
  4 +import lombok.AllArgsConstructor;
  5 +import lombok.Getter;
4 6
5 import java.util.Arrays; 7 import java.util.Arrays;
6 8
7 /** 9 /**
8 - * 促销活动状态枚举 10 + * 促销活动的状态枚举
  11 + *
  12 + * @author 芋道源码
9 */ 13 */
10 -public enum MarketActivityStatusEnum implements IntArrayValuable { 14 +@AllArgsConstructor
  15 +@Getter
  16 +public enum PromotionActivityStatusEnum implements IntArrayValuable {
11 17
12 WAIT(10, "未开始"), 18 WAIT(10, "未开始"),
13 RUN(20, "进行中"), 19 RUN(20, "进行中"),
14 END(30, "已结束"), 20 END(30, "已结束"),
15 - /**  
16 - * 1. WAIT、RUN、END 可以转换成 INVALID 状态。  
17 - * 2. INVALID 只可以转换成 DELETED 状态。  
18 - */  
19 - INVALID(40, "已撤销"),  
20 - DELETED(50, "已删除"),  
21 - ; 21 + CLOSE(40, "已关闭");
22 22
23 - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(MarketActivityStatusEnum::getValue).toArray(); 23 + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(PromotionActivityStatusEnum::getStatus).toArray();
24 24
25 /** 25 /**
26 * 状态值 26 * 状态值
27 */ 27 */
28 - private final Integer value; 28 + private final Integer status;
29 /** 29 /**
30 * 状态名 30 * 状态名
31 */ 31 */
32 private final String name; 32 private final String name;
33 33
34 - MarketActivityStatusEnum(Integer value, String name) {  
35 - this.value = value;  
36 - this.name = name;  
37 - }  
38 -  
39 - public Integer getValue() {  
40 - return value;  
41 - }  
42 -  
43 - public String getName() {  
44 - return name;  
45 - }  
46 -  
47 @Override 34 @Override
48 public int[] array() { 35 public int[] array() {
49 return ARRAYS; 36 return ARRAYS;
50 } 37 }
  38 +
51 } 39 }
yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/enums/common/PromotionConditionTypeEnum.java 0 → 100644
  1 +package cn.iocoder.yudao.module.market.enums.common;
  2 +
  3 +import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
  4 +import lombok.AllArgsConstructor;
  5 +import lombok.Getter;
  6 +
  7 +import java.util.Arrays;
  8 +
  9 +/**
  10 + * 营销的条件类型枚举
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +@AllArgsConstructor
  15 +@Getter
  16 +public enum PromotionConditionTypeEnum implements IntArrayValuable {
  17 +
  18 + PRICE(10, "满 N 元"),
  19 + COUNT(20, "满 N 件");
  20 +
  21 + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(PromotionConditionTypeEnum::getType).toArray();
  22 +
  23 + /**
  24 + * 类型值
  25 + */
  26 + private final Integer type;
  27 + /**
  28 + * 类型名
  29 + */
  30 + private final String name;
  31 +
  32 + @Override
  33 + public int[] array() {
  34 + return ARRAYS;
  35 + }
  36 +
  37 +}
yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/enums/common/PromotionLevelEnum.java 0 → 100644
  1 +package cn.iocoder.yudao.module.market.enums.common;
  2 +
  3 +import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
  4 +import lombok.AllArgsConstructor;
  5 +import lombok.Getter;
  6 +
  7 +import java.util.Arrays;
  8 +
  9 +/**
  10 + * 营销的级别枚举
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +@Getter
  15 +@AllArgsConstructor
  16 +public enum PromotionLevelEnum implements IntArrayValuable {
  17 +
  18 + ORDER(1, "订单级"),
  19 + SKU(2, "商品级"),
  20 + ;
  21 +
  22 + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(PromotionLevelEnum::getLevel).toArray();
  23 +
  24 + /**
  25 + * 级别值
  26 + */
  27 + private final Integer level;
  28 + /**
  29 + * 类型名
  30 + */
  31 + private final String name;
  32 +
  33 + @Override
  34 + public int[] array() {
  35 + return ARRAYS;
  36 + }
  37 +}
yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/enums/common/PromotionProductScopeEnum.java 0 → 100644
  1 +package cn.iocoder.yudao.module.market.enums.common;
  2 +
  3 +import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
  4 +import lombok.AllArgsConstructor;
  5 +import lombok.Getter;
  6 +
  7 +import java.util.Arrays;
  8 +
  9 +/**
  10 + * 营销的商品范围枚举
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +@Getter
  15 +@AllArgsConstructor
  16 +public enum PromotionProductScopeEnum implements IntArrayValuable {
  17 +
  18 + ALL(1, "全部商品参与"),
  19 + SPU(2, "指定商品参与"),
  20 + ;
  21 +
  22 + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(PromotionProductScopeEnum::getScope).toArray();
  23 +
  24 + /**
  25 + * 范围值
  26 + */
  27 + private final Integer scope;
  28 + /**
  29 + * 范围名
  30 + */
  31 + private final String name;
  32 +
  33 + @Override
  34 + public int[] array() {
  35 + return ARRAYS;
  36 + }
  37 +
  38 +}
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/enums/AddressTypeEnum.java renamed to yudao-module-mall/yudao-module-market-api/src/main/java/cn/iocoder/yudao/module/market/enums/common/PromotionTypeEnum.java
1 -package cn.iocoder.yudao.module.member.enums; 1 +package cn.iocoder.yudao.module.market.enums.common;
2 2
3 import cn.iocoder.yudao.framework.common.core.IntArrayValuable; 3 import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
4 import lombok.AllArgsConstructor; 4 import lombok.AllArgsConstructor;
@@ -7,21 +7,28 @@ import lombok.Getter; @@ -7,21 +7,28 @@ import lombok.Getter;
7 import java.util.Arrays; 7 import java.util.Arrays;
8 8
9 /** 9 /**
10 - * 用户收件地址的类型枚举 10 + * 营销类型枚举
  11 + *
  12 + * @author 芋道源码
11 */ 13 */
12 @Getter 14 @Getter
13 @AllArgsConstructor 15 @AllArgsConstructor
14 -public enum AddressTypeEnum implements IntArrayValuable {  
15 -  
16 - DEFAULT(1, "默认收件地址"),  
17 - NORMAL(2, "普通收件地址"), // 即非默认收件地址 16 +public enum PromotionTypeEnum implements IntArrayValuable {
18 17
  18 + DISCOUNT(1, "限时折扣"),
  19 + REWARD(2, "满减送"),
19 ; 20 ;
20 21
21 - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(AddressTypeEnum::getType).toArray(); 22 + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(PromotionTypeEnum::getType).toArray();
22 23
  24 + /**
  25 + * 类型值
  26 + */
23 private final Integer type; 27 private final Integer type;
24 - private final String desc; 28 + /**
  29 + * 类型名
  30 + */
  31 + private final String name;
25 32
26 @Override 33 @Override
27 public int[] array() { 34 public int[] array() {
yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/MarketTestController.java deleted
1 -package cn.iocoder.yudao.module.market.controller.admin;  
2 -  
3 -import cn.iocoder.yudao.framework.common.pojo.CommonResult;  
4 -import io.swagger.annotations.Api;  
5 -import io.swagger.annotations.ApiOperation;  
6 -import org.springframework.validation.annotation.Validated;  
7 -import org.springframework.web.bind.annotation.GetMapping;  
8 -import org.springframework.web.bind.annotation.RequestMapping;  
9 -import org.springframework.web.bind.annotation.RestController;  
10 -  
11 -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;  
12 -  
13 -@Api(tags = "管理后台 - 营销")  
14 -@RestController  
15 -@RequestMapping("/market/test")  
16 -@Validated  
17 -public class MarketTestController {  
18 -  
19 - @GetMapping("/get")  
20 - @ApiOperation("获取 market 信息")  
21 - public CommonResult<String> get() {  
22 - return success("true");  
23 - }  
24 -  
25 -}  
yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/activity/ActivityController.java deleted
1 -package cn.iocoder.yudao.module.market.controller.admin.activity;  
2 -  
3 -import org.springframework.web.bind.annotation.*;  
4 -import javax.annotation.Resource;  
5 -import org.springframework.validation.annotation.Validated;  
6 -import org.springframework.security.access.prepost.PreAuthorize;  
7 -import io.swagger.annotations.*;  
8 -import javax.validation.*;  
9 -import java.util.*;  
10 -import cn.iocoder.yudao.framework.common.pojo.PageResult;  
11 -import cn.iocoder.yudao.framework.common.pojo.CommonResult;  
12 -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;  
13 -import cn.iocoder.yudao.module.market.controller.admin.activity.vo.*;  
14 -import cn.iocoder.yudao.module.market.dal.dataobject.activity.ActivityDO;  
15 -import cn.iocoder.yudao.module.market.convert.activity.ActivityConvert;  
16 -import cn.iocoder.yudao.module.market.service.activity.ActivityService;  
17 -  
18 -@Api(tags = "管理后台 - 促销活动")  
19 -@RestController  
20 -@RequestMapping("/market/activity")  
21 -@Validated  
22 -public class ActivityController {  
23 -  
24 - @Resource  
25 - private ActivityService activityService;  
26 -  
27 - @PostMapping("/create")  
28 - @ApiOperation("创建促销活动")  
29 - @PreAuthorize("@ss.hasPermission('market:activity:create')")  
30 - public CommonResult<Long> createActivity(@Valid @RequestBody ActivityCreateReqVO createReqVO) {  
31 - return success(activityService.createActivity(createReqVO));  
32 - }  
33 -  
34 - @PutMapping("/update")  
35 - @ApiOperation("更新促销活动")  
36 - @PreAuthorize("@ss.hasPermission('market:activity:update')")  
37 - public CommonResult<Boolean> updateActivity(@Valid @RequestBody ActivityUpdateReqVO updateReqVO) {  
38 - activityService.updateActivity(updateReqVO);  
39 - return success(true);  
40 - }  
41 -  
42 - @DeleteMapping("/delete")  
43 - @ApiOperation("删除促销活动")  
44 - @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class)  
45 - @PreAuthorize("@ss.hasPermission('market:activity:delete')")  
46 - public CommonResult<Boolean> deleteActivity(@RequestParam("id") Long id) {  
47 - activityService.deleteActivity(id);  
48 - return success(true);  
49 - }  
50 -  
51 - @GetMapping("/get")  
52 - @ApiOperation("获得促销活动")  
53 - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)  
54 - @PreAuthorize("@ss.hasPermission('market:activity:query')")  
55 - public CommonResult<ActivityRespVO> getActivity(@RequestParam("id") Long id) {  
56 - ActivityDO activity = activityService.getActivity(id);  
57 - return success(ActivityConvert.INSTANCE.convert(activity));  
58 - }  
59 -  
60 - @GetMapping("/list")  
61 - @ApiOperation("获得促销活动列表")  
62 - @ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class)  
63 - @PreAuthorize("@ss.hasPermission('market:activity:query')")  
64 - public CommonResult<List<ActivityRespVO>> getActivityList(@RequestParam("ids") Collection<Long> ids) {  
65 - List<ActivityDO> list = activityService.getActivityList(ids);  
66 - return success(ActivityConvert.INSTANCE.convertList(list));  
67 - }  
68 -  
69 - @GetMapping("/page")  
70 - @ApiOperation("获得促销活动分页")  
71 - @PreAuthorize("@ss.hasPermission('market:activity:query')")  
72 - public CommonResult<PageResult<ActivityRespVO>> getActivityPage(@Valid ActivityPageReqVO pageVO) {  
73 - PageResult<ActivityDO> pageResult = activityService.getActivityPage(pageVO);  
74 - return success(ActivityConvert.INSTANCE.convertPage(pageResult));  
75 - }  
76 -  
77 -}  
yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/activity/vo/ActivityBaseVO.java deleted
1 -package cn.iocoder.yudao.module.market.controller.admin.activity.vo;  
2 -  
3 -import cn.iocoder.yudao.framework.common.validation.InEnum;  
4 -import cn.iocoder.yudao.module.market.enums.activity.MarketActivityStatusEnum;  
5 -import cn.iocoder.yudao.module.market.enums.activity.MarketActivityTypeEnum;  
6 -import lombok.*;  
7 -import java.util.*;  
8 -import io.swagger.annotations.*;  
9 -import javax.validation.constraints.*;  
10 -import org.springframework.format.annotation.DateTimeFormat;  
11 -  
12 -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;  
13 -  
14 -/**  
15 -* 促销活动 Base VO,提供给添加、修改、详细的子 VO 使用  
16 -* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成  
17 -*/  
18 -@Data  
19 -public class ActivityBaseVO {  
20 -  
21 - @ApiModelProperty(value = "活动标题", required = true)  
22 - @NotNull(message = "活动标题不能为空")  
23 - private String title;  
24 -  
25 - @ApiModelProperty(value = "活动类型", required = true)  
26 - @NotNull(message = "活动类型不能为空")  
27 - @InEnum(MarketActivityTypeEnum.class)  
28 - private Integer activityType;  
29 -  
30 - @ApiModelProperty(value = "活动状态", required = true)  
31 - @NotNull(message = "活动状态不能为空")  
32 - @InEnum(MarketActivityStatusEnum.class)  
33 - private Integer status;  
34 -  
35 - @ApiModelProperty(value = "开始时间", required = true)  
36 - @NotNull(message = "开始时间不能为空")  
37 - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)  
38 - private Date startTime;  
39 -  
40 - @ApiModelProperty(value = "结束时间", required = true)  
41 - @NotNull(message = "结束时间不能为空")  
42 - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)  
43 - private Date endTime;  
44 -  
45 - @ApiModelProperty(value = "失效时间")  
46 - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)  
47 - private Date invalidTime;  
48 -  
49 - @ApiModelProperty(value = "删除时间")  
50 - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)  
51 - private Date deleteTime;  
52 -  
53 - @ApiModelProperty(value = "限制折扣字符串,使用 JSON 序列化成字符串存储")  
54 - private String timeLimitedDiscount;  
55 -  
56 - @ApiModelProperty(value = "限制折扣字符串,使用 JSON 序列化成字符串存储")  
57 - private String fullPrivilege;  
58 -  
59 -}  
yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/activity/vo/ActivityPageReqVO.java deleted
1 -package cn.iocoder.yudao.module.market.controller.admin.activity.vo;  
2 -  
3 -import cn.iocoder.yudao.framework.common.validation.InEnum;  
4 -import cn.iocoder.yudao.module.market.enums.activity.MarketActivityStatusEnum;  
5 -import cn.iocoder.yudao.module.market.enums.activity.MarketActivityTypeEnum;  
6 -import lombok.*;  
7 -import java.util.*;  
8 -import io.swagger.annotations.*;  
9 -import cn.iocoder.yudao.framework.common.pojo.PageParam;  
10 -import org.springframework.format.annotation.DateTimeFormat;  
11 -  
12 -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;  
13 -  
14 -@ApiModel("管理后台 - 促销活动分页 Request VO")  
15 -@Data  
16 -@EqualsAndHashCode(callSuper = true)  
17 -@ToString(callSuper = true)  
18 -public class ActivityPageReqVO extends PageParam {  
19 -  
20 - @ApiModelProperty(value = "活动标题")  
21 - private String title;  
22 -  
23 - @ApiModelProperty(value = "活动类型")  
24 - @InEnum(MarketActivityTypeEnum.class)  
25 - private Integer activityType;  
26 -  
27 - @ApiModelProperty(value = "活动状态")  
28 - @InEnum(MarketActivityStatusEnum.class)  
29 - private Integer status;  
30 -  
31 - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)  
32 - @ApiModelProperty(value = "开始时间")  
33 - private Date[] startTime;  
34 -  
35 - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)  
36 - @ApiModelProperty(value = "结束时间")  
37 - private Date[] endTime;  
38 -  
39 - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)  
40 - @ApiModelProperty(value = "失效时间")  
41 - private Date[] invalidTime;  
42 -  
43 - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)  
44 - @ApiModelProperty(value = "删除时间")  
45 - private Date[] deleteTime;  
46 -  
47 - @ApiModelProperty(value = "限制折扣字符串,使用 JSON 序列化成字符串存储")  
48 - private String timeLimitedDiscount;  
49 -  
50 - @ApiModelProperty(value = "限制折扣字符串,使用 JSON 序列化成字符串存储")  
51 - private String fullPrivilege;  
52 -  
53 - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)  
54 - @ApiModelProperty(value = "创建时间")  
55 - private Date[] createTime;  
56 -  
57 -}  
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/enums/package-info.java renamed to yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/discount/package-info.java
1 /** 1 /**
2 - * 占位 2 + * TODO 占位
3 */ 3 */
4 -package cn.iocoder.yudao.module.member.enums; 4 +package cn.iocoder.yudao.module.market.controller.admin.discount;
yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/convert/activity/ActivityConvert.java deleted
1 -package cn.iocoder.yudao.module.market.convert.activity;  
2 -  
3 -import java.util.*;  
4 -  
5 -import cn.iocoder.yudao.framework.common.pojo.PageResult;  
6 -  
7 -import org.mapstruct.Mapper;  
8 -import org.mapstruct.factory.Mappers;  
9 -import cn.iocoder.yudao.module.market.controller.admin.activity.vo.*;  
10 -import cn.iocoder.yudao.module.market.dal.dataobject.activity.ActivityDO;  
11 -  
12 -/**  
13 - * 促销活动 Convert  
14 - *  
15 - * @author 芋道源码  
16 - */  
17 -@Mapper  
18 -public interface ActivityConvert {  
19 -  
20 - ActivityConvert INSTANCE = Mappers.getMapper(ActivityConvert.class);  
21 -  
22 - ActivityDO convert(ActivityCreateReqVO bean);  
23 -  
24 - ActivityDO convert(ActivityUpdateReqVO bean);  
25 -  
26 - ActivityRespVO convert(ActivityDO bean);  
27 -  
28 - List<ActivityRespVO> convertList(List<ActivityDO> list);  
29 -  
30 - PageResult<ActivityRespVO> convertPage(PageResult<ActivityDO> page);  
31 -  
32 -}  
yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/convert/discount/package-info.java 0 → 100644
  1 +/**
  2 + * TODO 占位
  3 + */
  4 +package cn.iocoder.yudao.module.market.convert.discount;
yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/dal/dataobject/discount/DiscountActivityDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.market.dal.dataobject.discount;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import cn.iocoder.yudao.module.market.enums.common.PromotionActivityStatusEnum;
  5 +import com.baomidou.mybatisplus.annotation.KeySequence;
  6 +import com.baomidou.mybatisplus.annotation.TableId;
  7 +import com.baomidou.mybatisplus.annotation.TableName;
  8 +import lombok.Data;
  9 +import lombok.EqualsAndHashCode;
  10 +
  11 +import java.util.Date;
  12 +
  13 +/**
  14 + * 限时折扣活动 DO
  15 + *
  16 + * 一个活动下,可以有 {@link DiscountProductDO} 商品;
  17 + * 一个商品,在指定时间段内,只能属于一个活动;
  18 + *
  19 + * @author 芋道源码
  20 + */
  21 +@TableName(value = "promotion_discount_activity", autoResultMap = true)
  22 +@KeySequence("promotion_discount_activity_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
  23 +@Data
  24 +@EqualsAndHashCode(callSuper = true)
  25 +public class DiscountActivityDO extends BaseDO {
  26 +
  27 + /**
  28 + * 活动编号,主键自增
  29 + */
  30 + @TableId
  31 + private Long id;
  32 + /**
  33 + * 活动标题
  34 + */
  35 + private String name;
  36 + /**
  37 + * 状态
  38 + *
  39 + * 枚举 {@link PromotionActivityStatusEnum}
  40 + */
  41 + private Integer status;
  42 + /**
  43 + * 开始时间
  44 + */
  45 + private Date startTime;
  46 + /**
  47 + * 结束时间
  48 + */
  49 + private Date endTime;
  50 + /**
  51 + * 备注
  52 + */
  53 + private String remark;
  54 +
  55 +}
yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/dal/dataobject/discount/DiscountProductDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.market.dal.dataobject.discount;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import com.baomidou.mybatisplus.annotation.KeySequence;
  5 +import com.baomidou.mybatisplus.annotation.TableId;
  6 +import com.baomidou.mybatisplus.annotation.TableName;
  7 +import lombok.Data;
  8 +import lombok.EqualsAndHashCode;
  9 +
  10 +import java.util.Date;
  11 +
  12 +/**
  13 + * 限时折扣商品 DO
  14 + *
  15 + * @author 芋道源码
  16 + */
  17 +@TableName(value = "promotion_discount_product", autoResultMap = true)
  18 +@KeySequence("promotion_discount_product_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
  19 +@Data
  20 +@EqualsAndHashCode(callSuper = true)
  21 +public class DiscountProductDO extends BaseDO {
  22 +
  23 + /**
  24 + * 编号,主键自增
  25 + */
  26 + @TableId
  27 + private Long id;
  28 + /**
  29 + * 限时折扣活动的编号
  30 + *
  31 + * 关联 {@link DiscountActivityDO#getId()}
  32 + */
  33 + private Long activityId;
  34 + /**
  35 + * 商品 SPU 编号
  36 + *
  37 + * 关联 ProductSpuDO 的 id 编号
  38 + */
  39 + private Long spuId;
  40 + /**
  41 + * 商品 SKU 编号
  42 + *
  43 + * 关联 ProductSkuDO 的 id 编号
  44 + */
  45 + private Long skuId;
  46 + /**
  47 + * 开始时间
  48 + */
  49 + private Date startTime;
  50 + /**
  51 + * 结束时间
  52 + */
  53 + private Date endTime;
  54 + /**
  55 + * 销售价格,单位:分
  56 + *
  57 + * 冗余 ProductSkuDO 的 price 字段
  58 + */
  59 + private Integer originalPrice;
  60 + /**
  61 + * 优惠价格,单位:分
  62 + */
  63 + private Integer promotionPrice;
  64 +
  65 +}
yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/dal/dataobject/reward/RewardActivityDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.market.dal.dataobject.reward;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import cn.iocoder.yudao.module.market.enums.common.PromotionActivityStatusEnum;
  5 +import cn.iocoder.yudao.module.market.enums.common.PromotionConditionTypeEnum;
  6 +import cn.iocoder.yudao.module.market.enums.common.PromotionProductScopeEnum;
  7 +import com.baomidou.mybatisplus.annotation.KeySequence;
  8 +import com.baomidou.mybatisplus.annotation.TableField;
  9 +import com.baomidou.mybatisplus.annotation.TableId;
  10 +import com.baomidou.mybatisplus.annotation.TableName;
  11 +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
  12 +import lombok.Data;
  13 +import lombok.EqualsAndHashCode;
  14 +
  15 +import java.util.Date;
  16 +import java.util.List;
  17 +
  18 +/**
  19 + * 满减送活动 DO
  20 + *
  21 + * @author 芋道源码
  22 + */
  23 +@TableName(value = "promotion_reward_activity", autoResultMap = true)
  24 +@KeySequence("promotion_reward_activity_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
  25 +@Data
  26 +@EqualsAndHashCode(callSuper = true)
  27 +public class RewardActivityDO extends BaseDO {
  28 +
  29 + /**
  30 + * 活动编号,主键自增
  31 + */
  32 + @TableId
  33 + private Long id;
  34 + /**
  35 + * 活动标题
  36 + */
  37 + private String name;
  38 + /**
  39 + * 状态
  40 + *
  41 + * 枚举 {@link PromotionActivityStatusEnum}
  42 + */
  43 + private Integer status;
  44 + /**
  45 + * 开始时间
  46 + */
  47 + private Date startTime;
  48 + /**
  49 + * 结束时间
  50 + */
  51 + private Date endTime;
  52 + /**
  53 + * 备注
  54 + */
  55 + private String remark;
  56 + /**
  57 + * 条件类型
  58 + *
  59 + * 枚举 {@link PromotionConditionTypeEnum}
  60 + */
  61 + private Integer conditionType;
  62 + /**
  63 + * 商品范围
  64 + *
  65 + * 枚举 {@link PromotionProductScopeEnum}
  66 + */
  67 + private Integer productScope;
  68 + /**
  69 + * 商品 SPU 编号的数组
  70 + */
  71 + @TableField(typeHandler = JacksonTypeHandler.class)
  72 + private List<Long> spuIds;
  73 + /**
  74 + * 优惠规则的数组
  75 + */
  76 + @TableField(typeHandler = JacksonTypeHandler.class)
  77 + private List<Rule> rules;
  78 +
  79 + /**
  80 + * 优惠规则
  81 + */
  82 + @Data
  83 + public static class Rule {
  84 +
  85 + /**
  86 + * 优惠门槛
  87 + *
  88 + * 1. 满 N 元,单位:分
  89 + * 2. 满 N 件
  90 + */
  91 + private Integer limit;
  92 + /**
  93 + * 优惠价格,单位:分
  94 + */
  95 + private Integer promotionPrice;
  96 + /**
  97 + * 是否包邮
  98 + */
  99 + private Boolean freeDelivery;
  100 + /**
  101 + * 赠送的积分
  102 + */
  103 + private Integer integral;
  104 + /**
  105 + * 赠送的优惠劵编号的数组
  106 + */
  107 + private List<Long> couponIds;
  108 + /**
  109 + * 赠送的优惠卷数量的数组
  110 + */
  111 + private List<Integer> couponCounts;
  112 +
  113 + }
  114 +
  115 +
  116 +}
yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/dal/mysql/activity/ActivityMapper.java deleted
1 -package cn.iocoder.yudao.module.market.dal.mysql.activity;  
2 -  
3 -import java.util.*;  
4 -  
5 -import cn.iocoder.yudao.framework.common.pojo.PageResult;  
6 -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;  
7 -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;  
8 -import cn.iocoder.yudao.module.market.dal.dataobject.activity.ActivityDO;  
9 -import org.apache.ibatis.annotations.Mapper;  
10 -import cn.iocoder.yudao.module.market.controller.admin.activity.vo.*;  
11 -  
12 -/**  
13 - * 促销活动 Mapper  
14 - *  
15 - * @author 芋道源码  
16 - */  
17 -@Mapper  
18 -public interface ActivityMapper extends BaseMapperX<ActivityDO> {  
19 -  
20 - default PageResult<ActivityDO> selectPage(ActivityPageReqVO reqVO) {  
21 - return selectPage(reqVO, new LambdaQueryWrapperX<ActivityDO>()  
22 - .eqIfPresent(ActivityDO::getTitle, reqVO.getTitle())  
23 - .eqIfPresent(ActivityDO::getActivityType, reqVO.getActivityType())  
24 - .eqIfPresent(ActivityDO::getStatus, reqVO.getStatus())  
25 - .betweenIfPresent(ActivityDO::getStartTime, reqVO.getStartTime())  
26 - .betweenIfPresent(ActivityDO::getEndTime, reqVO.getEndTime())  
27 - .betweenIfPresent(ActivityDO::getInvalidTime, reqVO.getInvalidTime())  
28 - .betweenIfPresent(ActivityDO::getDeleteTime, reqVO.getDeleteTime())  
29 - .eqIfPresent(ActivityDO::getTimeLimitedDiscount, reqVO.getTimeLimitedDiscount())  
30 - .eqIfPresent(ActivityDO::getFullPrivilege, reqVO.getFullPrivilege())  
31 - .betweenIfPresent(ActivityDO::getCreateTime, reqVO.getCreateTime())  
32 - .orderByDesc(ActivityDO::getId));  
33 - }  
34 -  
35 -}  
yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/dal/mysql/discount/package-info.java 0 → 100644
  1 +/**
  2 + * TODO 占位
  3 + */
  4 +package cn.iocoder.yudao.module.market.dal.mysql.discount;
yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/package-info.java
1 /** 1 /**
2 - * market 模块,我们放营销业务。 2 + * promotion 模块,我们放营销业务。
3 * 例如说:营销活动、banner、优惠券等等 3 * 例如说:营销活动、banner、优惠券等等
4 * 4 *
5 - * 1. Controller URL:以 /market/ 开头,避免和其它 Module 冲突  
6 - * 2. DataObject 表名:以 market_ 开头,方便在数据库中区分 5 + * 1. Controller URL:以 /promotion/ 开头,避免和其它 Module 冲突
  6 + * 2. DataObject 表名:以 promotion_ 开头,方便在数据库中区分
7 */ 7 */
8 package cn.iocoder.yudao.module.market; 8 package cn.iocoder.yudao.module.market;
yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/service/activity/ActivityServiceImpl.java deleted
1 -package cn.iocoder.yudao.module.market.service.activity;  
2 -  
3 -import org.springframework.stereotype.Service;  
4 -import javax.annotation.Resource;  
5 -import org.springframework.validation.annotation.Validated;  
6 -  
7 -import java.util.*;  
8 -import cn.iocoder.yudao.module.market.controller.admin.activity.vo.*;  
9 -import cn.iocoder.yudao.module.market.dal.dataobject.activity.ActivityDO;  
10 -import cn.iocoder.yudao.framework.common.pojo.PageResult;  
11 -  
12 -import cn.iocoder.yudao.module.market.convert.activity.ActivityConvert;  
13 -import cn.iocoder.yudao.module.market.dal.mysql.activity.ActivityMapper;  
14 -  
15 -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;  
16 -import static cn.iocoder.yudao.module.market.enums.ErrorCodeConstants.*;  
17 -  
18 -/**  
19 - * 促销活动 Service 实现类  
20 - *  
21 - * @author 芋道源码  
22 - */  
23 -@Service  
24 -@Validated  
25 -public class ActivityServiceImpl implements ActivityService {  
26 -  
27 - @Resource  
28 - private ActivityMapper activityMapper;  
29 -  
30 - @Override  
31 - public Long createActivity(ActivityCreateReqVO createReqVO) {  
32 - // 插入  
33 - ActivityDO activity = ActivityConvert.INSTANCE.convert(createReqVO);  
34 - activityMapper.insert(activity);  
35 - // 返回  
36 - return activity.getId();  
37 - }  
38 -  
39 - @Override  
40 - public void updateActivity(ActivityUpdateReqVO updateReqVO) {  
41 - // 校验存在  
42 - this.validateActivityExists(updateReqVO.getId());  
43 - // 更新  
44 - ActivityDO updateObj = ActivityConvert.INSTANCE.convert(updateReqVO);  
45 - activityMapper.updateById(updateObj);  
46 - }  
47 -  
48 - @Override  
49 - public void deleteActivity(Long id) {  
50 - // 校验存在  
51 - this.validateActivityExists(id);  
52 - // 删除  
53 - activityMapper.deleteById(id);  
54 - }  
55 -  
56 - private void validateActivityExists(Long id) {  
57 - if (activityMapper.selectById(id) == null) {  
58 - throw exception(ACTIVITY_NOT_EXISTS);  
59 - }  
60 - }  
61 -  
62 - @Override  
63 - public ActivityDO getActivity(Long id) {  
64 - return activityMapper.selectById(id);  
65 - }  
66 -  
67 - @Override  
68 - public List<ActivityDO> getActivityList(Collection<Long> ids) {  
69 - return activityMapper.selectBatchIds(ids);  
70 - }  
71 -  
72 - @Override  
73 - public PageResult<ActivityDO> getActivityPage(ActivityPageReqVO pageReqVO) {  
74 - return activityMapper.selectPage(pageReqVO);  
75 - }  
76 -  
77 -}  
yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/service/discount/package-info.java 0 → 100644
  1 +/**
  2 + * TODO 占位
  3 + */
  4 +package cn.iocoder.yudao.module.market.service.discount;
yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/service/price/PriceApiImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.market.service.price;
  2 +
  3 +import cn.iocoder.yudao.module.market.api.price.PriceApi;
  4 +import cn.iocoder.yudao.module.market.api.price.dto.PriceCalculateReqDTO;
  5 +import cn.iocoder.yudao.module.market.api.price.dto.PriceCalculateRespDTO;
  6 +import org.springframework.stereotype.Service;
  7 +
  8 +/**
  9 + * 价格 API 实现类
  10 + *
  11 + * TODO 完善注释
  12 + *
  13 + * @author TODO
  14 + */
  15 +@Service
  16 +public class PriceApiImpl implements PriceApi {
  17 +
  18 + @Override
  19 + public PriceCalculateRespDTO calculatePrice(PriceCalculateReqDTO calculateReqDTO) {
  20 + // TODO fixme:实现逻辑
  21 + return new PriceCalculateRespDTO();
  22 + }
  23 +
  24 +}
yudao-module-mall/yudao-module-market-biz/src/test/java/cn/iocoder/yudao/module/market/service/activity/ActivityServiceImplTest.java deleted
1 -package cn.iocoder.yudao.module.market.service.activity;  
2 -  
3 -import org.junit.jupiter.api.Disabled;  
4 -import org.junit.jupiter.api.Test;  
5 -  
6 -import javax.annotation.Resource;  
7 -  
8 -import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;  
9 -  
10 -import cn.iocoder.yudao.module.market.controller.admin.activity.vo.*;  
11 -import cn.iocoder.yudao.module.market.dal.dataobject.activity.ActivityDO;  
12 -import cn.iocoder.yudao.module.market.dal.mysql.activity.ActivityMapper;  
13 -import cn.iocoder.yudao.framework.common.pojo.PageResult;  
14 -  
15 -import org.springframework.context.annotation.Import;  
16 -  
17 -import static cn.iocoder.yudao.module.market.enums.ErrorCodeConstants.*;  
18 -import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.*;  
19 -import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;  
20 -import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.*;  
21 -import static org.junit.jupiter.api.Assertions.*;  
22 -  
23 -/**  
24 -* {@link ActivityServiceImpl} 的单元测试类  
25 -*  
26 -* @author 芋道源码  
27 -*/  
28 -@Import(ActivityServiceImpl.class)  
29 -public class ActivityServiceImplTest extends BaseDbUnitTest {  
30 -  
31 - @Resource  
32 - private ActivityServiceImpl activityService;  
33 -  
34 - @Resource  
35 - private ActivityMapper activityMapper;  
36 -  
37 - @Test  
38 - public void testCreateActivity_success() {  
39 - // 准备参数  
40 - ActivityCreateReqVO reqVO = randomPojo(ActivityCreateReqVO.class);  
41 -  
42 - // 调用  
43 - Long activityId = activityService.createActivity(reqVO);  
44 - // 断言  
45 - assertNotNull(activityId);  
46 - // 校验记录的属性是否正确  
47 - ActivityDO activity = activityMapper.selectById(activityId);  
48 - assertPojoEquals(reqVO, activity);  
49 - }  
50 -  
51 - @Test  
52 - public void testUpdateActivity_success() {  
53 - // mock 数据  
54 - ActivityDO dbActivity = randomPojo(ActivityDO.class);  
55 - activityMapper.insert(dbActivity);// @Sql: 先插入出一条存在的数据  
56 - // 准备参数  
57 - ActivityUpdateReqVO reqVO = randomPojo(ActivityUpdateReqVO.class, o -> {  
58 - o.setId(dbActivity.getId()); // 设置更新的 ID  
59 - });  
60 -  
61 - // 调用  
62 - activityService.updateActivity(reqVO);  
63 - // 校验是否更新正确  
64 - ActivityDO activity = activityMapper.selectById(reqVO.getId()); // 获取最新的  
65 - assertPojoEquals(reqVO, activity);  
66 - }  
67 -  
68 - @Test  
69 - public void testUpdateActivity_notExists() {  
70 - // 准备参数  
71 - ActivityUpdateReqVO reqVO = randomPojo(ActivityUpdateReqVO.class);  
72 -  
73 - // 调用, 并断言异常  
74 - assertServiceException(() -> activityService.updateActivity(reqVO), ACTIVITY_NOT_EXISTS);  
75 - }  
76 -  
77 - @Test  
78 - public void testDeleteActivity_success() {  
79 - // mock 数据  
80 - ActivityDO dbActivity = randomPojo(ActivityDO.class);  
81 - activityMapper.insert(dbActivity);// @Sql: 先插入出一条存在的数据  
82 - // 准备参数  
83 - Long id = dbActivity.getId();  
84 -  
85 - // 调用  
86 - activityService.deleteActivity(id);  
87 - // 校验数据不存在了  
88 - assertNull(activityMapper.selectById(id));  
89 - }  
90 -  
91 - @Test  
92 - public void testDeleteActivity_notExists() {  
93 - // 准备参数  
94 - Long id = randomLongId();  
95 -  
96 - // 调用, 并断言异常  
97 - assertServiceException(() -> activityService.deleteActivity(id), ACTIVITY_NOT_EXISTS);  
98 - }  
99 -  
100 - @Test  
101 - @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解  
102 - public void testGetActivityPage() {  
103 - // mock 数据  
104 - ActivityDO dbActivity = randomPojo(ActivityDO.class, o -> { // 等会查询到  
105 - o.setTitle(null);  
106 - o.setActivityType(null);  
107 - o.setStatus(null);  
108 - o.setStartTime(null);  
109 - o.setEndTime(null);  
110 - o.setInvalidTime(null);  
111 - o.setDeleteTime(null);  
112 - o.setTimeLimitedDiscount(null);  
113 - o.setFullPrivilege(null);  
114 - o.setCreateTime(null);  
115 - });  
116 - activityMapper.insert(dbActivity);  
117 - // 测试 title 不匹配  
118 - activityMapper.insert(cloneIgnoreId(dbActivity, o -> o.setTitle(null)));  
119 - // 测试 activityType 不匹配  
120 - activityMapper.insert(cloneIgnoreId(dbActivity, o -> o.setActivityType(null)));  
121 - // 测试 status 不匹配  
122 - activityMapper.insert(cloneIgnoreId(dbActivity, o -> o.setStatus(null)));  
123 - // 测试 startTime 不匹配  
124 - activityMapper.insert(cloneIgnoreId(dbActivity, o -> o.setStartTime(null)));  
125 - // 测试 endTime 不匹配  
126 - activityMapper.insert(cloneIgnoreId(dbActivity, o -> o.setEndTime(null)));  
127 - // 测试 invalidTime 不匹配  
128 - activityMapper.insert(cloneIgnoreId(dbActivity, o -> o.setInvalidTime(null)));  
129 - // 测试 deleteTime 不匹配  
130 - activityMapper.insert(cloneIgnoreId(dbActivity, o -> o.setDeleteTime(null)));  
131 - // 测试 timeLimitedDiscount 不匹配  
132 - activityMapper.insert(cloneIgnoreId(dbActivity, o -> o.setTimeLimitedDiscount(null)));  
133 - // 测试 fullPrivilege 不匹配  
134 - activityMapper.insert(cloneIgnoreId(dbActivity, o -> o.setFullPrivilege(null)));  
135 - // 测试 createTime 不匹配  
136 - activityMapper.insert(cloneIgnoreId(dbActivity, o -> o.setCreateTime(null)));  
137 - // 准备参数  
138 - ActivityPageReqVO reqVO = new ActivityPageReqVO();  
139 - reqVO.setTitle(null);  
140 - reqVO.setActivityType(null);  
141 - reqVO.setStatus(null);  
142 - reqVO.setStartTime(null);  
143 - reqVO.setEndTime(null);  
144 - reqVO.setInvalidTime(null);  
145 - reqVO.setDeleteTime(null);  
146 - reqVO.setTimeLimitedDiscount(null);  
147 - reqVO.setFullPrivilege(null);  
148 - reqVO.setCreateTime(null);  
149 -  
150 - // 调用  
151 - PageResult<ActivityDO> pageResult = activityService.getActivityPage(reqVO);  
152 - // 断言  
153 - assertEquals(1, pageResult.getTotal());  
154 - assertEquals(1, pageResult.getList().size());  
155 - assertPojoEquals(dbActivity, pageResult.getList().get(0));  
156 - }  
157 -  
158 - @Test  
159 - @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解  
160 - public void testGetActivityList() {  
161 - // mock 数据  
162 - ActivityDO dbActivity = randomPojo(ActivityDO.class, o -> { // 等会查询到  
163 - o.setTitle(null);  
164 - o.setActivityType(null);  
165 - o.setStatus(null);  
166 - o.setStartTime(null);  
167 - o.setEndTime(null);  
168 - o.setInvalidTime(null);  
169 - o.setDeleteTime(null);  
170 - o.setTimeLimitedDiscount(null);  
171 - o.setFullPrivilege(null);  
172 - o.setCreateTime(null);  
173 - });  
174 - activityMapper.insert(dbActivity);  
175 - // 测试 title 不匹配  
176 - activityMapper.insert(cloneIgnoreId(dbActivity, o -> o.setTitle(null)));  
177 - // 测试 activityType 不匹配  
178 - activityMapper.insert(cloneIgnoreId(dbActivity, o -> o.setActivityType(null)));  
179 - // 测试 status 不匹配  
180 - activityMapper.insert(cloneIgnoreId(dbActivity, o -> o.setStatus(null)));  
181 - // 测试 startTime 不匹配  
182 - activityMapper.insert(cloneIgnoreId(dbActivity, o -> o.setStartTime(null)));  
183 - // 测试 endTime 不匹配  
184 - activityMapper.insert(cloneIgnoreId(dbActivity, o -> o.setEndTime(null)));  
185 - // 测试 invalidTime 不匹配  
186 - activityMapper.insert(cloneIgnoreId(dbActivity, o -> o.setInvalidTime(null)));  
187 - // 测试 deleteTime 不匹配  
188 - activityMapper.insert(cloneIgnoreId(dbActivity, o -> o.setDeleteTime(null)));  
189 - // 测试 timeLimitedDiscount 不匹配  
190 - activityMapper.insert(cloneIgnoreId(dbActivity, o -> o.setTimeLimitedDiscount(null)));  
191 - // 测试 fullPrivilege 不匹配  
192 - activityMapper.insert(cloneIgnoreId(dbActivity, o -> o.setFullPrivilege(null)));  
193 - // 测试 createTime 不匹配  
194 - activityMapper.insert(cloneIgnoreId(dbActivity, o -> o.setCreateTime(null)));  
195 - }  
196 -  
197 -}  
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/ProductSkuApi.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.api.sku;
  2 +
  3 +import cn.iocoder.yudao.module.product.api.sku.dto.SkuDecrementStockBatchReqDTO;
  4 +import cn.iocoder.yudao.module.product.api.sku.dto.SkuInfoRespDTO;
  5 +
  6 +import java.util.Collection;
  7 +import java.util.List;
  8 +
  9 +/**
  10 + * @author LeeYan9
  11 + * @since 2022-08-26
  12 + */
  13 +public interface ProductSkuApi {
  14 +
  15 +
  16 + /**
  17 + * 根据skuId列表 查询sku信息
  18 + *
  19 + * @param skuIds sku ID列表
  20 + * @return sku信息列表
  21 + */
  22 + List<SkuInfoRespDTO> getSkusByIds(Collection<Long> skuIds);
  23 +
  24 + /**
  25 + * 批量扣减sku库存
  26 + *
  27 + * @param batchReqDTO sku库存信息列表
  28 + */
  29 + void decrementStockBatch(SkuDecrementStockBatchReqDTO batchReqDTO);
  30 +}
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/dto/SkuDecrementStockBatchReqDTO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.api.sku.dto;
  2 +
  3 +import lombok.AllArgsConstructor;
  4 +import lombok.Data;
  5 +import lombok.NoArgsConstructor;
  6 +
  7 +import java.util.List;
  8 +
  9 +/**
  10 + * @author LeeYan9
  11 + * @since 2022-08-26
  12 + */
  13 +@Data
  14 +@NoArgsConstructor
  15 +@AllArgsConstructor
  16 +public class SkuDecrementStockBatchReqDTO {
  17 +
  18 +
  19 + private List<Item> items;
  20 +
  21 + @Data
  22 + public static class Item {
  23 +
  24 + /**
  25 + * 商品 SPU 编号,自增
  26 + */
  27 + private Long productId;
  28 +
  29 + /**
  30 + * 商品 SKU 编号,自增
  31 + */
  32 + private Long skuId;
  33 +
  34 + /**
  35 + * 数量
  36 + */
  37 + private Integer count;
  38 +
  39 + }
  40 +
  41 + public static SkuDecrementStockBatchReqDTO of(List<Item> items) {
  42 + return new SkuDecrementStockBatchReqDTO(items);
  43 + }
  44 +
  45 +}
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/dto/SkuInfoRespDTO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.api.sku.dto;
  2 +
  3 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  4 +import lombok.Data;
  5 +
  6 +import java.util.List;
  7 +
  8 +/**
  9 + * @author LeeYan9
  10 + * @since 2022-08-26
  11 + */
  12 +@Data
  13 +public class SkuInfoRespDTO {
  14 +
  15 + /**
  16 + * 商品 SKU 编号,自增
  17 + */
  18 + private Long id;
  19 + /**
  20 + * 商品 SKU 名字
  21 + */
  22 + private String name;
  23 + /**
  24 + * SPU 编号
  25 + */
  26 + private Long spuId;
  27 +
  28 + /**
  29 + * 规格值数组,JSON 格式
  30 + */
  31 + private List<Property> properties;
  32 + /**
  33 + * 销售价格,单位:分
  34 + */
  35 + private Integer price;
  36 + /**
  37 + * 市场价,单位:分
  38 + */
  39 + private Integer marketPrice;
  40 + /**
  41 + * 成本价,单位:分
  42 + */
  43 + private Integer costPrice;
  44 + /**
  45 + * SKU 的条形码
  46 + */
  47 + private String barCode;
  48 + /**
  49 + * 图片地址
  50 + */
  51 + private String picUrl;
  52 + /**
  53 + * SKU 状态
  54 + * <p>
  55 + * 枚举 {@link CommonStatusEnum}
  56 + */
  57 + private Integer status;
  58 + /**
  59 + * 库存
  60 + */
  61 + private Integer stock;
  62 + /**
  63 + * 预警预存
  64 + */
  65 + private Integer warnStock;
  66 + /**
  67 + * 商品重量,单位:kg 千克
  68 + */
  69 + private Double weight;
  70 + /**
  71 + * 商品体积,单位:m^3 平米
  72 + */
  73 + private Double volume;
  74 +
  75 + /**
  76 + * 商品属性
  77 + */
  78 + @Data
  79 + public static class Property {
  80 +
  81 + /**
  82 + * 属性编号
  83 + */
  84 + private Long propertyId;
  85 + /**
  86 + * 属性值编号
  87 + */
  88 + private Long valueId;
  89 +
  90 + }
  91 +
  92 +
  93 +}
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/spu/ProductSpuApi.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.api.spu;
  2 +
  3 +import cn.iocoder.yudao.module.product.api.sku.dto.SkuInfoRespDTO;
  4 +import cn.iocoder.yudao.module.product.api.spu.dto.SpuInfoRespDTO;
  5 +
  6 +import java.util.Collection;
  7 +import java.util.List;
  8 +
  9 +/**
  10 + * @author LeeYan9
  11 + * @since 2022-08-26
  12 + */
  13 +public interface ProductSpuApi {
  14 +
  15 +
  16 + /**
  17 + * 根据spuId列表 查询spu信息
  18 + *
  19 + * @param spuIds spu ID列表
  20 + * @return spu信息列表
  21 + */
  22 + List<SpuInfoRespDTO> getSpusByIds(Collection<Long> spuIds);
  23 +}
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/spu/dto/SpuInfoRespDTO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.api.spu.dto;
  2 +
  3 +import cn.iocoder.yudao.module.product.api.sku.dto.SkuInfoRespDTO;
  4 +import cn.iocoder.yudao.module.product.enums.spu.ProductSpuSpecTypeEnum;
  5 +import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum;
  6 +import lombok.Data;
  7 +
  8 +import java.util.List;
  9 +
  10 +/**
  11 + * @author LeeYan9
  12 + * @since 2022-08-26
  13 + */
  14 +@Data
  15 +public class SpuInfoRespDTO {
  16 +
  17 + /**
  18 + * 商品 SPU 编号,自增
  19 + */
  20 + private Long id;
  21 +
  22 + // ========== 基本信息 =========
  23 +
  24 + /**
  25 + * 商品名称
  26 + */
  27 + private String name;
  28 + /**
  29 + * 商品编码
  30 + */
  31 + private String code;
  32 + /**
  33 + * 商品卖点
  34 + */
  35 + private String sellPoint;
  36 + /**
  37 + * 商品详情
  38 + */
  39 + private String description;
  40 + /**
  41 + * 商品分类编号
  42 + */
  43 + private Long categoryId;
  44 + /**
  45 + * 商品品牌编号
  46 + */
  47 + private Long brandId;
  48 + /**
  49 + * 商品图片的数组
  50 + * <p>
  51 + * 1. 第一张图片将作为商品主图,支持同时上传多张图;
  52 + * 2. 建议使用尺寸 800x800 像素以上、大小不超过 1M 的正方形图片;
  53 + * 3. 至少 1 张,最多上传 10 张
  54 + */
  55 + private List<String> picUrls;
  56 + /**
  57 + * 商品视频
  58 + */
  59 + private String videoUrl;
  60 +
  61 + /**
  62 + * 排序字段
  63 + */
  64 + private Integer sort;
  65 + /**
  66 + * 商品状态
  67 + * <p>
  68 + * 枚举 {@link ProductSpuStatusEnum}
  69 + */
  70 + private Integer status;
  71 +
  72 + // ========== SKU 相关字段 =========
  73 +
  74 + /**
  75 + * 规格类型
  76 + * <p>
  77 + * 枚举 {@link ProductSpuSpecTypeEnum}
  78 + */
  79 + private Integer specType;
  80 + /**
  81 + * 最小价格,单位使用:分
  82 + * <p>
  83 + * 基于其对应的 {@link SkuInfoRespDTO#getPrice()} 最小值
  84 + */
  85 + private Integer minPrice;
  86 + /**
  87 + * 最大价格,单位使用:分
  88 + * <p>
  89 + * 基于其对应的 {@link SkuInfoRespDTO#getPrice()} 最大值
  90 + */
  91 + private Integer maxPrice;
  92 + /**
  93 + * 市场价,单位使用:分
  94 + * <p>
  95 + * 基于其对应的 {@link SkuInfoRespDTO#getMarketPrice()} 最大值
  96 + */
  97 + private Integer marketPrice;
  98 + /**
  99 + * 总库存
  100 + * <p>
  101 + * 基于其对应的 {@link SkuInfoRespDTO#getStock()} 求和
  102 + */
  103 + private Integer totalStock;
  104 + /**
  105 + * 是否展示库存
  106 + */
  107 + private Boolean showStock;
  108 +
  109 + // ========== 统计相关字段 =========
  110 +
  111 + /**
  112 + * 商品销量
  113 + */
  114 + private Integer salesCount;
  115 + /**
  116 + * 虚拟销量
  117 + */
  118 + private Integer virtualSalesCount;
  119 + /**
  120 + * 商品点击量
  121 + */
  122 + private Integer clickCount;
  123 +
  124 +}
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java
@@ -3,30 +3,38 @@ package cn.iocoder.yudao.module.product.enums; @@ -3,30 +3,38 @@ package cn.iocoder.yudao.module.product.enums;
3 import cn.iocoder.yudao.framework.common.exception.ErrorCode; 3 import cn.iocoder.yudao.framework.common.exception.ErrorCode;
4 4
5 /** 5 /**
6 - * product 错误码枚举类  
7 - * <p> 6 + * Product 错误码枚举类
  7 + *
8 * product 系统,使用 1-008-000-000 段 8 * product 系统,使用 1-008-000-000 段
9 */ 9 */
10 public interface ErrorCodeConstants { 10 public interface ErrorCodeConstants {
11 11
12 - // ========== 商品分类相关 1008001000============ 12 + // ========== 商品分类相关 1008001000 ============
13 ErrorCode CATEGORY_NOT_EXISTS = new ErrorCode(1008001000, "商品分类不存在"); 13 ErrorCode CATEGORY_NOT_EXISTS = new ErrorCode(1008001000, "商品分类不存在");
14 ErrorCode CATEGORY_PARENT_NOT_EXISTS = new ErrorCode(1008001001, "父分类不存在"); 14 ErrorCode CATEGORY_PARENT_NOT_EXISTS = new ErrorCode(1008001001, "父分类不存在");
15 - ErrorCode CATEGORY_EXISTS_CHILDREN = new ErrorCode(1008001002, "存在子分类,无法删除"); 15 + ErrorCode CATEGORY_PARENT_NOT_FIRST_LEVEL = new ErrorCode(1008001002, "父分类不能是二级分类");
  16 + ErrorCode CATEGORY_EXISTS_CHILDREN = new ErrorCode(1008001003, "存在子分类,无法删除");
  17 + ErrorCode CATEGORY_DISABLED = new ErrorCode(1008001004, "商品分类({})已禁用,无法使用");
  18 + ErrorCode CATEGORY_LEVEL_ERROR = new ErrorCode(1008001005, "商品分类不正确,原因:必须使用第三级的商品分类下");
16 19
17 - // ========== 品牌相关编号 1008002000 ========== 20 + // ========== 商品品牌相关编号 1008002000 ==========
18 ErrorCode BRAND_NOT_EXISTS = new ErrorCode(1008002000, "品牌不存在"); 21 ErrorCode BRAND_NOT_EXISTS = new ErrorCode(1008002000, "品牌不存在");
  22 + ErrorCode BRAND_DISABLED = new ErrorCode(1008002001, "品牌不存在");
  23 + ErrorCode BRAND_NAME_EXISTS = new ErrorCode(1008002002, "品牌名称已存在");
19 24
20 - // ========== 规格名称 1008003000 ========== 25 + // ========== 商品规格名称 1008003000 ==========
21 ErrorCode PROPERTY_NOT_EXISTS = new ErrorCode(1008003000, "规格名称不存在"); 26 ErrorCode PROPERTY_NOT_EXISTS = new ErrorCode(1008003000, "规格名称不存在");
22 27
23 // ========== 规格值 1008004000 ========== 28 // ========== 规格值 1008004000 ==========
24 ErrorCode PROPERTY_VALUE_NOT_EXISTS = new ErrorCode(1008004000, "规格值不存在"); 29 ErrorCode PROPERTY_VALUE_NOT_EXISTS = new ErrorCode(1008004000, "规格值不存在");
25 30
26 - // ========== 商品spu 1008005000 ==========  
27 - ErrorCode SPU_NOT_EXISTS = new ErrorCode(1008005000, "商品spu不存在"); 31 + // ========== 商品 SPU 1008005000 ==========
  32 + ErrorCode SPU_NOT_EXISTS = new ErrorCode(1008005000, "商品 SPU 不存在");
  33 +
  34 + // ========== 商品 SKU 1008006000 ==========
  35 + ErrorCode SKU_NOT_EXISTS = new ErrorCode(1008006000, "商品 SKU 不存在");
  36 + ErrorCode SKU_PROPERTIES_DUPLICATED = new ErrorCode(1008006001, "商品 SKU 的属性组合存在重复");
  37 + ErrorCode SPU_ATTR_NUMBERS_MUST_BE_EQUALS = new ErrorCode(1008006002, "一个 SPU 下的每个 SKU,其规格数必须一致");
  38 + ErrorCode SPU_SKU_NOT_DUPLICATE = new ErrorCode(1008006003, "一个 SPU 下的每个 SKU,必须不重复");
28 39
29 - // ========== 商品sku 1008006000 ==========  
30 - ErrorCode SKU_NOT_EXISTS = new ErrorCode(1008006000, "商品sku不存在");  
31 - ErrorCode SKU_PROPERTIES_DUPLICATED = new ErrorCode(1008006001, "商品sku的属性组合存在重复");  
32 } 40 }
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/comment/ProductCommentAuditStatusEnum.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.enums.comment;
  2 +
  3 +import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
  4 +import lombok.AllArgsConstructor;
  5 +import lombok.Getter;
  6 +
  7 +import java.util.Arrays;
  8 +
  9 +/**
  10 + * 商品评论的审批状态枚举
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +@Getter
  15 +@AllArgsConstructor
  16 +public enum ProductCommentAuditStatusEnum implements IntArrayValuable {
  17 +
  18 + NONE(1, "待审核"),
  19 + APPROVE(2, "审批通过"),
  20 + REJECT(2, "审批不通过"),;
  21 +
  22 + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ProductCommentAuditStatusEnum::getStatus).toArray();
  23 +
  24 + /**
  25 + * 审批状态
  26 + */
  27 + private final Integer status;
  28 + /**
  29 + * 状态名
  30 + */
  31 + private final String name;
  32 +
  33 + @Override
  34 + public int[] array() {
  35 + return ARRAYS;
  36 + }
  37 +
  38 +}
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/delivery/DeliveryTypeEnum.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.enums.delivery;
  2 +
  3 +import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
  4 +import lombok.AllArgsConstructor;
  5 +import lombok.Getter;
  6 +
  7 +import java.util.Arrays;
  8 +
  9 +/**
  10 + * 配送方式枚举
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +@Getter
  15 +@AllArgsConstructor
  16 +public enum DeliveryTypeEnum implements IntArrayValuable {
  17 +
  18 + // TODO 芋艿:英文单词,需要再想下;
  19 + EXPRESS(1, "快递发货"),
  20 + USER(2, "用户自提"),;
  21 +
  22 + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(DeliveryTypeEnum::getMode).toArray();
  23 +
  24 + /**
  25 + * 配送方式
  26 + */
  27 + private final Integer mode;
  28 + /**
  29 + * 状态名
  30 + */
  31 + private final String name;
  32 +
  33 + @Override
  34 + public int[] array() {
  35 + return ARRAYS;
  36 + }
  37 +
  38 +}
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/group/ProductGroupStyleEnum.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.enums.group;
  2 +
  3 +import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
  4 +import lombok.AllArgsConstructor;
  5 +import lombok.Getter;
  6 +
  7 +import java.util.Arrays;
  8 +
  9 +/**
  10 + * 商品分组的样式枚举
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +@Getter
  15 +@AllArgsConstructor
  16 +public enum ProductGroupStyleEnum implements IntArrayValuable {
  17 +
  18 + ONE(1, "每列一个"),
  19 + TWO(2, "每列两个"),
  20 + THREE(2, "每列三个"),;
  21 +
  22 + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ProductGroupStyleEnum::getStyle).toArray();
  23 +
  24 + /**
  25 + * 列表样式
  26 + */
  27 + private final Integer style;
  28 + /**
  29 + * 状态名
  30 + */
  31 + private final String name;
  32 +
  33 + @Override
  34 + public int[] array() {
  35 + return ARRAYS;
  36 + }
  37 +
  38 +}
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductSpuSpecTypeEnum.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.enums.spu;
  2 +
  3 +import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
  4 +import lombok.AllArgsConstructor;
  5 +import lombok.Getter;
  6 +
  7 +import java.util.Arrays;
  8 +
  9 +/**
  10 + * 商品 SPU 规格类型
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +@Getter
  15 +@AllArgsConstructor
  16 +public enum ProductSpuSpecTypeEnum implements IntArrayValuable {
  17 +
  18 + RECYCLE(1, "统一规格"),
  19 + DISABLE(2, "多规格");
  20 +
  21 + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ProductSpuSpecTypeEnum::getType).toArray();
  22 +
  23 + /**
  24 + * 规格
  25 + */
  26 + private final Integer type;
  27 + /**
  28 + * 规格名
  29 + */
  30 + private final String name;
  31 +
  32 + @Override
  33 + public int[] array() {
  34 + return ARRAYS;
  35 + }
  36 +
  37 +}
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/spu/ProductSpuStatusEnum.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.enums.spu;
  2 +
  3 +import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
  4 +import lombok.AllArgsConstructor;
  5 +import lombok.Getter;
  6 +
  7 +import java.util.Arrays;
  8 +
  9 +/**
  10 + * 商品 SPU 状态
  11 + *
  12 + * @author 芋道源码
  13 + */
  14 +@Getter
  15 +@AllArgsConstructor
  16 +public enum ProductSpuStatusEnum implements IntArrayValuable {
  17 +
  18 + RECYCLE(-1, "回收站"),
  19 + DISABLE(0, "下架"),
  20 + ENABLE(1, "上架"),;
  21 +
  22 + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ProductSpuStatusEnum::getStyle).toArray();
  23 +
  24 + /**
  25 + * 状态
  26 + */
  27 + private final Integer style;
  28 + /**
  29 + * 状态名
  30 + */
  31 + private final String name;
  32 +
  33 + @Override
  34 + public int[] array() {
  35 + return ARRAYS;
  36 + }
  37 +
  38 +}
yudao-module-mall/yudao-module-product-biz/pom.xml
@@ -2,13 +2,12 @@ @@ -2,13 +2,12 @@
2 <project xmlns="http://maven.apache.org/POM/4.0.0" 2 <project xmlns="http://maven.apache.org/POM/4.0.0"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5 - <modelVersion>4.0.0</modelVersion>  
6 <parent> 5 <parent>
7 <groupId>cn.iocoder.boot</groupId> 6 <groupId>cn.iocoder.boot</groupId>
8 <artifactId>yudao-module-mall</artifactId> 7 <artifactId>yudao-module-mall</artifactId>
9 <version>${revision}</version> 8 <version>${revision}</version>
10 </parent> 9 </parent>
11 - 10 + <modelVersion>4.0.0</modelVersion>
12 <artifactId>yudao-module-product-biz</artifactId> 11 <artifactId>yudao-module-product-biz</artifactId>
13 <packaging>jar</packaging> 12 <packaging>jar</packaging>
14 13
@@ -18,7 +17,6 @@ @@ -18,7 +17,6 @@
18 例如:品牌、商品分类、spu、sku等功能。 17 例如:品牌、商品分类、spu、sku等功能。
19 </description> 18 </description>
20 19
21 -  
22 <dependencies> 20 <dependencies>
23 <dependency> 21 <dependency>
24 <groupId>cn.iocoder.boot</groupId> 22 <groupId>cn.iocoder.boot</groupId>
@@ -33,10 +31,6 @@ @@ -33,10 +31,6 @@
33 </dependency> 31 </dependency>
34 <dependency> 32 <dependency>
35 <groupId>cn.iocoder.boot</groupId> 33 <groupId>cn.iocoder.boot</groupId>
36 - <artifactId>yudao-spring-boot-starter-biz-weixin</artifactId>  
37 - </dependency>  
38 - <dependency>  
39 - <groupId>cn.iocoder.boot</groupId>  
40 <artifactId>yudao-spring-boot-starter-biz-tenant</artifactId> 34 <artifactId>yudao-spring-boot-starter-biz-tenant</artifactId>
41 </dependency> 35 </dependency>
42 36
@@ -64,4 +58,4 @@ @@ -64,4 +58,4 @@
64 58
65 </dependencies> 59 </dependencies>
66 60
67 -</project>  
68 \ No newline at end of file 61 \ No newline at end of file
  62 +</project>
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/package-info.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.api;
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/sku/ProductSkuApiImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.api.sku;
  2 +
  3 +import cn.iocoder.yudao.module.product.api.sku.dto.SkuDecrementStockBatchReqDTO;
  4 +import cn.iocoder.yudao.module.product.api.sku.dto.SkuInfoRespDTO;
  5 +import org.springframework.stereotype.Service;
  6 +
  7 +import java.util.Collection;
  8 +import java.util.List;
  9 +
  10 +/**
  11 + * todo 注释
  12 + */
  13 +@Service
  14 +public class ProductSkuApiImpl implements ProductSkuApi {
  15 +
  16 + @Override
  17 + public List<SkuInfoRespDTO> getSkusByIds(Collection<Long> skuIds) {
  18 + return null;
  19 + }
  20 +
  21 + @Override
  22 + public void decrementStockBatch(SkuDecrementStockBatchReqDTO batchReqDTO) {
  23 +
  24 + }
  25 +
  26 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/spu/ProductSpuApiImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.api.spu;
  2 +
  3 +import cn.iocoder.yudao.module.product.api.spu.dto.SpuInfoRespDTO;
  4 +import org.springframework.stereotype.Service;
  5 +
  6 +import java.util.Collection;
  7 +import java.util.List;
  8 +
  9 +/**
  10 + * todo 注释
  11 + */
  12 +@Service
  13 +public class ProductSpuApiImpl implements ProductSpuApi {
  14 +
  15 + @Override
  16 + public List<SpuInfoRespDTO> getSpusByIds(Collection<Long> spuIds) {
  17 + return null;
  18 + }
  19 +
  20 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/BrandController.java renamed to yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/ProductBrandController.java
@@ -2,12 +2,10 @@ package cn.iocoder.yudao.module.product.controller.admin.brand; @@ -2,12 +2,10 @@ package cn.iocoder.yudao.module.product.controller.admin.brand;
2 2
3 import cn.iocoder.yudao.framework.common.pojo.CommonResult; 3 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4 import cn.iocoder.yudao.framework.common.pojo.PageResult; 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 -import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;  
6 -import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;  
7 import cn.iocoder.yudao.module.product.controller.admin.brand.vo.*; 5 import cn.iocoder.yudao.module.product.controller.admin.brand.vo.*;
8 -import cn.iocoder.yudao.module.product.convert.brand.BrandConvert;  
9 -import cn.iocoder.yudao.module.product.dal.dataobject.brand.BrandDO;  
10 -import cn.iocoder.yudao.module.product.service.brand.BrandService; 6 +import cn.iocoder.yudao.module.product.convert.brand.ProductBrandConvert;
  7 +import cn.iocoder.yudao.module.product.dal.dataobject.brand.ProductBrandDO;
  8 +import cn.iocoder.yudao.module.product.service.brand.ProductBrandService;
11 import io.swagger.annotations.Api; 9 import io.swagger.annotations.Api;
12 import io.swagger.annotations.ApiImplicitParam; 10 import io.swagger.annotations.ApiImplicitParam;
13 import io.swagger.annotations.ApiOperation; 11 import io.swagger.annotations.ApiOperation;
@@ -16,34 +14,32 @@ import org.springframework.validation.annotation.Validated; @@ -16,34 +14,32 @@ import org.springframework.validation.annotation.Validated;
16 import org.springframework.web.bind.annotation.*; 14 import org.springframework.web.bind.annotation.*;
17 15
18 import javax.annotation.Resource; 16 import javax.annotation.Resource;
19 -import javax.servlet.http.HttpServletResponse;  
20 import javax.validation.Valid; 17 import javax.validation.Valid;
21 -import java.io.IOException; 18 +import java.util.Comparator;
22 import java.util.List; 19 import java.util.List;
23 20
24 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; 21 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
25 -import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;  
26 22
27 -@Api(tags = "管理后台 - 品牌") 23 +@Api(tags = "管理后台 - 商品品牌")
28 @RestController 24 @RestController
29 @RequestMapping("/product/brand") 25 @RequestMapping("/product/brand")
30 @Validated 26 @Validated
31 -public class BrandController { 27 +public class ProductBrandController {
32 28
33 @Resource 29 @Resource
34 - private BrandService brandService; 30 + private ProductBrandService brandService;
35 31
36 @PostMapping("/create") 32 @PostMapping("/create")
37 @ApiOperation("创建品牌") 33 @ApiOperation("创建品牌")
38 @PreAuthorize("@ss.hasPermission('product:brand:create')") 34 @PreAuthorize("@ss.hasPermission('product:brand:create')")
39 - public CommonResult<Long> createBrand(@Valid @RequestBody BrandCreateReqVO createReqVO) { 35 + public CommonResult<Long> createBrand(@Valid @RequestBody ProductBrandCreateReqVO createReqVO) {
40 return success(brandService.createBrand(createReqVO)); 36 return success(brandService.createBrand(createReqVO));
41 } 37 }
42 38
43 @PutMapping("/update") 39 @PutMapping("/update")
44 @ApiOperation("更新品牌") 40 @ApiOperation("更新品牌")
45 @PreAuthorize("@ss.hasPermission('product:brand:update')") 41 @PreAuthorize("@ss.hasPermission('product:brand:update')")
46 - public CommonResult<Boolean> updateBrand(@Valid @RequestBody BrandUpdateReqVO updateReqVO) { 42 + public CommonResult<Boolean> updateBrand(@Valid @RequestBody ProductBrandUpdateReqVO updateReqVO) {
47 brandService.updateBrand(updateReqVO); 43 brandService.updateBrand(updateReqVO);
48 return success(true); 44 return success(true);
49 } 45 }
@@ -61,29 +57,26 @@ public class BrandController { @@ -61,29 +57,26 @@ public class BrandController {
61 @ApiOperation("获得品牌") 57 @ApiOperation("获得品牌")
62 @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class) 58 @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
63 @PreAuthorize("@ss.hasPermission('product:brand:query')") 59 @PreAuthorize("@ss.hasPermission('product:brand:query')")
64 - public CommonResult<BrandRespVO> getBrand(@RequestParam("id") Long id) {  
65 - BrandDO brand = brandService.getBrand(id);  
66 - return success(BrandConvert.INSTANCE.convert(brand)); 60 + public CommonResult<ProductBrandRespVO> getBrand(@RequestParam("id") Long id) {
  61 + ProductBrandDO brand = brandService.getBrand(id);
  62 + return success(ProductBrandConvert.INSTANCE.convert(brand));
67 } 63 }
68 64
69 @GetMapping("/page") 65 @GetMapping("/page")
70 @ApiOperation("获得品牌分页") 66 @ApiOperation("获得品牌分页")
71 @PreAuthorize("@ss.hasPermission('product:brand:query')") 67 @PreAuthorize("@ss.hasPermission('product:brand:query')")
72 - public CommonResult<PageResult<BrandRespVO>> getBrandPage(@Valid BrandPageReqVO pageVO) {  
73 - PageResult<BrandDO> pageResult = brandService.getBrandPage(pageVO);  
74 - return success(BrandConvert.INSTANCE.convertPage(pageResult)); 68 + public CommonResult<PageResult<ProductBrandRespVO>> getBrandPage(@Valid ProductBrandPageReqVO pageVO) {
  69 + PageResult<ProductBrandDO> pageResult = brandService.getBrandPage(pageVO);
  70 + return success(ProductBrandConvert.INSTANCE.convertPage(pageResult));
75 } 71 }
76 72
77 - @GetMapping("/export-excel")  
78 - @ApiOperation("导出品牌 Excel")  
79 - @PreAuthorize("@ss.hasPermission('product:brand:export')")  
80 - @OperateLog(type = EXPORT)  
81 - public void exportBrandExcel(@Valid BrandExportReqVO exportReqVO,  
82 - HttpServletResponse response) throws IOException {  
83 - List<BrandDO> list = brandService.getBrandList(exportReqVO);  
84 - // 导出 Excel  
85 - List<BrandExcelVO> datas = BrandConvert.INSTANCE.convertList02(list);  
86 - ExcelUtils.write(response, "品牌.xls", "数据", BrandExcelVO.class, datas); 73 + @GetMapping("/list")
  74 + @ApiOperation("获得品牌列表")
  75 + @PreAuthorize("@ss.hasPermission('product:brand:query')")
  76 + public CommonResult<List<ProductBrandRespVO>> getBrandList(@Valid ProductBrandListReqVO listVO) {
  77 + List<ProductBrandDO> list = brandService.getBrandList(listVO);
  78 + list.sort(Comparator.comparing(ProductBrandDO::getSort));
  79 + return success(ProductBrandConvert.INSTANCE.convertList(list));
87 } 80 }
88 81
89 } 82 }
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/BrandExcelVO.java deleted
1 -package cn.iocoder.yudao.module.product.controller.admin.brand.vo;  
2 -  
3 -import lombok.*;  
4 -import java.util.*;  
5 -import io.swagger.annotations.*;  
6 -  
7 -import com.alibaba.excel.annotation.ExcelProperty;  
8 -import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;  
9 -import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;  
10 -  
11 -  
12 -/**  
13 - * 品牌 Excel VO  
14 - *  
15 - * @author 芋道源码  
16 - */  
17 -@Data  
18 -public class BrandExcelVO {  
19 -  
20 - @ExcelProperty("品牌编号")  
21 - private Long id;  
22 -  
23 - @ExcelProperty("分类编号")  
24 - private Long categoryId;  
25 -  
26 - @ExcelProperty("品牌名称")  
27 - private String name;  
28 -  
29 - @ExcelProperty("品牌图片")  
30 - private String bannerUrl;  
31 -  
32 - @ExcelProperty("品牌排序")  
33 - private Integer sort;  
34 -  
35 - @ExcelProperty("品牌描述")  
36 - private String description;  
37 -  
38 - @ExcelProperty(value = "状态", converter = DictConvert.class)  
39 - @DictFormat("common_status") // TODO 代码优化:建议设置到对应的 XXXDictTypeConstants 枚举类中  
40 - private Integer status;  
41 -  
42 - @ExcelProperty("创建时间")  
43 - private Date createTime;  
44 -  
45 -}  
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/BrandExportReqVO.java deleted
1 -package cn.iocoder.yudao.module.product.controller.admin.brand.vo;  
2 -  
3 -import lombok.*;  
4 -import java.util.*;  
5 -import io.swagger.annotations.*;  
6 -import cn.iocoder.yudao.framework.common.pojo.PageParam;  
7 -import org.springframework.format.annotation.DateTimeFormat;  
8 -  
9 -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;  
10 -  
11 -@ApiModel(value = "管理后台 - 品牌 Excel 导出 Request VO", description = "参数和 BrandPageReqVO 是一致的")  
12 -@Data  
13 -public class BrandExportReqVO {  
14 -  
15 - @ApiModelProperty(value = "分类编号", example = "1")  
16 - private Long categoryId;  
17 -  
18 - @ApiModelProperty(value = "品牌名称", example = "芋道")  
19 - private String name;  
20 -  
21 - @ApiModelProperty(value = "状态", example = "0")  
22 - private Integer status;  
23 -  
24 - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)  
25 - @ApiModelProperty(value = "创建时间")  
26 - private Date[] createTime;  
27 -  
28 -}  
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/BrandPageReqVO.java deleted
1 -package cn.iocoder.yudao.module.product.controller.admin.brand.vo;  
2 -  
3 -import lombok.*;  
4 -import java.util.*;  
5 -import io.swagger.annotations.*;  
6 -import cn.iocoder.yudao.framework.common.pojo.PageParam;  
7 -import org.springframework.format.annotation.DateTimeFormat;  
8 -  
9 -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;  
10 -  
11 -@ApiModel("管理后台 - 品牌分页 Request VO")  
12 -@Data  
13 -@EqualsAndHashCode(callSuper = true)  
14 -@ToString(callSuper = true)  
15 -public class BrandPageReqVO extends PageParam {  
16 -  
17 - @ApiModelProperty(value = "分类编号", example = "1")  
18 - private Long categoryId;  
19 -  
20 - @ApiModelProperty(value = "品牌名称", example = "芋道")  
21 - private String name;  
22 -  
23 - @ApiModelProperty(value = "状态", example = "0")  
24 - private Integer status;  
25 -  
26 - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)  
27 - @ApiModelProperty(value = "创建时间")  
28 - private Date[] createTime;  
29 -  
30 -}  
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/BrandBaseVO.java renamed to yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandBaseVO.java
1 package cn.iocoder.yudao.module.product.controller.admin.brand.vo; 1 package cn.iocoder.yudao.module.product.controller.admin.brand.vo;
2 2
3 -import lombok.*;  
4 -import java.util.*;  
5 -import io.swagger.annotations.*;  
6 -import javax.validation.constraints.*; 3 +import io.swagger.annotations.ApiModelProperty;
  4 +import lombok.Data;
  5 +
  6 +import javax.validation.constraints.NotNull;
7 7
8 /** 8 /**
9 -* 品牌 Base VO,提供给添加、修改、详细的子 VO 使用 9 +* 商品品牌 Base VO,提供给添加、修改、详细的子 VO 使用
10 * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 10 * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
11 */ 11 */
12 @Data 12 @Data
13 -public class BrandBaseVO {  
14 -  
15 - @ApiModelProperty(value = "分类编号", required = true, example = "1")  
16 - @NotNull(message = "分类编号不能为空")  
17 - private Long categoryId; 13 +public class ProductBrandBaseVO {
18 14
19 @ApiModelProperty(value = "品牌名称", required = true, example = "芋道") 15 @ApiModelProperty(value = "品牌名称", required = true, example = "芋道")
20 @NotNull(message = "品牌名称不能为空") 16 @NotNull(message = "品牌名称不能为空")
@@ -22,9 +18,10 @@ public class BrandBaseVO { @@ -22,9 +18,10 @@ public class BrandBaseVO {
22 18
23 @ApiModelProperty(value = "品牌图片", required = true) 19 @ApiModelProperty(value = "品牌图片", required = true)
24 @NotNull(message = "品牌图片不能为空") 20 @NotNull(message = "品牌图片不能为空")
25 - private String bannerUrl; 21 + private String picUrl;
26 22
27 - @ApiModelProperty(value = "品牌排序", example = "1") 23 + @ApiModelProperty(value = "品牌排序", required = true, example = "1")
  24 + @NotNull(message = "品牌排序不能为空")
28 private Integer sort; 25 private Integer sort;
29 26
30 @ApiModelProperty(value = "品牌描述", example = "描述") 27 @ApiModelProperty(value = "品牌描述", example = "描述")
yudao-module-mall/yudao-module-market-biz/src/main/java/cn/iocoder/yudao/module/market/controller/admin/activity/vo/ActivityCreateReqVO.java renamed to yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandCreateReqVO.java
1 -package cn.iocoder.yudao.module.market.controller.admin.activity.vo; 1 +package cn.iocoder.yudao.module.product.controller.admin.brand.vo;
2 2
3 import lombok.*; 3 import lombok.*;
4 -import java.util.*;  
5 import io.swagger.annotations.*; 4 import io.swagger.annotations.*;
6 -import javax.validation.constraints.*;  
7 5
8 -/**  
9 - * @author xia  
10 - */  
11 -@ApiModel("管理后台 - 促销活动创建 Request VO") 6 +@ApiModel("管理后台 - 商品品牌创建 Request VO")
12 @Data 7 @Data
13 @EqualsAndHashCode(callSuper = true) 8 @EqualsAndHashCode(callSuper = true)
14 @ToString(callSuper = true) 9 @ToString(callSuper = true)
15 -public class ActivityCreateReqVO extends ActivityBaseVO { 10 +public class ProductBrandCreateReqVO extends ProductBrandBaseVO {
16 11
17 } 12 }
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandListReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.controller.admin.brand.vo;
  2 +
  3 +import io.swagger.annotations.ApiModel;
  4 +import io.swagger.annotations.ApiModelProperty;
  5 +import lombok.Data;
  6 +
  7 +@ApiModel(value = "管理后台 - 商品品牌分页 Request VO")
  8 +@Data
  9 +public class ProductBrandListReqVO {
  10 +
  11 + @ApiModelProperty(value = "品牌名称", example = "芋道")
  12 + private String name;
  13 +
  14 +}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/category/vo/CategoryPageReqVO.java renamed to yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandPageReqVO.java
1 -package cn.iocoder.yudao.module.product.controller.admin.category.vo; 1 +package cn.iocoder.yudao.module.product.controller.admin.brand.vo;
2 2
3 import cn.iocoder.yudao.framework.common.pojo.PageParam; 3 import cn.iocoder.yudao.framework.common.pojo.PageParam;
4 import io.swagger.annotations.ApiModel; 4 import io.swagger.annotations.ApiModel;
@@ -12,16 +12,16 @@ import java.util.Date; @@ -12,16 +12,16 @@ import java.util.Date;
12 12
13 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; 13 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
14 14
15 -@ApiModel("管理后台 - 商品分类分页 Request VO") 15 +@ApiModel("管理后台 - 商品品牌分页 Request VO")
16 @Data 16 @Data
17 @EqualsAndHashCode(callSuper = true) 17 @EqualsAndHashCode(callSuper = true)
18 @ToString(callSuper = true) 18 @ToString(callSuper = true)
19 -public class CategoryPageReqVO extends PageParam { 19 +public class ProductBrandPageReqVO extends PageParam {
20 20
21 - @ApiModelProperty(value = "分类名称", example = "办公文具") 21 + @ApiModelProperty(value = "品牌名称", example = "芋道")
22 private String name; 22 private String name;
23 23
24 - @ApiModelProperty(value = "开启状态", example = "0") 24 + @ApiModelProperty(value = "状态", example = "0", notes = "参考 CommonStatusEnum 枚举")
25 private Integer status; 25 private Integer status;
26 26
27 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) 27 @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/brand/vo/ProductBrandRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.product.controller.admin.brand.vo;
  2 +
  3 +import io.swagger.annotations.ApiModel;
  4 +import io.swagger.annotations.ApiModelProperty;
  5 +import lombok.Data;
  6 +import lombok.EqualsAndHashCode;
  7 +import lombok.ToString;
  8 +
  9 +import java.util.Date;
  10 +
  11 +@ApiModel("管理后台 - 品牌 Response VO")
  12 +@Data
  13 +@EqualsAndHashCode(callSuper = true)
  14 +@ToString(callSuper = true)
  15 +public class ProductBrandRespVO extends ProductBrandBaseVO {
  16 +
  17 + @ApiModelProperty(value = "品牌编号", required = true, example = "1")
  18 + private Long id;
  19 +
  20 + @ApiModelProperty(value = "创建时间", required = true)
  21 + private Date createTime;
  22 +
  23 +}