Commit 0657c357bf156552fba3fa6ee10cbaf91b3cbf6c

Authored by YunaiV
2 parents d8e49fa0 126dc610

Merge branch 'master' of https://gitee.com/zhijiantianya/ruoyi-vue-pro into feature/crm

Showing 390 changed files with 6912 additions and 3458 deletions

Too many changes.

To preserve performance only 100 of 390 files are displayed.

README.md
... ... @@ -256,7 +256,7 @@ _鍓嶇鍩轰簬 crmeb uniapp 缁忚繃鎺堟潈閲嶆瀯锛屼紭鍖栦唬鐮佸疄鐜帮紝鎺ュ叆鑺嬮
256 256  
257 257 | 妗嗘灦 | 璇存槑 | 鐗堟湰 | 瀛︿範鎸囧崡 |
258 258 |---------------------------------------------------------------------------------------------|------------------|----------------|----------------------------------------------------------------|
259   -| [Spring Boot](https://spring.io/projects/spring-boot) | 搴旂敤寮鍙戞鏋 | 2.7.16 | [鏂囨。](https://github.com/YunaiV/SpringBoot-Labs) |
  259 +| [Spring Boot](https://spring.io/projects/spring-boot) | 搴旂敤寮鍙戞鏋 | 2.7.17 | [鏂囨。](https://github.com/YunaiV/SpringBoot-Labs) |
260 260 | [MySQL](https://www.mysql.com/cn/) | 鏁版嵁搴撴湇鍔″櫒 | 5.7 / 8.0+ | |
261 261 | [Druid](https://github.com/alibaba/druid) | JDBC 杩炴帴姹犮佺洃鎺х粍浠 | 1.2.19 | [鏂囨。](http://www.iocoder.cn/Spring-Boot/datasource-pool/?yudao) |
262 262 | [MyBatis Plus](https://mp.baomidou.com/) | MyBatis 澧炲己宸ュ叿鍖 | 3.5.3.2 | [鏂囨。](http://www.iocoder.cn/Spring-Boot/MyBatis/?yudao) |
... ...
... ... @@ -13,17 +13,17 @@
13 13 <!-- Server 主项目 -->
14 14 <module>yudao-server</module>
15 15 <!-- 各种 module 拓展 -->
16   -<!-- <module>yudao-module-member</module>-->
17 16 <module>yudao-module-system</module>
18 17 <module>yudao-module-infra</module>
19   - <!-- <module>yudao-module-bpm</module>-->
  18 +<!-- <module>yudao-module-member</module>-->
  19 +<!-- <module>yudao-module-bpm</module>-->
20 20 <!-- <module>yudao-module-report</module>-->
21 21 <!-- <module>yudao-module-mp</module>-->
22 22 <!-- <module>yudao-module-pay</module>-->
23 23 <!-- <module>yudao-module-mall</module>-->
24 24 <module>yudao-module-crm</module>
25 25 <!-- 示例项目 -->
26   - <module>yudao-example</module>
  26 +<!-- <module>yudao-example</module>-->
27 27 </modules>
28 28  
29 29 <name>${project.artifactId}</name>
... ... @@ -31,7 +31,7 @@
31 31 <url>https://github.com/YunaiV/ruoyi-vue-pro</url>
32 32  
33 33 <properties>
34   - <revision>1.8.2-snapshot</revision>
  34 + <revision>1.8.3-snapshot</revision>
35 35 <!-- Maven 相关 -->
36 36 <java.version>1.8</java.version>
37 37 <maven.compiler.source>${java.version}</maven.compiler.source>
... ... @@ -41,7 +41,7 @@
41 41 <flatten-maven-plugin.version>1.5.0</flatten-maven-plugin.version>
42 42 <!-- 看看咋放到 bom 里 -->
43 43 <lombok.version>1.18.30</lombok.version>
44   - <spring.boot.version>2.7.16</spring.boot.version>
  44 + <spring.boot.version>2.7.17</spring.boot.version>
45 45 <mapstruct.version>1.5.5.Final</mapstruct.version>
46 46 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
47 47 </properties>
... ...
sql/mysql/pay_wallet.sql
... ... @@ -9,7 +9,7 @@ CREATE TABLE `pay_transfer`
9 9 `app_id` bigint NOT NULL COMMENT '应用编号',
10 10 `merchant_order_id` varchar(64) NOT NULL COMMENT '商户订单编号',
11 11 `price` int NOT NULL COMMENT '转账金额,单位:分',
12   - `title` varchar(512) NOT NULL COMMENT '转账标题',
  12 + `subject` varchar(512) NOT NULL COMMENT '转账标题',
13 13 `payee_info` varchar(512) NOT NULL COMMENT '收款人信息,不同类型和渠道不同',
14 14 `status` tinyint NOT NULL COMMENT '转账状态',
15 15 `success_time` datetime NULL COMMENT '转账成功时间',
... ... @@ -76,3 +76,130 @@ CREATE TABLE `pay_demo_transfer` (
76 76 ALTER TABLE `pay_channel`
77 77 MODIFY COLUMN `config` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '支付渠道配置' AFTER `app_id`;
78 78  
  79 +-- ----------------------------
  80 +-- 充值套餐表
  81 +-- ----------------------------
  82 +DROP TABLE IF EXISTS `pay_wallet_recharge_package`;
  83 +CREATE TABLE `pay_wallet_recharge_package`
  84 +(
  85 + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
  86 + `name` varchar(64) NOT NULL COMMENT '套餐名',
  87 + `pay_price` int NOT NULL COMMENT '支付金额',
  88 + `bonus_price` int NOT NULL COMMENT '赠送金额',
  89 + `status` tinyint NOT NULL COMMENT '状态',
  90 + `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin 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 +) ENGINE=InnoDB COMMENT='充值套餐表';
  98 +
  99 +-- ----------------------------
  100 +-- Table structure for pay_wallet_recharge
  101 +-- ----------------------------
  102 +DROP TABLE IF EXISTS `pay_wallet_recharge`;
  103 +CREATE TABLE `pay_wallet_recharge` (
  104 + `id` bigint(0) NOT NULL AUTO_INCREMENT COMMENT '编号',
  105 + `wallet_id` bigint(0) NOT NULL COMMENT '会员钱包 id',
  106 + `total_price` int(0) NOT NULL COMMENT '用户实际到账余额,例如充 100 送 20,则该值是 120',
  107 + `pay_price` int(0) NOT NULL COMMENT '实际支付金额',
  108 + `bonus_price` int(0) NOT NULL COMMENT '钱包赠送金额',
  109 + `package_id` bigint(0) DEFAULT NULL COMMENT '充值套餐编号',
  110 + `pay_status` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否已支付:[0:未支付 1:已经支付过]',
  111 + `pay_order_id` bigint(0) DEFAULT NULL COMMENT '支付订单编号',
  112 + `pay_channel_code` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '支付成功的支付渠道',
  113 + `pay_time` datetime(0) DEFAULT NULL COMMENT '订单支付时间',
  114 + `pay_refund_id` bigint(0) DEFAULT NULL COMMENT '支付退款单编号',
  115 + `refund_total_price` int(0) NOT NULL DEFAULT 0 COMMENT '退款金额,包含赠送金额',
  116 + `refund_pay_price` int(0) NOT NULL DEFAULT 0 COMMENT '退款支付金额',
  117 + `refund_bonus_price` int(0) NOT NULL DEFAULT 0 COMMENT '退款钱包赠送金额',
  118 + `refund_time` datetime(0) DEFAULT NULL COMMENT '退款时间',
  119 + `refund_status` int(0) NOT NULL DEFAULT 0 COMMENT '退款状态',
  120 + `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '创建者',
  121 + `create_time` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  122 + `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '更新者',
  123 + `update_time` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '更新时间',
  124 + `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
  125 + `tenant_id` bigint(0) NOT NULL DEFAULT 0 COMMENT '租户编号',
  126 + PRIMARY KEY (`id`) USING BTREE
  127 +) ENGINE = InnoDB AUTO_INCREMENT = 9 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '会员钱包充值' ROW_FORMAT = Dynamic;
  128 +
  129 +-- 钱包充值套餐,钱包余额菜单脚本
  130 +
  131 +INSERT INTO system_menu(
  132 + name, permission, type, sort, parent_id,
  133 + path, icon, component, status, component_name
  134 +)
  135 +VALUES (
  136 + '钱包管理', '', 1, 5, 1117,
  137 + 'wallet', 'ep:caret-right', '', 0, ''
  138 + );
  139 +SELECT @parentId1 := LAST_INSERT_ID();
  140 +
  141 +INSERT INTO system_menu(
  142 + name, permission, type, sort, parent_id,
  143 + path, icon, component, status, component_name
  144 +)
  145 +VALUES (
  146 + '充值套餐', '', 2, 2, @parentId1,
  147 + 'wallet-recharge-package', 'fa:leaf', 'pay/wallet/rechargePackage/index', 0, 'WalletRechargePackage'
  148 + );
  149 +SELECT @parentId := LAST_INSERT_ID();
  150 +
  151 +-- 按钮 SQL
  152 +INSERT INTO system_menu(
  153 + name, permission, type, sort, parent_id,
  154 + path, icon, component, status
  155 +)
  156 +VALUES (
  157 + '钱包充值套餐查询', 'pay:wallet-recharge-package:query', 3, 1, @parentId,
  158 + '', '', '', 0
  159 + );
  160 +INSERT INTO system_menu(
  161 + name, permission, type, sort, parent_id,
  162 + path, icon, component, status
  163 +)
  164 +VALUES (
  165 + '钱包充值套餐创建', 'pay:wallet-recharge-package:create', 3, 2, @parentId,
  166 + '', '', '', 0
  167 + );
  168 +INSERT INTO system_menu(
  169 + name, permission, type, sort, parent_id,
  170 + path, icon, component, status
  171 +)
  172 +VALUES (
  173 + '钱包充值套餐更新', 'pay:wallet-recharge-package:update', 3, 3, @parentId,
  174 + '', '', '', 0
  175 + );
  176 +INSERT INTO system_menu(
  177 + name, permission, type, sort, parent_id,
  178 + path, icon, component, status
  179 +)
  180 +VALUES (
  181 + '钱包充值套餐删除', 'pay:wallet-recharge-package:delete', 3, 4, @parentId,
  182 + '', '', '', 0
  183 + );
  184 +
  185 +INSERT INTO system_menu(
  186 + name, permission, type, sort, parent_id,
  187 + path, icon, component, status, component_name
  188 +)
  189 +VALUES (
  190 + '钱包余额', '', 2, 1, @parentId1,
  191 + 'wallet-balance', 'fa:leaf', 'pay/wallet/balance/index', 0, 'WalletBalance'
  192 + );
  193 +
  194 +SELECT @parentId := LAST_INSERT_ID();
  195 +
  196 +-- 按钮 SQL
  197 +INSERT INTO system_menu(
  198 + name, permission, type, sort, parent_id,
  199 + path, icon, component, status
  200 +)
  201 +VALUES (
  202 + '钱包余额查询', 'pay:wallet:query', 3, 1, @parentId,
  203 + '', '', '', 0
  204 + );
  205 +
... ...
sql/mysql/ruoyi-vue-pro.sql
... ... @@ -11,7 +11,7 @@
11 11 Target Server Version : 80034
12 12 File Encoding : 65001
13 13  
14   - Date: 05/10/2023 12:42:16
  14 + Date: 24/10/2023 20:48:38
15 15 */
16 16  
17 17 SET NAMES utf8mb4;
... ... @@ -384,7 +384,7 @@ CREATE TABLE `infra_api_error_log` (
384 384 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
385 385 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
386 386 PRIMARY KEY (`id`) USING BTREE
387   -) ENGINE = InnoDB AUTO_INCREMENT = 1662 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '系统异常日志';
  387 +) ENGINE = InnoDB AUTO_INCREMENT = 1745 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '系统异常日志';
388 388  
389 389 -- ----------------------------
390 390 -- Records of infra_api_error_log
... ... @@ -422,7 +422,7 @@ CREATE TABLE `infra_codegen_column` (
422 422 `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
423 423 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
424 424 PRIMARY KEY (`id`) USING BTREE
425   -) ENGINE = InnoDB AUTO_INCREMENT = 1778 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '代码生成表字段定义';
  425 +) ENGINE = InnoDB AUTO_INCREMENT = 1805 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '代码生成表字段定义';
426 426  
427 427 -- ----------------------------
428 428 -- Records of infra_codegen_column
... ... @@ -455,7 +455,7 @@ CREATE TABLE `infra_codegen_table` (
455 455 `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
456 456 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
457 457 PRIMARY KEY (`id`) USING BTREE
458   -) ENGINE = InnoDB AUTO_INCREMENT = 135 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '代码生成表定义';
  458 +) ENGINE = InnoDB AUTO_INCREMENT = 137 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '代码生成表定义';
459 459  
460 460 -- ----------------------------
461 461 -- Records of infra_codegen_table
... ... @@ -538,7 +538,7 @@ CREATE TABLE `infra_file` (
538 538 `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
539 539 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
540 540 PRIMARY KEY (`id`) USING BTREE
541   -) ENGINE = InnoDB AUTO_INCREMENT = 1095 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '文件表';
  541 +) ENGINE = InnoDB AUTO_INCREMENT = 1108 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '文件表';
542 542  
543 543 -- ----------------------------
544 544 -- Records of infra_file
... ... @@ -587,7 +587,7 @@ CREATE TABLE `infra_file_content` (
587 587 `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
588 588 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
589 589 PRIMARY KEY (`id`) USING BTREE
590   -) ENGINE = InnoDB AUTO_INCREMENT = 188 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '文件表';
  590 +) ENGINE = InnoDB AUTO_INCREMENT = 201 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '文件表';
591 591  
592 592 -- ----------------------------
593 593 -- Records of infra_file_content
... ... @@ -709,7 +709,7 @@ CREATE TABLE `member_address` (
709 709 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
710 710 PRIMARY KEY (`id`) USING BTREE,
711 711 INDEX `idx_userId`(`user_id` ASC) USING BTREE
712   -) ENGINE = InnoDB AUTO_INCREMENT = 24 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin COMMENT = '用户收件地址';
  712 +) ENGINE = InnoDB AUTO_INCREMENT = 25 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin COMMENT = '用户收件地址';
713 713  
714 714 -- ----------------------------
715 715 -- Records of member_address
... ... @@ -717,6 +717,33 @@ CREATE TABLE `member_address` (
717 717 BEGIN;
718 718 INSERT INTO `member_address` (`id`, `user_id`, `name`, `mobile`, `area_id`, `detail_address`, `default_status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (21, 247, 'yunai', '15601691300', 140302, '芋道源码 233 号 666 室', b'1', '1', '2022-08-01 22:46:35', '247', '2023-06-26 19:47:46', b'0', 1);
719 719 INSERT INTO `member_address` (`id`, `user_id`, `name`, `mobile`, `area_id`, `detail_address`, `default_status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (23, 247, '测试', '15601691300', 120103, '13232312', b'0', '247', '2023-06-26 19:47:40', '247', '2023-06-26 19:47:46', b'0', 1);
  720 +INSERT INTO `member_address` (`id`, `user_id`, `name`, `mobile`, `area_id`, `detail_address`, `default_status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (24, 248, '芋头', '15601691234', 110101, '灌灌灌灌灌', b'1', '248', '2023-10-06 10:08:24', '248', '2023-10-06 10:08:24', b'0', 1);
  721 +COMMIT;
  722 +
  723 +-- ----------------------------
  724 +-- Table structure for member_config
  725 +-- ----------------------------
  726 +DROP TABLE IF EXISTS `member_config`;
  727 +CREATE TABLE `member_config` (
  728 + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '自增主键',
  729 + `point_trade_deduct_enable` bit(1) NOT NULL COMMENT '是否开启积分抵扣',
  730 + `point_trade_deduct_unit_price` int NOT NULL COMMENT '积分抵扣(单位:分)',
  731 + `point_trade_deduct_max_price` int NULL DEFAULT NULL COMMENT '积分抵扣最大值',
  732 + `point_trade_give_point` bigint NULL DEFAULT NULL COMMENT '1 元赠送多少分',
  733 + `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者',
  734 + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  735 + `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者',
  736 + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  737 + `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
  738 + `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
  739 + PRIMARY KEY (`id`) USING BTREE
  740 +) ENGINE = InnoDB AUTO_INCREMENT = 6 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '会员配置表';
  741 +
  742 +-- ----------------------------
  743 +-- Records of member_config
  744 +-- ----------------------------
  745 +BEGIN;
  746 +INSERT INTO `member_config` (`id`, `point_trade_deduct_enable`, `point_trade_deduct_unit_price`, `point_trade_deduct_max_price`, `point_trade_give_point`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (5, b'1', 100, 2, 3, '1', '2023-08-20 09:54:42', '1', '2023-10-01 23:44:01', b'0', 1);
720 747 COMMIT;
721 748  
722 749 -- ----------------------------
... ... @@ -741,7 +768,7 @@ CREATE TABLE `member_experience_record` (
741 768 PRIMARY KEY (`id`) USING BTREE,
742 769 INDEX `idx_user_id`(`user_id` ASC) USING BTREE COMMENT '会员经验记录-用户编号',
743 770 INDEX `idx_user_biz_type`(`user_id` ASC, `biz_type` ASC) USING BTREE COMMENT '会员经验记录-用户业务类型'
744   -) ENGINE = InnoDB AUTO_INCREMENT = 13 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '会员经验记录';
  771 +) ENGINE = InnoDB AUTO_INCREMENT = 41 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '会员经验记录';
745 772  
746 773 -- ----------------------------
747 774 -- Records of member_experience_record
... ... @@ -759,6 +786,28 @@ INSERT INTO `member_experience_record` (`id`, `user_id`, `biz_id`, `biz_type`, `
759 786 INSERT INTO `member_experience_record` (`id`, `user_id`, `biz_id`, `biz_type`, `title`, `description`, `experience`, `total_experience`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (10, 247, '97', 2, '下单奖励', '下单获得 384945 经验', 384945, 5529343, NULL, '2023-10-02 10:21:12', NULL, '2023-10-02 10:21:12', b'0', 1);
760 787 INSERT INTO `member_experience_record` (`id`, `user_id`, `biz_id`, `biz_type`, `title`, `description`, `experience`, `total_experience`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (11, 247, '11', 3, '退单扣除', '退单获得 -699900 经验', -699900, 4829443, NULL, '2023-10-02 15:19:37', NULL, '2023-10-02 15:19:37', b'0', 1);
761 788 INSERT INTO `member_experience_record` (`id`, `user_id`, `biz_id`, `biz_type`, `title`, `description`, `experience`, `total_experience`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (12, 247, '98', 2, '下单奖励', '下单获得 384945 经验', 384945, 5214388, NULL, '2023-10-02 15:38:39', NULL, '2023-10-02 15:38:39', b'0', 1);
  789 +INSERT INTO `member_experience_record` (`id`, `user_id`, `biz_id`, `biz_type`, `title`, `description`, `experience`, `total_experience`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (13, 247, '102', 2, '下单奖励', '下单获得 201 经验', 201, 5214589, NULL, '2023-10-05 23:05:29', NULL, '2023-10-05 23:05:29', b'0', 1);
  790 +INSERT INTO `member_experience_record` (`id`, `user_id`, `biz_id`, `biz_type`, `title`, `description`, `experience`, `total_experience`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (14, 247, '107', 2, '下单奖励', '下单获得 201 经验', 201, 5214790, NULL, '2023-10-05 23:23:00', NULL, '2023-10-05 23:23:00', b'0', 1);
  791 +INSERT INTO `member_experience_record` (`id`, `user_id`, `biz_id`, `biz_type`, `title`, `description`, `experience`, `total_experience`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (15, 248, '108', 2, '下单奖励', '下单获得 275 经验', 275, 275, NULL, '2023-10-06 10:13:44', NULL, '2023-10-06 10:13:44', b'0', 1);
  792 +INSERT INTO `member_experience_record` (`id`, `user_id`, `biz_id`, `biz_type`, `title`, `description`, `experience`, `total_experience`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (16, 248, '118', 2, '下单奖励', '下单获得 203 经验', 203, 478, NULL, '2023-10-07 06:58:52', NULL, '2023-10-07 06:58:52', b'0', 1);
  793 +INSERT INTO `member_experience_record` (`id`, `user_id`, `biz_id`, `biz_type`, `title`, `description`, `experience`, `total_experience`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (17, 248, '119', 2, '下单奖励', '下单获得 700100 经验', 700100, 700578, NULL, '2023-10-10 23:02:36', NULL, '2023-10-10 23:02:36', b'0', 1);
  794 +INSERT INTO `member_experience_record` (`id`, `user_id`, `biz_id`, `biz_type`, `title`, `description`, `experience`, `total_experience`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (21, 248, '15', 3, '退单扣除', '退单获得 -700100 经验', -700100, 478, '1', '2023-10-10 23:11:19', '1', '2023-10-10 23:11:19', b'0', 1);
  795 +INSERT INTO `member_experience_record` (`id`, `user_id`, `biz_id`, `biz_type`, `title`, `description`, `experience`, `total_experience`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (22, 248, '119', 3, '退单扣除', '退单获得 -700100 经验', -700100, 0, '1', '2023-10-10 23:11:23', '1', '2023-10-10 23:11:23', b'0', 1);
  796 +INSERT INTO `member_experience_record` (`id`, `user_id`, `biz_id`, `biz_type`, `title`, `description`, `experience`, `total_experience`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (23, 248, '120', 2, '下单奖励', '下单获得 700100 经验', 700100, 700100, NULL, '2023-10-10 23:16:09', NULL, '2023-10-10 23:16:09', b'0', 1);
  797 +INSERT INTO `member_experience_record` (`id`, `user_id`, `biz_id`, `biz_type`, `title`, `description`, `experience`, `total_experience`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (24, 248, '16', 3, '退单扣除', '退单获得 -700100 经验', -700100, 0, '1', '2023-10-10 23:20:10', '1', '2023-10-10 23:20:10', b'0', 1);
  798 +INSERT INTO `member_experience_record` (`id`, `user_id`, `biz_id`, `biz_type`, `title`, `description`, `experience`, `total_experience`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (25, 248, '120', 3, '退单扣除', '退单获得 -700100 经验', -700100, 0, '1', '2023-10-10 23:20:16', '1', '2023-10-10 23:20:16', b'0', 1);
  799 +INSERT INTO `member_experience_record` (`id`, `user_id`, `biz_id`, `biz_type`, `title`, `description`, `experience`, `total_experience`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (26, 248, '121', 2, '下单奖励', '下单获得 700100 经验', 700100, 700100, NULL, '2023-10-10 23:23:30', NULL, '2023-10-10 23:23:30', b'0', 1);
  800 +INSERT INTO `member_experience_record` (`id`, `user_id`, `biz_id`, `biz_type`, `title`, `description`, `experience`, `total_experience`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (27, 248, '17', 3, '退单扣除', '退单获得 -700100 经验', -700100, 0, '1', '2023-10-10 23:23:50', '1', '2023-10-10 23:23:50', b'0', 1);
  801 +INSERT INTO `member_experience_record` (`id`, `user_id`, `biz_id`, `biz_type`, `title`, `description`, `experience`, `total_experience`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (28, 248, '121', 3, '退单扣除', '退单获得 -700100 经验', -700100, 0, '1', '2023-10-10 23:23:55', '1', '2023-10-10 23:23:55', b'0', 1);
  802 +INSERT INTO `member_experience_record` (`id`, `user_id`, `biz_id`, `biz_type`, `title`, `description`, `experience`, `total_experience`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (29, 248, '122', 2, '下单奖励', '下单获得 700100 经验', 700100, 700100, NULL, '2023-10-10 23:28:07', NULL, '2023-10-10 23:28:07', b'0', 1);
  803 +INSERT INTO `member_experience_record` (`id`, `user_id`, `biz_id`, `biz_type`, `title`, `description`, `experience`, `total_experience`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (30, 248, '18', 3, '退单扣除', '退单获得 -700100 经验', -700100, 0, '1', '2023-10-10 23:29:55', '1', '2023-10-10 23:29:55', b'0', 1);
  804 +INSERT INTO `member_experience_record` (`id`, `user_id`, `biz_id`, `biz_type`, `title`, `description`, `experience`, `total_experience`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (31, 248, '123', 2, '下单奖励', '下单获得 300 经验', 300, 300, NULL, '2023-10-10 23:44:45', NULL, '2023-10-10 23:44:45', b'0', 1);
  805 +INSERT INTO `member_experience_record` (`id`, `user_id`, `biz_id`, `biz_type`, `title`, `description`, `experience`, `total_experience`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (32, 248, '124', 2, '下单奖励', '下单获得 560120 经验', 560120, 560420, NULL, '2023-10-11 07:03:46', NULL, '2023-10-11 07:03:46', b'0', 1);
  806 +INSERT INTO `member_experience_record` (`id`, `user_id`, `biz_id`, `biz_type`, `title`, `description`, `experience`, `total_experience`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (33, 248, '19', 3, '退单扣除', '退单获得 -300 经验', -300, 560120, '1', '2023-10-11 07:04:28', '1', '2023-10-11 07:04:28', b'0', 1);
  807 +INSERT INTO `member_experience_record` (`id`, `user_id`, `biz_id`, `biz_type`, `title`, `description`, `experience`, `total_experience`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (34, 248, '125', 11, '下单奖励', '下单获得 700100 经验', 700100, 700100, NULL, '2023-10-11 07:33:29', NULL, '2023-10-11 07:33:29', b'0', 1);
  808 +INSERT INTO `member_experience_record` (`id`, `user_id`, `biz_id`, `biz_type`, `title`, `description`, `experience`, `total_experience`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (37, 248, '127', 11, '下单奖励', '下单获得 385145 经验', 385145, 385145, NULL, '2023-10-11 07:36:44', NULL, '2023-10-11 07:36:44', b'0', 1);
  809 +INSERT INTO `member_experience_record` (`id`, `user_id`, `biz_id`, `biz_type`, `title`, `description`, `experience`, `total_experience`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (40, 248, '120', 13, '下单奖励(单个取消)', '退款订单获得 -385145 经验', -385145, 0, '1', '2023-10-11 07:39:26', '1', '2023-10-11 07:39:26', b'0', 1);
  810 +INSERT INTO `member_experience_record` (`id`, `user_id`, `biz_id`, `biz_type`, `title`, `description`, `experience`, `total_experience`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (41, 248, '131', 11, '下单奖励', '下单获得 700100 经验', 700100, 700100, NULL, '2023-10-24 12:33:22', NULL, '2023-10-24 12:33:22', b'0', 1);
762 811 COMMIT;
763 812  
764 813 -- ----------------------------
... ... @@ -835,7 +884,7 @@ CREATE TABLE `member_level_record` (
835 884 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
836 885 PRIMARY KEY (`id`) USING BTREE,
837 886 INDEX `idx_user_id`(`user_id` ASC) USING BTREE COMMENT '会员等级记录-用户编号'
838   -) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '会员等级记录';
  887 +) ENGINE = InnoDB AUTO_INCREMENT = 20 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '会员等级记录';
839 888  
840 889 -- ----------------------------
841 890 -- Records of member_level_record
... ... @@ -865,7 +914,7 @@ CREATE TABLE `member_point_record` (
865 914 PRIMARY KEY (`id`) USING BTREE,
866 915 INDEX `index_userId`(`user_id` ASC) USING BTREE,
867 916 INDEX `index_title`(`title` ASC) USING BTREE
868   -) ENGINE = InnoDB AUTO_INCREMENT = 32 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '用户积分记录';
  917 +) ENGINE = InnoDB AUTO_INCREMENT = 60 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '用户积分记录';
869 918  
870 919 -- ----------------------------
871 920 -- Records of member_point_record
... ... @@ -902,6 +951,28 @@ INSERT INTO `member_point_record` (`id`, `user_id`, `biz_id`, `biz_type`, `title
902 951 INSERT INTO `member_point_record` (`id`, `user_id`, `biz_id`, `biz_type`, `title`, `description`, `point`, `total_point`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (29, 247, '96', 10, '订单奖励', '下单获得 20997 积分', 20997, 10547883, NULL, '2023-10-02 09:40:20', NULL, '2023-10-02 09:40:20', b'0', 1);
903 952 INSERT INTO `member_point_record` (`id`, `user_id`, `biz_id`, `biz_type`, `title`, `description`, `point`, `total_point`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (30, 247, '97', 10, '订单奖励', '下单获得 11548 积分', 11548, 10559431, NULL, '2023-10-02 10:21:12', NULL, '2023-10-02 10:21:12', b'0', 1);
904 953 INSERT INTO `member_point_record` (`id`, `user_id`, `biz_id`, `biz_type`, `title`, `description`, `point`, `total_point`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (31, 247, '98', 10, '订单奖励', '下单获得 11548 积分', 11548, 10570979, NULL, '2023-10-02 15:38:39', NULL, '2023-10-02 15:38:39', b'0', 1);
  954 +INSERT INTO `member_point_record` (`id`, `user_id`, `biz_id`, `biz_type`, `title`, `description`, `point`, `total_point`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (32, 247, '102', 10, '订单奖励', '下单获得 6 积分', 6, 10570985, NULL, '2023-10-05 23:05:29', NULL, '2023-10-05 23:05:29', b'0', 1);
  955 +INSERT INTO `member_point_record` (`id`, `user_id`, `biz_id`, `biz_type`, `title`, `description`, `point`, `total_point`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (33, 247, '107', 10, '订单奖励', '下单获得 6 积分', 6, 10570991, NULL, '2023-10-05 23:23:00', NULL, '2023-10-05 23:23:00', b'0', 1);
  956 +INSERT INTO `member_point_record` (`id`, `user_id`, `biz_id`, `biz_type`, `title`, `description`, `point`, `total_point`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (34, 248, '108', 10, '订单奖励', '下单获得 8 积分', 8, 8, NULL, '2023-10-06 10:13:44', NULL, '2023-10-06 10:13:44', b'0', 1);
  957 +INSERT INTO `member_point_record` (`id`, `user_id`, `biz_id`, `biz_type`, `title`, `description`, `point`, `total_point`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (35, 248, '118', 10, '订单奖励', '下单获得 6 积分', 6, 14, NULL, '2023-10-07 06:58:51', NULL, '2023-10-07 06:58:51', b'0', 1);
  958 +INSERT INTO `member_point_record` (`id`, `user_id`, `biz_id`, `biz_type`, `title`, `description`, `point`, `total_point`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (36, 248, '119', 10, '订单奖励', '下单获得 21003 积分', 21003, 21017, NULL, '2023-10-10 23:02:35', NULL, '2023-10-10 23:02:35', b'0', 1);
  959 +INSERT INTO `member_point_record` (`id`, `user_id`, `biz_id`, `biz_type`, `title`, `description`, `point`, `total_point`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (40, 248, '15', 14, '订单退款', '订单退款,扣除赠送的 -21003 积分', -21003, 2080697, '1', '2023-10-10 23:11:19', '1', '2023-10-10 23:11:19', b'0', 1);
  960 +INSERT INTO `member_point_record` (`id`, `user_id`, `biz_id`, `biz_type`, `title`, `description`, `point`, `total_point`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (41, 248, '119', 11, '订单取消', '订单取消,退还 -21003 积分', -21003, 2059694, '1', '2023-10-10 23:11:23', '1', '2023-10-10 23:11:23', b'0', 1);
  961 +INSERT INTO `member_point_record` (`id`, `user_id`, `biz_id`, `biz_type`, `title`, `description`, `point`, `total_point`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (42, 248, '120', 10, '订单奖励', '下单获得 21003 积分', 21003, 2080697, NULL, '2023-10-10 23:16:09', NULL, '2023-10-10 23:16:09', b'0', 1);
  962 +INSERT INTO `member_point_record` (`id`, `user_id`, `biz_id`, `biz_type`, `title`, `description`, `point`, `total_point`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (43, 248, '16', 14, '订单退款', '订单退款,扣除赠送的 -21003 积分', -21003, 2059694, '1', '2023-10-10 23:20:10', '1', '2023-10-10 23:20:10', b'0', 1);
  963 +INSERT INTO `member_point_record` (`id`, `user_id`, `biz_id`, `biz_type`, `title`, `description`, `point`, `total_point`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (44, 248, '120', 11, '订单取消', '订单取消,退还 -21003 积分', -21003, 2038691, '1', '2023-10-10 23:20:16', '1', '2023-10-10 23:20:16', b'0', 1);
  964 +INSERT INTO `member_point_record` (`id`, `user_id`, `biz_id`, `biz_type`, `title`, `description`, `point`, `total_point`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (45, 248, '121', 10, '订单奖励', '下单获得 21003 积分', 21003, 2059694, NULL, '2023-10-10 23:23:30', NULL, '2023-10-10 23:23:30', b'0', 1);
  965 +INSERT INTO `member_point_record` (`id`, `user_id`, `biz_id`, `biz_type`, `title`, `description`, `point`, `total_point`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (46, 248, '17', 14, '订单退款', '订单退款,扣除赠送的 -21003 积分', -21003, 2038691, '1', '2023-10-10 23:23:50', '1', '2023-10-10 23:23:50', b'0', 1);
  966 +INSERT INTO `member_point_record` (`id`, `user_id`, `biz_id`, `biz_type`, `title`, `description`, `point`, `total_point`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (47, 248, '121', 11, '订单取消', '订单取消,退还 -21003 积分', -21003, 2017688, '1', '2023-10-10 23:23:55', '1', '2023-10-10 23:23:55', b'0', 1);
  967 +INSERT INTO `member_point_record` (`id`, `user_id`, `biz_id`, `biz_type`, `title`, `description`, `point`, `total_point`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (48, 248, '122', 10, '订单奖励', '下单获得 21003 积分', 21003, 2038691, NULL, '2023-10-10 23:28:07', NULL, '2023-10-10 23:28:07', b'0', 1);
  968 +INSERT INTO `member_point_record` (`id`, `user_id`, `biz_id`, `biz_type`, `title`, `description`, `point`, `total_point`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (49, 248, '18', 14, '订单退款', '订单退款,扣除赠送的 -21003 积分', -21003, 2017688, '1', '2023-10-10 23:29:55', '1', '2023-10-10 23:29:55', b'0', 1);
  969 +INSERT INTO `member_point_record` (`id`, `user_id`, `biz_id`, `biz_type`, `title`, `description`, `point`, `total_point`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (50, 248, '123', 10, '订单奖励', '下单获得 9 积分', 9, 2017697, NULL, '2023-10-10 23:44:45', NULL, '2023-10-10 23:44:45', b'0', 1);
  970 +INSERT INTO `member_point_record` (`id`, `user_id`, `biz_id`, `biz_type`, `title`, `description`, `point`, `total_point`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (51, 248, '124', 10, '订单奖励', '下单获得 16803 积分', 16803, 2034500, NULL, '2023-10-11 07:03:46', NULL, '2023-10-11 07:03:46', b'0', 1);
  971 +INSERT INTO `member_point_record` (`id`, `user_id`, `biz_id`, `biz_type`, `title`, `description`, `point`, `total_point`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (52, 248, '19', 14, '订单退款', '订单退款,扣除赠送的 -9 积分', -9, 2034491, '1', '2023-10-11 07:04:28', '1', '2023-10-11 07:04:28', b'0', 1);
  972 +INSERT INTO `member_point_record` (`id`, `user_id`, `biz_id`, `biz_type`, `title`, `description`, `point`, `total_point`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (53, 248, '125', 21, '订单积分奖励', '下单获得 21003 积分', 21003, 21003, NULL, '2023-10-11 07:33:29', NULL, '2023-10-11 07:33:29', b'0', 1);
  973 +INSERT INTO `member_point_record` (`id`, `user_id`, `biz_id`, `biz_type`, `title`, `description`, `point`, `total_point`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (56, 248, '127', 21, '订单积分奖励', '下单获得 11554 积分', 11554, 11554, NULL, '2023-10-11 07:36:44', NULL, '2023-10-11 07:36:44', b'0', 1);
  974 +INSERT INTO `member_point_record` (`id`, `user_id`, `biz_id`, `biz_type`, `title`, `description`, `point`, `total_point`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (59, 248, '120', 23, '订单积分奖励(单个退款)', '订单退款,扣除赠送的 -11554 积分', -11554, 0, '1', '2023-10-11 07:39:26', '1', '2023-10-11 07:39:26', b'0', 1);
  975 +INSERT INTO `member_point_record` (`id`, `user_id`, `biz_id`, `biz_type`, `title`, `description`, `point`, `total_point`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (60, 248, '131', 21, '订单积分奖励', '下单获得 21003 积分', 21003, 21003, NULL, '2023-10-24 12:33:22', NULL, '2023-10-24 12:33:22', b'0', 1);
905 976 COMMIT;
906 977  
907 978 -- ----------------------------
... ... @@ -1003,6 +1074,7 @@ CREATE TABLE `member_user` (
1003 1074 `password` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '密码',
1004 1075 `status` tinyint NOT NULL COMMENT '状态',
1005 1076 `register_ip` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '注册 IP',
  1077 + `register_terminal` tinyint NULL DEFAULT NULL COMMENT '注册终端',
1006 1078 `login_ip` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '最后登录IP',
1007 1079 `login_date` datetime NULL DEFAULT NULL COMMENT '最后登录时间',
1008 1080 `nickname` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '用户昵称',
... ... @@ -1092,7 +1164,7 @@ CREATE TABLE `system_dict_data` (
1092 1164 `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
1093 1165 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
1094 1166 PRIMARY KEY (`id`) USING BTREE
1095   -) ENGINE = InnoDB AUTO_INCREMENT = 1386 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '字典数据表';
  1167 +) ENGINE = InnoDB AUTO_INCREMENT = 1398 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '字典数据表';
1096 1168  
1097 1169 -- ----------------------------
1098 1170 -- Records of system_dict_data
... ... @@ -1178,6 +1250,11 @@ INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `st
1178 1250 INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (123, 10, '支付成功', '10', 'pay_order_status', 0, 'success', '', '支付成功', '1', '2021-12-03 11:18:29', '1', '2023-07-19 18:04:28', b'0');
1179 1251 INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (124, 30, '支付关闭', '30', 'pay_order_status', 0, 'info', '', '支付关闭', '1', '2021-12-03 11:18:42', '1', '2023-07-19 18:05:07', b'0');
1180 1252 INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (125, 0, '等待支付', '0', 'pay_order_status', 0, 'info', '', '未支付', '1', '2021-12-03 11:18:18', '1', '2023-07-19 18:04:15', b'0');
  1253 +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (600, 5, '首页', '1', 'promotion_banner_position', 0, 'warning', '', '', '1', '2023-10-11 07:45:24', '1', '2023-10-11 07:45:38', b'0');
  1254 +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (601, 4, '秒杀活动页', '2', 'promotion_banner_position', 0, 'warning', '', '', '1', '2023-10-11 07:45:24', '1', '2023-10-11 07:45:38', b'0');
  1255 +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (602, 3, '砍价活动页', '3', 'promotion_banner_position', 0, 'warning', '', '', '1', '2023-10-11 07:45:24', '1', '2023-10-11 07:45:38', b'0');
  1256 +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (603, 2, '限时折扣页', '4', 'promotion_banner_position', 0, 'warning', '', '', '1', '2023-10-11 07:45:24', '1', '2023-10-11 07:45:38', b'0');
  1257 +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (604, 1, '满减送页', '5', 'promotion_banner_position', 0, 'warning', '', '', '1', '2023-10-11 07:45:24', '1', '2023-10-11 07:45:38', b'0');
1181 1258 INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1118, 0, '等待退款', '0', 'pay_refund_status', 0, 'info', '', '等待退款', '1', '2021-12-10 16:44:59', '1', '2023-07-19 10:14:39', b'0');
1182 1259 INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1119, 20, '退款失败', '20', 'pay_refund_status', 0, 'danger', '', '退款失败', '1', '2021-12-10 16:45:10', '1', '2023-07-19 10:15:10', b'0');
1183 1260 INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1124, 10, '退款成功', '10', 'pay_refund_status', 0, 'success', '', '退款成功', '1', '2021-12-10 16:46:26', '1', '2023-07-19 10:15:00', b'0');
... ... @@ -1298,7 +1375,7 @@ INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `st
1298 1375 INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1244, 0, '按件', '1', 'trade_delivery_express_charge_mode', 0, '', '', '', '1', '2023-05-21 22:46:40', '1', '2023-05-21 22:46:40', b'0');
1299 1376 INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1245, 1, '按重量', '2', 'trade_delivery_express_charge_mode', 0, '', '', '', '1', '2023-05-21 22:46:58', '1', '2023-05-21 22:46:58', b'0');
1300 1377 INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1246, 2, '按体积', '3', 'trade_delivery_express_charge_mode', 0, '', '', '', '1', '2023-05-21 22:47:18', '1', '2023-05-21 22:47:18', b'0');
1301   -INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1335, 11, '订单消费', '11', 'member_point_biz_type', 0, '', '', '', '1', '2023-06-10 12:15:27', '1', '2023-08-20 11:59:47', b'0');
  1378 +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1335, 11, '订单积分抵扣', '11', 'member_point_biz_type', 0, '', '', '', '1', '2023-06-10 12:15:27', '1', '2023-10-11 07:41:43', b'0');
1302 1379 INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1336, 1, '签到', '1', 'member_point_biz_type', 0, '', '', '', '1', '2023-06-10 12:15:48', '1', '2023-08-20 11:59:53', b'0');
1303 1380 INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1341, 20, '已退款', '20', 'pay_order_status', 0, 'danger', '', '已退款', '1', '2023-07-19 18:05:37', '1', '2023-07-19 18:05:37', b'0');
1304 1381 INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1342, 21, '请求成功,但是结果失败', '21', 'pay_notify_status', 0, 'warning', '', '请求成功,但是结果失败', '1', '2023-07-19 18:10:47', '1', '2023-07-19 18:11:38', b'0');
... ... @@ -1308,11 +1385,11 @@ INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `st
1308 1385 INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1346, 1, '支付单', '1', 'pay_notify_type', 0, 'primary', '', '支付单', '1', '2023-07-20 12:23:17', '1', '2023-07-20 12:23:17', b'0');
1309 1386 INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1347, 2, '退款单', '2', 'pay_notify_type', 0, 'danger', '', NULL, '1', '2023-07-20 12:23:26', '1', '2023-07-20 12:23:26', b'0');
1310 1387 INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1348, 20, '模拟支付', 'mock', 'pay_channel_code', 0, 'default', '', '模拟支付', '1', '2023-07-29 11:10:51', '1', '2023-07-29 03:14:10', b'0');
1311   -INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1349, 12, '订单取消', '12', 'member_point_biz_type', 0, '', '', '', '1', '2023-08-20 12:00:03', '1', '2023-08-20 12:00:03', b'0');
  1388 +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1349, 12, '订单积分抵扣(整单取消)', '12', 'member_point_biz_type', 0, '', '', '', '1', '2023-08-20 12:00:03', '1', '2023-10-11 07:42:01', b'0');
1312 1389 INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1350, 0, '管理员调整', '0', 'member_experience_biz_type', 0, '', '', NULL, '', '2023-08-22 12:41:01', '', '2023-08-22 12:41:01', b'0');
1313 1390 INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1351, 1, '邀新奖励', '1', 'member_experience_biz_type', 0, '', '', NULL, '', '2023-08-22 12:41:01', '', '2023-08-22 12:41:01', b'0');
1314   -INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1352, 2, '下单奖励', '2', 'member_experience_biz_type', 0, '', '', NULL, '', '2023-08-22 12:41:01', '', '2023-08-22 12:41:01', b'0');
1315   -INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1353, 3, '退单扣除', '3', 'member_experience_biz_type', 0, '', '', NULL, '', '2023-08-22 12:41:01', '', '2023-08-22 12:41:01', b'0');
  1391 +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1352, 11, '下单奖励', '11', 'member_experience_biz_type', 0, 'success', '', NULL, '', '2023-08-22 12:41:01', '1', '2023-10-11 07:45:09', b'0');
  1392 +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1353, 12, '下单奖励(整单取消)', '12', 'member_experience_biz_type', 0, 'warning', '', NULL, '', '2023-08-22 12:41:01', '1', '2023-10-11 07:45:01', b'0');
1316 1393 INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1354, 4, '签到奖励', '4', 'member_experience_biz_type', 0, '', '', NULL, '', '2023-08-22 12:41:01', '', '2023-08-22 12:41:01', b'0');
1317 1394 INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1355, 5, '抽奖奖励', '5', 'member_experience_biz_type', 0, '', '', NULL, '', '2023-08-22 12:41:01', '', '2023-08-22 12:41:01', b'0');
1318 1395 INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1356, 1, '快递发货', '1', 'trade_delivery_type', 0, '', '', '', '1', '2023-08-23 00:04:55', '1', '2023-08-23 00:04:55', b'0');
... ... @@ -1348,6 +1425,15 @@ INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `st
1348 1425 INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1386, 1, '砍价中', '1', 'promotion_bargain_record_status', 0, 'default', '', '', '1', '2023-10-05 10:41:26', '1', '2023-10-05 10:41:26', b'0');
1349 1426 INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1387, 2, '砍价成功', '2', 'promotion_bargain_record_status', 0, 'success', '', '', '1', '2023-10-05 10:41:39', '1', '2023-10-05 10:41:39', b'0');
1350 1427 INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1388, 3, '砍价失败', '3', 'promotion_bargain_record_status', 0, 'warning', '', '', '1', '2023-10-05 10:41:57', '1', '2023-10-05 10:41:57', b'0');
  1428 +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1389, 1, '拼团中', '1', 'promotion_combination_record_status', 0, '', '', '', '1', '2023-10-08 07:24:44', '1', '2023-10-08 07:24:44', b'0');
  1429 +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1390, 2, '拼团成功', '2', 'promotion_combination_record_status', 0, 'success', '', '', '1', '2023-10-08 07:24:56', '1', '2023-10-08 07:24:56', b'0');
  1430 +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1391, 3, '拼团失败', '3', 'promotion_combination_record_status', 0, 'warning', '', '', '1', '2023-10-08 07:25:11', '1', '2023-10-08 07:25:11', b'0');
  1431 +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1392, 2, '管理员修改', '2', 'member_point_biz_type', 0, 'default', '', '', '1', '2023-10-11 07:41:34', '1', '2023-10-11 07:41:34', b'0');
  1432 +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1393, 13, '订单积分抵扣(单个退款)', '13', 'member_point_biz_type', 0, '', '', '', '1', '2023-10-11 07:42:29', '1', '2023-10-11 07:42:29', b'0');
  1433 +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1394, 21, '订单积分奖励', '21', 'member_point_biz_type', 0, 'default', '', '', '1', '2023-10-11 07:42:44', '1', '2023-10-11 07:42:44', b'0');
  1434 +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1395, 22, '订单积分奖励(整单取消)', '22', 'member_point_biz_type', 0, 'default', '', '', '1', '2023-10-11 07:42:55', '1', '2023-10-11 07:43:01', b'0');
  1435 +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1396, 23, '订单积分奖励(单个退款)', '23', 'member_point_biz_type', 0, 'default', '', '', '1', '2023-10-11 07:43:16', '1', '2023-10-11 07:43:16', b'0');
  1436 +INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `status`, `color_type`, `css_class`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (1397, 13, '下单奖励(单个退款)', '13', 'member_experience_biz_type', 0, 'warning', '', '', '1', '2023-10-11 07:45:24', '1', '2023-10-11 07:45:38', b'0');
1351 1437 COMMIT;
1352 1438  
1353 1439 -- ----------------------------
... ... @@ -1368,7 +1454,7 @@ CREATE TABLE `system_dict_type` (
1368 1454 `deleted_time` datetime NULL DEFAULT NULL COMMENT '删除时间',
1369 1455 PRIMARY KEY (`id`) USING BTREE,
1370 1456 UNIQUE INDEX `dict_type`(`type` ASC) USING BTREE
1371   -) ENGINE = InnoDB AUTO_INCREMENT = 183 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '字典类型表';
  1457 +) ENGINE = InnoDB AUTO_INCREMENT = 185 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '字典类型表';
1372 1458  
1373 1459 -- ----------------------------
1374 1460 -- Records of system_dict_type
... ... @@ -1441,6 +1527,8 @@ INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creat
1441 1527 INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (181, '佣金提现状态', 'brokerage_withdraw_status', 0, NULL, '', '2023-09-28 02:46:05', '', '2023-09-28 02:46:05', b'0', NULL);
1442 1528 INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (182, '佣金提现银行', 'brokerage_bank_name', 0, NULL, '', '2023-09-28 02:46:05', '', '2023-09-28 02:46:05', b'0', NULL);
1443 1529 INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (183, '砍价记录的状态', 'promotion_bargain_record_status', 0, '', '1', '2023-10-05 10:41:08', '1', '2023-10-05 10:41:08', b'0', '1970-01-01 00:00:00');
  1530 +INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (184, '拼团记录的状态', 'promotion_combination_record_status', 0, '', '1', '2023-10-08 07:24:25', '1', '2023-10-08 07:24:25', b'0', '1970-01-01 00:00:00');
  1531 +INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (600, 'Banner Position', 'promotion_banner_position', 0, '', '1', '2023-10-08 07:24:25', '1', '2023-10-08 07:24:25', b'0', '1970-01-01 00:00:00');
1444 1532 COMMIT;
1445 1533  
1446 1534 -- ----------------------------
... ... @@ -1489,7 +1577,7 @@ CREATE TABLE `system_login_log` (
1489 1577 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
1490 1578 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
1491 1579 PRIMARY KEY (`id`) USING BTREE
1492   -) ENGINE = InnoDB AUTO_INCREMENT = 2516 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '系统访问记录';
  1580 +) ENGINE = InnoDB AUTO_INCREMENT = 2620 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '系统访问记录';
1493 1581  
1494 1582 -- ----------------------------
1495 1583 -- Records of system_login_log
... ... @@ -1619,7 +1707,7 @@ CREATE TABLE `system_menu` (
1619 1707 `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
1620 1708 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
1621 1709 PRIMARY KEY (`id`) USING BTREE
1622   -) ENGINE = InnoDB AUTO_INCREMENT = 2366 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '菜单权限表';
  1710 +) ENGINE = InnoDB AUTO_INCREMENT = 2391 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '菜单权限表';
1623 1711  
1624 1712 -- ----------------------------
1625 1713 -- Records of system_menu
... ... @@ -1871,11 +1959,11 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i
1871 1959 INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2021, '规格创建', 'product:property:create', 3, 2, 2019, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-08-01 14:55:35', '', '2022-12-12 20:26:30', b'0');
1872 1960 INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2022, '规格更新', 'product:property:update', 3, 3, 2019, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-08-01 14:55:35', '', '2022-12-12 20:26:33', b'0');
1873 1961 INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2023, '规格删除', 'product:property:delete', 3, 4, 2019, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-08-01 14:55:35', '', '2022-12-12 20:26:37', b'0');
1874   -INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2025, 'Banner管理', '', 2, 100, 2030, 'banner', '', 'mall/market/banner/index', NULL, 0, b'1', b'1', b'1', '', '2022-08-01 14:56:14', '1', '2023-08-21 10:27:51', b'0');
1875   -INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2026, 'Banner查询', 'market:banner:query', 3, 1, 2025, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-08-01 14:56:14', '', '2022-08-01 14:56:14', b'0');
1876   -INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2027, 'Banner创建', 'market:banner:create', 3, 2, 2025, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-08-01 14:56:14', '', '2022-08-01 14:56:14', b'0');
1877   -INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2028, 'Banner更新', 'market:banner:update', 3, 3, 2025, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-08-01 14:56:14', '', '2022-08-01 14:56:14', b'0');
1878   -INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2029, 'Banner删除', 'market:banner:delete', 3, 4, 2025, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-08-01 14:56:14', '', '2022-08-01 14:56:14', b'0');
  1962 +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2025, 'Banner', '', 2, 100, 2387, 'banner', 'fa:bandcamp', 'mall/promotion/banner/index', NULL, 0, b'1', b'1', b'1', '', '2022-08-01 14:56:14', '1', '2023-10-24 20:20:06', b'0');
  1963 +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2026, 'Banner查询', 'promotion:banner:query', 3, 1, 2025, '', '', '', '', 0, b'1', b'1', b'1', '', '2022-08-01 14:56:14', '1', '2023-10-24 20:20:18', b'0');
  1964 +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2027, 'Banner创建', 'promotion:banner:create', 3, 2, 2025, '', '', '', '', 0, b'1', b'1', b'1', '', '2022-08-01 14:56:14', '1', '2023-10-24 20:20:23', b'0');
  1965 +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2028, 'Banner更新', 'promotion:banner:update', 3, 3, 2025, '', '', '', '', 0, b'1', b'1', b'1', '', '2022-08-01 14:56:14', '1', '2023-10-24 20:20:28', b'0');
  1966 +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2029, 'Banner删除', 'promotion:banner:delete', 3, 4, 2025, '', '', '', '', 0, b'1', b'1', b'1', '', '2022-08-01 14:56:14', '1', '2023-10-24 20:20:36', b'0');
1879 1967 INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2030, '营销中心', '', 1, 70, 2362, 'promotion', 'ep:present', NULL, NULL, 0, b'1', b'1', b'1', '1', '2022-10-31 21:25:09', '1', '2023-09-30 11:54:27', b'0');
1880 1968 INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2032, '优惠劵列表', '', 2, 1, 2365, 'template', 'ep:discount', 'mall/promotion/coupon/template/index', 'PromotionCouponTemplate', 0, b'1', b'1', b'1', '', '2022-10-31 22:27:14', '1', '2023-10-03 12:40:06', b'0');
1881 1969 INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2033, '优惠劵模板查询', 'promotion:coupon-template:query', 3, 1, 2032, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-10-31 22:27:14', '', '2022-10-31 22:27:14', b'0');
... ... @@ -1885,13 +1973,13 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i
1885 1973 INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2038, '领取记录', '', 2, 2, 2365, 'list', 'ep:collection-tag', 'mall/promotion/coupon/index', 'PromotionCoupon', 0, b'1', b'1', b'1', '', '2022-11-03 23:21:31', '1', '2023-10-03 12:55:30', b'0');
1886 1974 INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2039, '优惠劵查询', 'promotion:coupon:query', 3, 1, 2038, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-11-03 23:21:31', '', '2022-11-03 23:21:31', b'0');
1887 1975 INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2040, '优惠劵删除', 'promotion:coupon:delete', 3, 4, 2038, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-11-03 23:21:31', '', '2022-11-03 23:21:31', b'0');
1888   -INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2041, '满减送活动', '', 2, 10, 2030, 'reward-activity', 'ep:goblet-square-full', 'mall/promotion/rewardActivity/index', 'PromotionRewardActivity', 0, b'1', b'1', b'1', '', '2022-11-04 23:47:49', '1', '2023-10-05 00:16:38', b'0');
  1976 +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2041, '满减送', '', 2, 10, 2390, 'reward-activity', 'ep:goblet-square-full', 'mall/promotion/rewardActivity/index', 'PromotionRewardActivity', 0, b'1', b'1', b'1', '', '2022-11-04 23:47:49', '1', '2023-10-21 19:24:46', b'0');
1889 1977 INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2042, '满减送活动查询', 'promotion:reward-activity:query', 3, 1, 2041, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-11-04 23:47:49', '', '2022-11-04 23:47:49', b'0');
1890 1978 INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2043, '满减送活动创建', 'promotion:reward-activity:create', 3, 2, 2041, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-11-04 23:47:49', '', '2022-11-04 23:47:49', b'0');
1891 1979 INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2044, '满减送活动更新', 'promotion:reward-activity:update', 3, 3, 2041, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-11-04 23:47:50', '', '2022-11-04 23:47:50', b'0');
1892 1980 INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2045, '满减送活动删除', 'promotion:reward-activity:delete', 3, 4, 2041, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-11-04 23:47:50', '', '2022-11-04 23:47:50', b'0');
1893 1981 INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2046, '满减送活动关闭', 'promotion:reward-activity:close', 3, 5, 2041, '', '', '', NULL, 0, b'1', b'1', b'1', '1', '2022-11-05 10:42:53', '1', '2022-11-05 10:42:53', b'0');
1894   -INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2047, '限时折扣活动', '', 2, 7, 2030, 'discount-activity', 'ep:timer', 'mall/promotion/discountActivity/index', 'PromotionDiscountActivity', 0, b'1', b'1', b'1', '', '2022-11-05 17:12:15', '1', '2023-10-05 00:16:25', b'0');
  1982 +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2047, '限时折扣', '', 2, 7, 2390, 'discount-activity', 'ep:timer', 'mall/promotion/discountActivity/index', 'PromotionDiscountActivity', 0, b'1', b'1', b'1', '', '2022-11-05 17:12:15', '1', '2023-10-21 19:24:21', b'0');
1895 1983 INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2048, '限时折扣活动查询', 'promotion:discount-activity:query', 3, 1, 2047, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-11-05 17:12:15', '', '2022-11-05 17:12:15', b'0');
1896 1984 INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2049, '限时折扣活动创建', 'promotion:discount-activity:create', 3, 2, 2047, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-11-05 17:12:15', '', '2022-11-05 17:12:15', b'0');
1897 1985 INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2050, '限时折扣活动更新', 'promotion:discount-activity:update', 3, 3, 2047, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-11-05 17:12:16', '', '2022-11-05 17:12:16', b'0');
... ... @@ -2037,7 +2125,7 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i
2037 2125 INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2306, '拼团活动创建', 'promotion:combination-activity:create', 3, 2, 2304, '', '', '', '', 0, b'1', b'1', b'1', '1', '2023-08-12 17:54:49', '1', '2023-08-12 17:54:49', b'0');
2038 2126 INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2307, '拼团活动更新', 'promotion:combination-activity:update', 3, 3, 2304, '', '', '', '', 0, b'1', b'1', b'1', '1', '2023-08-12 17:55:04', '1', '2023-08-12 17:55:04', b'0');
2039 2127 INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2308, '拼团活动删除', 'promotion:combination-activity:delete', 3, 4, 2304, '', '', '', '', 0, b'1', b'1', b'1', '1', '2023-08-12 17:55:23', '1', '2023-08-12 17:55:23', b'0');
2040   -INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2309, '秒杀活动关闭', 'promotion:combination-activity:close ', 3, 5, 2304, '', '', '', '', 0, b'1', b'1', b'1', '1', '2023-08-12 17:55:37', '1', '2023-08-12 17:55:37', b'0');
  2128 +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2309, '拼团活动关闭', 'promotion:combination-activity:close', 3, 5, 2304, '', '', '', '', 0, b'1', b'1', b'1', '1', '2023-08-12 17:55:37', '1', '2023-10-06 10:51:57', b'0');
2041 2129 INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2310, '砍价活动', '', 2, 4, 2030, 'bargain', 'ep:box', '', '', 0, b'1', b'1', b'1', '1', '2023-08-13 00:27:25', '1', '2023-08-13 00:27:25', b'0');
2042 2130 INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2311, '砍价商品', '', 2, 1, 2310, 'activity', 'ep:burger', 'mall/promotion/bargain/activity/index', 'PromotionBargainActivity', 0, b'1', b'1', b'1', '1', '2023-08-13 00:28:49', '1', '2023-10-05 01:16:23', b'0');
2043 2131 INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2312, '砍价活动查询', 'promotion:bargain-activity:query', 3, 1, 2311, '', '', '', '', 0, b'1', b'1', b'1', '1', '2023-08-13 00:32:30', '1', '2023-08-13 00:32:30', b'0');
... ... @@ -2097,6 +2185,24 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i
2097 2185 INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2366, '砍价记录', '', 2, 2, 2310, 'record', 'ep:list', 'mall/promotion/bargain/record/index', 'PromotionBargainRecord', 0, b'1', b'1', b'1', '', '2023-10-05 02:49:06', '1', '2023-10-05 10:50:38', b'0');
2098 2186 INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2367, '砍价记录查询', 'promotion:bargain-record:query', 3, 1, 2366, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-10-05 02:49:06', '', '2023-10-05 02:49:06', b'0');
2099 2187 INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2368, '助力记录查询', 'promotion:bargain-help:query', 3, 2, 2366, '', '', '', '', 0, b'1', b'1', b'1', '1', '2023-10-05 12:27:49', '1', '2023-10-05 12:27:49', b'0');
  2188 +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2369, '拼团记录', 'promotion:combination-record:query', 2, 2, 2303, 'record', 'ep:avatar', 'mall/promotion/combination/record/index.vue', 'PromotionCombinationRecord', 0, b'1', b'1', b'1', '1', '2023-10-08 07:10:22', '1', '2023-10-08 07:34:11', b'0');
  2189 +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2374, '会员统计', '', 2, 2, 2358, 'member', 'ep:avatar', 'statistics/member/index', 'MemberStatistics', 0, b'1', b'1', b'1', '', '2023-10-11 04:39:24', '1', '2023-10-11 12:50:22', b'0');
  2190 +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2375, '会员统计查询', 'statistics:member:query', 3, 1, 2374, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-10-11 04:39:24', '', '2023-10-11 04:39:24', b'0');
  2191 +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2376, '订单核销', 'trade:order:pick-up', 3, 10, 2076, '', '', '', '', 0, b'1', b'1', b'1', '1', '2023-10-14 17:11:58', '1', '2023-10-14 17:11:58', b'0');
  2192 +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2377, '文章分类', '', 2, 0, 2387, 'article/category', 'fa:certificate', 'mall/promotion/article/category/index', 'ArticleCategory', 0, b'1', b'1', b'1', '', '2023-10-16 01:26:18', '1', '2023-10-16 09:38:26', b'0');
  2193 +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2378, '分类查询', 'promotion:article-category:query', 3, 1, 2377, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-10-16 01:26:18', '', '2023-10-16 01:26:18', b'0');
  2194 +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2379, '分类创建', 'promotion:article-category:create', 3, 2, 2377, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-10-16 01:26:18', '', '2023-10-16 01:26:18', b'0');
  2195 +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2380, '分类更新', 'promotion:article-category:update', 3, 3, 2377, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-10-16 01:26:18', '', '2023-10-16 01:26:18', b'0');
  2196 +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2381, '分类删除', 'promotion:article-category:delete', 3, 4, 2377, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-10-16 01:26:18', '', '2023-10-16 01:26:18', b'0');
  2197 +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2382, '文章列表', '', 2, 2, 2387, 'article', 'ep:connection', 'mall/promotion/article/index', 'Article', 0, b'1', b'1', b'1', '', '2023-10-16 01:26:18', '1', '2023-10-16 09:41:19', b'0');
  2198 +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2383, '文章管理查询', 'promotion:article:query', 3, 1, 2382, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-10-16 01:26:18', '', '2023-10-16 01:26:18', b'0');
  2199 +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2384, '文章管理创建', 'promotion:article:create', 3, 2, 2382, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-10-16 01:26:18', '', '2023-10-16 01:26:18', b'0');
  2200 +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2385, '文章管理更新', 'promotion:article:update', 3, 3, 2382, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-10-16 01:26:18', '', '2023-10-16 01:26:18', b'0');
  2201 +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2386, '文章管理删除', 'promotion:article:delete', 3, 4, 2382, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-10-16 01:26:18', '', '2023-10-16 01:26:18', b'0');
  2202 +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2387, '内容管理', '', 1, 1, 2030, 'content', 'ep:collection', '', '', 0, b'1', b'1', b'1', '1', '2023-10-16 09:37:31', '1', '2023-10-16 09:37:31', b'0');
  2203 +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2388, '商城首页', '', 2, 1, 2362, 'home', 'ep:home-filled', 'mall/home/index', 'MallHome', 0, b'1', b'1', b'1', '', '2023-10-16 12:10:33', '', '2023-10-16 12:10:33', b'0');
  2204 +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2389, '核销订单', '', 2, 2, 2166, 'pick-up-order', 'ep:list', 'mall/trade/delivery/pickUpOrder/index', 'PickUpOrder', 0, b'1', b'1', b'1', '', '2023-10-19 16:09:51', '', '2023-10-19 16:09:51', b'0');
  2205 +INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_id`, `path`, `icon`, `component`, `component_name`, `status`, `visible`, `keep_alive`, `always_show`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (2390, '优惠活动', '', 1, 99, 2030, 'youhui', 'ep:aim', '', '', 0, b'1', b'1', b'1', '1', '2023-10-21 19:23:49', '1', '2023-10-21 19:23:49', b'0');
2100 2206 COMMIT;
2101 2207  
2102 2208 -- ----------------------------
... ... @@ -2215,7 +2321,7 @@ CREATE TABLE `system_oauth2_access_token` (
2215 2321 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
2216 2322 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
2217 2323 PRIMARY KEY (`id`) USING BTREE
2218   -) ENGINE = InnoDB AUTO_INCREMENT = 2880 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'OAuth2 访问令牌';
  2324 +) ENGINE = InnoDB AUTO_INCREMENT = 3130 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'OAuth2 访问令牌';
2219 2325  
2220 2326 -- ----------------------------
2221 2327 -- Records of system_oauth2_access_token
... ... @@ -2337,7 +2443,7 @@ CREATE TABLE `system_oauth2_refresh_token` (
2337 2443 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
2338 2444 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
2339 2445 PRIMARY KEY (`id`) USING BTREE
2340   -) ENGINE = InnoDB AUTO_INCREMENT = 1014 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'OAuth2 刷新令牌';
  2446 +) ENGINE = InnoDB AUTO_INCREMENT = 1089 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'OAuth2 刷新令牌';
2341 2447  
2342 2448 -- ----------------------------
2343 2449 -- Records of system_oauth2_refresh_token
... ... @@ -2377,7 +2483,7 @@ CREATE TABLE `system_operate_log` (
2377 2483 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
2378 2484 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
2379 2485 PRIMARY KEY (`id`) USING BTREE
2380   -) ENGINE = InnoDB AUTO_INCREMENT = 8643 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '操作日志记录';
  2486 +) ENGINE = InnoDB AUTO_INCREMENT = 8757 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '操作日志记录';
2381 2487  
2382 2488 -- ----------------------------
2383 2489 -- Records of system_operate_log
... ... @@ -3385,7 +3491,7 @@ CREATE TABLE `system_sms_code` (
3385 3491 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
3386 3492 PRIMARY KEY (`id`) USING BTREE,
3387 3493 INDEX `idx_mobile`(`mobile` ASC) USING BTREE COMMENT '手机号'
3388   -) ENGINE = InnoDB AUTO_INCREMENT = 515 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '手机验证码';
  3494 +) ENGINE = InnoDB AUTO_INCREMENT = 535 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '手机验证码';
3389 3495  
3390 3496 -- ----------------------------
3391 3497 -- Records of system_sms_code
... ... @@ -3428,7 +3534,7 @@ CREATE TABLE `system_sms_log` (
3428 3534 `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
3429 3535 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
3430 3536 PRIMARY KEY (`id`) USING BTREE
3431   -) ENGINE = InnoDB AUTO_INCREMENT = 426 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '短信日志';
  3537 +) ENGINE = InnoDB AUTO_INCREMENT = 449 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '短信日志';
3432 3538  
3433 3539 -- ----------------------------
3434 3540 -- Records of system_sms_log
... ... @@ -3479,6 +3585,33 @@ INSERT INTO `system_sms_template` (`id`, `type`, `status`, `code`, `name`, `cont
3479 3585 COMMIT;
3480 3586  
3481 3587 -- ----------------------------
  3588 +-- Table structure for system_social_client
  3589 +-- ----------------------------
  3590 +DROP TABLE IF EXISTS `system_social_client`;
  3591 +CREATE TABLE `system_social_client` (
  3592 + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
  3593 + `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '应用名',
  3594 + `social_type` tinyint NOT NULL COMMENT '社交平台的类型',
  3595 + `user_type` tinyint NOT NULL COMMENT '用户类型',
  3596 + `client_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '客户端编号',
  3597 + `client_secret` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '客户端密钥',
  3598 + `status` tinyint NOT NULL COMMENT '状态',
  3599 + `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者',
  3600 + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  3601 + `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者',
  3602 + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  3603 + `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
  3604 + `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
  3605 + PRIMARY KEY (`id`) USING BTREE
  3606 +) ENGINE = InnoDB AUTO_INCREMENT = 44 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '社交客户端表';
  3607 +
  3608 +-- ----------------------------
  3609 +-- Records of system_social_client
  3610 +-- ----------------------------
  3611 +BEGIN;
  3612 +COMMIT;
  3613 +
  3614 +-- ----------------------------
3482 3615 -- Table structure for system_social_user
3483 3616 -- ----------------------------
3484 3617 DROP TABLE IF EXISTS `system_social_user`;
... ... @@ -3500,7 +3633,7 @@ CREATE TABLE `system_social_user` (
3500 3633 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
3501 3634 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
3502 3635 PRIMARY KEY (`id`) USING BTREE
3503   -) ENGINE = InnoDB AUTO_INCREMENT = 22 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '社交用户表';
  3636 +) ENGINE = InnoDB AUTO_INCREMENT = 25 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '社交用户表';
3504 3637  
3505 3638 -- ----------------------------
3506 3639 -- Records of system_social_user
... ... @@ -3525,7 +3658,7 @@ CREATE TABLE `system_social_user_bind` (
3525 3658 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
3526 3659 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
3527 3660 PRIMARY KEY (`id`) USING BTREE
3528   -) ENGINE = InnoDB AUTO_INCREMENT = 77 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '社交绑定表';
  3661 +) ENGINE = InnoDB AUTO_INCREMENT = 81 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '社交绑定表';
3529 3662  
3530 3663 -- ----------------------------
3531 3664 -- Records of system_social_user_bind
... ... @@ -3701,7 +3834,7 @@ CREATE TABLE `system_users` (
3701 3834 -- Records of system_users
3702 3835 -- ----------------------------
3703 3836 BEGIN;
3704   -INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1, 'admin', '$2a$10$mRMIYLDtRHlf6.9ipiqH1.Z.bh/R9dO9d5iHiGYPigi6r5KOoR2Wm', '芋道源码', '管理员', 103, '[1]', 'aoteman@126.com', '15612345678', 1, 'http://test.yudao.iocoder.cn/e1fdd7271685ec143a0900681606406621717a666ad0b2798b096df41422b32f.png', 0, '0:0:0:0:0:0:0:1', '2023-10-05 12:34:11', 'admin', '2021-01-05 17:03:47', NULL, '2023-10-05 12:34:11', b'0', 1);
  3837 +INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1, 'admin', '$2a$10$mRMIYLDtRHlf6.9ipiqH1.Z.bh/R9dO9d5iHiGYPigi6r5KOoR2Wm', '芋道源码', '管理员', 103, '[1]', 'aoteman@126.com', '15612345678', 1, 'http://127.0.0.1:48080/admin-api/infra/file/4/get/37e56010ecbee472cdd821ac4b608e151e62a74d9633f15d085aee026eedeb60.png', 0, '0:0:0:0:0:0:0:1', '2023-10-24 20:20:54', 'admin', '2021-01-05 17:03:47', NULL, '2023-10-24 20:20:54', b'0', 1);
3705 3838 INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (100, 'yudao', '$2a$10$11U48RhyJ5pSBYWSn12AD./ld671.ycSzJHbyrtpeoMeYiw31eo8a', '芋道', '不要吓我', 104, '[1]', 'yudao@iocoder.cn', '15601691300', 1, '', 1, '127.0.0.1', '2022-07-09 23:03:33', '', '2021-01-07 09:07:17', NULL, '2022-07-09 23:03:33', b'0', 1);
3706 3839 INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (103, 'yuanma', '$2a$10$YMpimV4T6BtDhIaA8jSW.u8UTGBeGhc/qwXP4oxoMr4mOw9.qttt6', '源码', NULL, 106, NULL, 'yuanma@iocoder.cn', '15601701300', 0, '', 0, '127.0.0.1', '2022-07-08 01:26:27', '', '2021-01-13 23:50:35', NULL, '2022-07-08 01:26:27', b'0', 1);
3707 3840 INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (104, 'test', '$2a$10$GP8zvqHB//TekuzYZSBYAuBQJiNq1.fxQVDYJ.uBCOnWCtDVKE4H6', '测试号', NULL, 107, '[1,2]', '111@qq.com', '15601691200', 1, '', 0, '0:0:0:0:0:0:0:1', '2023-09-24 18:21:19', '', '2021-01-21 02:13:53', NULL, '2023-09-24 18:21:19', b'0', 1);
... ... @@ -3709,7 +3842,7 @@ INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`,
3709 3842 INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (108, 'admin108', '$2a$10$y6mfvKoNYL1GXWak8nYwVOH.kCWqjactkzdoIDgiKl93WN3Ejg.Lu', '芋艿', NULL, NULL, NULL, '', '15601691300', 0, '', 0, '', NULL, '1', '2022-02-20 23:00:50', '1', '2022-02-27 08:26:53', b'0', 119);
3710 3843 INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (109, 'admin109', '$2a$10$JAqvH0tEc0I7dfDVBI7zyuB4E3j.uH6daIjV53.vUS6PknFkDJkuK', '芋艿', NULL, NULL, NULL, '', '15601691300', 0, '', 0, '', NULL, '1', '2022-02-20 23:11:50', '1', '2022-02-27 08:26:56', b'0', 120);
3711 3844 INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (110, 'admin110', '$2a$10$mRMIYLDtRHlf6.9ipiqH1.Z.bh/R9dO9d5iHiGYPigi6r5KOoR2Wm', '小王', NULL, NULL, NULL, '', '15601691300', 0, '', 0, '127.0.0.1', '2022-09-25 22:47:33', '1', '2022-02-22 00:56:14', NULL, '2022-09-25 22:47:33', b'0', 121);
3712   -INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (111, 'test', '$2a$10$mExveopHUx9Q4QiLtAzhDeH3n4/QlNLzEsM4AqgxKrU.ciUZDXZCy', '测试用户', NULL, NULL, '[]', '', '', 0, '', 0, '', NULL, '110', '2022-02-23 13:14:33', '110', '2022-02-23 13:14:33', b'0', 121);
  3845 +INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (111, 'test', '$2a$10$mRMIYLDtRHlf6.9ipiqH1.Z.bh/R9dO9d5iHiGYPigi6r5KOoR2Wm', '测试用户', NULL, NULL, '[]', '', '', 0, '', 0, '0:0:0:0:0:0:0:1', '2023-10-18 23:31:51', '110', '2022-02-23 13:14:33', NULL, '2023-10-18 23:31:51', b'0', 121);
3713 3846 INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (112, 'newobject', '$2a$10$3alwklxqfq8/hKoW6oUV0OJp0IdQpBDauLy4633SpUjrRsStl6kMa', '新对象', NULL, 100, '[]', '', '', 1, '', 0, '0:0:0:0:0:0:0:1', '2023-02-10 13:48:13', '1', '2022-02-23 19:08:03', NULL, '2023-02-10 13:48:13', b'0', 1);
3714 3847 INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (113, 'aoteman', '$2a$10$0acJOIk2D25/oC87nyclE..0lzeu9DtQ/n3geP4fkun/zIVRhHJIO', '芋道', NULL, NULL, NULL, '', '15601691300', 0, '', 0, '127.0.0.1', '2022-03-19 18:38:51', '1', '2022-03-07 21:37:58', NULL, '2022-03-19 18:38:51', b'0', 122);
3715 3848 INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (114, 'hrmgr', '$2a$10$TR4eybBioGRhBmDBWkqWLO6NIh3mzYa8KBKDDB5woiGYFVlRAi.fu', 'hr 小姐姐', NULL, NULL, '[3]', '', '', 0, '', 0, '127.0.0.1', '2022-03-19 22:15:43', '1', '2022-03-19 21:50:58', NULL, '2022-03-19 22:15:43', b'0', 1);
... ...
sql/mysql/statistics.sql deleted
1   --- 交易统计表
2   -CREATE TABLE trade_statistics
3   -(
4   - id bigint AUTO_INCREMENT COMMENT '编号,主键自增'
5   - PRIMARY KEY,
6   - time datetime NOT NULL COMMENT '统计日期',
7   - order_create_count int DEFAULT 0 NOT NULL COMMENT '创建订单数',
8   - order_pay_count int DEFAULT 0 NOT NULL COMMENT '支付订单商品数',
9   - order_pay_price int DEFAULT 0 NOT NULL COMMENT '总支付金额,单位:分',
10   - order_wallet_pay_price int DEFAULT 0 NOT NULL COMMENT '总支付金额(余额),单位:分',
11   - after_sale_count int DEFAULT 0 NOT NULL COMMENT '退款订单数',
12   - after_sale_refund_price int DEFAULT 0 NOT NULL COMMENT '总退款金额,单位:分',
13   - brokerage_settlement_price int DEFAULT 0 NOT NULL COMMENT '佣金金额(已结算),单位:分',
14   - recharge_pay_count int DEFAULT 0 NOT NULL COMMENT '充值订单数',
15   - recharge_pay_price int DEFAULT 0 NOT NULL COMMENT '充值金额,单位:分',
16   - recharge_refund_count int DEFAULT 0 NOT NULL COMMENT '充值退款订单数',
17   - recharge_refund_price int DEFAULT 0 NOT NULL COMMENT '充值退款金额,单位:分',
18   - creator varchar(64) DEFAULT '' NULL COMMENT '创建者',
19   - create_time datetime DEFAULT CURRENT_TIMESTAMP NOT NULL COMMENT '创建时间',
20   - updater varchar(64) DEFAULT '' NULL COMMENT '更新者',
21   - update_time datetime DEFAULT CURRENT_TIMESTAMP NOT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
22   - deleted bit DEFAULT b'0' NOT NULL COMMENT '是否删除',
23   - tenant_id bigint DEFAULT 0 NOT NULL COMMENT '租户编号'
24   -)
25   - COMMENT '交易统计表';
26   -
27   -CREATE INDEX trade_statistics_time_index
28   - ON trade_statistics (time);
29   -
30   --- 菜单
31   -INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, component_name)
32   -VALUES ('统计管理', '', 1, 4, 0, '/statistics', 'ep:data-line', '', '');
33   -SELECT @parentId := LAST_INSERT_ID();
34   --- 交易统计
35   -INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, component_name)
36   -VALUES ('交易统计', '', 2, 1, @parentId, 'trade', 'fa-solid:credit-card', 'statistics/trade/index', 'TradeStatistics');
37   -SELECT @parentId := LAST_INSERT_ID();
38   -INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status)
39   -VALUES ('交易统计查询', 'statistics:trade:query', 3, 1, @parentId, '', '', '', 0);
40   -INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status)
41   -VALUES ('交易统计导出', 'statistics:trade:export', 3, 2, @parentId, '', '', '', 0);
42   --- 会员统计
43   -INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, component_name)
44   -VALUES ('会员统计', '', 2, 2, @parentId, 'member', 'ep:avatar', 'statistics/member/index', 'MemberStatistics');
45   -SELECT @parentId := LAST_INSERT_ID();
46   -INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status)
47   -VALUES ('会员统计查询', 'statistics:member:query', 3, 1, @parentId, '', '', '', 0);
48   -
49   -
yudao-dependencies/pom.xml
... ... @@ -14,28 +14,28 @@
14 14 <url>https://github.com/YunaiV/ruoyi-vue-pro</url>
15 15  
16 16 <properties>
17   - <revision>1.8.2-snapshot</revision>
  17 + <revision>1.8.3-snapshot</revision>
18 18 <flatten-maven-plugin.version>1.5.0</flatten-maven-plugin.version>
19 19 <!-- 统一依赖管理 -->
20   - <spring.boot.version>2.7.16</spring.boot.version>
  20 + <spring.boot.version>2.7.17</spring.boot.version>
21 21 <!-- Web 相关 -->
22 22 <springdoc.version>1.6.15</springdoc.version>
23 23 <knife4j.version>4.3.0</knife4j.version>
24 24 <servlet.versoin>2.5</servlet.versoin>
25 25 <!-- DB 相关 -->
26   - <druid.version>1.2.19</druid.version>
27   - <mybatis-plus.version>3.5.3.2</mybatis-plus.version>
28   - <mybatis-plus-generator.version>3.5.3.2</mybatis-plus-generator.version>
  26 + <druid.version>1.2.20</druid.version>
  27 + <mybatis-plus.version>3.5.4</mybatis-plus.version>
  28 + <mybatis-plus-generator.version>3.5.4</mybatis-plus-generator.version>
29 29 <dynamic-datasource.version>3.6.1</dynamic-datasource.version>
30 30 <mybatis-plus-join.version>1.4.6</mybatis-plus-join.version>
31 31 <redisson.version>3.18.0</redisson.version>
32   - <dm8.jdbc.version>8.1.2.141</dm8.jdbc.version>
  32 + <dm8.jdbc.version>8.1.3.62</dm8.jdbc.version>
33 33 <!-- 服务保障相关 -->
34   - <lock4j.version>2.2.3</lock4j.version>
  34 + <lock4j.version>2.2.5</lock4j.version>
35 35 <resilience4j.version>1.7.1</resilience4j.version>
36 36 <!-- 监控相关 -->
37 37 <skywalking.version>8.12.0</skywalking.version>
38   - <spring-boot-admin.version>2.7.10</spring-boot-admin.version>
  38 + <spring-boot-admin.version>2.7.11</spring-boot-admin.version>
39 39 <opentracing.version>0.33.0</opentracing.version>
40 40 <!-- Test 测试相关 -->
41 41 <podam.version>7.2.11.RELEASE</podam.version>
... ... @@ -44,8 +44,8 @@
44 44 <!-- Bpm 工作流相关 -->
45 45 <flowable.version>6.8.0</flowable.version>
46 46 <!-- 工具类相关 -->
47   - <captcha-plus.version>1.0.8</captcha-plus.version>
48   - <jsoup.version>1.16.1</jsoup.version>
  47 + <captcha-plus.version>1.0.10</captcha-plus.version>
  48 + <jsoup.version>1.16.2</jsoup.version>
49 49 <lombok.version>1.18.30</lombok.version>
50 50 <mapstruct.version>1.5.5.Final</mapstruct.version>
51 51 <hutool.version>5.8.22</hutool.version>
... ... @@ -53,10 +53,10 @@
53 53 <velocity.version>2.3</velocity.version>
54 54 <screw.version>1.0.5</screw.version>
55 55 <fastjson.version>1.2.83</fastjson.version>
56   - <guava.version>32.1.2-jre</guava.version>
  56 + <guava.version>32.1.3-jre</guava.version>
57 57 <guice.version>5.1.0</guice.version>
58 58 <transmittable-thread-local.version>2.14.2</transmittable-thread-local.version>
59   - <commons-net.version>3.9.0</commons-net.version>
  59 + <commons-net.version>3.10.0</commons-net.version>
60 60 <jsch.version>0.1.55</jsch.version>
61 61 <tika-core.version>2.7.0</tika-core.version>
62 62 <ip2region.version>2.7.0</ip2region.version>
... ... @@ -67,8 +67,8 @@
67 67 <minio.version>8.5.6</minio.version>
68 68 <aliyun-java-sdk-core.version>4.6.4</aliyun-java-sdk-core.version>
69 69 <aliyun-java-sdk-dysmsapi.version>2.2.1</aliyun-java-sdk-dysmsapi.version>
70   - <tencentcloud-sdk-java.version>3.1.853</tencentcloud-sdk-java.version>
71   - <justauth.version>1.0.5</justauth.version>
  70 + <tencentcloud-sdk-java.version>3.1.880</tencentcloud-sdk-java.version>
  71 + <justauth.version>1.0.7</justauth.version>
72 72 <jimureport.version>1.6.1</jimureport.version>
73 73 <xercesImpl.version>2.12.2</xercesImpl.version>
74 74 <weixin-java.version>4.5.0</weixin-java.version>
... ...
yudao-example/yudao-sso-demo-by-code/pom.xml
... ... @@ -21,7 +21,7 @@
21 21 <maven.compiler.target>8</maven.compiler.target>
22 22 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
23 23 <!-- 统一依赖管理 -->
24   - <spring.boot.version>2.7.16</spring.boot.version>
  24 + <spring.boot.version>2.7.17</spring.boot.version>
25 25 </properties>
26 26  
27 27 <dependencyManagement>
... ...
yudao-example/yudao-sso-demo-by-password/pom.xml
... ... @@ -21,7 +21,7 @@
21 21 <maven.compiler.target>8</maven.compiler.target>
22 22 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
23 23 <!-- 统一依赖管理 -->
24   - <spring.boot.version>2.7.16</spring.boot.version>
  24 + <spring.boot.version>2.7.17</spring.boot.version>
25 25 </properties>
26 26  
27 27 <dependencyManagement>
... ...
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/enums/CommonStatusEnum.java
1 1 package cn.iocoder.yudao.framework.common.enums;
2 2  
  3 +import cn.hutool.core.util.ObjUtil;
3 4 import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
4 5 import lombok.AllArgsConstructor;
5 6 import lombok.Getter;
... ... @@ -34,4 +35,12 @@ public enum CommonStatusEnum implements IntArrayValuable {
34 35 return ARRAYS;
35 36 }
36 37  
  38 + public static boolean isEnable(Integer status) {
  39 + return ObjUtil.equal(ENABLE.status, status);
  40 + }
  41 +
  42 + public static boolean isDisable(Integer status) {
  43 + return ObjUtil.equal(DISABLE.status, status);
  44 + }
  45 +
37 46 }
... ...
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/enums/SymbolConstant.java deleted
1   -package cn.iocoder.yudao.framework.common.enums;
2   -
3   -// TODO 这种简单的,暂时不用枚举哈,直接代码里写死就好啦;
4   -/**
5   - * 符号常量
6   - */
7   -public interface SymbolConstant {
8   -
9   - String D =",";
10   -
11   - /**
12   - * _
13   - */
14   - String XH="_";
15   - /**
16   - * -
17   - */
18   - String HG="-";
19   -
20   - /**
21   - * /
22   - */
23   - String XG="/";
24   -
25   - /**
26   - * 箭头
27   - */
28   - String ARROWHEAD="->";
29   -
30   - /**
31   - * 数组的开始元素
32   - */
33   - String ARRAY_START="[";
34   -
35   - /**
36   - * 数组的结束元素
37   - */
38   - String ARRAY_END="]";
39   -
40   - /**
41   - * null 字符串
42   - */
43   - String NULL_STRING="null";
44   -
45   - /**
46   - * 点号
47   - */
48   - String DIAN="\\.";
49   -}
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/enums/TerminalEnum.java
... ... @@ -18,8 +18,7 @@ public enum TerminalEnum implements IntArrayValuable {
18 18 WECHAT_MINI_PROGRAM(10, "微信小程序"),
19 19 WECHAT_WAP(11, "微信公众号"),
20 20 H5(20, "H5 网页"),
21   - IOS(31, "苹果 App"),
22   - ANDROID(32, "安卓 App"),
  21 + APP(31, "手机 App"),
23 22 ;
24 23  
25 24 public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(TerminalEnum::getTerminal).toArray();
... ...
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/collection/CollectionUtils.java
... ... @@ -8,6 +8,7 @@ import com.google.common.collect.ImmutableMap;
8 8 import java.util.*;
9 9 import java.util.function.*;
10 10 import java.util.stream.Collectors;
  11 +import java.util.stream.Stream;
11 12  
12 13 import static java.util.Arrays.asList;
13 14  
... ... @@ -267,4 +268,20 @@ public class CollectionUtils {
267 268 return deptId == null ? Collections.emptyList() : Collections.singleton(deptId);
268 269 }
269 270  
  271 + public static <T, U> List<U> convertListByFlatMap(Collection<T> from,
  272 + Function<T, ? extends Stream<? extends U>> func) {
  273 + if (CollUtil.isEmpty(from)) {
  274 + return new ArrayList<>();
  275 + }
  276 + return from.stream().flatMap(func).filter(Objects::nonNull).collect(Collectors.toList());
  277 + }
  278 +
  279 + public static <T, U> Set<U> convertSetByFlatMap(Collection<T> from,
  280 + Function<T, ? extends Stream<? extends U>> func) {
  281 + if (CollUtil.isEmpty(from)) {
  282 + return new HashSet<>();
  283 + }
  284 + return from.stream().flatMap(func).filter(Objects::nonNull).collect(Collectors.toSet());
  285 + }
  286 +
270 287 }
... ...
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/servlet/ServletUtils.java
... ... @@ -27,7 +27,7 @@ public class ServletUtils {
27 27 * 返回 JSON 字符串
28 28 *
29 29 * @param response 响应
30   - * @param object 对象,会序列化成 JSON 字符串
  30 + * @param object 对象,会序列化成 JSON 字符串
31 31 */
32 32 @SuppressWarnings("deprecation") // 必须使用 APPLICATION_JSON_UTF8_VALUE,否则会乱码
33 33 public static void writeJSON(HttpServletResponse response, Object object) {
... ... @@ -40,7 +40,7 @@ public class ServletUtils {
40 40 *
41 41 * @param response 响应
42 42 * @param filename 文件名
43   - * @param content 附件内容
  43 + * @param content 附件内容
44 44 */
45 45 public static void writeAttachment(HttpServletResponse response, String filename, byte[] content) throws IOException {
46 46 // 设置 header 和 contentType
... ... @@ -88,6 +88,8 @@ public class ServletUtils {
88 88 return ServletUtil.getClientIP(request);
89 89 }
90 90  
  91 + // TODO @疯狂:terminal 还是从 ServletUtils 里拿,更容易全局治理;
  92 +
91 93 public static boolean isJsonRequest(ServletRequest request) {
92 94 return StrUtil.startWithIgnoreCase(request.getContentType(), MediaType.APPLICATION_JSON_VALUE);
93 95 }
... ... @@ -107,4 +109,5 @@ public class ServletUtils {
107 109 public static Map<String, String> getParamMap(HttpServletRequest request) {
108 110 return ServletUtil.getParamMap(request);
109 111 }
  112 +
110 113 }
... ...
yudao-framework/yudao-spring-boot-starter-biz-error-code/src/main/java/cn/iocoder/yudao/framework/errorcode/config/YudaoErrorCodeConfiguration.java renamed to yudao-framework/yudao-spring-boot-starter-biz-error-code/src/main/java/cn/iocoder/yudao/framework/errorcode/config/YudaoErrorCodeAutoConfiguration.java
... ... @@ -21,7 +21,7 @@ import org.springframework.scheduling.annotation.EnableScheduling;
21 21 @ConditionalOnProperty(prefix = "yudao.error-code", value = "enable", matchIfMissing = true) // 允许使用 yudao.error-code.enable=false 禁用访问日志
22 22 @EnableConfigurationProperties(ErrorCodeProperties.class)
23 23 @EnableScheduling // 开启调度任务的功能,因为 ErrorCodeRemoteLoader 通过定时刷新错误码
24   -public class YudaoErrorCodeConfiguration {
  24 +public class YudaoErrorCodeAutoConfiguration {
25 25  
26 26 @Bean
27 27 public ErrorCodeAutoGenerator errorCodeAutoGenerator(@Value("${spring.application.name}") String applicationName,
... ...
yudao-framework/yudao-spring-boot-starter-biz-error-code/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
1   -cn.iocoder.yudao.framework.errorcode.config.YudaoErrorCodeConfiguration
2 1 \ No newline at end of file
  2 +cn.iocoder.yudao.framework.errorcode.config.YudaoErrorCodeAutoConfiguration
... ...
yudao-framework/yudao-spring-boot-starter-biz-ip/src/main/java/cn/iocoder/yudao/framework/ip/core/utils/AreaUtils.java
... ... @@ -132,25 +132,31 @@ public class AreaUtils {
132 132 return convertList(areas.values(), func, area -> type.getType().equals(area.getType()));
133 133 }
134 134  
135   - // TODO @疯狂:注释写下;
  135 + /**
  136 + * 根据区域编号、上级区域类型,获取上级区域编号
  137 + *
  138 + * @param id 区域编号
  139 + * @param type 区域类型
  140 + * @return 上级区域编号
  141 + */
136 142 public static Integer getParentIdByType(Integer id, @NonNull AreaTypeEnum type) {
137   - // TODO @疯狂:这种不要用 while true;因为万一脏数据,可能会死循环;可以转换成 for (int i = 0; i < Byte.MAX; i++) 一般是优先层级;
138   - do {
  143 + for (int i = 0; i < Byte.MAX_VALUE; i++) {
139 144 Area area = AreaUtils.getArea(id);
140 145 if (area == null) {
141 146 return null;
142 147 }
143   -
  148 + // 情况一:匹配到,返回它
144 149 if (type.getType().equals(area.getType())) {
145 150 return area.getId();
146 151 }
147   -
  152 + // 情况二:找到根节点,返回空
148 153 if (area.getParent() == null || area.getParent().getId() == null) {
149 154 return null;
150 155 }
151   -
  156 + // 其它:继续向上查找
152 157 id = area.getParent().getId();
153   - } while (true);
  158 + }
  159 + return null;
154 160 }
155 161  
156 162 }
... ...
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/transfer/PayTransferUnifiedReqDTO.java
... ... @@ -51,7 +51,9 @@ public class PayTransferUnifiedReqDTO {
51 51 private String title;
52 52  
53 53 /**
54   - * 收款方信息,转账类型不同,收款方信息不同
  54 + * 收款方信息。
  55 + *
  56 + * 转账类型 {@link #type} 不同,收款方信息不同
55 57 */
56 58 @NotEmpty(message = "收款方信息 不能为空")
57 59 private Map<String, String> payeeInfo;
... ...
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/PayClientFactoryImpl.java
... ... @@ -50,8 +50,6 @@ public class PayClientFactoryImpl implements PayClientFactory {
50 50 clientClass.put(ALIPAY_APP, AlipayAppPayClient.class);
51 51 clientClass.put(ALIPAY_PC, AlipayPcPayClient.class);
52 52 clientClass.put(ALIPAY_BAR, AlipayBarPayClient.class);
53   - // 支付包转账客户端
54   - clientClass.put(ALIPAY_TRANSFER, AlipayTransferClient.class);
55 53 // Mock 支付客户端
56 54 clientClass.put(MOCK, MockPayClient.class);
57 55 }
... ...
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AbstractAlipayPayClient.java
... ... @@ -6,24 +6,28 @@ import cn.hutool.core.lang.Assert;
6 6 import cn.hutool.core.map.MapUtil;
7 7 import cn.hutool.core.util.StrUtil;
8 8 import cn.hutool.http.HttpUtil;
  9 +import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
9 10 import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
10 11 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
11 12 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
12 13 import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO;
13 14 import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO;
  15 +import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferRespDTO;
  16 +import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferUnifiedReqDTO;
14 17 import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient;
15 18 import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderStatusRespEnum;
  19 +import cn.iocoder.yudao.framework.pay.core.enums.transfer.PayTransferTypeEnum;
16 20 import com.alipay.api.AlipayApiException;
17 21 import com.alipay.api.AlipayConfig;
18 22 import com.alipay.api.AlipayResponse;
19 23 import com.alipay.api.DefaultAlipayClient;
20   -import com.alipay.api.domain.AlipayTradeFastpayRefundQueryModel;
21   -import com.alipay.api.domain.AlipayTradeQueryModel;
22   -import com.alipay.api.domain.AlipayTradeRefundModel;
  24 +import com.alipay.api.domain.*;
23 25 import com.alipay.api.internal.util.AlipaySignature;
  26 +import com.alipay.api.request.AlipayFundTransUniTransferRequest;
24 27 import com.alipay.api.request.AlipayTradeFastpayRefundQueryRequest;
25 28 import com.alipay.api.request.AlipayTradeQueryRequest;
26 29 import com.alipay.api.request.AlipayTradeRefundRequest;
  30 +import com.alipay.api.response.AlipayFundTransUniTransferResponse;
27 31 import com.alipay.api.response.AlipayTradeFastpayRefundQueryResponse;
28 32 import com.alipay.api.response.AlipayTradeQueryResponse;
29 33 import com.alipay.api.response.AlipayTradeRefundResponse;
... ... @@ -39,6 +43,9 @@ import java.util.Objects;
39 43 import java.util.function.Supplier;
40 44  
41 45 import static cn.hutool.core.date.DatePattern.NORM_DATETIME_FORMATTER;
  46 +import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.BAD_REQUEST;
  47 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception0;
  48 +import static cn.iocoder.yudao.framework.pay.core.client.impl.alipay.AlipayPayClientConfig.MODE_CERTIFICATE;
42 49  
43 50 /**
44 51 * 支付宝抽象类,实现支付宝统一的接口、以及部分实现(退款)
... ... @@ -105,16 +112,20 @@ public abstract class AbstractAlipayPayClient extends AbstractPayClient&lt;AlipayPa
105 112 // 1.2 构建 AlipayTradeQueryRequest 请求
106 113 AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
107 114 request.setBizModel(model);
108   -
109   - // 2.1 执行请求
110   - AlipayTradeQueryResponse response = client.execute(request);
  115 + AlipayTradeQueryResponse response;
  116 + if (Objects.equals(config.getMode(), MODE_CERTIFICATE)) {
  117 + // 证书模式
  118 + response = client.certificateExecute(request);
  119 + } else {
  120 + response = client.execute(request);
  121 + }
111 122 if (!response.isSuccess()) { // 不成功,例如说订单不存在
112 123 return PayOrderRespDTO.closedOf(response.getSubCode(), response.getSubMsg(),
113 124 outTradeNo, response);
114 125 }
115 126 // 2.2 解析订单的状态
116 127 Integer status = parseStatus(response.getTradeStatus());
117   - Assert.notNull(status, (Supplier<Throwable>) () -> {
  128 + Assert.notNull(status, () -> {
118 129 throw new IllegalArgumentException(StrUtil.format("body({}) 的 trade_status 不正确", response.getBody()));
119 130 });
120 131 return PayOrderRespDTO.of(status, response.getTradeNo(), response.getBuyerUserId(), LocalDateTimeUtil.of(response.getSendPayDate()),
... ... @@ -148,7 +159,12 @@ public abstract class AbstractAlipayPayClient extends AbstractPayClient&lt;AlipayPa
148 159 request.setBizModel(model);
149 160  
150 161 // 2.1 执行请求
151   - AlipayTradeRefundResponse response = client.execute(request);
  162 + AlipayTradeRefundResponse response;
  163 + if (Objects.equals(config.getMode(), MODE_CERTIFICATE)) { // 证书模式
  164 + response = client.certificateExecute(request);
  165 + } else {
  166 + response = client.execute(request);
  167 + }
152 168 if (!response.isSuccess()) {
153 169 // 当出现 ACQ.SYSTEM_ERROR, 退款可能成功也可能失败。 返回 WAIT 状态. 后续 job 会轮询
154 170 if (ObjectUtils.equalsAny(response.getSubCode(), "ACQ.SYSTEM_ERROR", "SYSTEM_ERROR")) {
... ... @@ -185,7 +201,12 @@ public abstract class AbstractAlipayPayClient extends AbstractPayClient&lt;AlipayPa
185 201 request.setBizModel(model);
186 202  
187 203 // 2.1 执行请求
188   - AlipayTradeFastpayRefundQueryResponse response = client.execute(request);
  204 + AlipayTradeFastpayRefundQueryResponse response;
  205 + if (Objects.equals(config.getMode(), MODE_CERTIFICATE)) { // 证书模式
  206 + response = client.certificateExecute(request);
  207 + } else {
  208 + response = client.execute(request);
  209 + }
189 210 if (!response.isSuccess()) {
190 211 // 明确不存在的情况,应该就是失败,可进行关闭
191 212 if (ObjectUtils.equalsAny(response.getSubCode(), "TRADE_NOT_EXIST", "ACQ.TRADE_NOT_EXIST")) {
... ... @@ -202,7 +223,69 @@ public abstract class AbstractAlipayPayClient extends AbstractPayClient&lt;AlipayPa
202 223 return PayRefundRespDTO.waitingOf(null, outRefundNo, response);
203 224 }
204 225  
  226 + @Override
  227 + protected PayTransferRespDTO doUnifiedTransfer(PayTransferUnifiedReqDTO reqDTO) throws AlipayApiException {
  228 + // 1.1 校验公钥类型 必须使用公钥证书模式
  229 + if (!Objects.equals(config.getMode(), MODE_CERTIFICATE)) {
  230 + throw new IllegalStateException("支付宝单笔转账必须使用公钥证书模式");
  231 + }
205 232  
  233 + // 1.2 构建 AlipayFundTransUniTransferModel
  234 + AlipayFundTransUniTransferModel model = new AlipayFundTransUniTransferModel();
  235 + // ① 通用的参数
  236 + model.setTransAmount(formatAmount(reqDTO.getPrice())); // 转账金额
  237 + model.setOrderTitle(reqDTO.getTitle()); // 转账业务的标题,用于在支付宝用户的账单里显示。
  238 + model.setOutBizNo(reqDTO.getOutTransferNo());
  239 + model.setProductCode("TRANS_ACCOUNT_NO_PWD"); // 销售产品码。单笔无密转账固定为 TRANS_ACCOUNT_NO_PWD
  240 + model.setBizScene("DIRECT_TRANSFER"); // 业务场景 单笔无密转账固定为 DIRECT_TRANSFER
  241 + model.setBusinessParams(JsonUtils.toJsonString(reqDTO.getChannelExtras()));
  242 + PayTransferTypeEnum transferType = PayTransferTypeEnum.typeOf(reqDTO.getType());
  243 + switch (transferType) {
  244 + // TODO @jason:是不是不用传递 transferType 参数哈?因为应该已经明确是支付宝啦?
  245 + // @芋艿。 是不是还要考虑转账到银行卡。所以传 transferType 但是转账到银行卡不知道要如何测试??
  246 + case ALIPAY_BALANCE: {
  247 + // ② 个性化的参数
  248 + Participant payeeInfo = new Participant();
  249 + payeeInfo.setIdentityType("ALIPAY_LOGON_ID");
  250 + String logonId = MapUtil.getStr(reqDTO.getPayeeInfo(), "ALIPAY_LOGON_ID");
  251 + if (StrUtil.isEmpty(logonId)) {
  252 + throw exception0(BAD_REQUEST.getCode(), "支付包登录 ID 不能为空");
  253 + }
  254 + String accountName = MapUtil.getStr(reqDTO.getPayeeInfo(), "ALIPAY_ACCOUNT_NAME");
  255 + if (StrUtil.isEmpty(accountName)) {
  256 + throw exception0(BAD_REQUEST.getCode(), "支付包账户名称不能为空");
  257 + }
  258 + payeeInfo.setIdentity(logonId); // 支付宝登录号
  259 + payeeInfo.setName(accountName); // 支付宝账号姓名
  260 + model.setPayeeInfo(payeeInfo);
  261 + // 1.3 构建 AlipayFundTransUniTransferRequest
  262 + AlipayFundTransUniTransferRequest request = new AlipayFundTransUniTransferRequest();
  263 + request.setBizModel(model);
  264 + // 执行请求
  265 + AlipayFundTransUniTransferResponse response = client.certificateExecute(request);
  266 + // 处理结果
  267 + if (!response.isSuccess()) {
  268 + // 当出现 SYSTEM_ERROR, 转账可能成功也可能失败。 返回 WAIT 状态. 后续 job 会轮询
  269 + if (ObjectUtils.equalsAny(response.getSubCode(), "SYSTEM_ERROR", "ACQ.SYSTEM_ERROR")) {
  270 + return PayTransferRespDTO.waitingOf(null, reqDTO.getOutTransferNo(), response);
  271 + }
  272 + return PayTransferRespDTO.closedOf(response.getSubCode(), response.getSubMsg(),
  273 + reqDTO.getOutTransferNo(), response);
  274 + }
  275 + return PayTransferRespDTO.successOf(response.getOrderId(), parseTime(response.getTransDate()),
  276 + response.getOutBizNo(), response);
  277 + }
  278 + case BANK_CARD: {
  279 + Participant payeeInfo = new Participant();
  280 + payeeInfo.setIdentityType("BANKCARD_ACCOUNT");
  281 + // TODO 待实现
  282 + throw new UnsupportedOperationException("待实现");
  283 + }
  284 + default: {
  285 + throw new IllegalStateException("不正确的转账类型: " + transferType);
  286 + }
  287 + }
  288 + }
206 289  
207 290 // ========== 各种工具方法 ==========
208 291  
... ...
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayAppPayClient.java
... ... @@ -2,8 +2,6 @@ package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
2 2  
3 3 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
4 4 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
5   -import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferRespDTO;
6   -import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferUnifiedReqDTO;
7 5 import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
8 6 import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum;
9 7 import com.alipay.api.AlipayApiException;
... ... @@ -58,9 +56,4 @@ public class AlipayAppPayClient extends AbstractAlipayPayClient {
58 56 return PayOrderRespDTO.waitingOf(displayMode, response.getBody(),
59 57 reqDTO.getOutTradeNo(), response);
60 58 }
61   -
62   - @Override
63   - protected PayTransferRespDTO doUnifiedTransfer(PayTransferUnifiedReqDTO reqDTO) {
64   - throw new UnsupportedOperationException("支付宝【App 支付】不支持转账操作");
65   - }
66 59 }
... ...
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayBarPayClient.java
... ... @@ -5,8 +5,6 @@ import cn.hutool.core.map.MapUtil;
5 5 import cn.hutool.core.util.StrUtil;
6 6 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
7 7 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
8   -import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferRespDTO;
9   -import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferUnifiedReqDTO;
10 8 import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
11 9 import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum;
12 10 import com.alipay.api.AlipayApiException;
... ... @@ -16,9 +14,11 @@ import com.alipay.api.response.AlipayTradePayResponse;
16 14 import lombok.extern.slf4j.Slf4j;
17 15  
18 16 import java.time.LocalDateTime;
  17 +import java.util.Objects;
19 18  
20 19 import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.BAD_REQUEST;
21 20 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception0;
  21 +import static cn.iocoder.yudao.framework.pay.core.client.impl.alipay.AlipayPayClientConfig.MODE_CERTIFICATE;
22 22  
23 23 /**
24 24 * 支付宝【条码支付】的 PayClient 实现类
... ... @@ -61,7 +61,13 @@ public class AlipayBarPayClient extends AbstractAlipayPayClient {
61 61 request.setReturnUrl(reqDTO.getReturnUrl());
62 62  
63 63 // 2.1 执行请求
64   - AlipayTradePayResponse response = client.execute(request);
  64 + AlipayTradePayResponse response;
  65 + if (Objects.equals(config.getMode(), MODE_CERTIFICATE)) {
  66 + // 证书模式
  67 + response = client.certificateExecute(request);
  68 + } else {
  69 + response = client.execute(request);
  70 + }
65 71 // 2.2 处理结果
66 72 if (!response.isSuccess()) {
67 73 return buildClosedPayOrderRespDTO(reqDTO, response);
... ... @@ -76,9 +82,4 @@ public class AlipayBarPayClient extends AbstractAlipayPayClient {
76 82 return PayOrderRespDTO.waitingOf(displayMode, "",
77 83 reqDTO.getOutTradeNo(), response);
78 84 }
79   -
80   - @Override
81   - protected PayTransferRespDTO doUnifiedTransfer(PayTransferUnifiedReqDTO reqDTO) {
82   - throw new UnsupportedOperationException("支付宝【条码支付】不支持转账操作");
83   - }
84 85 }
... ...
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayPcPayClient.java
... ... @@ -4,8 +4,6 @@ import cn.hutool.core.util.ObjectUtil;
4 4 import cn.hutool.http.Method;
5 5 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
6 6 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
7   -import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferRespDTO;
8   -import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferUnifiedReqDTO;
9 7 import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
10 8 import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum;
11 9 import com.alipay.api.AlipayApiException;
... ... @@ -68,9 +66,4 @@ public class AlipayPcPayClient extends AbstractAlipayPayClient {
68 66 return PayOrderRespDTO.waitingOf(displayMode, response.getBody(),
69 67 reqDTO.getOutTradeNo(), response);
70 68 }
71   -
72   - @Override
73   - protected PayTransferRespDTO doUnifiedTransfer(PayTransferUnifiedReqDTO reqDTO) {
74   - throw new UnsupportedOperationException("支付宝【PC 网站】不支持转账操作");
75   - }
76 69 }
... ...
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayQrPayClient.java
... ... @@ -2,8 +2,6 @@ package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
2 2  
3 3 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
4 4 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
5   -import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferRespDTO;
6   -import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferUnifiedReqDTO;
7 5 import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
8 6 import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum;
9 7 import com.alipay.api.AlipayApiException;
... ... @@ -12,6 +10,10 @@ import com.alipay.api.request.AlipayTradePrecreateRequest;
12 10 import com.alipay.api.response.AlipayTradePrecreateResponse;
13 11 import lombok.extern.slf4j.Slf4j;
14 12  
  13 +import java.util.Objects;
  14 +
  15 +import static cn.iocoder.yudao.framework.pay.core.client.impl.alipay.AlipayPayClientConfig.MODE_CERTIFICATE;
  16 +
15 17 /**
16 18 * 支付宝【扫码支付】的 PayClient 实现类
17 19 *
... ... @@ -47,7 +49,13 @@ public class AlipayQrPayClient extends AbstractAlipayPayClient {
47 49 request.setReturnUrl(reqDTO.getReturnUrl());
48 50  
49 51 // 2.1 执行请求
50   - AlipayTradePrecreateResponse response = client.execute(request);
  52 + AlipayTradePrecreateResponse response;
  53 + if (Objects.equals(config.getMode(), MODE_CERTIFICATE)) {
  54 + // 证书模式
  55 + response = client.certificateExecute(request);
  56 + } else {
  57 + response = client.execute(request);
  58 + }
51 59 // 2.2 处理结果
52 60 if (!response.isSuccess()) {
53 61 return buildClosedPayOrderRespDTO(reqDTO, response);
... ... @@ -55,9 +63,4 @@ public class AlipayQrPayClient extends AbstractAlipayPayClient {
55 63 return PayOrderRespDTO.waitingOf(displayMode, response.getQrCode(),
56 64 reqDTO.getOutTradeNo(), response);
57 65 }
58   -
59   - @Override
60   - protected PayTransferRespDTO doUnifiedTransfer(PayTransferUnifiedReqDTO reqDTO) {
61   - throw new UnsupportedOperationException("支付宝【扫码支付】不支持转账操作");
62   - }
63 66 }
... ...
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayTransferClient.java deleted
1   -package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
2   -
3   -import cn.hutool.core.map.MapUtil;
4   -import cn.hutool.core.util.StrUtil;
5   -import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
6   -import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
7   -import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
8   -import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
9   -import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO;
10   -import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO;
11   -import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferRespDTO;
12   -import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferUnifiedReqDTO;
13   -import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
14   -import cn.iocoder.yudao.framework.pay.core.enums.transfer.PayTransferTypeEnum;
15   -import com.alipay.api.AlipayApiException;
16   -import com.alipay.api.domain.AlipayFundTransUniTransferModel;
17   -import com.alipay.api.domain.Participant;
18   -import com.alipay.api.request.AlipayFundTransUniTransferRequest;
19   -import com.alipay.api.response.AlipayFundTransUniTransferResponse;
20   -import lombok.extern.slf4j.Slf4j;
21   -
22   -import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.BAD_REQUEST;
23   -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception0;
24   -
25   -/**
26   - * 支付宝转账的 PayClient 实现类
27   - *
28   - * @author jason
29   - */
30   -@Slf4j
31   -public class AlipayTransferClient extends AbstractAlipayPayClient {
32   - public AlipayTransferClient(Long channelId, AlipayPayClientConfig config) {
33   - super(channelId, PayChannelEnum.ALIPAY_TRANSFER.getCode(), config);
34   - }
35   - @Override
36   - protected PayOrderRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) {
37   - throw new UnsupportedOperationException("支付宝转账不支持统一下单请求");
38   - }
39   - @Override
40   - protected PayRefundRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) {
41   - throw new UnsupportedOperationException("支付宝转账不支持统一退款请求");
42   - }
43   - @Override
44   - protected PayTransferRespDTO doUnifiedTransfer(PayTransferUnifiedReqDTO reqDTO) throws AlipayApiException {
45   - // 1.1 构建 AlipayFundTransUniTransferModel
46   - AlipayFundTransUniTransferModel model = new AlipayFundTransUniTransferModel();
47   - // ① 通用的参数
48   - model.setTransAmount(formatAmount(reqDTO.getPrice())); // 转账金额
49   - model.setOrderTitle(reqDTO.getTitle()); // 转账业务的标题,用于在支付宝用户的账单里显示。
50   - model.setOutBizNo(reqDTO.getOutTransferNo());
51   - model.setProductCode("TRANS_ACCOUNT_NO_PWD"); // 销售产品码。单笔无密转账固定为 TRANS_ACCOUNT_NO_PWD
52   - model.setBizScene("DIRECT_TRANSFER"); // 业务场景 单笔无密转账固定为 DIRECT_TRANSFER。
53   - model.setBusinessParams(JsonUtils.toJsonString(reqDTO.getChannelExtras()));
54   - PayTransferTypeEnum transferType = PayTransferTypeEnum.ofType(reqDTO.getType());
55   - switch(transferType){
56   - case WX_BALANCE :
57   - case WALLET_BALANCE : {
58   - log.error("[doUnifiedTransfer],支付宝转账不支持的转账类型{}", transferType);
59   - throw new UnsupportedOperationException(String.format("支付宝转账不支持转账类型: %s",transferType.getName()));
60   - }
61   - case ALIPAY_BALANCE : {
62   - // ② 个性化的参数
63   - Participant payeeInfo = new Participant();
64   - payeeInfo.setIdentityType("ALIPAY_LOGON_ID");
65   - String logonId = MapUtil.getStr(reqDTO.getPayeeInfo(), "ALIPAY_LOGON_ID");
66   - if (StrUtil.isEmpty(logonId)) {
67   - throw exception0(BAD_REQUEST.getCode(), "支付包登录 ID 不能为空");
68   - }
69   - String accountName = MapUtil.getStr(reqDTO.getPayeeInfo(), "ALIPAY_ACCOUNT_NAME");
70   - if (StrUtil.isEmpty(accountName)) {
71   - throw exception0(BAD_REQUEST.getCode(), "支付包账户名称不能为空");
72   - }
73   - payeeInfo.setIdentity(logonId); // 支付宝登录号
74   - payeeInfo.setName(accountName); // 支付宝账号姓名
75   - model.setPayeeInfo(payeeInfo);
76   - // 1.2 构建 AlipayFundTransUniTransferRequest
77   - AlipayFundTransUniTransferRequest request = new AlipayFundTransUniTransferRequest();
78   - request.setBizModel(model);
79   - // 执行请求
80   - AlipayFundTransUniTransferResponse response = client.certificateExecute(request);
81   - // 处理结果
82   - if (!response.isSuccess()) {
83   - // 当出现 SYSTEM_ERROR, 转账可能成功也可能失败。 返回 WAIT 状态. 后续 job 会轮询
84   - if (ObjectUtils.equalsAny(response.getSubCode(), "SYSTEM_ERROR", "ACQ.SYSTEM_ERROR")) {
85   - return PayTransferRespDTO.waitingOf(null, reqDTO.getOutTransferNo(), response);
86   - }
87   - return PayTransferRespDTO.closedOf(response.getSubCode(), response.getSubMsg(),
88   - reqDTO.getOutTransferNo(), response);
89   - }
90   - return PayTransferRespDTO.successOf(response.getOrderId(), parseTime(response.getTransDate()),
91   - response.getOutBizNo(), response);
92   - }
93   - case BANK_CARD : {
94   - Participant payeeInfo = new Participant();
95   - payeeInfo.setIdentityType("BANKCARD_ACCOUNT");
96   - throw new UnsupportedOperationException("待实现");
97   - }
98   - default: {
99   - throw new IllegalStateException("不正确的转账类型: " + transferType);
100   - }
101   - }
102   - }
103   -}
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayWapPayClient.java
... ... @@ -3,8 +3,6 @@ package cn.iocoder.yudao.framework.pay.core.client.impl.alipay;
3 3 import cn.hutool.http.Method;
4 4 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
5 5 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
6   -import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferRespDTO;
7   -import cn.iocoder.yudao.framework.pay.core.client.dto.transfer.PayTransferUnifiedReqDTO;
8 6 import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
9 7 import cn.iocoder.yudao.framework.pay.core.enums.order.PayOrderDisplayModeEnum;
10 8 import com.alipay.api.AlipayApiException;
... ... @@ -57,9 +55,4 @@ public class AlipayWapPayClient extends AbstractAlipayPayClient {
57 55 return PayOrderRespDTO.waitingOf(displayMode, response.getBody(),
58 56 reqDTO.getOutTradeNo(), response);
59 57 }
60   -
61   - @Override
62   - public PayTransferRespDTO doUnifiedTransfer(PayTransferUnifiedReqDTO reqDTO) {
63   - throw new UnsupportedOperationException("支付宝【Wap 网站】不支持转账操作");
64   - }
65 58 }
... ...
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/mock/MockPayClient.java
... ... @@ -70,4 +70,5 @@ public class MockPayClient extends AbstractPayClient&lt;NonePayClientConfig&gt; {
70 70 protected PayTransferRespDTO doUnifiedTransfer(PayTransferUnifiedReqDTO reqDTO) {
71 71 throw new UnsupportedOperationException("待实现");
72 72 }
  73 +
73 74 }
... ...
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/channel/PayChannelEnum.java
... ... @@ -28,8 +28,6 @@ public enum PayChannelEnum {
28 28 ALIPAY_APP("alipay_app", "支付宝App 支付", AlipayPayClientConfig.class),
29 29 ALIPAY_QR("alipay_qr", "支付宝扫码支付", AlipayPayClientConfig.class),
30 30 ALIPAY_BAR("alipay_bar", "支付宝条码支付", AlipayPayClientConfig.class),
31   - ALIPAY_TRANSFER("alipay_transfer", "支付宝转账", AlipayPayClientConfig.class),
32   -
33 31 MOCK("mock", "模拟支付", NonePayClientConfig.class),
34 32  
35 33 WALLET("wallet", "钱包支付", NonePayClientConfig.class);
... ...
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/transfer/PayTransferStatusRespEnum.java
... ... @@ -18,10 +18,10 @@ public enum PayTransferStatusRespEnum {
18 18  
19 19 /**
20 20 * TODO 转账到银行卡. 会有T+0 T+1 到账的请情况。 还未实现
  21 + * TODO @jason:可以看看其它开源项目,针对这个场景,处理策略是怎么样的?例如说,每天主动轮询?这个状态的单子?
21 22 */
22 23 IN_PROGRESS(10, "转账进行中"),
23 24  
24   -
25 25 SUCCESS(20, "转账成功"),
26 26 /**
27 27 * 转账关闭 (失败,或者其它情况)
... ...
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/transfer/PayTransferTypeEnum.java
... ... @@ -15,6 +15,7 @@ import java.util.Arrays;
15 15 @AllArgsConstructor
16 16 @Getter
17 17 public enum PayTransferTypeEnum implements IntArrayValuable {
  18 +
18 19 ALIPAY_BALANCE(1, "支付宝余额"),
19 20 WX_BALANCE(2, "微信余额"),
20 21 BANK_CARD(3, "银行卡"),
... ... @@ -33,7 +34,8 @@ public enum PayTransferTypeEnum implements IntArrayValuable {
33 34 return ARRAYS;
34 35 }
35 36  
36   - public static PayTransferTypeEnum ofType(Integer type) {
  37 + public static PayTransferTypeEnum typeOf(Integer type) {
37 38 return ArrayUtil.firstMatch(item -> item.getType().equals(type), values());
38 39 }
  40 +
39 41 }
... ...
yudao-framework/yudao-spring-boot-starter-biz-tenant/src/test/java/cn/iocoder/yudao/framework/tenant/core/job/TestJob.java deleted
1   -package cn.iocoder.yudao.framework.tenant.core.job;
2   -
3   -import cn.hutool.core.collection.CollUtil;
4   -import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler;
5   -import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
6   -import org.springframework.stereotype.Component;
7   -
8   -import java.util.List;
9   -import java.util.concurrent.CopyOnWriteArrayList;
10   -
11   -@Component
12   -public class TestJob implements JobHandler {
13   -
14   - private final List<Long> tenantIds = new CopyOnWriteArrayList<>();
15   -
16   - @Override
17   - @TenantJob // 标记多租户
18   - public String execute(String param) throws Exception {
19   - tenantIds.add(TenantContextHolder.getTenantId());
20   - return "success";
21   - }
22   -
23   - public List<Long> getTenantIds() {
24   - CollUtil.sort(tenantIds, Long::compareTo);
25   - return tenantIds;
26   - }
27   -
28   -}
yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/query/MPJLambdaWrapperX.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.mybatis.core.query;
  2 +
  3 +import cn.hutool.core.util.ArrayUtil;
  4 +import cn.hutool.core.util.ObjectUtil;
  5 +import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils;
  6 +import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
  7 +import com.github.yulichang.toolkit.MPJWrappers;
  8 +import com.github.yulichang.wrapper.MPJLambdaWrapper;
  9 +import org.springframework.util.StringUtils;
  10 +
  11 +import java.util.Collection;
  12 +import java.util.function.Consumer;
  13 +
  14 +/**
  15 + * 拓展 MyBatis Plus Join QueryWrapper 类,主要增加如下功能:
  16 + * <p>
  17 + * 1. 拼接条件的方法,增加 xxxIfPresent 方法,用于判断值不存在的时候,不要拼接到条件中。
  18 + *
  19 + * @param <T> 数据类型
  20 + */
  21 +public class MPJLambdaWrapperX<T> extends MPJLambdaWrapper<T> {
  22 +
  23 + public MPJLambdaWrapperX<T> likeIfPresent(SFunction<T, ?> column, String val) {
  24 + MPJWrappers.lambdaJoin().like(column, val);
  25 + if (StringUtils.hasText(val)) {
  26 + return (MPJLambdaWrapperX<T>) super.like(column, val);
  27 + }
  28 + return this;
  29 + }
  30 +
  31 + public MPJLambdaWrapperX<T> inIfPresent(SFunction<T, ?> column, Collection<?> values) {
  32 + if (ObjectUtil.isAllNotEmpty(values) && !ArrayUtil.isEmpty(values)) {
  33 + return (MPJLambdaWrapperX<T>) super.in(column, values);
  34 + }
  35 + return this;
  36 + }
  37 +
  38 + public MPJLambdaWrapperX<T> inIfPresent(SFunction<T, ?> column, Object... values) {
  39 + if (ObjectUtil.isAllNotEmpty(values) && !ArrayUtil.isEmpty(values)) {
  40 + return (MPJLambdaWrapperX<T>) super.in(column, values);
  41 + }
  42 + return this;
  43 + }
  44 +
  45 + public MPJLambdaWrapperX<T> eqIfPresent(SFunction<T, ?> column, Object val) {
  46 + if (ObjectUtil.isNotEmpty(val)) {
  47 + return (MPJLambdaWrapperX<T>) super.eq(column, val);
  48 + }
  49 + return this;
  50 + }
  51 +
  52 + public MPJLambdaWrapperX<T> neIfPresent(SFunction<T, ?> column, Object val) {
  53 + if (ObjectUtil.isNotEmpty(val)) {
  54 + return (MPJLambdaWrapperX<T>) super.ne(column, val);
  55 + }
  56 + return this;
  57 + }
  58 +
  59 + public MPJLambdaWrapperX<T> gtIfPresent(SFunction<T, ?> column, Object val) {
  60 + if (val != null) {
  61 + return (MPJLambdaWrapperX<T>) super.gt(column, val);
  62 + }
  63 + return this;
  64 + }
  65 +
  66 + public MPJLambdaWrapperX<T> geIfPresent(SFunction<T, ?> column, Object val) {
  67 + if (val != null) {
  68 + return (MPJLambdaWrapperX<T>) super.ge(column, val);
  69 + }
  70 + return this;
  71 + }
  72 +
  73 + public MPJLambdaWrapperX<T> ltIfPresent(SFunction<T, ?> column, Object val) {
  74 + if (val != null) {
  75 + return (MPJLambdaWrapperX<T>) super.lt(column, val);
  76 + }
  77 + return this;
  78 + }
  79 +
  80 + public MPJLambdaWrapperX<T> leIfPresent(SFunction<T, ?> column, Object val) {
  81 + if (val != null) {
  82 + return (MPJLambdaWrapperX<T>) super.le(column, val);
  83 + }
  84 + return this;
  85 + }
  86 +
  87 + public MPJLambdaWrapperX<T> betweenIfPresent(SFunction<T, ?> column, Object val1, Object val2) {
  88 + if (val1 != null && val2 != null) {
  89 + return (MPJLambdaWrapperX<T>) super.between(column, val1, val2);
  90 + }
  91 + if (val1 != null) {
  92 + return (MPJLambdaWrapperX<T>) ge(column, val1);
  93 + }
  94 + if (val2 != null) {
  95 + return (MPJLambdaWrapperX<T>) le(column, val2);
  96 + }
  97 + return this;
  98 + }
  99 +
  100 + public MPJLambdaWrapperX<T> betweenIfPresent(SFunction<T, ?> column, Object[] values) {
  101 + Object val1 = ArrayUtils.get(values, 0);
  102 + Object val2 = ArrayUtils.get(values, 1);
  103 + return betweenIfPresent(column, val1, val2);
  104 + }
  105 +
  106 + // ========== 重写父类方法,方便链式调用 ==========
  107 +
  108 + @Override
  109 + public <X> MPJLambdaWrapperX<T> eq(boolean condition, SFunction<X, ?> column, Object val) {
  110 + super.eq(condition, column, val);
  111 + return this;
  112 + }
  113 +
  114 + @Override
  115 + public <X> MPJLambdaWrapperX<T> eq(SFunction<X, ?> column, Object val) {
  116 + super.eq(column, val);
  117 + return this;
  118 + }
  119 +
  120 + @Override
  121 + public <X> MPJLambdaWrapperX<T> orderByDesc(SFunction<X, ?> column) {
  122 + //noinspection unchecked
  123 + super.orderByDesc(true, column);
  124 + return this;
  125 + }
  126 +
  127 + @Override
  128 + public MPJLambdaWrapperX<T> last(String lastSql) {
  129 + super.last(lastSql);
  130 + return this;
  131 + }
  132 +
  133 + @Override
  134 + public <X> MPJLambdaWrapperX<T> in(SFunction<X, ?> column, Collection<?> coll) {
  135 + super.in(column, coll);
  136 + return this;
  137 + }
  138 +
  139 + @Override
  140 + public MPJLambdaWrapperX<T> selectAll(Class<?> clazz) {
  141 + super.selectAll(clazz);
  142 + return this;
  143 + }
  144 +
  145 + @Override
  146 + public MPJLambdaWrapperX<T> selectAll(Class<?> clazz, String prefix) {
  147 + super.selectAll(clazz, prefix);
  148 + return this;
  149 + }
  150 +
  151 + @Override
  152 + public <S> MPJLambdaWrapperX<T> selectAs(SFunction<S, ?> column, String alias) {
  153 + super.selectAs(column, alias);
  154 + return this;
  155 + }
  156 +
  157 + @Override
  158 + public <E> MPJLambdaWrapperX<T> selectAs(String column, SFunction<E, ?> alias) {
  159 + super.selectAs(column, alias);
  160 + return this;
  161 + }
  162 +
  163 + @Override
  164 + public <S, X> MPJLambdaWrapperX<T> selectAs(SFunction<S, ?> column, SFunction<X, ?> alias) {
  165 + super.selectAs(column, alias);
  166 + return this;
  167 + }
  168 +
  169 + @Override
  170 + public <E, X> MPJLambdaWrapperX<T> selectAs(String index, SFunction<E, ?> column, SFunction<X, ?> alias) {
  171 + super.selectAs(index, column, alias);
  172 + return this;
  173 + }
  174 +
  175 + @Override
  176 + public <E> MPJLambdaWrapperX<T> selectAsClass(Class<E> source, Class<?> tag) {
  177 + super.selectAsClass(source, tag);
  178 + return this;
  179 + }
  180 +
  181 + @Override
  182 + public <E, F> MPJLambdaWrapperX<T> selectSub(Class<E> clazz, Consumer<MPJLambdaWrapper<E>> consumer, SFunction<F, ?> alias) {
  183 + super.selectSub(clazz, consumer, alias);
  184 + return this;
  185 + }
  186 +
  187 + @Override
  188 + public <E, F> MPJLambdaWrapperX<T> selectSub(Class<E> clazz, String st, Consumer<MPJLambdaWrapper<E>> consumer, SFunction<F, ?> alias) {
  189 + super.selectSub(clazz, st, consumer, alias);
  190 + return this;
  191 + }
  192 +
  193 + @Override
  194 + public <S> MPJLambdaWrapperX<T> selectCount(SFunction<S, ?> column) {
  195 + super.selectCount(column);
  196 + return this;
  197 + }
  198 +
  199 + @Override
  200 + public MPJLambdaWrapperX<T> selectCount(Object column, String alias) {
  201 + super.selectCount(column, alias);
  202 + return this;
  203 + }
  204 +
  205 + @Override
  206 + public <X> MPJLambdaWrapperX<T> selectCount(Object column, SFunction<X, ?> alias) {
  207 + super.selectCount(column, alias);
  208 + return this;
  209 + }
  210 +
  211 + @Override
  212 + public <S, X> MPJLambdaWrapperX<T> selectCount(SFunction<S, ?> column, String alias) {
  213 + super.selectCount(column, alias);
  214 + return this;
  215 + }
  216 +
  217 + @Override
  218 + public <S, X> MPJLambdaWrapperX<T> selectCount(SFunction<S, ?> column, SFunction<X, ?> alias) {
  219 + super.selectCount(column, alias);
  220 + return this;
  221 + }
  222 +
  223 + @Override
  224 + public <S> MPJLambdaWrapperX<T> selectSum(SFunction<S, ?> column) {
  225 + super.selectSum(column);
  226 + return this;
  227 + }
  228 +
  229 + @Override
  230 + public <S, X> MPJLambdaWrapperX<T> selectSum(SFunction<S, ?> column, String alias) {
  231 + super.selectSum(column, alias);
  232 + return this;
  233 + }
  234 +
  235 + @Override
  236 + public <S, X> MPJLambdaWrapperX<T> selectSum(SFunction<S, ?> column, SFunction<X, ?> alias) {
  237 + super.selectSum(column, alias);
  238 + return this;
  239 + }
  240 +
  241 + @Override
  242 + public <S> MPJLambdaWrapperX<T> selectMax(SFunction<S, ?> column) {
  243 + super.selectMax(column);
  244 + return this;
  245 + }
  246 +
  247 + @Override
  248 + public <S, X> MPJLambdaWrapperX<T> selectMax(SFunction<S, ?> column, String alias) {
  249 + super.selectMax(column, alias);
  250 + return this;
  251 + }
  252 +
  253 + @Override
  254 + public <S, X> MPJLambdaWrapperX<T> selectMax(SFunction<S, ?> column, SFunction<X, ?> alias) {
  255 + super.selectMax(column, alias);
  256 + return this;
  257 + }
  258 +
  259 + @Override
  260 + public <S> MPJLambdaWrapperX<T> selectMin(SFunction<S, ?> column) {
  261 + super.selectMin(column);
  262 + return this;
  263 + }
  264 +
  265 + @Override
  266 + public <S, X> MPJLambdaWrapperX<T> selectMin(SFunction<S, ?> column, String alias) {
  267 + super.selectMin(column, alias);
  268 + return this;
  269 + }
  270 +
  271 + @Override
  272 + public <S, X> MPJLambdaWrapperX<T> selectMin(SFunction<S, ?> column, SFunction<X, ?> alias) {
  273 + super.selectMin(column, alias);
  274 + return this;
  275 + }
  276 +
  277 + @Override
  278 + public <S> MPJLambdaWrapperX<T> selectAvg(SFunction<S, ?> column) {
  279 + super.selectAvg(column);
  280 + return this;
  281 + }
  282 +
  283 + @Override
  284 + public <S, X> MPJLambdaWrapperX<T> selectAvg(SFunction<S, ?> column, String alias) {
  285 + super.selectAvg(column, alias);
  286 + return this;
  287 + }
  288 +
  289 + @Override
  290 + public <S, X> MPJLambdaWrapperX<T> selectAvg(SFunction<S, ?> column, SFunction<X, ?> alias) {
  291 + super.selectAvg(column, alias);
  292 + return this;
  293 + }
  294 +
  295 + @Override
  296 + public <S> MPJLambdaWrapperX<T> selectLen(SFunction<S, ?> column) {
  297 + super.selectLen(column);
  298 + return this;
  299 + }
  300 +
  301 + @Override
  302 + public <S, X> MPJLambdaWrapperX<T> selectLen(SFunction<S, ?> column, String alias) {
  303 + super.selectLen(column, alias);
  304 + return this;
  305 + }
  306 +
  307 + @Override
  308 + public <S, X> MPJLambdaWrapperX<T> selectLen(SFunction<S, ?> column, SFunction<X, ?> alias) {
  309 + super.selectLen(column, alias);
  310 + return this;
  311 + }
  312 +
  313 +}
... ...
yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/apilog/core/service/ApiAccessLog.java
... ... @@ -5,7 +5,6 @@ import lombok.Data;
5 5 import javax.validation.constraints.NotNull;
6 6 import java.time.LocalDateTime;
7 7  
8   -// TODO @小吉祥:搞个 job,清理 14 天外的访问日志;
9 8 /**
10 9 * API 访问日志
11 10 *
... ...
yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/apilog/core/service/ApiErrorLog.java
... ... @@ -5,7 +5,6 @@ import lombok.Data;
5 5 import javax.validation.constraints.NotNull;
6 6 import java.time.LocalDateTime;
7 7  
8   -// TODO @小吉祥:搞个 job,清理 14 天外的异常日志;
9 8 /**
10 9 * API 错误日志
11 10 *
... ...
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/task/BpmCommentTypeEnum.java
... ... @@ -10,26 +10,26 @@ import lombok.Getter;
10 10 @AllArgsConstructor
11 11 public enum BpmCommentTypeEnum {
12 12  
13   - APPROVE(1, "通过"),
14   - REJECT(2, "不通过"),
15   - CANCEL(3, "已取消"),
16   -
17   - // TODO @海:18 行可以去掉哈;这个是之前为了 status 隔离用的;
18   - // ========== 流程任务独有的状态 ==========
19   -
20   - BACK(4, "退回"), // 退回
21   - DELEGATE(5, "委派"),
22   - ADD_SIGN(6, "加签"),
23   - SUB_SIGN(7,"减签"),
  13 + APPROVE(1, "通过", ""),
  14 + REJECT(2, "不通过", ""),
  15 + CANCEL(3, "已取消", ""),
  16 + BACK(4, "退回", ""),
  17 + DELEGATE(5, "委派", ""),
  18 + ADD_SIGN(6, "加签", "[{}]{}给了[{}],理由为:{}"),
  19 + SUB_SIGN(7, "减签", "[{}]操作了【减签】,审批人[{}]的任务被取消"),
24 20 ;
25 21  
26   - // TODO @海:字段叫 type 更合适噢
27 22 /**
28   - * 结果
  23 + * 操作类型
29 24 */
30   - private final Integer result;
  25 + private final Integer type;
31 26 /**
32   - * 描述
  27 + * 操作名字
33 28 */
34   - private final String desc;
  29 + private final String name;
  30 + /**
  31 + * 操作描述
  32 + */
  33 + private final String comment;
  34 +
35 35 }
... ...
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/task/BpmProcessInstanceResultEnum.java
... ... @@ -27,19 +27,27 @@ public enum BpmProcessInstanceResultEnum {
27 27 DELEGATE(6, "委派"),
28 28 /**
29 29 * 【加签】源任务已经审批完成,但是它使用了后加签,后加签的任务未完成,源任务就会是这个状态
  30 + * 相当于是 通过 APPROVE 的特殊状态
30 31 * 例如:A审批, A 后加签了 B,并且审批通过了任务,但是 B 还未审批,则当前任务状态为“待后加签任务完成”
31 32 */
32   - ADD_SIGN_AFTER(7, "待后加签任务完成"), // TODO @海:这个定义,是不是 通过(待后加签任务完成),相当于是 APPROVE 的特殊状态
  33 + SIGN_AFTER(7, "待后加签任务完成"),
33 34 /**
34 35 * 【加签】源任务未审批,但是向前加签了,所以源任务状态变为“待前加签任务完成”
  36 + * 相当于是 处理中 PROCESS 的特殊状态
35 37 * 例如:A 审批, A 前加签了 B,B 还未审核
36 38 */
37   - ADD_SIGN_BEFORE(8, "待前加签任务完成"), // TODO @海:这个定义,是不是 处理中(待前加签任务审批),相当于是 PROCESS 的特殊状态
  39 + SIGN_BEFORE(8, "待前加签任务完成"),
38 40 /**
39 41 * 【加签】后加签任务被创建时的初始状态
  42 + * 相当于是 处理中 PROCESS 的特殊状态
40 43 * 因为需要源任务先完成,才能到后加签的人来审批,所以加了一个状态区分
41 44 */
42   - WAIT_BEFORE_TASK(9, "待前置任务完成"); // TODO @海:这个定义,是不是 处理中(待前置任务审批),相当于是 PROCESS 的特殊状态
  45 + WAIT_BEFORE_TASK(9, "待前置任务完成");
  46 +
  47 + /**
  48 + * 能被减签的状态
  49 + */
  50 + public static final List<Integer> CAN_SUB_SIGN_STATUS_LIST = Arrays.asList(PROCESS.result, WAIT_BEFORE_TASK.result);
43 51  
44 52 /**
45 53 * 结果
... ... @@ -63,13 +71,7 @@ public enum BpmProcessInstanceResultEnum {
63 71 public static boolean isEndResult(Integer result) {
64 72 return ObjectUtils.equalsAny(result, APPROVE.getResult(), REJECT.getResult(),
65 73 CANCEL.getResult(), BACK.getResult(),
66   - ADD_SIGN_AFTER.getResult());
  74 + SIGN_AFTER.getResult());
67 75 }
68 76  
69   - // TODO @海:静态变量,需要放到成员变量前面;另外,如果是复数,可以加 S(ES) 或者 LIST
70   - /**
71   - * 能被减签的状态
72   - */
73   - public static final List<Integer> CAN_SUB_SIGN_STATUS = Arrays.asList(PROCESS.result, WAIT_BEFORE_TASK.result);
74   -
75 77 }
... ...
yudao-module-bpm/yudao-module-bpm-api/src/main/java/cn/iocoder/yudao/module/bpm/enums/task/BpmTaskAddSignTypeEnum.java
... ... @@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.bpm.enums.task;
3 3 import lombok.AllArgsConstructor;
4 4 import lombok.Getter;
5 5  
6   -
7 6 /**
8 7 * 流程任务 -- 加签类型枚举类型
9 8 */
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmTaskController.java
... ... @@ -4,16 +4,15 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 5 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.*;
6 6 import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService;
7   -import io.swagger.v3.oas.annotations.tags.Tag;
8   -import io.swagger.v3.oas.annotations.Parameter;
9 7 import io.swagger.v3.oas.annotations.Operation;
  8 +import io.swagger.v3.oas.annotations.Parameter;
  9 +import io.swagger.v3.oas.annotations.tags.Tag;
10 10 import org.springframework.security.access.prepost.PreAuthorize;
11 11 import org.springframework.validation.annotation.Validated;
12 12 import org.springframework.web.bind.annotation.*;
13 13  
14 14 import javax.annotation.Resource;
15 15 import javax.validation.Valid;
16   -
17 16 import java.util.List;
18 17  
19 18 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
... ... @@ -75,7 +74,7 @@ public class BpmTaskController {
75 74 return success(true);
76 75 }
77 76  
78   - @GetMapping("/get-return-list")
  77 + @GetMapping("/return-list")
79 78 @Operation(summary = "获取所有可回退的节点", description = "用于【流程详情】的【回退】按钮")
80 79 @Parameter(name = "taskId", description = "当前任务ID", required = true)
81 80 @PreAuthorize("@ss.hasPermission('bpm:task:update')")
... ... @@ -95,37 +94,32 @@ public class BpmTaskController {
95 94 @Operation(summary = "委派任务", description = "用于【流程详情】的【委派】按钮。和向前【加签】有点像,唯一区别是【委托】没有单独创立任务")
96 95 @PreAuthorize("@ss.hasPermission('bpm:task:update')")
97 96 public CommonResult<Boolean> delegateTask(@Valid @RequestBody BpmTaskDelegateReqVO reqVO) {
98   - // TODO @海:, 后面要有空格
99   - taskService.delegateTask(reqVO,getLoginUserId());
  97 + taskService.delegateTask(getLoginUserId(), reqVO);
100 98 return success(true);
101 99 }
102 100  
103   - // TODO @海:权限统一使用 bpm:task:update;是否可以加减签,可以交给后续的权限配置实现;
104   - @PutMapping("/add-sign")
  101 + @PutMapping("/create-sign")
105 102 @Operation(summary = "加签", description = "before 前加签,after 后加签")
106   - @PreAuthorize("@ss.hasPermission('bpm:task:add-sign')")
107   - public CommonResult<Boolean> addSign(@Valid @RequestBody BpmTaskAddSignReqVO reqVO) {
108   - // TODO @海:userId 建议作为第一个参数;一般是,谁做了什么操作;另外,addSignTask,保持风格统一哈;
109   - taskService.addSign(reqVO,getLoginUserId());
  103 + @PreAuthorize("@ss.hasPermission('bpm:task:update')")
  104 + public CommonResult<Boolean> createSignTask(@Valid @RequestBody BpmTaskAddSignReqVO reqVO) {
  105 + taskService.createSignTask(getLoginUserId(), reqVO);
110 106 return success(true);
111 107 }
112 108  
113   - // TODO @海:权限统一使用 bpm:task:update;是否可以加减签,可以交给后续的权限配置实现;
114   - @PutMapping("/sub-sign")
  109 + @DeleteMapping("/delete-sign")
115 110 @Operation(summary = "减签")
116   - @PreAuthorize("@ss.hasPermission('bpm:task:sub-sign')")
117   - // TODO @海: @RequestBody BpmTaskSubSignReqVO 应该是一个空格;然后参数名可以简写成 reqVO;
118   - public CommonResult<Boolean> subSign(@Valid @RequestBody BpmTaskSubSignReqVO bpmTaskSubSignReqVO) {
119   - taskService.subSign(bpmTaskSubSignReqVO,getLoginUserId());
  111 + @PreAuthorize("@ss.hasPermission('bpm:task:update')")
  112 + public CommonResult<Boolean> deleteSignTask(@Valid @RequestBody BpmTaskSubSignReqVO reqVO) {
  113 + taskService.deleteSignTask(getLoginUserId(), reqVO);
120 114 return success(true);
121 115 }
122 116  
123   - // TODO @海:是不是 url 和方法名,叫 get-child-task-list,更抽象和复用一些?
124   - @GetMapping("/get-sub-sign")
  117 + @GetMapping("children-list")
125 118 @Operation(summary = "获取能被减签的任务")
126   - @PreAuthorize("@ss.hasPermission('bpm:task:sub-sign')")
127   - public CommonResult<List<BpmTaskSubSignRespVO>> getChildrenTaskList(@RequestParam("taskId") String taskId) {
128   - return success(taskService.getChildrenTaskList(taskId));
  119 + @Parameter(name = "parentId", description = "父级任务 ID", required = true)
  120 + @PreAuthorize("@ss.hasPermission('bpm:task:update')")
  121 + public CommonResult<List<BpmTaskSubSignRespVO>> getChildrenTaskList(@RequestParam("parentId") String parentId) {
  122 + return success(taskService.getChildrenTaskList(parentId));
129 123 }
130 124  
131 125 }
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskAddSignReqVO.java
... ... @@ -4,13 +4,17 @@ import io.swagger.v3.oas.annotations.media.Schema;
4 4 import lombok.Data;
5 5  
6 6 import javax.validation.constraints.NotEmpty;
7   -import java.util.List;
8 7 import java.util.Set;
9 8  
  9 +// TODO @海洋:类名,应该是 create 哈
10 10 @Schema(description = "管理后台 - 加签流程任务的 Request VO")
11 11 @Data
12 12 public class BpmTaskAddSignReqVO {
13 13  
  14 + @Schema(description = "需要加签的任务 ID")
  15 + @NotEmpty(message = "任务编号不能为空")
  16 + private String id;
  17 +
14 18 @Schema(description = "加签的用户 ID")
15 19 @NotEmpty(message = "加签用户 ID 不能为空")
16 20 private Set<Long> userIdList;
... ... @@ -23,9 +27,4 @@ public class BpmTaskAddSignReqVO {
23 27 @NotEmpty(message = "加签原因不能为空")
24 28 private String reason;
25 29  
26   - // TODO @海:重要参数,可以放到最前面哈;
27   - @Schema(description = "需要加签的任务 ID")
28   - @NotEmpty(message = "任务编号不能为空")
29   - private String id;
30   -
31   -}
32 30 \ No newline at end of file
  31 +}
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/task/BpmTaskSubSignReqVO.java
... ... @@ -5,6 +5,7 @@ import lombok.Data;
5 5  
6 6 import javax.validation.constraints.NotEmpty;
7 7  
  8 +// TODO @海洋:类名,应该是 delete 哈
8 9 @Schema(description = "管理后台 - 减签流程任务的 Request VO")
9 10 @Data
10 11 public class BpmTaskSubSignReqVO {
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java
1 1 package cn.iocoder.yudao.module.bpm.convert.task;
2 2  
3   -import cn.hutool.core.collection.CollUtil;
4 3 import cn.hutool.core.date.LocalDateTimeUtil;
  4 +import cn.hutool.core.util.ObjectUtil;
5 5 import cn.hutool.core.util.StrUtil;
6 6 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
  7 +import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
7 8 import cn.iocoder.yudao.framework.common.util.date.DateUtils;
8 9 import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
9 10 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.*;
... ... @@ -25,6 +26,9 @@ import java.util.Date;
25 26 import java.util.List;
26 27 import java.util.Map;
27 28  
  29 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMultiMap;
  30 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.filterList;
  31 +
28 32 /**
29 33 * Bpm 任务 Convert
30 34 *
... ... @@ -147,7 +151,8 @@ public interface BpmTaskConvert {
147 151 .setDefinitionKey(element.getId()));
148 152 }
149 153  
150   - // TODO @海:可以使用 mapstruct 映射么?
  154 + //此处不用 mapstruct 映射,因为 TaskEntityImpl 还有很多其他属性,这里我们只设置我们需要的
  155 + //使用 mapstruct 会将里面嵌套的各个属性值都设置进去,会出现意想不到的问题
151 156 default TaskEntityImpl convert(TaskEntityImpl task,TaskEntityImpl parentTask){
152 157 task.setCategory(parentTask.getCategory());
153 158 task.setDescription(parentTask.getDescription());
... ... @@ -166,32 +171,31 @@ public interface BpmTaskConvert {
166 171 default List<BpmTaskSubSignRespVO> convertList(List<BpmTaskExtDO> bpmTaskExtDOList,
167 172 Map<Long, AdminUserRespDTO> userMap,
168 173 Map<String, Task> idTaskMap){
169   - return CollectionUtils.convertList(bpmTaskExtDOList, task->{
170   - BpmTaskSubSignRespVO bpmTaskSubSignRespVO = new BpmTaskSubSignRespVO();
171   - bpmTaskSubSignRespVO.setName(task.getName());
172   - bpmTaskSubSignRespVO.setId(task.getTaskId());
173   - Task sourceTask = idTaskMap.get(task.getTaskId());
  174 + return CollectionUtils.convertList(bpmTaskExtDOList, task -> {
  175 + BpmTaskSubSignRespVO bpmTaskSubSignRespVO = new BpmTaskSubSignRespVO()
  176 + .setId(task.getTaskId()).setName(task.getName());
174 177 // 后加签任务不会直接设置 assignee ,所以不存在 assignee 的情况,则去取 owner
175   - String assignee = StrUtil.isNotEmpty(sourceTask.getAssignee()) ? sourceTask.getAssignee() : sourceTask.getOwner();
176   - AdminUserRespDTO assignUser = userMap.get(NumberUtils.parseLong(assignee));
177   - if (assignUser != null) {
178   - bpmTaskSubSignRespVO.setAssigneeUser(convert3(assignUser));
179   - }
  178 + Task sourceTask = idTaskMap.get(task.getTaskId());
  179 + String assignee = ObjectUtil.defaultIfBlank(sourceTask.getOwner(),sourceTask.getAssignee());
  180 + MapUtils.findAndThen(userMap,NumberUtils.parseLong(assignee),
  181 + assignUser-> bpmTaskSubSignRespVO.setAssigneeUser(convert3(assignUser)));
180 182 return bpmTaskSubSignRespVO;
181 183 });
182 184 }
183 185  
184 186 /**
185 187 * 转换任务为父子级
186   - * @param result
187   - * @return
  188 + *
  189 + * @param sourceList 原始数据
  190 + * @return 转换后的父子级数组
188 191 */
189   - default List<BpmTaskRespVO> convertChildrenList(List<BpmTaskRespVO> result){
190   - List<BpmTaskRespVO> childrenTaskList = CollectionUtils.filterList(result, r -> StrUtil.isNotEmpty(r.getParentTaskId()));
191   - Map<String, List<BpmTaskRespVO>> parentChildrenTaskListMap = CollectionUtils.convertMultiMap(childrenTaskList, BpmTaskRespVO::getParentTaskId);
192   - for (BpmTaskRespVO bpmTaskRespVO : result) {
  192 + default List<BpmTaskRespVO> convertChildrenList(List<BpmTaskRespVO> sourceList) {
  193 + List<BpmTaskRespVO> childrenTaskList = filterList(sourceList, r -> StrUtil.isNotEmpty(r.getParentTaskId()));
  194 + Map<String, List<BpmTaskRespVO>> parentChildrenTaskListMap = convertMultiMap(childrenTaskList, BpmTaskRespVO::getParentTaskId);
  195 + for (BpmTaskRespVO bpmTaskRespVO : sourceList) {
193 196 bpmTaskRespVO.setChildren(parentChildrenTaskListMap.get(bpmTaskRespVO.getId()));
194 197 }
195   - return CollectionUtils.filterList(result, r -> StrUtil.isEmpty(r.getParentTaskId()));
  198 + return filterList(sourceList, r -> StrUtil.isEmpty(r.getParentTaskId()));
196 199 }
  200 +
197 201 }
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/dal/mysql/task/BpmTaskExtMapper.java
... ... @@ -21,13 +21,13 @@ public interface BpmTaskExtMapper extends BaseMapperX&lt;BpmTaskExtDO&gt; {
21 21 return selectList(BpmTaskExtDO::getTaskId, taskIds);
22 22 }
23 23  
  24 + // TODO @海:BpmProcessInstanceResultEnum.CAN_SUB_SIGN_STATUS_LIST) 应该作为条件,mapper 不要有业务
24 25 default List<BpmTaskExtDO> selectProcessListByTaskIds(Collection<String> taskIds) {
25 26 return selectList(new LambdaQueryWrapperX<BpmTaskExtDO>()
26 27 .in(BpmTaskExtDO::getTaskId, taskIds)
27   - .in(BpmTaskExtDO::getResult, BpmProcessInstanceResultEnum.CAN_SUB_SIGN_STATUS));
  28 + .in(BpmTaskExtDO::getResult, BpmProcessInstanceResultEnum.CAN_SUB_SIGN_STATUS_LIST));
28 29 }
29 30  
30   -
31 31 default BpmTaskExtDO selectByTaskId(String taskId) {
32 32 return selectOne(BpmTaskExtDO::getTaskId, taskId);
33 33 }
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/framework/bpm/config/BpmSecurityConfiguration.java deleted
1   -package cn.iocoder.yudao.module.bpm.framework.bpm.config;
2   -
3   -import cn.iocoder.yudao.framework.security.config.AuthorizeRequestsCustomizer;
4   -import org.springframework.context.annotation.Bean;
5   -import org.springframework.context.annotation.Configuration;
6   -import org.springframework.security.config.annotation.web.builders.HttpSecurity;
7   -import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
8   -
9   -/**
10   - * @author kemengkai
11   - * @create 2022-05-07 08:15
12   - */
13   -@Configuration("bpmSecurityConfiguration")
14   -public class BpmSecurityConfiguration {
15   -
16   - @Bean("bpmAuthorizeRequestsCustomizer")
17   - public AuthorizeRequestsCustomizer authorizeRequestsCustomizer() {
18   - return new AuthorizeRequestsCustomizer() {
19   -
20   - @Override
21   - public void customize(ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry) {
22   - // 任务回退接口
23   - registry.antMatchers(buildAdminApi("/bpm/task/back")).permitAll();
24   - }
25   -
26   - };
27   - }
28   -}
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelService.java
... ... @@ -12,6 +12,7 @@ import javax.validation.Valid;
12 12 * @author yunlongn
13 13 */
14 14 public interface BpmModelService {
  15 +
15 16 /**
16 17 * 获得流程模型分页
17 18 *
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/definition/BpmModelServiceImpl.java
... ... @@ -288,5 +288,4 @@ public class BpmModelServiceImpl implements BpmModelService {
288 288 processDefinitionService.updateProcessDefinitionState(oldDefinition.getId(), SuspensionState.SUSPENDED.getStateCode());
289 289 }
290 290  
291   -
292 291 }
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java
... ... @@ -65,7 +65,8 @@ public interface BpmTaskService {
65 65  
66 66  
67 67 /**
68   - * 通过任务 ID 集合,获取任务扩展表信息集合 // TODO @海洋:方法注释,和下面的参数,需要空一行
  68 + * 通过任务 ID 集合,获取任务扩展表信息集合
  69 + *
69 70 * @param taskIdList 任务 ID 集合
70 71 * @return 任务列表
71 72 */
... ... @@ -143,41 +144,41 @@ public interface BpmTaskService {
143 144 * 将任务回退到指定的 targetDefinitionKey 位置
144 145 *
145 146 * @param userId 用户编号
146   - * @param reqVO 回退的任务key和当前所在的任务ID
  147 + * @param reqVO 回退的任务key和当前所在的任务ID
147 148 */
148 149 void returnTask(Long userId, BpmTaskReturnReqVO reqVO);
149 150  
150   - // TODO @海:userId 放前面
  151 +
151 152 /**
152 153 * 将指定任务委派给其他人处理,等接收人处理后再回到原审批人手中审批
153 154 *
154   - * @param reqVO 被委派人和被委派的任务编号理由参数
155 155 * @param userId 用户编号
  156 + * @param reqVO 被委派人和被委派的任务编号理由参数
156 157 */
157   - void delegateTask(BpmTaskDelegateReqVO reqVO, Long userId);
  158 + void delegateTask(Long userId, BpmTaskDelegateReqVO reqVO);
158 159  
159 160 /**
160 161 * 任务加签
161 162 *
162   - * @param reqVO 被加签的用户和任务 ID,加签类型
163   - * @param userId 当前用户 ID
  163 + * @param userId 被加签的用户和任务 ID,加签类型
  164 + * @param reqVO 当前用户 ID
164 165 */
165   - void addSign(BpmTaskAddSignReqVO reqVO, Long userId);
  166 + void createSignTask(Long userId, BpmTaskAddSignReqVO reqVO);
166 167  
167 168 /**
168 169 * 任务减签名
169 170 *
170   - * @param bpmTaskSubSignReqVO 被减签的任务 ID,理由
171   - * @param loginUserId 当前用户ID
  171 + * @param userId 当前用户ID
  172 + * @param reqVO 被减签的任务 ID,理由
172 173 */
173   - void subSign(BpmTaskSubSignReqVO bpmTaskSubSignReqVO, Long loginUserId);
  174 + void deleteSignTask(Long userId, BpmTaskSubSignReqVO reqVO);
174 175  
175 176 /**
176 177 * 获取指定任务的子任务和审批人信息
177 178 *
178   - * @param taskId 指定任务ID
  179 + * @param parentId 指定任务ID
179 180 * @return 子任务列表
180 181 */
181   - List<BpmTaskSubSignRespVO> getChildrenTaskList(String taskId);
  182 + List<BpmTaskSubSignRespVO> getChildrenTaskList(String parentId);
182 183  
183 184 }
... ...
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java
... ... @@ -3,8 +3,8 @@ package cn.iocoder.yudao.module.bpm.service.task;
3 3 import cn.hutool.core.collection.CollUtil;
4 4 import cn.hutool.core.util.ArrayUtil;
5 5 import cn.hutool.core.util.IdUtil;
  6 +import cn.hutool.core.util.ObjectUtil;
6 7 import cn.hutool.core.util.StrUtil;
7   -import cn.iocoder.yudao.framework.common.enums.SymbolConstant;
8 8 import cn.iocoder.yudao.framework.common.pojo.PageResult;
9 9 import cn.iocoder.yudao.framework.common.util.date.DateUtils;
10 10 import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
... ... @@ -15,7 +15,10 @@ import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.*;
15 15 import cn.iocoder.yudao.module.bpm.convert.task.BpmTaskConvert;
16 16 import cn.iocoder.yudao.module.bpm.dal.dataobject.task.BpmTaskExtDO;
17 17 import cn.iocoder.yudao.module.bpm.dal.mysql.task.BpmTaskExtMapper;
18   -import cn.iocoder.yudao.module.bpm.enums.task.*;
  18 +import cn.iocoder.yudao.module.bpm.enums.task.BpmCommentTypeEnum;
  19 +import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceDeleteReasonEnum;
  20 +import cn.iocoder.yudao.module.bpm.enums.task.BpmProcessInstanceResultEnum;
  21 +import cn.iocoder.yudao.module.bpm.enums.task.BpmTaskAddSignTypeEnum;
19 22 import cn.iocoder.yudao.module.bpm.service.definition.BpmModelService;
20 23 import cn.iocoder.yudao.module.bpm.service.message.BpmMessageService;
21 24 import cn.iocoder.yudao.module.system.api.dept.DeptApi;
... ... @@ -50,7 +53,6 @@ import javax.annotation.Resource;
50 53 import javax.validation.Valid;
51 54 import java.time.LocalDateTime;
52 55 import java.util.*;
53   -import java.util.stream.Collectors;
54 56 import java.util.stream.Stream;
55 57  
56 58 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
... ... @@ -222,8 +224,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
222 224 // 情况二:后加签的任务
223 225 if (BpmTaskAddSignTypeEnum.AFTER.getType().equals(task.getScopeType())) {
224 226 // 后加签处理
225   - // TODO @海洋:这个是不是 approveAfterSignTask
226   - handleAfterSignTask(task, reqVO);
  227 + approveAfterSignTask(task, reqVO);
227 228 return;
228 229 }
229 230  
... ... @@ -238,18 +239,19 @@ public class BpmTaskServiceImpl implements BpmTaskService {
238 239 handleParentTask(task);
239 240 }
240 241  
  242 +
241 243 /**
242 244 * 审批通过存在“后加签”的任务。
  245 + * <p>
  246 + * 注意:该任务不能马上完成,需要一个中间状态(SIGN_AFTER),并激活剩余所有子任务(PROCESS)为可审批处理
243 247 *
244   - * 注意:该任务不能马上完成,需要一个中间状态(ADD_SIGN_AFTER),并激活剩余所有子任务(PROCESS)为可审批处理
245   - *
246   - * @param task 当前任务
  248 + * @param task 当前任务
247 249 * @param reqVO 前端请求参数
248 250 */
249   - private void handleAfterSignTask(Task task,BpmTaskApproveReqVO reqVO){
  251 + private void approveAfterSignTask(Task task, BpmTaskApproveReqVO reqVO) {
250 252 // 1. 有向后加签,则该任务状态临时设置为 ADD_SIGN_AFTER 状态
251 253 taskExtMapper.updateByTaskId(
252   - new BpmTaskExtDO().setTaskId(task.getId()).setResult(BpmProcessInstanceResultEnum.ADD_SIGN_AFTER.getResult())
  254 + new BpmTaskExtDO().setTaskId(task.getId()).setResult(BpmProcessInstanceResultEnum.SIGN_AFTER.getResult())
253 255 .setReason(reqVO.getReason()).setEndTime(LocalDateTime.now()));
254 256  
255 257 // 2. 激活子任务
... ... @@ -257,118 +259,123 @@ public class BpmTaskServiceImpl implements BpmTaskService {
257 259 for (String childrenTaskId : childrenTaskIdList) {
258 260 taskService.resolveTask(childrenTaskId);
259 261 }
260   - // 更新任务扩展表中子任务为进行中
  262 + // 2.1 更新任务扩展表中子任务为进行中
261 263 taskExtMapper.updateBatchByTaskIdList(childrenTaskIdList,
262 264 new BpmTaskExtDO().setResult(BpmProcessInstanceResultEnum.PROCESS.getResult()));
263 265 }
264 266  
265 267 /**
266   - * 处理当前任务的父任务
  268 + * 处理当前任务的父任务,主要处理“加签”的情况
267 269 *
268 270 * @param task 当前任务
269 271 */
270 272 private void handleParentTask(Task task) {
271 273 String parentTaskId = task.getParentTaskId();
272   - // TODO @ 海:if return 原则
273   - if (StrUtil.isNotBlank(parentTaskId)) {
274   - // 1. 判断当前任务的父任务是否还有子任务
275   - long subTaskCount = getSubTaskCount(parentTaskId);
276   - // TODO @ 海:if >= 0 return;这样括号又可以少一层;
277   - if (subTaskCount == 0) {
278   - // 2. 获取父任务
279   - Task parentTask = validateTaskExist(parentTaskId);
280   -
281   - // 3. 情况一:处理向前加签
282   - String scopeType = parentTask.getScopeType();
283   - if (BpmTaskAddSignTypeEnum.BEFORE.getType().equals(scopeType)) {
284   - // 3.1 如果是向前加签的任务,则调用 resolveTask 指派父任务,将 owner 重新赋值给父任务的 assignee
285   - taskService.resolveTask(parentTaskId);
286   - // 3.2 更新任务拓展表为处理中
287   - taskExtMapper.updateByTaskId(
288   - new BpmTaskExtDO().setTaskId(parentTask.getId()).setResult(BpmProcessInstanceResultEnum.PROCESS.getResult()));
289   - } else if (BpmTaskAddSignTypeEnum.AFTER.getType().equals(scopeType)) {
290   - // 3. 情况二:处理向后加签
291   - handleAfterSign(parentTask);
292   - }
  274 + if (StrUtil.isBlank(parentTaskId)) {
  275 + return;
  276 + }
  277 + // 1. 判断当前任务的父任务是否还有子任务
  278 + Long childrenTaskCount = getChildrenTaskCount(parentTaskId);
  279 + if (childrenTaskCount > 0) {
  280 + return;
  281 + }
  282 + // 2. 获取父任务
  283 + Task parentTask = validateTaskExist(parentTaskId);
293 284  
294   - // 4. 子任务已处理完成,清空 scopeType 字段,修改 parentTask 信息,方便后续可以继续向前后向后加签
295   - // 再查询一次的原因是避免报错:Task was updated by another transaction concurrently
296   - // 因为前面处理后可能会导致 parentTask rev 字段被修改,需要重新获取最新的
297   - parentTask = getTask(parentTaskId);
298   - // TODO @ 海:if return 原则;
299   - if (parentTask != null) {
300   - // 为空的情况是:已经通过 handleAfterSign 方法将任务完成了,所以 ru_task 表会查不到数据
301   - clearTaskScopeTypeAndSave(parentTask);
302   - }
303   - }
  285 + // 3. 处理加签情况
  286 + String scopeType = parentTask.getScopeType();
  287 + if(!validateSignType(scopeType)){
  288 + return;
  289 + }
  290 + // 3.1 情况一:处理向前加签
  291 + if (BpmTaskAddSignTypeEnum.BEFORE.getType().equals(scopeType)) {
  292 + // 3.1.1 如果是向前加签的任务,则调用 resolveTask 指派父任务,将 owner 重新赋值给父任务的 assignee,这样它就可以被审批
  293 + taskService.resolveTask(parentTaskId);
  294 + // 3.1.2 更新任务拓展表为处理中
  295 + taskExtMapper.updateByTaskId(
  296 + new BpmTaskExtDO().setTaskId(parentTask.getId()).setResult(BpmProcessInstanceResultEnum.PROCESS.getResult()));
  297 + } else if (BpmTaskAddSignTypeEnum.AFTER.getType().equals(scopeType)) {
  298 + // 3.2 情况二:处理向后加签
  299 + handleParentTaskForAfterSign(parentTask);
  300 + }
  301 +
  302 + // 4. 子任务已处理完成,清空 scopeType 字段,修改 parentTask 信息,方便后续可以继续向前后向后加签
  303 + // 再查询一次的原因是避免报错:Task was updated by another transaction concurrently
  304 + // 因为前面处理后可能会导致 parentTask rev 字段被修改,需要重新获取最新的
  305 + parentTask = getTask(parentTaskId);
  306 + if (parentTask == null) {
  307 + // 为空的情况是:已经通过 handleAfterSign 方法将任务完成了,所以 ru_task 表会查不到数据
  308 + return;
304 309 }
  310 + clearTaskScopeTypeAndSave(parentTask);
305 311 }
306 312  
307   - // TODO @海:这个方法的 4.1 从 1 开始计数哈;另外;看看能不能用 if return 进一步简化代码的层级;
  313 +
308 314 /**
309 315 * 处理后加签任务
310 316 *
311   - * @param parentTask 当前审批任务的父任务
  317 + * @param parentTask 当前审批任务的父任务
312 318 */
313   - private void handleAfterSign(Task parentTask) {
314   - // TODO @海:这个方法在注释下。感觉整体是,先完成自己;然后递归处理父节点;但是完成机子被放到了 5.1,就感觉上有点割裂;
  319 + // TODO @海:这个逻辑,怎么感觉可以是 parentTask 的 parent,再去调用 handleParentTask 方法;可以微信聊下;
  320 + private void handleParentTaskForAfterSign(Task parentTask) {
315 321 String parentTaskId = parentTask.getId();
316   - //4.1 更新 parentTask 的任务拓展表为通过
  322 + // 1. 更新 parentTask 的任务拓展表为通过,并调用 complete 完成自己
317 323 BpmTaskExtDO currentTaskExt = taskExtMapper.selectByTaskId(parentTask.getId());
318   - BpmTaskExtDO currentTaskUpdateEntity = new BpmTaskExtDO().setTaskId(parentTask.getId())
  324 + BpmTaskExtDO currentTaskExtUpdateObj = new BpmTaskExtDO().setTaskId(parentTask.getId())
319 325 .setResult(BpmProcessInstanceResultEnum.APPROVE.getResult());
320 326 if (currentTaskExt.getEndTime() == null) {
321   - // 有这个判断是因为
322   - // 4.2 以前没设置过结束时间,才去设置
323   - currentTaskUpdateEntity.setEndTime(LocalDateTime.now());
  327 + // 1.1 有这个判断是因为,以前没设置过结束时间,才去设置
  328 + currentTaskExtUpdateObj.setEndTime(LocalDateTime.now());
324 329 }
325   - taskExtMapper.updateByTaskId(currentTaskUpdateEntity);
326   -
327   - // 5. 继续往上处理,父任务继续往上查询
328   - // 5.1 先完成自己
  330 + taskExtMapper.updateByTaskId(currentTaskExtUpdateObj);
  331 + // 1.2 完成自己(因为它已经没有子任务,所以也可以完成)
329 332 taskService.complete(parentTaskId);
330   - // 5.2 如果有父级,递归查询上级任务是否都已经完成
331   - // TODO @海:这块待讨论,脑子略乱;感觉 handleAfterSign 的后半段,和 handleParentTask 有点重叠???
332   - if (StrUtil.isNotEmpty(parentTask.getParentTaskId())) {
333   - // 判断整条链路的任务是否完成
334   - // 例如从 A 任务加签了一个 B 任务,B 任务又加签了一个 C 任务,C 任务加签了 D 任务
335   - // 此时,D 任务完成,要一直往上找到祖先任务 A调用 complete 方法完成 A 任务
336   - boolean allChildrenTaskFinish = true;
337   - while (StrUtil.isNotBlank(parentTask.getParentTaskId())) {
338   - parentTask = validateTaskExist(parentTask.getParentTaskId());
339   - BpmTaskExtDO bpmTaskExtDO = taskExtMapper.selectByTaskId(parentTask.getId());
340   - if (bpmTaskExtDO == null) {
341   - break;
342   - }
343   - boolean currentTaskFinish = BpmProcessInstanceResultEnum.isEndResult(bpmTaskExtDO.getResult());
344   - // 5.3 如果 allChildrenTaskFinish 已经被赋值为 false ,则不会再赋值为 true,因为整个链路没有完成
345   - if (allChildrenTaskFinish) {
346   - allChildrenTaskFinish = currentTaskFinish;
347   - }
348   - if (!currentTaskFinish) {
349   - // 6 处理非完成状态的任务
350   - // 6.1 判断当前任务的父任务是否还有子任务
351   - Long subTaskCount = getSubTaskCount(bpmTaskExtDO.getTaskId());
352   - if (subTaskCount == 0) {
353   - // 6.2 没有子任务,判断当前任务状态是否为 ADD_SIGN_BEFORE 待前加签任务完成
354   - if (BpmProcessInstanceResultEnum.ADD_SIGN_BEFORE.getResult().equals(bpmTaskExtDO.getResult())) {
355   - // 6.3 需要修改该任务状态为处理中
356   - taskService.resolveTask(bpmTaskExtDO.getTaskId());
357   - bpmTaskExtDO.setResult(BpmProcessInstanceResultEnum.PROCESS.getResult());
358   - taskExtMapper.updateByTaskId(bpmTaskExtDO);
359   - }
360   - // 6.4 清空 scopeType 字段,用于任务没有子任务时使用该方法,方便任务可以再次被不同的方式加签
361   - parentTask = getTask(bpmTaskExtDO.getTaskId());
362   - if (parentTask != null) {
363   - clearTaskScopeTypeAndSave(parentTask);
364   - }
365   - }
366   - }
  333 +
  334 + // 2. 如果有父级,递归查询上级任务是否都已经完成
  335 + if (StrUtil.isEmpty(parentTask.getParentTaskId())) {
  336 + return;
  337 + }
  338 + // 2.1 判断整条链路的任务是否完成
  339 + // 例如从 A 任务加签了一个 B 任务,B 任务又加签了一个 C 任务,C 任务加签了 D 任务
  340 + // 此时,D 任务完成,要一直往上找到祖先任务 A调用 complete 方法完成 A 任务
  341 + boolean allChildrenTaskFinish = true;
  342 + while (StrUtil.isNotBlank(parentTask.getParentTaskId())) {
  343 + parentTask = validateTaskExist(parentTask.getParentTaskId());
  344 + BpmTaskExtDO parentTaskExt = taskExtMapper.selectByTaskId(parentTask.getId());
  345 + if (parentTaskExt == null) {
  346 + break;
367 347 }
  348 + boolean currentTaskFinish = BpmProcessInstanceResultEnum.isEndResult(parentTaskExt.getResult());
  349 + // 2.2 如果 allChildrenTaskFinish 已经被赋值为 false,则不会再赋值为 true,因为整个链路没有完成
368 350 if (allChildrenTaskFinish) {
369   - // 7. 完成最后的顶级祖先任务
370   - taskService.complete(parentTask.getId());
  351 + allChildrenTaskFinish = currentTaskFinish;
  352 + }
  353 + // 2.3 任务已完成则不处理
  354 + if (currentTaskFinish) {
  355 + continue;
  356 + }
  357 +
  358 + // 3 处理非完成状态的任务
  359 + // 3.1 判断当前任务的父任务是否还有子任务
  360 + Long childrenTaskCount = getChildrenTaskCount(parentTaskExt.getTaskId());
  361 + if (childrenTaskCount > 0) {
  362 + continue;
371 363 }
  364 + // 3.2 没有子任务,判断当前任务状态是否为 ADD_SIGN_BEFORE 待前加签任务完成
  365 + if (BpmProcessInstanceResultEnum.SIGN_BEFORE.getResult().equals(parentTaskExt.getResult())) {
  366 + // 3.3 需要修改该任务状态为处理中
  367 + taskService.resolveTask(parentTaskExt.getTaskId());
  368 + parentTaskExt.setResult(BpmProcessInstanceResultEnum.PROCESS.getResult());
  369 + taskExtMapper.updateByTaskId(parentTaskExt);
  370 + }
  371 + // 3.4 清空 scopeType 字段,用于任务没有子任务时使用该方法,方便任务可以再次被不同的方式加签
  372 + parentTask = validateTaskExist(parentTaskExt.getTaskId());
  373 + clearTaskScopeTypeAndSave(parentTask);
  374 + }
  375 +
  376 + // 4. 完成最后的顶级祖先任务
  377 + if (allChildrenTaskFinish) {
  378 + taskService.complete(parentTask.getId());
372 379 }
373 380 }
374 381  
... ... @@ -383,14 +390,13 @@ public class BpmTaskServiceImpl implements BpmTaskService {
383 390 taskService.saveTask(task);
384 391 }
385 392  
386   - // TODO @海:Sub 还有 Child 感觉整体用词不是很统一;是不是要统一下;然后 Sub 还可以指的减签;看看是不是名词确实得一致哈;
387 393 /**
388 394 * 获取子任务个数
389 395 *
390 396 * @param parentTaskId 父任务 ID
391 397 * @return 剩余子任务个数
392 398 */
393   - private Long getSubTaskCount(String parentTaskId) {
  399 + private Long getChildrenTaskCount(String parentTaskId) {
394 400 String tableName = managementService.getTableName(TaskEntity.class);
395 401 String sql = "SELECT COUNT(1) from " + tableName + " WHERE PARENT_TASK_ID_=#{parentTaskId}";
396 402 return taskService.createNativeTaskQuery().sql(sql).parameter("parentTaskId", parentTaskId).count();
... ... @@ -410,7 +416,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
410 416 String comment = StrUtil.format("[{}]完成委派任务,任务重新回到[{}]手中,审批意见为:{}", currentUser.getNickname(),
411 417 sourceApproveUser.getNickname(), reqVO.getReason());
412 418 taskService.addComment(reqVO.getId(), task.getProcessInstanceId(),
413   - BpmCommentTypeEnum.DELEGATE.getResult().toString(), comment);
  419 + BpmCommentTypeEnum.DELEGATE.getType().toString(), comment);
414 420  
415 421 // 2.1 调用 resolveTask 完成任务。
416 422 // 底层调用 TaskHelper.changeTaskAssignee(task, task.getOwner()):将 owner 设置为 assignee
... ... @@ -528,7 +534,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
528 534 TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
529 535 @Override
530 536 public void afterCommit() {
531   - if(StrUtil.isNotEmpty(task.getAssignee())){
  537 + if (StrUtil.isNotEmpty(task.getAssignee())) {
532 538 ProcessInstance processInstance =
533 539 processInstanceService.getProcessInstance(task.getProcessInstanceId());
534 540 AdminUserRespDTO startUser = adminUserApi.getUser(Long.valueOf(processInstance.getStartUserId()));
... ... @@ -539,8 +545,8 @@ public class BpmTaskServiceImpl implements BpmTaskService {
539 545 });
540 546 }
541 547  
542   - private Task validateTaskExist(String id){
543   - Task task = taskService.createTaskQuery().taskId(id).singleResult();
  548 + private Task validateTaskExist(String id) {
  549 + Task task = getTask(id);
544 550 if (task == null) {
545 551 throw exception(TASK_NOT_EXISTS);
546 552 }
... ... @@ -646,7 +652,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
646 652 return;
647 653 }
648 654 taskService.addComment(task.getId(), currentTask.getProcessInstanceId(),
649   - BpmCommentTypeEnum.BACK.getResult().toString(), reqVO.getReason());
  655 + BpmCommentTypeEnum.BACK.getType().toString(), reqVO.getReason());
650 656 });
651 657  
652 658 // 3. 执行驳回
... ... @@ -659,7 +665,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
659 665  
660 666 @Override
661 667 @Transactional(rollbackFor = Exception.class)
662   - public void delegateTask(BpmTaskDelegateReqVO reqVO, Long userId) {
  668 + public void delegateTask(Long userId, BpmTaskDelegateReqVO reqVO) {
663 669 // 1.1 校验任务
664 670 Task task = validateTaskCanDelegate(userId, reqVO);
665 671 // 1.2 校验目标用户存在
... ... @@ -674,7 +680,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
674 680 delegateUser.getNickname(), reqVO.getReason());
675 681 String taskId = reqVO.getId();
676 682 taskService.addComment(taskId, task.getProcessInstanceId(),
677   - BpmCommentTypeEnum.DELEGATE.getResult().toString(), comment);
  683 + BpmCommentTypeEnum.DELEGATE.getType().toString(), comment);
678 684  
679 685 // 3.1 设置任务所有人 (owner) 为原任务的处理人 (assignee)
680 686 taskService.setOwner(taskId, task.getAssignee());
... ... @@ -705,23 +711,18 @@ public class BpmTaskServiceImpl implements BpmTaskService {
705 711  
706 712 @Override
707 713 @Transactional(rollbackFor = Exception.class)
708   - public void addSign(BpmTaskAddSignReqVO reqVO, Long userId) {
709   - // TODO @海:// 后面要有个空格;中英文之间,也要有空格;例如说:// 1. 获取和校验任务
710   - //1.获取和校验任务
  714 + public void createSignTask(Long userId, BpmTaskAddSignReqVO reqVO) {
  715 + // 1. 获取和校验任务
711 716 TaskEntityImpl taskEntity = validateAddSign(userId, reqVO);
712   - // TODO @海:每个变量,以及相关逻辑,一定要和自己的逻辑块呆在一起。例如说这里的 currentUser 获取,应该在 4. 那块
713   - AdminUserRespDTO currentUser = adminUserApi.getUser(userId);
714 717 List<AdminUserRespDTO> userList = adminUserApi.getUserList(reqVO.getUserIdList());
715 718 if (CollUtil.isEmpty(userList)) {
716 719 throw exception(TASK_ADD_SIGN_USER_NOT_EXIST);
717 720 }
718   - // TODO @海:大的逻辑块之间,最好有一个空格。这样的目的,是避免逻辑堆砌在一起,方便流量;
719   - // 2.处理当前任务
720   - // 2.1 开启计数功能 // TODO @海:这个目的可以写下;
  721 +
  722 + // 2. 处理当前任务
  723 + // 2.1 开启计数功能,主要用于为了让表 ACT_RU_TASK 中的 SUB_TASK_COUNT_ 字段记录下总共有多少子任务,后续可能有用
721 724 taskEntity.setCountEnabled(true);
722   - // TODO @海:可以直接 if,不搞一个变量哈
723   - boolean addSignToBefore = reqVO.getType().equals(BpmTaskAddSignTypeEnum.BEFORE.getType());
724   - if (addSignToBefore) {
  725 + if (reqVO.getType().equals(BpmTaskAddSignTypeEnum.BEFORE.getType())) {
725 726 // 2.2 向前加签,设置 owner,置空 assign。等子任务都完成后,再调用 resolveTask 重新将 owner 设置为 assign
726 727 // 原因是:不能和向前加签的子任务一起审批,需要等前面的子任务都完成才能审批
727 728 taskEntity.setOwner(taskEntity.getAssignee());
... ... @@ -729,7 +730,7 @@ public class BpmTaskServiceImpl implements BpmTaskService {
729 730 // 2.3 更新扩展表状态
730 731 taskExtMapper.updateByTaskId(
731 732 new BpmTaskExtDO().setTaskId(taskEntity.getId())
732   - .setResult(BpmProcessInstanceResultEnum.ADD_SIGN_BEFORE.getResult())
  733 + .setResult(BpmProcessInstanceResultEnum.SIGN_BEFORE.getResult())
733 734 .setReason(reqVO.getReason()));
734 735 }
735 736 // 2.4 记录加签方式,完成任务时需要用到判断
... ... @@ -738,20 +739,20 @@ public class BpmTaskServiceImpl implements BpmTaskService {
738 739 taskService.saveTask(taskEntity);
739 740  
740 741 // 3. 创建加签任务
741   - createSignSubTasks(convertList(reqVO.getUserIdList(), String::valueOf), taskEntity);
  742 + createSignTask(convertList(reqVO.getUserIdList(), String::valueOf), taskEntity);
742 743  
743 744 // 4. 记录加签 comment,拼接结果为: [当前用户]向前加签/向后加签给了[多个用户],理由为:reason
744   - // TODO @海:BpmCommentTypeEnum 可以加一个 comment 字段,作为评论模版,统一管理;
745   - String comment = StrUtil.format("[{}]{}给了[{}],理由为:{}", currentUser.getNickname(), BpmTaskAddSignTypeEnum.formatDesc(reqVO.getType()),
746   - String.join(SymbolConstant.D, convertList(userList, AdminUserRespDTO::getNickname)), reqVO.getReason());
  745 + AdminUserRespDTO currentUser = adminUserApi.getUser(userId);
  746 + String comment = StrUtil.format(BpmCommentTypeEnum.ADD_SIGN.getComment(), currentUser.getNickname(),
  747 + BpmTaskAddSignTypeEnum.formatDesc(reqVO.getType()), String.join(",", convertList(userList, AdminUserRespDTO::getNickname)), reqVO.getReason());
747 748 taskService.addComment(reqVO.getId(), taskEntity.getProcessInstanceId(),
748   - BpmCommentTypeEnum.ADD_SIGN.getResult().toString(), comment);
  749 + BpmCommentTypeEnum.ADD_SIGN.getType().toString(), comment);
749 750 }
750 751  
751 752  
752 753 /**
753 754 * 校验任务的加签是否一致
754   - *
  755 + * <p>
755 756 * 1. 如果存在“向前加签”的任务,则不能“向后加签”
756 757 * 2. 如果存在“向后加签”的任务,则不能“向前加签”
757 758 *
... ... @@ -763,25 +764,20 @@ public class BpmTaskServiceImpl implements BpmTaskService {
763 764 TaskEntityImpl taskEntity = (TaskEntityImpl) validateTask(userId, reqVO.getId());
764 765 // 向前加签和向后加签不能同时存在
765 766 if (StrUtil.isNotBlank(taskEntity.getScopeType())
766   - && !BpmTaskAddSignTypeEnum.AFTER_CHILDREN_TASK.getDesc().equals(taskEntity.getScopeType())) {
767   - // TODO @海:下面这个判断,是不是可以写上面这个判断后面?
768   - // TODO @海:一个小技巧,如果写不等于的时候,一般可以用 ObjectUtil.notEquals,这样少一层取反,理解起来简单点;
769   - if (!taskEntity.getScopeType().equals(reqVO.getType())) {
770   - throw exception(TASK_ADD_SIGN_TYPE_ERROR,
771   - BpmTaskAddSignTypeEnum.formatDesc(taskEntity.getScopeType()), BpmTaskAddSignTypeEnum.formatDesc(reqVO.getType()));
772   - }
  767 + && ObjectUtil.notEqual(BpmTaskAddSignTypeEnum.AFTER_CHILDREN_TASK.getType(), taskEntity.getScopeType())
  768 + && ObjectUtil.notEqual(taskEntity.getScopeType(), reqVO.getType())) {
  769 + throw exception(TASK_ADD_SIGN_TYPE_ERROR,
  770 + BpmTaskAddSignTypeEnum.formatDesc(taskEntity.getScopeType()), BpmTaskAddSignTypeEnum.formatDesc(reqVO.getType()));
773 771 }
774 772 // 同一个 key 的任务,审批人不重复
775 773 List<Task> taskList = taskService.createTaskQuery().processInstanceId(taskEntity.getProcessInstanceId())
776 774 .taskDefinitionKey(taskEntity.getTaskDefinitionKey()).list();
777   - // TODO @海:这里是不是 Task::getAssignee 解析成 List<Long> 下面会更简洁一点?
778   - List<String> currentAssigneeList = convertList(taskList, Task::getAssignee);
779   - // TODO @海:frontAssigneeList 改成 addAssigneeList,新增的;避免和 front 前端这样界面耦合的名词哈;
780   - List<String> frontAssigneeList = convertList(reqVO.getUserIdList(), String::valueOf);
781   - currentAssigneeList.retainAll(frontAssigneeList);
  775 + List<Long> currentAssigneeList = convertList(taskList, task -> NumberUtils.parseLong(task.getAssignee()));
  776 + // 保留交集在 currentAssigneeList 中
  777 + currentAssigneeList.retainAll(reqVO.getUserIdList());
782 778 if (CollUtil.isNotEmpty(currentAssigneeList)) {
783   - List<AdminUserRespDTO> userList = adminUserApi.getUserList(convertList(currentAssigneeList, NumberUtils::parseLong));
784   - throw exception(TASK_ADD_SIGN_USER_REPEAT, String.join(SymbolConstant.D, convertList(userList, AdminUserRespDTO::getNickname)));
  779 + List<AdminUserRespDTO> userList = adminUserApi.getUserList(currentAssigneeList);
  780 + throw exception(TASK_ADD_SIGN_USER_REPEAT, String.join(",", convertList(userList, AdminUserRespDTO::getNickname)));
785 781 }
786 782 return taskEntity;
787 783 }
... ... @@ -792,32 +788,31 @@ public class BpmTaskServiceImpl implements BpmTaskService {
792 788 * @param addSingUserIdList 被加签的用户 ID
793 789 * @param taskEntity 被加签的任务
794 790 */
795   - private void createSignSubTasks(List<String> addSingUserIdList, TaskEntityImpl taskEntity) {
796   - // TODO @海:可以 if return;这样括号层级少一点;下面的 if (StrUtil.isNotBlank(addSignId)) { 也是类似;
797   - if (CollUtil.isNotEmpty(addSingUserIdList)) {
798   - // 创建加签人的新任务,全部基于 taskEntity 为父任务来创建
799   - addSingUserIdList.forEach(addSignId -> {
800   - if (StrUtil.isNotBlank(addSignId)) {
801   - createSubTask(taskEntity, addSignId);
802   - }
803   - });
  791 + private void createSignTask(List<String> addSingUserIdList, TaskEntityImpl taskEntity) {
  792 + if (CollUtil.isEmpty(addSingUserIdList)) {
  793 + return;
  794 + }
  795 + // 创建加签人的新任务,全部基于 taskEntity 为父任务来创建
  796 + for (String addSignId : addSingUserIdList) {
  797 + if (StrUtil.isBlank(addSignId)) {
  798 + continue;
  799 + }
  800 + createSignTask(taskEntity, addSignId);
804 801 }
805 802 }
806 803  
807   - // TODO @海:这个是不是命名上,要和 createSignSubTasks 保持一致?
808 804 /**
809   - * 创建子任务
  805 + * 创建加签子任务
810 806 *
811 807 * @param parentTask 父任务
812 808 * @param assignee 子任务的执行人
813   - * @return
814 809 */
815   - private void createSubTask(TaskEntityImpl parentTask, String assignee) {
  810 + private void createSignTask(TaskEntityImpl parentTask, String assignee) {
816 811 // 1. 生成子任务
817 812 TaskEntityImpl task = (TaskEntityImpl) taskService.newTask(IdUtil.fastSimpleUUID());
818   - task = BpmTaskConvert.INSTANCE.convert(task,parentTask);
  813 + task = BpmTaskConvert.INSTANCE.convert(task, parentTask);
819 814 if (BpmTaskAddSignTypeEnum.BEFORE.getType().equals(parentTask.getScopeType())) {
820   - // 2.1 前加签,才设置审批人,否则设置 owner
  815 + // 2.1 前加签,设置审批人
821 816 task.setAssignee(assignee);
822 817 } else {
823 818 // 2.2.1 设置 owner 不设置 assignee 是因为不能同时审批,需要等父任务完成
... ... @@ -831,106 +826,144 @@ public class BpmTaskServiceImpl implements BpmTaskService {
831 826  
832 827 @Override
833 828 @Transactional(rollbackFor = Exception.class)
834   - public void subSign(BpmTaskSubSignReqVO reqVO,Long userId) {
  829 + public void deleteSignTask(Long userId, BpmTaskSubSignReqVO reqVO) {
  830 + // 1.1 校验 task 可以被减签
835 831 Task task = validateSubSign(reqVO.getId());
836   - AdminUserRespDTO user = adminUserApi.getUser(userId);
  832 + // 1.2 校验取消人存在
837 833 AdminUserRespDTO cancelUser = null;
838   - if(StrUtil.isNotBlank(task.getAssignee())){
  834 + if (StrUtil.isNotBlank(task.getAssignee())) {
839 835 cancelUser = adminUserApi.getUser(NumberUtils.parseLong(task.getAssignee()));
840 836 }
841   - if(cancelUser == null && StrUtil.isNotBlank(task.getOwner())){
  837 + if (cancelUser == null && StrUtil.isNotBlank(task.getOwner())) {
842 838 cancelUser = adminUserApi.getUser(NumberUtils.parseLong(task.getOwner()));
843 839 }
844   - Assert.notNull(cancelUser,"任务中没有所有者和审批人,数据错误");
845   - //1. 获取所有需要删除的任务 ID ,包含当前任务和所有子任务
  840 + Assert.notNull(cancelUser, "任务中没有所有者和审批人,数据错误");
  841 +
  842 + // 2. 删除任务和对应子任务
  843 + // 2.1 获取所有需要删除的任务 ID ,包含当前任务和所有子任务
846 844 List<String> allTaskIdList = getAllChildTaskIds(task.getId());
847   - //2. 删除任务和所有子任务
  845 + // 2.2 删除任务和所有子任务
848 846 taskService.deleteTasks(allTaskIdList);
849   - //3. 修改扩展表状态为取消
850   - taskExtMapper.updateBatchByTaskIdList(allTaskIdList,new BpmTaskExtDO().setResult(BpmProcessInstanceResultEnum.CANCEL.getResult())
851   - .setReason(StrUtil.format("由于{}操作[减签],任务被取消",user.getNickname())));
852   - //4.记录日志到父任务中 先记录日志是因为,通过 handleParentTask 方法之后,任务可能被完成了,并且不存在了,会报异常,所以先记录
853   - String comment = StrUtil.format("{}操作了【减签】,审批人{}的任务被取消",user.getNickname(),cancelUser.getNickname());
854   - taskService.addComment(task.getParentTaskId(),task.getProcessInstanceId(),
855   - BpmCommentTypeEnum.SUB_SIGN.getResult().toString(),comment);
856   - //5. 处理当前任务的父任务
857   - this.handleParentTask(task);
  847 + // 2.3 修改扩展表状态为取消
  848 + AdminUserRespDTO user = adminUserApi.getUser(userId);
  849 + taskExtMapper.updateBatchByTaskIdList(allTaskIdList, new BpmTaskExtDO().setResult(BpmProcessInstanceResultEnum.CANCEL.getResult())
  850 + .setReason(StrUtil.format("由于{}操作[减签],任务被取消", user.getNickname())));
  851 +
  852 + // 3. 记录日志到父任务中。先记录日志是因为,通过 handleParentTask 方法之后,任务可能被完成了,并且不存在了,会报异常,所以先记录
  853 + String comment = StrUtil.format(BpmCommentTypeEnum.SUB_SIGN.getComment(), user.getNickname(), cancelUser.getNickname());
  854 + taskService.addComment(task.getParentTaskId(), task.getProcessInstanceId(),
  855 + BpmCommentTypeEnum.SUB_SIGN.getType().toString(), comment);
858 856  
  857 + // 4. 处理当前任务的父任务
  858 + handleParentTask(task);
859 859 }
860 860  
861 861 /**
862 862 * 校验任务是否能被减签
  863 + *
863 864 * @param id 任务ID
864 865 * @return 任务信息
865 866 */
866 867 private Task validateSubSign(String id) {
867 868 Task task = validateTaskExist(id);
868   - //必须有parentId
869   - if(StrUtil.isEmpty(task.getParentTaskId())){
  869 +
  870 + // 必须有 scopeType
  871 + String scopeType = task.getScopeType();
  872 + if (StrUtil.isEmpty(scopeType)) {
  873 + throw exception(TASK_SUB_SIGN_NO_PARENT);
  874 + }
  875 + // 并且值为 向前和向后加签
  876 + if (!validateSignType(scopeType)) {
870 877 throw exception(TASK_SUB_SIGN_NO_PARENT);
871 878 }
872 879 return task;
873 880 }
874 881  
875 882 /**
  883 + * 判断当前类型是否为加签
  884 + * @param scopeType 任务的 scopeType
  885 + * @return 当前 scopeType 为加签则返回 true
  886 + */
  887 + private boolean validateSignType(String scopeType){
  888 + return StrUtil.equalsAny(scopeType,BpmTaskAddSignTypeEnum.BEFORE.getType(),scopeType, BpmTaskAddSignTypeEnum.AFTER.getType());
  889 + }
  890 +
  891 + /**
876 892 * 获取所有要被取消的删除的任务 ID 集合
  893 + *
877 894 * @param parentTaskId 父级任务ID
878 895 * @return 所有任务ID
879 896 */
880 897 public List<String> getAllChildTaskIds(String parentTaskId) {
881 898 List<String> allChildTaskIds = new ArrayList<>();
882   - //1. 先将自己放入
883   - allChildTaskIds.add(parentTaskId);
884   - //2. 递归获取子级
885   - recursiveGetChildTaskIds(parentTaskId, allChildTaskIds);
  899 + // 1. 递归获取子级
  900 + Stack<String> stack = new Stack<>();
  901 + // 1.1 将根任务ID入栈
  902 + stack.push(parentTaskId);
  903 + //控制遍历的次数不超过 Byte.MAX_VALUE,避免脏数据造成死循环
  904 + int count = 0;
  905 + // TODO @海:< 的前后空格,要注意哈;
  906 + while (!stack.isEmpty() && count<Byte.MAX_VALUE) {
  907 + // 1.2 弹出栈顶任务ID
  908 + String taskId = stack.pop();
  909 + // 1.3 将任务ID添加到结果集合中
  910 + allChildTaskIds.add(taskId);
  911 + // 1.4 获取该任务的子任务列表
  912 + // TODO @海:有个更高效的写法;一次性去 in 一层;不然每个节点,都去查询一次 db, 太浪费了;每次 in,最终就是 O(h) 查询,而不是 O(n) 查询;
  913 + List<String> childrenTaskIdList = getChildrenTaskIdList(taskId);
  914 + if (CollUtil.isNotEmpty(childrenTaskIdList)) {
  915 + for (String childTaskId : childrenTaskIdList) {
  916 + // 1.5 将子任务ID入栈,以便后续处理
  917 + stack.push(childTaskId);
  918 + }
  919 + }
  920 + count++;
  921 + }
886 922 return allChildTaskIds;
887 923 }
888 924  
889 925 /**
890   - * 递归处理子级任务
891   - * @param taskId 当前任务ID
892   - * @param taskIds 结果
  926 + * 获取指定父级任务的所有子任务 ID 集合
  927 + *
  928 + * @param parentTaskId 父任务 ID
  929 + * @return 所有子任务的 ID 集合
893 930 */
894   - private void recursiveGetChildTaskIds(String taskId, List<String> taskIds) {
895   - List<String> childrenTaskIdList = getChildrenTaskIdList(taskId);
896   - for (String childTaskId : childrenTaskIdList) {
897   - taskIds.add(childTaskId); // 将子任务的ID添加到集合中
898   - recursiveGetChildTaskIds(childTaskId, taskIds); // 递归获取子任务的子任务
899   - }
  931 + private List<String> getChildrenTaskIdList(String parentTaskId) {
  932 + return convertList(getChildrenTaskList0(parentTaskId), Task::getId);
900 933 }
901 934  
902 935 /**
903 936 * 获取指定父级任务的所有子任务 ID 集合
  937 + *
904 938 * @param parentTaskId 父任务 ID
905 939 * @return 所有子任务的 ID 集合
906 940 */
907   - private List<String> getChildrenTaskIdList(String parentTaskId){
  941 + private List<Task> getChildrenTaskList0(String parentTaskId) {
908 942 String tableName = managementService.getTableName(TaskEntity.class);
909   - String sql = "select ID_ from " + tableName + " where PARENT_TASK_ID_=#{parentTaskId}";
910   - List<Task> childrenTaskList = taskService.createNativeTaskQuery().sql(sql).parameter("parentTaskId", parentTaskId).list();
911   - return convertList(childrenTaskList, Task::getId);
  943 + // taskService.createTaskQuery() 没有 parentId 参数,所以写 sql 查询
  944 + String sql = "select ID_,OWNER_,ASSIGNEE_ from " + tableName + " where PARENT_TASK_ID_=#{parentTaskId}";
  945 + return taskService.createNativeTaskQuery().sql(sql).parameter("parentTaskId", parentTaskId).list();
912 946 }
913 947  
  948 +
914 949 @Override
915   - public List<BpmTaskSubSignRespVO> getChildrenTaskList(String taskId){
916   - List<String> childrenTaskIdList = getChildrenTaskIdList(taskId);
917   - if(CollUtil.isEmpty(childrenTaskIdList)){
  950 + public List<BpmTaskSubSignRespVO> getChildrenTaskList(String parentId) {
  951 + // 1. 只查询进行中的任务 后加签的任务,可能不存在 assignee,所以还需要查询 owner
  952 + List<Task> taskList = getChildrenTaskList0(parentId);
  953 + if (CollUtil.isEmpty(taskList)) {
918 954 return Collections.emptyList();
919 955 }
920   - //1. 只查询进行中的任务
921   - List<BpmTaskExtDO> bpmTaskExtDOList = taskExtMapper.selectProcessListByTaskIds(childrenTaskIdList);
922   - //2. 后加签的任务,可能不存在 assignee,所以还需要查询 owner
923   - List<Task> taskList = taskService.createTaskQuery().taskIds(childrenTaskIdList).list();
924   - Map<String, Task> idTaskMap = convertMap(taskList, TaskInfo::getId);
925   - //3. 将 owner 和 assignee 统一到一个集合中
926   - List<Long> userIds = taskList.stream()
927   - .flatMap(control ->
928   - Stream.of(control.getAssignee(), control.getOwner())
929   - .filter(Objects::nonNull))
930   - .distinct()
931   - .map(NumberUtils::parseLong)
932   - .collect(Collectors.toList());
  956 + List<String> childrenTaskIdList = convertList(taskList, Task::getId);
  957 +
  958 + // 2.1 将 owner 和 assignee 统一到一个集合中
  959 + List<Long> userIds = convertListByFlatMap(taskList, control ->
  960 + Stream.of(NumberUtils.parseLong(control.getAssignee()), NumberUtils.parseLong(control.getOwner()))
  961 + .filter(Objects::nonNull));
  962 + // 2.2 组装数据
933 963 Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(userIds);
934   - return BpmTaskConvert.INSTANCE.convertList(bpmTaskExtDOList,userMap,idTaskMap);
  964 + List<BpmTaskExtDO> taskExtList = taskExtMapper.selectProcessListByTaskIds(childrenTaskIdList);
  965 + Map<String, Task> idTaskMap = convertMap(taskList, TaskInfo::getId);
  966 + return BpmTaskConvert.INSTANCE.convertList(taskExtList, userMap, idTaskMap);
935 967 }
  968 +
936 969 }
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/db/DatabaseDocController.java
... ... @@ -147,7 +147,7 @@ public class DatabaseDocController {
147 147 */
148 148 private static ProcessConfig buildProcessConfig() {
149 149 return ProcessConfig.builder()
150   - .ignoreTablePrefix(Arrays.asList("QRTZ_", "ACT_")) // 忽略表前缀
  150 + .ignoreTablePrefix(Arrays.asList("QRTZ_", "ACT_", "FLW_")) // 忽略表前缀
151 151 .build();
152 152 }
153 153  
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/framework/security/config/SecurityConfiguration.java
... ... @@ -29,8 +29,6 @@ public class SecurityConfiguration {
29 29 .antMatchers("/swagger-resources/**").anonymous()
30 30 .antMatchers("/webjars/**").anonymous()
31 31 .antMatchers("/*/api-docs").anonymous();
32   - // 积木报表
33   - registry.antMatchers("/jmreport/**").permitAll();
34 32 // Spring Boot Actuator 的安全配置
35 33 registry.antMatchers("/actuator").anonymous()
36 34 .antMatchers("/actuator/**").anonymous();
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/job/logger/JobLogCleanJob.java renamed to yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/job/job/JobLogCleanJob.java
1   -package cn.iocoder.yudao.module.infra.job.logger;
  1 +package cn.iocoder.yudao.module.infra.job.job;
2 2  
3 3 import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler;
4 4 import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
... ... @@ -33,7 +33,7 @@ public class JobLogCleanJob implements JobHandler {
33 33 @TenantIgnore
34 34 public String execute(String param) {
35 35 Integer count = jobLogService.cleanJobLog(JOB_CLEAN_RETAIN_DAY, DELETE_LIMIT);
36   - log.info("[count][定时执行清理定时任务日志数量 ({}) 个]", count);
  36 + log.info("[execute][定时执行清理定时任务日志数量 ({}) 个]", count);
37 37 return String.format("定时执行清理定时任务日志数量 %s 个", count);
38 38 }
39 39  
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/job/job/AccessLogCleanJob.java renamed to yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/job/logger/AccessLogCleanJob.java
1   -package cn.iocoder.yudao.module.infra.job.job;
  1 +package cn.iocoder.yudao.module.infra.job.logger;
2 2  
3 3 import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler;
4 4 import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
... ... @@ -34,7 +34,7 @@ public class AccessLogCleanJob implements JobHandler {
34 34 @TenantIgnore
35 35 public String execute(String param) {
36 36 Integer count = apiAccessLogService.cleanAccessLog(JOB_CLEAN_RETAIN_DAY, DELETE_LIMIT);
37   - log.info("[count][定时执行清理访问日志数量 ({}) 个]", count);
  37 + log.info("[execute][定时执行清理访问日志数量 ({}) 个]", count);
38 38 return String.format("定时执行清理错误日志数量 %s 个", count);
39 39 }
40 40  
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/job/job/ErrorLogCleanJob.java renamed to yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/job/logger/ErrorLogCleanJob.java
1   -package cn.iocoder.yudao.module.infra.job.job;
  1 +package cn.iocoder.yudao.module.infra.job.logger;
2 2  
3 3 import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler;
4 4 import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
... ... @@ -34,7 +34,7 @@ public class ErrorLogCleanJob implements JobHandler {
34 34 @TenantIgnore
35 35 public String execute(String param) {
36 36 Integer count = apiErrorLogService.cleanErrorLog(JOB_CLEAN_RETAIN_DAY,DELETE_LIMIT);
37   - log.info("[count][定时执行清理错误日志数量 ({}) 个]", count);
  37 + log.info("[execute][定时执行清理错误日志数量 ({}) 个]", count);
38 38 return String.format("定时执行清理错误日志数量 %s 个", count);
39 39 }
40 40  
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/file/FileConfigServiceImpl.java
... ... @@ -58,9 +58,9 @@ public class FileConfigServiceImpl implements FileConfigService {
58 58 FileConfigDO config = Objects.equals(CACHE_MASTER_ID, id) ?
59 59 fileConfigMapper.selectByMaster() : fileConfigMapper.selectById(id);
60 60 if (config != null) {
61   - fileClientFactory.createOrUpdateFileClient(id, config.getStorage(), config.getConfig());
  61 + fileClientFactory.createOrUpdateFileClient(config.getId(), config.getStorage(), config.getConfig());
62 62 }
63   - return fileClientFactory.getFileClient(id);
  63 + return fileClientFactory.getFileClient(null == config ? id : config.getId());
64 64 }
65 65  
66 66 });
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben/api/api.ts.vm
1   -import { defHttp } from '@/utils/http/axios'
  1 +import {defHttp} from '@/utils/http/axios'
2 2 #set ($baseURL = "/${table.moduleName}/${simpleClassName_strikeCase}")
3 3  
4 4 // 查询${table.classComment}列表
... ... @@ -28,5 +28,5 @@ export function delete${simpleClassName}(id: number) {
28 28  
29 29 // 导出${table.classComment} Excel
30 30 export function export${simpleClassName}(params) {
31   - return defHttp.download({ url: '${baseURL}/export-excel', params }, '${table.classComment}.xls')
  31 + return defHttp.download({ url: '${baseURL}/export-excel', params }, '${table.classComment}.xls')
32 32 }
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben/views/data.ts.vm
1   -import type { BasicColumn, FormSchema } from '@/components/Table'
2   -import { useRender } from '@/components/Table'
3   -import { DICT_TYPE, getDictOptions } from '@/utils/dict'
  1 +import type {BasicColumn, FormSchema} from '@/components/Table'
  2 +import {useRender} from '@/components/Table'
  3 +import {DICT_TYPE, getDictOptions} from '@/utils/dict'
4 4  
5 5 export const columns: BasicColumn[] = [
6 6 #foreach($column in $columns)
... ... @@ -50,7 +50,7 @@ export const searchFormSchema: FormSchema[] = [
50 50 field: '${javaField}',
51 51 #if ($column.htmlType == "input")
52 52 component: 'Input',
53   - #elseif ($column.htmlType == "select" || $column.htmlType == "radio")
  53 + #elseif ($column.htmlType == "select")
54 54 component: 'Select',
55 55 componentProps: {
56 56 #if ("" != $dictType)## 设置了 dictType 数据字典的情况
... ... @@ -59,6 +59,15 @@ export const searchFormSchema: FormSchema[] = [
59 59 options: [],
60 60 #end
61 61 },
  62 + #elseif ($column.htmlType == "radio")
  63 + component: 'Radio',
  64 + componentProps: {
  65 + #if ("" != $dictType)## 设置了 dictType 数据字典的情况
  66 + options: getDictOptions(DICT_TYPE.$dictType.toUpperCase()),
  67 + #else## 未设置 dictType 数据字典的情况
  68 + options: [],
  69 + #end
  70 + },
62 71 #elseif($column.htmlType == "datetime")
63 72 component: 'RangePicker',
64 73 #end
... ... @@ -181,7 +190,8 @@ export const updateFormSchema: FormSchema[] = [
181 190 fileType: 'file',
182 191 maxCount: 1,
183 192 },
184   - #elseif($column.htmlType == "editor")## 文本编辑器component: 'Editor',
  193 + #elseif($column.htmlType == "editor")## 文本编辑器
  194 + component: 'Editor',
185 195 #elseif($column.htmlType == "select")## 下拉框
186 196 component: 'Select',
187 197 componentProps: {
... ...
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben/views/index.vue.vm
1 1 <script lang="ts" setup>
2   -import ${ simpleClassName }Modal from './${simpleClassName}Modal.vue'
3   -import { columns, searchFormSchema } from './${classNameVar}.data'
4   -import { useI18n } from '@/hooks/web/useI18n'
5   -import { useMessage } from '@/hooks/web/useMessage'
6   -import { useModal } from '@/components/Modal'
7   -import { IconEnum } from '@/enums/appEnum'
8   -import { BasicTable, useTable, TableAction } from '@/components/Table'
9   -import { delete${ simpleClassName }, export${ simpleClassName }, get${ simpleClassName } Page } from '@/api/${table.moduleName}/${classNameVar}'
  2 + import {columns, searchFormSchema} from './'
  3 + import {useI18n} from '@/hooks/web/useI18n'
  4 + import {useMessage} from '@/hooks/web/useMessage'
  5 + import {useModal} from '@/components/Modal'
  6 + import {useTable} from '@/components/Table'
  7 + import { delete${ simpleClassName }, export${ simpleClassName }, get${ simpleClassName } Page } from '@/api/${table.moduleName}/${classNameVar}'
10 8  
11 9 defineOptions({ name: '${table.className}' })
12 10  
... ... @@ -62,7 +60,7 @@ async function handleDelete(record: Recordable) {
62 60 <a-button type="primary" v-auth="['${permissionPrefix}:create']" :preIcon="IconEnum.ADD" @click="handleCreate">
63 61 {{ t('action.create') }}
64 62 </a-button>
65   - <a-button type="warning" v-auth="['${permissionPrefix}:export']" :preIcon="IconEnum.EXPORT" @click="handleExport">
  63 + <a-button v-auth="['${permissionPrefix}:export']" :preIcon="IconEnum.EXPORT" @click="handleExport">
66 64 {{ t('action.export') }}
67 65 </a-button>
68 66 </template>
... ...
yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/file/FileConfigServiceImplTest.java
... ... @@ -258,12 +258,12 @@ public class FileConfigServiceImplTest extends BaseDbUnitTest {
258 258 Long id = fileConfig.getId();
259 259 // mock 获得 Client
260 260 FileClient fileClient = new LocalFileClient(id, new LocalFileClientConfig());
261   - when(fileClientFactory.getFileClient(eq(0L))).thenReturn(fileClient);
  261 + when(fileClientFactory.getFileClient(eq(fileConfig.getId()))).thenReturn(fileClient);
262 262  
263 263 // 调用,并断言
264 264 assertSame(fileClient, fileConfigService.getMasterFileClient());
265 265 // 断言缓存
266   - verify(fileClientFactory).createOrUpdateFileClient(eq(0L), eq(fileConfig.getStorage()),
  266 + verify(fileClientFactory).createOrUpdateFileClient(eq(fileConfig.getId()), eq(fileConfig.getStorage()),
267 267 eq(fileConfig.getConfig()));
268 268 }
269 269  
... ...
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/comment/dto/ProductCommentCreateReqDTO.java
... ... @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.product.api.comment.dto;
2 2  
3 3 import lombok.Data;
4 4  
  5 +import javax.validation.constraints.NotNull;
5 6 import java.util.List;
6 7  
7 8 /**
... ... @@ -15,6 +16,7 @@ public class ProductCommentCreateReqDTO {
15 16 /**
16 17 * 商品 SKU 编号
17 18 */
  19 + @NotNull(message = "商品 SKU 编号不能为空")
18 20 private Long skuId;
19 21 /**
20 22 * 订单编号
... ... @@ -26,20 +28,19 @@ public class ProductCommentCreateReqDTO {
26 28 private Long orderItemId;
27 29  
28 30 /**
29   - * 评分星级 1-5 分
30   - */
31   - private Integer scores;
32   - /**
33 31 * 描述星级 1-5 分
34 32 */
  33 + @NotNull(message = "描述星级不能为空")
35 34 private Integer descriptionScores;
36 35 /**
37 36 * 服务星级 1-5 分
38 37 */
  38 + @NotNull(message = "服务星级不能为空")
39 39 private Integer benefitScores;
40 40 /**
41 41 * 评论内容
42 42 */
  43 + @NotNull(message = "评论内容不能为空")
43 44 private String content;
44 45 /**
45 46 * 评论图片地址数组,以逗号分隔最多上传 9 张
... ... @@ -49,11 +50,12 @@ public class ProductCommentCreateReqDTO {
49 50 /**
50 51 * 是否匿名
51 52 */
  53 + @NotNull(message = "是否匿名不能为空")
52 54 private Boolean anonymous;
53 55 /**
54 56 * 评价人
55 57 */
  58 + @NotNull(message = "评价人不能为空")
56 59 private Long userId;
57 60  
58   -
59 61 }
... ...
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/property/ProductPropertyValueApi.java deleted
1   -package cn.iocoder.yudao.module.product.api.property;
2   -
3   -import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO;
4   -
5   -import java.util.Collection;
6   -import java.util.List;
7   -
8   -/**
9   - * 商品属性值 API 接口
10   - *
11   - * @author 芋道源码
12   - */
13   -public interface ProductPropertyValueApi {
14   -
15   - /**
16   - * 根据编号数组,获得属性值列表
17   - *
18   - * @param ids 编号数组
19   - * @return 属性值明细列表
20   - */
21   - List<ProductPropertyValueDetailRespDTO> getPropertyValueDetailList(Collection<Long> ids);
22   -
23   -}
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/spu/dto/ProductSpuRespDTO.java
... ... @@ -3,8 +3,6 @@ package cn.iocoder.yudao.module.product.api.spu.dto;
3 3 import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum;
4 4 import lombok.Data;
5 5  
6   -import java.util.List;
7   -
8 6 // TODO @LeeYan9: ProductSpuRespDTO
9 7 /**
10 8 * 商品 SPU 信息 Response DTO
... ... @@ -27,55 +25,22 @@ public class ProductSpuRespDTO {
27 25 */
28 26 private String name;
29 27 /**
30   - * 关键字
31   - */
32   - private String keyword;
33   - /**
34 28 * 单位
35 29 *
36 30 * 对应 product_unit 数据字典
37 31 */
38 32 private Integer unit;
39   - /**
40   - * 商品简介
41   - */
42   - private String introduction;
43   - /**
44   - * 商品详情
45   - */
46   - private String description;
47   - // TODO @芋艿:是不是要删除
48   - /**
49   - * 商品条码(一维码)
50   - */
51   - private String barCode;
52 33  
53 34 /**
54 35 * 商品分类编号
55 36 */
56 37 private Long categoryId;
57 38 /**
58   - * 商品品牌编号
59   - */
60   - private Long brandId;
61   - /**
62 39 * 商品封面图
63 40 */
64 41 private String picUrl;
65   - /**
66   - * 商品轮播图
67   - */
68   - private List<String> sliderPicUrls;
69   - /**
70   - * 商品视频
71   - */
72   - private String videoUrl;
73 42  
74 43 /**
75   - * 排序字段
76   - */
77   - private Integer sort;
78   - /**
79 44 * 商品状态
80 45 * <p>
81 46 * 枚举 {@link ProductSpuStatusEnum}
... ... @@ -124,22 +89,6 @@ public class ProductSpuRespDTO {
124 89 */
125 90 private Integer giveIntegral;
126 91  
127   - // ========== 统计相关字段 =========
128   -
129   - /**
130   - * 商品销量
131   - */
132   - private Integer salesCount;
133   - /**
134   - * 虚拟销量
135   - */
136   - private Integer virtualSalesCount;
137   - /**
138   - * 商品点击量
139   - */
140   - private Integer clickCount;
141   -
142   -
143 92 // ========== 分销相关字段 =========
144 93  
145 94 /**
... ...
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/ErrorCodeConstants.java
... ... @@ -34,8 +34,9 @@ public interface ErrorCodeConstants {
34 34 // ========== 商品 SPU 1-008-005-000 ==========
35 35 ErrorCode SPU_NOT_EXISTS = new ErrorCode(1_008_005_000, "商品 SPU 不存在");
36 36 ErrorCode SPU_SAVE_FAIL_CATEGORY_LEVEL_ERROR = new ErrorCode(1_008_005_001, "商品分类不正确,原因:必须使用第二级的商品分类及以下");
37   - ErrorCode SPU_NOT_ENABLE = new ErrorCode(1_008_005_002, "商品 SPU【{}】不处于上架状态");
38   - ErrorCode SPU_NOT_RECYCLE = new ErrorCode(1_008_005_003, "商品 SPU 不处于回收站状态");
  37 + ErrorCode SPU_SAVE_FAIL_COUPON_TEMPLATE_NOT_EXISTS = new ErrorCode(1_008_005_002, "商品 SPU 保存失败,原因:优惠卷不存在");
  38 + ErrorCode SPU_NOT_ENABLE = new ErrorCode(1_008_005_003, "商品 SPU【{}】不处于上架状态");
  39 + ErrorCode SPU_NOT_RECYCLE = new ErrorCode(1_008_005_004, "商品 SPU 不处于回收站状态");
39 40  
40 41 // ========== 商品 SKU 1-008-006-000 ==========
41 42 ErrorCode SKU_NOT_EXISTS = new ErrorCode(1_008_006_000, "商品 SKU 不存在");
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/property/ProductPropertyValueApiImpl.java deleted
1   -package cn.iocoder.yudao.module.product.api.property;
2   -
3   -import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO;
4   -import cn.iocoder.yudao.module.product.convert.property.ProductPropertyValueConvert;
5   -import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService;
6   -import org.springframework.stereotype.Service;
7   -import org.springframework.validation.annotation.Validated;
8   -
9   -import javax.annotation.Resource;
10   -import java.util.Collection;
11   -import java.util.List;
12   -
13   -/**
14   - * 商品属性值 API 实现类
15   - *
16   - * @author 芋道源码
17   - */
18   -@Service
19   -@Validated
20   -public class ProductPropertyValueApiImpl implements ProductPropertyValueApi {
21   -
22   - @Resource
23   - private ProductPropertyValueService productPropertyValueService;
24   -
25   - @Override
26   - public List<ProductPropertyValueDetailRespDTO> getPropertyValueDetailList(Collection<Long> ids) {
27   - return ProductPropertyValueConvert.INSTANCE.convertList02(
28   - productPropertyValueService.getPropertyValueDetailList(ids));
29   - }
30   -
31   -}
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/sku/ProductSkuApiImpl.java
1 1 package cn.iocoder.yudao.module.product.api.sku;
2 2  
3   -import cn.hutool.core.collection.CollUtil;
4 3 import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
5 4 import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO;
6 5 import cn.iocoder.yudao.module.product.convert.sku.ProductSkuConvert;
... ... @@ -11,7 +10,6 @@ import org.springframework.validation.annotation.Validated;
11 10  
12 11 import javax.annotation.Resource;
13 12 import java.util.Collection;
14   -import java.util.Collections;
15 13 import java.util.List;
16 14  
17 15 /**
... ... @@ -35,18 +33,12 @@ public class ProductSkuApiImpl implements ProductSkuApi {
35 33  
36 34 @Override
37 35 public List<ProductSkuRespDTO> getSkuList(Collection<Long> ids) {
38   - if (CollUtil.isEmpty(ids)) {
39   - return Collections.emptyList();
40   - }
41 36 List<ProductSkuDO> skus = productSkuService.getSkuList(ids);
42 37 return ProductSkuConvert.INSTANCE.convertList04(skus);
43 38 }
44 39  
45 40 @Override
46 41 public List<ProductSkuRespDTO> getSkuListBySpuId(Collection<Long> spuIds) {
47   - if (CollUtil.isEmpty(spuIds)) {
48   - return Collections.emptyList();
49   - }
50 42 List<ProductSkuDO> skus = productSkuService.getSkuListBySpuId(spuIds);
51 43 return ProductSkuConvert.INSTANCE.convertList04(skus);
52 44 }
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/api/spu/ProductSpuApiImpl.java
... ... @@ -27,9 +27,6 @@ public class ProductSpuApiImpl implements ProductSpuApi {
27 27  
28 28 @Override
29 29 public List<ProductSpuRespDTO> getSpuList(Collection<Long> ids) {
30   - if (CollectionUtil.isEmpty(ids)) {
31   - return Collections.emptyList();
32   - }
33 30 return ProductSpuConvert.INSTANCE.convertList2(spuService.getSpuList(ids));
34 31 }
35 32  
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java
... ... @@ -8,6 +8,7 @@ import cn.iocoder.yudao.module.product.controller.admin.spu.vo.*;
8 8 import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert;
9 9 import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
10 10 import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
  11 +import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum;
11 12 import cn.iocoder.yudao.module.product.service.sku.ProductSkuService;
12 13 import cn.iocoder.yudao.module.product.service.spu.ProductSpuService;
13 14 import io.swagger.v3.oas.annotations.Operation;
... ... @@ -22,6 +23,7 @@ import javax.servlet.http.HttpServletResponse;
22 23 import javax.validation.Valid;
23 24 import java.io.IOException;
24 25 import java.util.Collection;
  26 +import java.util.Comparator;
25 27 import java.util.List;
26 28 import java.util.Map;
27 29  
... ... @@ -88,11 +90,13 @@ public class ProductSpuController {
88 90 return success(ProductSpuConvert.INSTANCE.convertForSpuDetailRespVO(spu, skus));
89 91 }
90 92  
91   - @GetMapping("/get-simple-list")
  93 + @GetMapping("/list-all-simple")
92 94 @Operation(summary = "获得商品 SPU 精简列表")
93 95 @PreAuthorize("@ss.hasPermission('product:spu:query')")
94 96 public CommonResult<List<ProductSpuSimpleRespVO>> getSpuSimpleList() {
95   - List<ProductSpuDO> list = productSpuService.getSpuList();
  97 + List<ProductSpuDO> list = productSpuService.getSpuListByStatus(ProductSpuStatusEnum.ENABLE.getStatus());
  98 + // 降序排序后,返回给前端
  99 + list.sort(Comparator.comparing(ProductSpuDO::getSort).reversed());
96 100 return success(ProductSpuConvert.INSTANCE.convertList02(list));
97 101 }
98 102  
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/vo/ProductSpuBaseVO.java
... ... @@ -96,19 +96,16 @@ public class ProductSpuBaseVO {
96 96 @NotNull(message = "商品赠送积分不能为空")
97 97 private Integer giveIntegral;
98 98  
99   - @Schema(description = "赠送的优惠劵编号的数组", example = "[1, 10]") // TODO 这块前端还未实现
100   - private List<Long> giveCouponTemplateIds;
101   -
102 99 @Schema(description = "分销类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
103 100 @NotNull(message = "商品分销类型不能为空")
104 101 private Boolean subCommissionType;
105 102  
106   - @Schema(description = "活动展示顺序", example = "[1, 3, 2, 4, 5]") // TODO 这块前端还未实现
  103 + @Schema(description = "活动展示顺序", example = "[1, 3, 2, 4, 5]")
107 104 private List<Integer> activityOrders;
108 105  
109 106 // ========== 统计相关字段 =========
110 107  
111   - @Schema(description = "虚拟销量", example = "芋道")
  108 + @Schema(description = "虚拟销量", example = "66")
112 109 private Integer virtualSalesCount;
113 110  
114 111 }
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/property/ProductPropertyValueConvert.java
1 1 package cn.iocoder.yudao.module.product.convert.property;
2 2  
3 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4   -import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
5   -import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
6   -import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO;
7 4 import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueCreateReqVO;
8 5 import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueRespVO;
9 6 import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueUpdateReqVO;
10   -import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO;
11 7 import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO;
12   -import cn.iocoder.yudao.module.product.service.property.bo.ProductPropertyValueDetailRespBO;
13 8 import org.mapstruct.Mapper;
14 9 import org.mapstruct.factory.Mappers;
15 10  
16 11 import java.util.List;
17   -import java.util.Map;
18   -
19   -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
20 12  
21 13 /**
22 14 * 属性值 Convert
... ... @@ -38,18 +30,4 @@ public interface ProductPropertyValueConvert {
38 30  
39 31 PageResult<ProductPropertyValueRespVO> convertPage(PageResult<ProductPropertyValueDO> page);
40 32  
41   - default List<ProductPropertyValueDetailRespBO> convertList(List<ProductPropertyValueDO> values, List<ProductPropertyDO> keys) {
42   - Map<Long, ProductPropertyDO> keyMap = convertMap(keys, ProductPropertyDO::getId);
43   - return CollectionUtils.convertList(values, value -> {
44   - ProductPropertyValueDetailRespBO valueDetail = new ProductPropertyValueDetailRespBO()
45   - .setValueId(value.getId()).setValueName(value.getName());
46   - // 设置属性项
47   - MapUtils.findAndThen(keyMap, value.getPropertyId(),
48   - key -> valueDetail.setPropertyId(key.getId()).setPropertyName(key.getName()));
49   - return valueDetail;
50   - });
51   - }
52   -
53   - List<ProductPropertyValueDetailRespDTO> convertList02(List<ProductPropertyValueDetailRespBO> list);
54   -
55 33 }
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/convert/spu/ProductSpuConvert.java
... ... @@ -101,9 +101,7 @@ public interface ProductSpuConvert {
101 101 List<AppProductSpuDetailRespVO.Sku> convertListForGetSpuDetail(List<ProductSkuDO> skus);
102 102  
103 103 default ProductSpuDetailRespVO convertForSpuDetailRespVO(ProductSpuDO spu, List<ProductSkuDO> skus) {
104   - ProductSpuDetailRespVO detailRespVO = convert03(spu);
105   - detailRespVO.setSkus(ProductSkuConvert.INSTANCE.convertList(skus));
106   - return detailRespVO;
  104 + return convert03(spu).setSkus(ProductSkuConvert.INSTANCE.convertList(skus));
107 105 }
108 106  
109 107 default List<ProductSpuDetailRespVO> convertForSpuDetailRespListVO(List<ProductSpuDO> spus, List<ProductSkuDO> skus) {
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/spu/ProductSpuDO.java
... ... @@ -194,7 +194,7 @@ public class ProductSpuDO extends BaseDO {
194 194 * 对应 PromotionTypeEnum 枚举
195 195 */
196 196 @TableField(typeHandler = JacksonTypeHandler.class)
197   - private List<Integer> activityOrders;
  197 + private List<Integer> activityOrders; // TODO @芋艿: 活动顺序字段长度需要增加
198 198  
199 199 // ========== 统计相关字段 =========
200 200  
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyValueService.java
... ... @@ -5,7 +5,6 @@ import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.Produc
5 5 import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValuePageReqVO;
6 6 import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueUpdateReqVO;
7 7 import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO;
8   -import cn.iocoder.yudao.module.product.service.property.bo.ProductPropertyValueDetailRespBO;
9 8  
10 9 import java.util.Collection;
11 10 import java.util.List;
... ... @@ -57,14 +56,6 @@ public interface ProductPropertyValueService {
57 56 List<ProductPropertyValueDO> getPropertyValueListByPropertyId(Collection<Long> propertyIds);
58 57  
59 58 /**
60   - * 根据编号数组,获得属性值列表
61   - *
62   - * @param ids 编号数组
63   - * @return 属性值明细列表
64   - */
65   - List<ProductPropertyValueDetailRespBO> getPropertyValueDetailList(Collection<Long> ids);
66   -
67   - /**
68 59 * 根据属性项编号,活的属性值数量
69 60 *
70 61 * @param propertyId 属性项编号数
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/property/ProductPropertyValueServiceImpl.java
1 1 package cn.iocoder.yudao.module.product.service.property;
2 2  
3   -import cn.hutool.core.collection.CollUtil;
4 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 4 import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueCreateReqVO;
6 5 import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValuePageReqVO;
7 6 import cn.iocoder.yudao.module.product.controller.admin.property.vo.value.ProductPropertyValueUpdateReqVO;
8 7 import cn.iocoder.yudao.module.product.convert.property.ProductPropertyValueConvert;
9   -import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyDO;
10 8 import cn.iocoder.yudao.module.product.dal.dataobject.property.ProductPropertyValueDO;
11 9 import cn.iocoder.yudao.module.product.dal.mysql.property.ProductPropertyValueMapper;
12   -import cn.iocoder.yudao.module.product.service.property.bo.ProductPropertyValueDetailRespBO;
13 10 import cn.iocoder.yudao.module.product.service.sku.ProductSkuService;
14 11 import org.springframework.context.annotation.Lazy;
15 12 import org.springframework.stereotype.Service;
... ... @@ -17,11 +14,9 @@ import org.springframework.validation.annotation.Validated;
17 14  
18 15 import javax.annotation.Resource;
19 16 import java.util.Collection;
20   -import java.util.Collections;
21 17 import java.util.List;
22 18  
23 19 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
24   -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
25 20 import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.PROPERTY_VALUE_EXISTS;
26 21 import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.PROPERTY_VALUE_NOT_EXISTS;
27 22  
... ... @@ -100,23 +95,6 @@ public class ProductPropertyValueServiceImpl implements ProductPropertyValueServ
100 95 }
101 96  
102 97 @Override
103   - public List<ProductPropertyValueDetailRespBO> getPropertyValueDetailList(Collection<Long> ids) {
104   - // 获得属性值列表
105   - if (CollUtil.isEmpty(ids)) {
106   - return Collections.emptyList();
107   - }
108   - List<ProductPropertyValueDO> values = productPropertyValueMapper.selectBatchIds(ids);
109   - if (CollUtil.isEmpty(values)) {
110   - return Collections.emptyList();
111   - }
112   - // 获得属性项列表
113   - List<ProductPropertyDO> keys = productPropertyService.getPropertyList(
114   - convertSet(values, ProductPropertyValueDO::getPropertyId));
115   - // 组装明细
116   - return ProductPropertyValueConvert.INSTANCE.convertList(values, keys);
117   - }
118   -
119   - @Override
120 98 public Integer getPropertyValueCountByPropertyId(Long propertyId) {
121 99 return productPropertyValueMapper.selectCountByPropertyId(propertyId);
122 100 }
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/sku/ProductSkuServiceImpl.java
... ... @@ -153,6 +153,9 @@ public class ProductSkuServiceImpl implements ProductSkuService {
153 153  
154 154 @Override
155 155 public List<ProductSkuDO> getSkuListBySpuId(Collection<Long> spuIds) {
  156 + if (CollUtil.isEmpty(spuIds)) {
  157 + return Collections.emptyList();
  158 + }
156 159 return productSkuMapper.selectListBySpuId(spuIds);
157 160 }
158 161  
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuService.java
... ... @@ -68,11 +68,12 @@ public interface ProductSpuService {
68 68 }
69 69  
70 70 /**
71   - * 获得所有商品 SPU 列表
  71 + * 获得指定状态的商品 SPU 列表
72 72 *
  73 + * @param status 状态
73 74 * @return 商品 SPU 列表
74 75 */
75   - List<ProductSpuDO> getSpuList();
  76 + List<ProductSpuDO> getSpuListByStatus(Integer status);
76 77  
77 78 /**
78 79 * 获得所有商品 SPU 列表
... ... @@ -146,4 +147,5 @@ public interface ProductSpuService {
146 147 * @return 商品 SPU 列表
147 148 */
148 149 List<ProductSpuDO> validateSpuList(Collection<Long> ids);
  150 +
149 151 }
... ...
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImpl.java
... ... @@ -16,7 +16,6 @@ import cn.iocoder.yudao.module.product.dal.mysql.spu.ProductSpuMapper;
16 16 import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum;
17 17 import cn.iocoder.yudao.module.product.service.brand.ProductBrandService;
18 18 import cn.iocoder.yudao.module.product.service.category.ProductCategoryService;
19   -import cn.iocoder.yudao.module.product.service.property.ProductPropertyValueService;
20 19 import cn.iocoder.yudao.module.product.service.sku.ProductSkuService;
21 20 import com.google.common.collect.Maps;
22 21 import org.springframework.context.annotation.Lazy;
... ... @@ -52,9 +51,6 @@ public class ProductSpuServiceImpl implements ProductSpuService {
52 51 private ProductBrandService brandService;
53 52 @Resource
54 53 private ProductCategoryService categoryService;
55   - @Resource
56   - @Lazy // 循环依赖,避免报错
57   - private ProductPropertyValueService productPropertyValueService;
58 54  
59 55 @Override
60 56 @Transactional(rollbackFor = Exception.class)
... ... @@ -192,12 +188,15 @@ public class ProductSpuServiceImpl implements ProductSpuService {
192 188  
193 189 @Override
194 190 public List<ProductSpuDO> getSpuList(Collection<Long> ids) {
  191 + if (CollUtil.isEmpty(ids)) {
  192 + return Collections.emptyList();
  193 + }
195 194 return productSpuMapper.selectBatchIds(ids);
196 195 }
197 196  
198 197 @Override
199   - public List<ProductSpuDO> getSpuList() {
200   - return productSpuMapper.selectList();
  198 + public List<ProductSpuDO> getSpuListByStatus(Integer status) {
  199 + return productSpuMapper.selectList(ProductSpuDO::getStatus, status);
201 200 }
202 201  
203 202 @Override
... ...
yudao-module-mall/yudao-module-promotion-api/pom.xml
... ... @@ -13,7 +13,7 @@
13 13  
14 14 <name>${project.artifactId}</name>
15 15 <description>
16   - market 模块 API,暴露给其它模块调用
  16 + promotion 模块 API,暴露给其它模块调用
17 17 </description>
18 18  
19 19 <dependencies>
... ...
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationRecordApi.java
1 1 package cn.iocoder.yudao.module.promotion.api.combination;
2 2  
3   -import cn.iocoder.yudao.framework.common.core.KeyValue;
4 3 import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO;
  4 +import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateRespDTO;
5 5 import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationValidateJoinRespDTO;
6 6  
7 7 import javax.validation.Valid;
... ... @@ -28,9 +28,9 @@ public interface CombinationRecordApi {
28 28 * 创建开团记录
29 29 *
30 30 * @param reqDTO 请求 DTO
31   - * @return key 开团记录编号、value 团长编号
  31 + * @return 拼团信息
32 32 */
33   - KeyValue<Long, Long> createCombinationRecord(@Valid CombinationRecordCreateReqDTO reqDTO);
  33 + CombinationRecordCreateRespDTO createCombinationRecord(@Valid CombinationRecordCreateReqDTO reqDTO);
34 34  
35 35 /**
36 36 * 查询拼团记录是否成功
... ... @@ -42,14 +42,6 @@ public interface CombinationRecordApi {
42 42 boolean isCombinationRecordSuccess(Long userId, Long orderId);
43 43  
44 44 /**
45   - * 更新拼团状态为【失败】
46   - *
47   - * @param userId 用户编号
48   - * @param orderId 订单编号
49   - */
50   - void updateRecordStatusToFailed(Long userId, Long orderId);
51   -
52   - /**
53 45 * 【下单前】校验是否满足拼团活动条件
54 46 *
55 47 * 如果校验失败,则抛出业务异常
... ...
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/dto/CombinationRecordCreateRespDTO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.api.combination.dto;
  2 +
  3 +import lombok.Data;
  4 +
  5 +/**
  6 + * 拼团记录的创建 Response DTO
  7 + *
  8 + * @author HUIHUI
  9 + */
  10 +@Data
  11 +public class CombinationRecordCreateRespDTO {
  12 +
  13 + /**
  14 + * 拼团活动编号
  15 + *
  16 + * 关联 CombinationActivityDO 的 id 字段
  17 + */
  18 + private Long combinationActivityId;
  19 + /**
  20 + * 拼团团长编号
  21 + *
  22 + * 关联 CombinationRecordDO 的 headId 字段
  23 + */
  24 + private Long combinationHeadId;
  25 + /**
  26 + * 拼团记录编号
  27 + *
  28 + * 关联 CombinationRecordDO 的 id 字段
  29 + */
  30 + private Long combinationRecordId;
  31 +
  32 +}
... ...
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/PriceApi.java deleted
1   -package cn.iocoder.yudao.module.promotion.api.price;
2   -
3   -import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateReqDTO;
4   -import cn.iocoder.yudao.module.promotion.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-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/CouponMeetRespDTO.java deleted
1   -package cn.iocoder.yudao.module.promotion.api.price.dto;
2   -
3   -import lombok.Data;
4   -
5   -/**
6   - * 优惠劵的匹配信息 Response DTO
7   - *
8   - * why 放在 price 包下?主要获取的时候,需要涉及到较多的价格计算逻辑,放在 price 可以更好的复用逻辑
9   - *
10   - * @author 芋道源码
11   - */
12   -@Data
13   -public class CouponMeetRespDTO {
14   -
15   - /**
16   - * 优惠劵编号
17   - */
18   - private Long id;
19   -
20   - // ========== 非优惠劵的基本信息字段 ==========
21   - /**
22   - * 是否匹配
23   - */
24   - private Boolean meet;
25   - /**
26   - * 不匹配的提示,即 {@link #meet} = true 才有值
27   - *
28   - * 例如说:
29   - * 1. 所结算商品没有符合条件的商品
30   - * 2. 差 XXX 元可用优惠劵
31   - * 3. 优惠劵未到使用时间
32   - */
33   - private String meetTip;
34   -
35   -}
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateReqDTO.java deleted
1   -package cn.iocoder.yudao.module.promotion.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   -@Deprecated
16   -public class PriceCalculateReqDTO {
17   -
18   - /**
19   - * 用户编号
20   - *
21   - * 对应 MemberUserDO 的 id 编号
22   - */
23   - private Long userId;
24   -
25   - /**
26   - * 优惠劵编号
27   - */
28   - private Long couponId;
29   -
30   - /**
31   - * 收货地址编号
32   - */
33   - private Long addressId;
34   -
35   - /**
36   - * 商品 SKU 数组
37   - */
38   - @NotNull(message = "商品数组不能为空")
39   - private List<Item> items;
40   -
41   - /**
42   - * 商品 SKU
43   - */
44   - @Data
45   - public static class Item {
46   -
47   - /**
48   - * SKU 编号
49   - */
50   - @NotNull(message = "商品 SKU 编号不能为空")
51   - private Long skuId;
52   -
53   - /**
54   - * SKU 数量
55   - */
56   - @NotNull(message = "商品 SKU 数量不能为空")
57   - @Min(value = 0L, message = "商品 SKU 数量必须大于等于 0") // 可传递 0 数量,用于购物车未选中的情况
58   - private Integer count;
59   -
60   - }
61   -
62   -}
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/price/dto/PriceCalculateRespDTO.java deleted
1   -package cn.iocoder.yudao.module.promotion.api.price.dto;
2   -
3   -import cn.iocoder.yudao.module.promotion.enums.common.PromotionTypeEnum;
4   -import lombok.Data;
5   -
6   -import java.util.List;
7   -
8   -/**
9   - * 价格计算 Response DTO
10   - *
11   - * 整体设计,参考 taobao 的技术文档:
12   - * 1. <a href="https://developer.alibaba.com/docs/doc.htm?treeId=1&articleId=1029&docType=1">订单管理</a>
13   - * 2. <a href="https://open.taobao.com/docV3.htm?docId=108471&docType=1">常用订单金额说明</a>
14   - *
15   - * 举个例子:<a href="https://img.alicdn.com/top/i1/LB1mALAi4HI8KJjy1zbXXaxdpXa">订单图</a>
16   - * 输入:
17   - * 1. 订单实付: trade.payment = 198.00;订单邮费:5 元;
18   - * 2. 商品级优惠 圣诞价: 省 29.00 元 和 圣诞价:省 150.00 元; 订单级优惠,圣诞 2:省 5.00 元;
19   - * 分摊:
20   - * 1. 商品 1:原价 108 元,优惠 29 元,子订单实付 79 元,分摊主订单优惠 1.99 元;
21   - * 2. 商品 2:原价 269 元,优惠 150 元,子订单实付 119 元,分摊主订单优惠 3.01 元;
22   - *
23   - * @author 芋道源码
24   - */
25   -@Data
26   -@Deprecated
27   -public class PriceCalculateRespDTO {
28   -
29   - /**
30   - * 订单
31   - */
32   - private Order order;
33   -
34   - /**
35   - * 营销活动数组
36   - *
37   - * 只对应 {@link Order#items} 商品匹配的活动
38   - */
39   - private List<Promotion> promotions;
40   -
41   - // TODO @芋艿:需要改造下,主要是价格字段
42   - /**
43   - * 订单
44   - */
45   - @Data
46   - public static class Order {
47   -
48   - /**
49   - * 商品原价(总),单位:分
50   - *
51   - * 基于 {@link OrderItem#getOriginalPrice()} 求和
52   - *
53   - * 对应 taobao 的 trade.total_fee 字段
54   - */
55   - private Integer totalPrice;
56   - /**
57   - * 订单优惠(总),单位:分
58   - *
59   - * 订单级优惠:对主订单的优惠,常见如:订单满 200 元减 10 元;订单满 80 包邮。
60   - *
61   - * 对应 taobao 的 order.discount_fee 字段
62   - */
63   - private Integer discountPrice;
64   - /**
65   - * 优惠劵减免金额(总),单位:分
66   - *
67   - * 对应 taobao 的 trade.coupon_fee 字段
68   - */
69   - private Integer couponPrice;
70   - /**
71   - * 积分减免金额(总),单位:分
72   - *
73   - * 对应 taobao 的 trade.point_fee 字段
74   - */
75   - private Integer pointPrice;
76   - /**
77   - * 运费金额,单位:分
78   - */
79   - private Integer deliveryPrice;
80   - /**
81   - * 最终购买金额(总),单位:分
82   - *
83   - * = {@link OrderItem#getPayPrice()} 求和
84   - * - {@link #couponPrice}
85   - * - {@link #pointPrice}
86   - * + {@link #deliveryPrice}
87   - * - {@link #discountPrice}
88   - */
89   - private Integer payPrice;
90   - /**
91   - * 商品 SKU 数组
92   - */
93   - private List<OrderItem> items;
94   -
95   - // ========== 营销基本信息 ==========
96   - /**
97   - * 优惠劵编号
98   - */
99   - private Long couponId;
100   -
101   - }
102   -
103   - /**
104   - * 订单商品 SKU
105   - */
106   - @Data
107   - public static class OrderItem {
108   -
109   - /**
110   - * SPU 编号
111   - */
112   - private Long spuId;
113   - /**
114   - * SKU 编号
115   - */
116   - private Long skuId;
117   - /**
118   - * 购买数量
119   - */
120   - private Integer count;
121   -
122   - /**
123   - * 商品原价(总),单位:分
124   - *
125   - * = {@link #originalUnitPrice} * {@link #getCount()}
126   - */
127   - private Integer originalPrice;
128   - /**
129   - * 商品原价(单),单位:分
130   - *
131   - * 对应 ProductSkuDO 的 price 字段
132   - * 对应 taobao 的 order.price 字段
133   - */
134   - private Integer originalUnitPrice;
135   - /**
136   - * 商品优惠(总),单位:分
137   - *
138   - * 商品级优惠:对单个商品的,常见如:商品原价的 8 折;商品原价的减 50 元
139   - *
140   - * 对应 taobao 的 order.discount_fee 字段
141   - */
142   - private Integer discountPrice;
143   - /**
144   - * 子订单实付金额,不算主订单分摊金额,单位:分
145   - *
146   - * = {@link #originalPrice}
147   - * - {@link #discountPrice}
148   - *
149   - * 对应 taobao 的 order.payment 字段
150   - */
151   - private Integer payPrice;
152   -
153   - /**
154   - * 子订单分摊金额(总),单位:分
155   - * 需要分摊 {@link Order#discountPrice}、{@link Order#couponPrice}、{@link Order#pointPrice}
156   - *
157   - * 对应 taobao 的 order.part_mjz_discount 字段
158   - * 淘宝说明:子订单分摊优惠基础逻辑:一般正常优惠券和满减优惠按照子订单的金额进行分摊,特殊情况如果优惠券是指定商品使用的,只会分摊到对应商品子订单上不分摊。
159   - */
160   - private Integer orderPartPrice;
161   - /**
162   - * 分摊后子订单实付金额(总),单位:分
163   - *
164   - * = {@link #payPrice}
165   - * - {@link #orderPartPrice}
166   - *
167   - * 对应 taobao 的 divide_order_fee 字段
168   - */
169   - private Integer orderDividePrice;
170   -
171   - }
172   -
173   - /**
174   - * 营销明细
175   - */
176   - @Data
177   - @Deprecated
178   - public static class Promotion {
179   -
180   - /**
181   - * 营销编号
182   - *
183   - * 例如说:营销活动的编号、优惠劵的编号
184   - */
185   - private Long id;
186   - /**
187   - * 营销名字
188   - */
189   - private String name;
190   - /**
191   - * 营销类型
192   - *
193   - * 枚举 {@link PromotionTypeEnum}
194   - */
195   - private Integer type;
196   - /**
197   - * 营销级别
198   - *
199   - * 枚举 @link PromotionLevelEnum} TODO PromotionLevelEnum 没有这个枚举类
200   - */
201   - private Integer level;
202   - /**
203   - * 计算时的原价(总),单位:分
204   - */
205   - private Integer totalPrice;
206   - /**
207   - * 计算时的优惠(总),单位:分
208   - */
209   - private Integer discountPrice;
210   - /**
211   - * 匹配的商品 SKU 数组
212   - */
213   - private List<PromotionItem> items;
214   -
215   - // ========== 匹配情况 ==========
216   -
217   - /**
218   - * 是否满足优惠条件
219   - */
220   - private Boolean match;
221   - /**
222   - * 满足条件的提示
223   - *
224   - * 如果 {@link #match} = true 满足,则提示“圣诞价:省 150.00 元”
225   - * 如果 {@link #match} = false 不满足,则提示“购满 85 元,可减 40 元”
226   - */
227   - private String description;
228   -
229   - }
230   -
231   - /**
232   - * 营销匹配的商品 SKU
233   - */
234   - @Data
235   - public static class PromotionItem {
236   -
237   - /**
238   - * 商品 SKU 编号
239   - */
240   - private Long skuId;
241   - /**
242   - * 计算时的原价(总),单位:分
243   - */
244   - private Integer originalPrice;
245   - /**
246   - * 计算时的优惠(总),单位:分
247   - */
248   - private Integer discountPrice;
249   -
250   - }
251   -
252   -}
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationActivityApi.java renamed to yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/DictTypeConstants.java
1   -package cn.iocoder.yudao.module.promotion.api.combination;
  1 +package cn.iocoder.yudao.module.promotion.enums;
2 2  
3 3 /**
4   - * 拼团活动 Api 接口
  4 + * promotion 字典类型的枚举类
5 5 *
6 6 * @author HUIHUI
7 7 */
8   -public interface CombinationActivityApi {
  8 +public class DictTypeConstants {
9 9  
10 10 }
... ...
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java
... ... @@ -15,7 +15,6 @@ public interface ErrorCodeConstants {
15 15 ErrorCode DISCOUNT_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED = new ErrorCode(1_013_001_002, "限时折扣活动已关闭,不能修改");
16 16 ErrorCode DISCOUNT_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED = new ErrorCode(1_013_001_003, "限时折扣活动未关闭,不能删除");
17 17 ErrorCode DISCOUNT_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED = new ErrorCode(1_013_001_004, "限时折扣活动已关闭,不能重复关闭");
18   - ErrorCode DISCOUNT_ACTIVITY_CLOSE_FAIL_STATUS_END = new ErrorCode(1_013_001_005, "限时折扣活动已结束,不能关闭");
19 18  
20 19 // ========== Banner 相关 1-013-002-000 ============
21 20 ErrorCode BANNER_NOT_EXISTS = new ErrorCode(1_013_002_000, "Banner 不存在");
... ... @@ -110,4 +109,11 @@ public interface ErrorCodeConstants {
110 109 ErrorCode BARGAIN_HELP_CREATE_FAIL_CONFLICT = new ErrorCode(1_013_014_003, "助力失败,请重试");
111 110 ErrorCode BARGAIN_HELP_CREATE_FAIL_HELP_EXISTS = new ErrorCode(1_013_014_004, "助力失败,您已经助力过了");
112 111  
  112 + // ========== 文章分类 1-013-015-000 ==========
  113 + ErrorCode ARTICLE_CATEGORY_NOT_EXISTS = new ErrorCode(1_013_015_000, "文章分类不存在");
  114 + ErrorCode ARTICLE_CATEGORY_DELETE_FAIL_HAVE_ARTICLES = new ErrorCode(1_013_015_001, "文章分类删除失败,存在关联文章");
  115 +
  116 + // ========== 文章管理 1-013-016-000 ==========
  117 + ErrorCode ARTICLE_NOT_EXISTS = new ErrorCode(1_013_016_000, "文章不存在");
  118 +
113 119 }
... ...
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/enums/group/ProductGroupStyleEnum.java renamed to yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/banner/BannerPositionEnum.java
1   -package cn.iocoder.yudao.module.product.enums.group;
  1 +package cn.iocoder.yudao.module.promotion.enums.banner;
2 2  
3 3 import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
4 4 import lombok.AllArgsConstructor;
... ... @@ -7,26 +7,28 @@ import lombok.Getter;
7 7 import java.util.Arrays;
8 8  
9 9 /**
10   - * 商品分组的样式枚举
  10 + * Banner Position 枚举
11 11 *
12   - * @author 芋道源码
  12 + * @author HUIHUI
13 13 */
14   -@Getter
15 14 @AllArgsConstructor
16   -public enum ProductGroupStyleEnum implements IntArrayValuable {
  15 +@Getter
  16 +public enum BannerPositionEnum implements IntArrayValuable {
17 17  
18   - ONE(1, "每列一个"),
19   - TWO(2, "每列两个"),
20   - THREE(2, "每列三个"),;
  18 + HOME_POSITION(1, "首页"),
  19 + SECKILL_POSITION(2, "秒杀活动页"),
  20 + COMBINATION_POSITION(3, "砍价活动页"),
  21 + DISCOUNT_POSITION(4, "限时折扣页"),
  22 + REWARD_POSITION(5, "满减送页");
21 23  
22   - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(ProductGroupStyleEnum::getStyle).toArray();
  24 + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(BannerPositionEnum::getPosition).toArray();
23 25  
24 26 /**
25   - * 列表样式
  27 + * 值
26 28 */
27   - private final Integer style;
  29 + private final Integer position;
28 30 /**
29   - * 状态名
  31 + * 名字
30 32 */
31 33 private final String name;
32 34  
... ...
yudao-module-mall/yudao-module-promotion-biz/pom.xml
... ... @@ -14,8 +14,8 @@
14 14 <name>${project.artifactId}</name>
15 15  
16 16 <description>
17   - market模块,主要实现营销相关功能
18   - 例如:营销活动、banner广告、优惠券、优惠码等功能。
  17 + promotion 模块,主要实现营销相关功能
  18 + 例如:营销活动、banner 广告、优惠券、优惠码等功能。
19 19 </description>
20 20  
21 21 <dependencies>
... ... @@ -49,10 +49,6 @@
49 49 <groupId>cn.iocoder.boot</groupId>
50 50 <artifactId>yudao-spring-boot-starter-biz-tenant</artifactId>
51 51 </dependency>
52   - <dependency>
53   - <groupId>cn.iocoder.boot</groupId>
54   - <artifactId>yudao-spring-boot-starter-biz-weixin</artifactId>
55   - </dependency>
56 52  
57 53 <!-- Web 相关 -->
58 54 <dependency>
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/bargain/BargainActivityApiImpl.java
... ... @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.promotion.api.bargain;
2 2  
3 3 import cn.iocoder.yudao.module.promotion.service.bargain.BargainActivityService;
4 4 import org.springframework.stereotype.Service;
  5 +import org.springframework.validation.annotation.Validated;
5 6  
6 7 import javax.annotation.Resource;
7 8  
... ... @@ -11,6 +12,7 @@ import javax.annotation.Resource;
11 12 * @author HUIHUI
12 13 */
13 14 @Service
  15 +@Validated
14 16 public class BargainActivityApiImpl implements BargainActivityApi {
15 17  
16 18 @Resource
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/bargain/BargainRecordApiImpl.java
... ... @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.promotion.api.bargain;
3 3 import cn.iocoder.yudao.module.promotion.api.bargain.dto.BargainValidateJoinRespDTO;
4 4 import cn.iocoder.yudao.module.promotion.service.bargain.BargainRecordService;
5 5 import org.springframework.stereotype.Service;
  6 +import org.springframework.validation.annotation.Validated;
6 7  
7 8 import javax.annotation.Resource;
8 9  
... ... @@ -12,6 +13,7 @@ import javax.annotation.Resource;
12 13 * @author HUIHUI
13 14 */
14 15 @Service
  16 +@Validated
15 17 public class BargainRecordApiImpl implements BargainRecordApi {
16 18  
17 19 @Resource
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationActivityApiImpl.java deleted
1   -package cn.iocoder.yudao.module.promotion.api.combination;
2   -
3   -import org.springframework.stereotype.Service;
4   -
5   -/**
6   - * 拼团活动 Api 接口实现类
7   - *
8   - * @author HUIHUI
9   - */
10   -@Service
11   -public class CombinationActivityApiImpl implements CombinationActivityApi {
12   -
13   -}
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationRecordApiImpl.java
1 1 package cn.iocoder.yudao.module.promotion.api.combination;
2 2  
3   -import cn.iocoder.yudao.framework.common.core.KeyValue;
4 3 import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO;
  4 +import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateRespDTO;
5 5 import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationValidateJoinRespDTO;
  6 +import cn.iocoder.yudao.module.promotion.convert.combination.CombinationActivityConvert;
6 7 import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationRecordDO;
7 8 import cn.iocoder.yudao.module.promotion.enums.combination.CombinationRecordStatusEnum;
8 9 import cn.iocoder.yudao.module.promotion.service.combination.CombinationRecordService;
9 10 import org.springframework.stereotype.Service;
  11 +import org.springframework.validation.annotation.Validated;
10 12  
11 13 import javax.annotation.Resource;
12 14  
... ... @@ -19,6 +21,7 @@ import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.COMBINA
19 21 * @author HUIHUI
20 22 */
21 23 @Service
  24 +@Validated
22 25 public class CombinationRecordApiImpl implements CombinationRecordApi {
23 26  
24 27 @Resource
... ... @@ -29,10 +32,9 @@ public class CombinationRecordApiImpl implements CombinationRecordApi {
29 32 recordService.validateCombinationRecord(userId, activityId, headId, skuId, count);
30 33 }
31 34  
32   - // TODO @puhui999:搞个创建的 RespDTO 哈;
33 35 @Override
34   - public KeyValue<Long, Long> createCombinationRecord(CombinationRecordCreateReqDTO reqDTO) {
35   - return recordService.createCombinationRecord(reqDTO);
  36 + public CombinationRecordCreateRespDTO createCombinationRecord(CombinationRecordCreateReqDTO reqDTO) {
  37 + return CombinationActivityConvert.INSTANCE.convert4(recordService.createCombinationRecord(reqDTO));
36 38 }
37 39  
38 40 @Override
... ... @@ -45,11 +47,6 @@ public class CombinationRecordApiImpl implements CombinationRecordApi {
45 47 }
46 48  
47 49 @Override
48   - public void updateRecordStatusToFailed(Long userId, Long orderId) {
49   - recordService.updateCombinationRecordStatusByUserIdAndOrderId(CombinationRecordStatusEnum.FAILED.getStatus(), userId, orderId);
50   - }
51   -
52   - @Override
53 50 public CombinationValidateJoinRespDTO validateJoinCombination(Long userId, Long activityId, Long headId, Long skuId, Integer count) {
54 51 return recordService.validateJoinCombination(userId, activityId, headId, skuId, count);
55 52 }
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/CouponApiImpl.java
... ... @@ -8,6 +8,7 @@ import cn.iocoder.yudao.module.promotion.convert.coupon.CouponConvert;
8 8 import cn.iocoder.yudao.module.promotion.dal.dataobject.coupon.CouponDO;
9 9 import cn.iocoder.yudao.module.promotion.service.coupon.CouponService;
10 10 import org.springframework.stereotype.Service;
  11 +import org.springframework.validation.annotation.Validated;
11 12  
12 13 import javax.annotation.Resource;
13 14  
... ... @@ -17,6 +18,7 @@ import javax.annotation.Resource;
17 18 * @author 芋道源码
18 19 */
19 20 @Service
  21 +@Validated
20 22 public class CouponApiImpl implements CouponApi {
21 23  
22 24 @Resource
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/discount/DiscountActivityApiImpl.java
... ... @@ -4,6 +4,7 @@ import cn.iocoder.yudao.module.promotion.api.discount.dto.DiscountProductRespDTO
4 4 import cn.iocoder.yudao.module.promotion.convert.discount.DiscountActivityConvert;
5 5 import cn.iocoder.yudao.module.promotion.service.discount.DiscountActivityService;
6 6 import org.springframework.stereotype.Service;
  7 +import org.springframework.validation.annotation.Validated;
7 8  
8 9 import javax.annotation.Resource;
9 10 import java.util.Collection;
... ... @@ -15,6 +16,7 @@ import java.util.List;
15 16 * @author 芋道源码
16 17 */
17 18 @Service
  19 +@Validated
18 20 public class DiscountActivityApiImpl implements DiscountActivityApi {
19 21  
20 22 @Resource
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/price/PriceApiImpl.java deleted
1   -package cn.iocoder.yudao.module.promotion.api.price;
2   -
3   -import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateReqDTO;
4   -import cn.iocoder.yudao.module.promotion.api.price.dto.PriceCalculateRespDTO;
5   -import cn.iocoder.yudao.module.promotion.service.price.PriceService;
6   -import org.springframework.stereotype.Service;
7   -
8   -import javax.annotation.Resource;
9   -
10   -/**
11   - * 价格 API 实现类
12   - *
13   - * @author 芋道源码
14   - */
15   -@Service
16   -public class PriceApiImpl implements PriceApi {
17   -
18   - @Resource
19   - private PriceService priceService;
20   -
21   - @Override
22   - public PriceCalculateRespDTO calculatePrice(PriceCalculateReqDTO calculateReqDTO) {
23   - //return priceService.calculatePrice(calculateReqDTO); TODO 没有 calculatePrice 这个方法
24   -
25   - return null;
26   - }
27   -
28   -}
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/reward/RewardActivityApiImpl.java
... ... @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.promotion.api.reward;
3 3 import cn.iocoder.yudao.module.promotion.api.reward.dto.RewardActivityMatchRespDTO;
4 4 import cn.iocoder.yudao.module.promotion.service.reward.RewardActivityService;
5 5 import org.springframework.stereotype.Service;
  6 +import org.springframework.validation.annotation.Validated;
6 7  
7 8 import javax.annotation.Resource;
8 9 import java.util.Collection;
... ... @@ -14,6 +15,7 @@ import java.util.List;
14 15 * @author 芋道源码
15 16 */
16 17 @Service
  18 +@Validated
17 19 public class RewardActivityApiImpl implements RewardActivityApi {
18 20  
19 21 @Resource
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/seckill/SeckillActivityApiImpl.java
... ... @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.promotion.api.seckill;
3 3 import cn.iocoder.yudao.module.promotion.api.seckill.dto.SeckillValidateJoinRespDTO;
4 4 import cn.iocoder.yudao.module.promotion.service.seckill.SeckillActivityService;
5 5 import org.springframework.stereotype.Service;
  6 +import org.springframework.validation.annotation.Validated;
6 7  
7 8 import javax.annotation.Resource;
8 9  
... ... @@ -12,6 +13,7 @@ import javax.annotation.Resource;
12 13 * @author HUIHUI
13 14 */
14 15 @Service
  16 +@Validated
15 17 public class SeckillActivityApiImpl implements SeckillActivityApi {
16 18  
17 19 @Resource
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/article/ArticleCategoryController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.controller.admin.article;
  2 +
  3 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  4 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  5 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  6 +import cn.iocoder.yudao.module.promotion.controller.admin.article.vo.category.*;
  7 +import cn.iocoder.yudao.module.promotion.convert.article.ArticleCategoryConvert;
  8 +import cn.iocoder.yudao.module.promotion.dal.dataobject.article.ArticleCategoryDO;
  9 +import cn.iocoder.yudao.module.promotion.service.article.ArticleCategoryService;
  10 +import io.swagger.v3.oas.annotations.Operation;
  11 +import io.swagger.v3.oas.annotations.Parameter;
  12 +import io.swagger.v3.oas.annotations.tags.Tag;
  13 +import org.springframework.security.access.prepost.PreAuthorize;
  14 +import org.springframework.validation.annotation.Validated;
  15 +import org.springframework.web.bind.annotation.*;
  16 +
  17 +import javax.annotation.Resource;
  18 +import javax.validation.Valid;
  19 +import java.util.Comparator;
  20 +import java.util.List;
  21 +
  22 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  23 +
  24 +@Tag(name = "管理后台 - 文章分类")
  25 +@RestController
  26 +@RequestMapping("/promotion/article-category")
  27 +@Validated
  28 +public class ArticleCategoryController {
  29 +
  30 + @Resource
  31 + private ArticleCategoryService articleCategoryService;
  32 +
  33 + @PostMapping("/create")
  34 + @Operation(summary = "创建文章分类")
  35 + @PreAuthorize("@ss.hasPermission('promotion:article-category:create')")
  36 + public CommonResult<Long> createArticleCategory(@Valid @RequestBody ArticleCategoryCreateReqVO createReqVO) {
  37 + return success(articleCategoryService.createArticleCategory(createReqVO));
  38 + }
  39 +
  40 + @PutMapping("/update")
  41 + @Operation(summary = "更新文章分类")
  42 + @PreAuthorize("@ss.hasPermission('promotion:article-category:update')")
  43 + public CommonResult<Boolean> updateArticleCategory(@Valid @RequestBody ArticleCategoryUpdateReqVO updateReqVO) {
  44 + articleCategoryService.updateArticleCategory(updateReqVO);
  45 + return success(true);
  46 + }
  47 +
  48 + @DeleteMapping("/delete")
  49 + @Operation(summary = "删除文章分类")
  50 + @Parameter(name = "id", description = "编号", required = true)
  51 + @PreAuthorize("@ss.hasPermission('promotion:article-category:delete')")
  52 + public CommonResult<Boolean> deleteArticleCategory(@RequestParam("id") Long id) {
  53 + articleCategoryService.deleteArticleCategory(id);
  54 + return success(true);
  55 + }
  56 +
  57 + @GetMapping("/get")
  58 + @Operation(summary = "获得文章分类")
  59 + @Parameter(name = "id", description = "编号", required = true, example = "1024")
  60 + @PreAuthorize("@ss.hasPermission('promotion:article-category:query')")
  61 + public CommonResult<ArticleCategoryRespVO> getArticleCategory(@RequestParam("id") Long id) {
  62 + ArticleCategoryDO category = articleCategoryService.getArticleCategory(id);
  63 + return success(ArticleCategoryConvert.INSTANCE.convert(category));
  64 + }
  65 +
  66 + @GetMapping("/list-all-simple")
  67 + @Operation(summary = "获取文章分类精简信息列表", description = "只包含被开启的文章分类,主要用于前端的下拉选项")
  68 + public CommonResult<List<ArticleCategorySimpleRespVO>> getSimpleDeptList() {
  69 + // 获得分类列表,只要开启状态的
  70 + List<ArticleCategoryDO> list = articleCategoryService.getArticleCategoryListByStatus(CommonStatusEnum.ENABLE.getStatus());
  71 + // 降序排序后,返回给前端
  72 + list.sort(Comparator.comparing(ArticleCategoryDO::getSort).reversed());
  73 + return success(ArticleCategoryConvert.INSTANCE.convertList03(list));
  74 + }
  75 +
  76 + @GetMapping("/page")
  77 + @Operation(summary = "获得文章分类分页")
  78 + @PreAuthorize("@ss.hasPermission('promotion:article-category:query')")
  79 + public CommonResult<PageResult<ArticleCategoryRespVO>> getArticleCategoryPage(@Valid ArticleCategoryPageReqVO pageVO) {
  80 + PageResult<ArticleCategoryDO> pageResult = articleCategoryService.getArticleCategoryPage(pageVO);
  81 + return success(ArticleCategoryConvert.INSTANCE.convertPage(pageResult));
  82 + }
  83 +
  84 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/article/ArticleController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.controller.admin.article;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  5 +import cn.iocoder.yudao.module.promotion.controller.admin.article.vo.article.ArticleCreateReqVO;
  6 +import cn.iocoder.yudao.module.promotion.controller.admin.article.vo.article.ArticlePageReqVO;
  7 +import cn.iocoder.yudao.module.promotion.controller.admin.article.vo.article.ArticleRespVO;
  8 +import cn.iocoder.yudao.module.promotion.controller.admin.article.vo.article.ArticleUpdateReqVO;
  9 +import cn.iocoder.yudao.module.promotion.convert.article.ArticleConvert;
  10 +import cn.iocoder.yudao.module.promotion.dal.dataobject.article.ArticleDO;
  11 +import cn.iocoder.yudao.module.promotion.service.article.ArticleService;
  12 +import io.swagger.v3.oas.annotations.Operation;
  13 +import io.swagger.v3.oas.annotations.Parameter;
  14 +import io.swagger.v3.oas.annotations.tags.Tag;
  15 +import org.springframework.security.access.prepost.PreAuthorize;
  16 +import org.springframework.validation.annotation.Validated;
  17 +import org.springframework.web.bind.annotation.*;
  18 +
  19 +import javax.annotation.Resource;
  20 +import javax.validation.Valid;
  21 +
  22 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  23 +
  24 +@Tag(name = "管理后台 - 文章管理")
  25 +@RestController
  26 +@RequestMapping("/promotion/article")
  27 +@Validated
  28 +public class ArticleController {
  29 +
  30 + @Resource
  31 + private ArticleService articleService;
  32 +
  33 + @PostMapping("/create")
  34 + @Operation(summary = "创建文章管理")
  35 + @PreAuthorize("@ss.hasPermission('promotion:article:create')")
  36 + public CommonResult<Long> createArticle(@Valid @RequestBody ArticleCreateReqVO createReqVO) {
  37 + return success(articleService.createArticle(createReqVO));
  38 + }
  39 +
  40 + @PutMapping("/update")
  41 + @Operation(summary = "更新文章管理")
  42 + @PreAuthorize("@ss.hasPermission('promotion:article:update')")
  43 + public CommonResult<Boolean> updateArticle(@Valid @RequestBody ArticleUpdateReqVO updateReqVO) {
  44 + articleService.updateArticle(updateReqVO);
  45 + return success(true);
  46 + }
  47 +
  48 + @DeleteMapping("/delete")
  49 + @Operation(summary = "删除文章管理")
  50 + @Parameter(name = "id", description = "编号", required = true)
  51 + @PreAuthorize("@ss.hasPermission('promotion:article:delete')")
  52 + public CommonResult<Boolean> deleteArticle(@RequestParam("id") Long id) {
  53 + articleService.deleteArticle(id);
  54 + return success(true);
  55 + }
  56 +
  57 + @GetMapping("/get")
  58 + @Operation(summary = "获得文章管理")
  59 + @Parameter(name = "id", description = "编号", required = true, example = "1024")
  60 + @PreAuthorize("@ss.hasPermission('promotion:article:query')")
  61 + public CommonResult<ArticleRespVO> getArticle(@RequestParam("id") Long id) {
  62 + ArticleDO article = articleService.getArticle(id);
  63 + return success(ArticleConvert.INSTANCE.convert(article));
  64 + }
  65 +
  66 + @GetMapping("/page")
  67 + @Operation(summary = "获得文章管理分页")
  68 + @PreAuthorize("@ss.hasPermission('promotion:article:query')")
  69 + public CommonResult<PageResult<ArticleRespVO>> getArticlePage(@Valid ArticlePageReqVO pageVO) {
  70 + PageResult<ArticleDO> pageResult = articleService.getArticlePage(pageVO);
  71 + return success(ArticleConvert.INSTANCE.convertPage(pageResult));
  72 + }
  73 +
  74 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/article/vo/article/ArticleBaseVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.controller.admin.article.vo.article;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +import javax.validation.constraints.NotNull;
  7 +
  8 +/**
  9 + * 文章管理 Base VO,提供给添加、修改、详细的子 VO 使用
  10 + * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
  11 + */
  12 +@Data
  13 +public class ArticleBaseVO {
  14 +
  15 + @Schema(description = "文章分类编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "15458")
  16 + @NotNull(message = "文章分类编号不能为空")
  17 + private Long categoryId;
  18 +
  19 + @Schema(description = "关联商品编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "22378")
  20 + @NotNull(message = "关联商品不能为空")
  21 + private Long spuId;
  22 +
  23 + @Schema(description = "文章标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "这是一个标题")
  24 + @NotNull(message = "文章标题不能为空")
  25 + private String title;
  26 +
  27 + @Schema(description = "文章作者", requiredMode = Schema.RequiredMode.REQUIRED, example = "张三")
  28 + private String author;
  29 +
  30 + @Schema(description = "文章封面图片地址", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn")
  31 + @NotNull(message = "文章封面图片地址不能为空")
  32 + private String picUrl;
  33 +
  34 + @Schema(description = "文章简介", requiredMode = Schema.RequiredMode.REQUIRED, example = "这是一个简介")
  35 + private String introduction;
  36 +
  37 + @Schema(description = "排序", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  38 + @NotNull(message = "排序不能为空")
  39 + private Integer sort;
  40 +
  41 + @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
  42 + @NotNull(message = "状态不能为空")
  43 + private Integer status;
  44 +
  45 + @Schema(description = "是否热门(小程序)", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
  46 + @NotNull(message = "是否热门(小程序)不能为空")
  47 + private Boolean recommendHot;
  48 +
  49 + @Schema(description = "是否轮播图(小程序)", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
  50 + @NotNull(message = "是否轮播图(小程序)不能为空")
  51 + private Boolean recommendBanner;
  52 +
  53 + @Schema(description = "文章内容", requiredMode = Schema.RequiredMode.REQUIRED, example = "这是文章内容")
  54 + @NotNull(message = "文章内容不能为空")
  55 + private String content;
  56 +
  57 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/article/vo/article/ArticleCreateReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.controller.admin.article.vo.article;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +import lombok.EqualsAndHashCode;
  6 +import lombok.ToString;
  7 +
  8 +@Schema(description = "管理后台 - 文章管理创建 Request VO")
  9 +@Data
  10 +@EqualsAndHashCode(callSuper = true)
  11 +@ToString(callSuper = true)
  12 +public class ArticleCreateReqVO extends ArticleBaseVO {
  13 +
  14 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/article/vo/article/ArticlePageReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.controller.admin.article.vo.article;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  4 +import io.swagger.v3.oas.annotations.media.Schema;
  5 +import lombok.Data;
  6 +import lombok.EqualsAndHashCode;
  7 +import lombok.ToString;
  8 +import org.springframework.format.annotation.DateTimeFormat;
  9 +
  10 +import java.time.LocalDateTime;
  11 +
  12 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  13 +
  14 +@Schema(description = "管理后台 - 文章管理分页 Request VO")
  15 +@Data
  16 +@EqualsAndHashCode(callSuper = true)
  17 +@ToString(callSuper = true)
  18 +public class ArticlePageReqVO extends PageParam {
  19 +
  20 + @Schema(description = "文章分类编号", example = "15458")
  21 + private Long categoryId;
  22 +
  23 + @Schema(description = "关联商品编号", example = "22378")
  24 + private Long spuId;
  25 +
  26 + @Schema(description = "文章标题")
  27 + private String title;
  28 +
  29 + @Schema(description = "文章作者")
  30 + private String author;
  31 +
  32 + @Schema(description = "状态", example = "2")
  33 + private Integer status;
  34 +
  35 + @Schema(description = "是否热门(小程序)")
  36 + private Boolean recommendHot;
  37 +
  38 + @Schema(description = "是否轮播图(小程序)")
  39 + private Boolean recommendBanner;
  40 +
  41 + @Schema(description = "创建时间")
  42 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  43 + private LocalDateTime[] createTime;
  44 +
  45 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/article/vo/article/ArticleRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.controller.admin.article.vo.article;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +import lombok.EqualsAndHashCode;
  6 +import lombok.ToString;
  7 +
  8 +import java.time.LocalDateTime;
  9 +
  10 +@Schema(description = "管理后台 - 文章管理 Response VO")
  11 +@Data
  12 +@EqualsAndHashCode(callSuper = true)
  13 +@ToString(callSuper = true)
  14 +public class ArticleRespVO extends ArticleBaseVO {
  15 +
  16 + @Schema(description = "文章编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "8606")
  17 + private Long id;
  18 +
  19 + @Schema(description = "浏览量", requiredMode = Schema.RequiredMode.REQUIRED, example = "99999")
  20 + private Integer browseCount;
  21 +
  22 + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
  23 + private LocalDateTime createTime;
  24 +
  25 +}
... ...
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/article/vo/article/ArticleUpdateReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.promotion.controller.admin.article.vo.article;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +import lombok.EqualsAndHashCode;
  6 +import lombok.ToString;
  7 +
  8 +import javax.validation.constraints.NotNull;
  9 +
  10 +@Schema(description = "管理后台 - 文章管理更新 Request VO")
  11 +@Data
  12 +@EqualsAndHashCode(callSuper = true)
  13 +@ToString(callSuper = true)
  14 +public class ArticleUpdateReqVO extends ArticleBaseVO {
  15 +
  16 + @Schema(description = "文章编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "8606")
  17 + @NotNull(message = "文章编号不能为空")
  18 + private Long id;
  19 +
  20 +}
... ...