Commit 5d6bb84d2565df76f0c25a448e3ef127dd1bad6b

Authored by puhui999
2 parents 0e875597 5808f77a

Merge remote-tracking branch 'yudao/feature/mall_product' into feature/mall_product

Showing 169 changed files with 4078 additions and 689 deletions
.gitignore
@@ -8,6 +8,8 @@ @@ -8,6 +8,8 @@
8 target/ 8 target/
9 !.mvn/wrapper/maven-wrapper.jar 9 !.mvn/wrapper/maven-wrapper.jar
10 10
  11 +.flattened-pom.xml
  12 +
11 ###################################################################### 13 ######################################################################
12 # IDE 14 # IDE
13 15
@@ -16,10 +16,10 @@ @@ -16,10 +16,10 @@
16 <module>yudao-module-member</module> 16 <module>yudao-module-member</module>
17 <module>yudao-module-system</module> 17 <module>yudao-module-system</module>
18 <module>yudao-module-infra</module> 18 <module>yudao-module-infra</module>
  19 + <!-- <module>yudao-module-bpm</module>-->
  20 +<!-- <module>yudao-module-report</module>-->
  21 +<!-- <module>yudao-module-mp</module>-->
19 <module>yudao-module-pay</module> 22 <module>yudao-module-pay</module>
20 - <module>yudao-module-bpm</module>  
21 - <module>yudao-module-report</module>  
22 - <module>yudao-module-mp</module>  
23 <module>yudao-module-mall</module> 23 <module>yudao-module-mall</module>
24 <!-- 示例项目 --> 24 <!-- 示例项目 -->
25 <module>yudao-example</module> 25 <module>yudao-example</module>
@@ -30,13 +30,14 @@ @@ -30,13 +30,14 @@
30 <url>https://github.com/YunaiV/ruoyi-vue-pro</url> 30 <url>https://github.com/YunaiV/ruoyi-vue-pro</url>
31 31
32 <properties> 32 <properties>
33 - <revision>1.8.0-snapshot</revision> 33 + <revision>1.8.1-snapshot</revision>
34 <!-- Maven 相关 --> 34 <!-- Maven 相关 -->
35 <java.version>1.8</java.version> 35 <java.version>1.8</java.version>
36 <maven.compiler.source>${java.version}</maven.compiler.source> 36 <maven.compiler.source>${java.version}</maven.compiler.source>
37 <maven.compiler.target>${java.version}</maven.compiler.target> 37 <maven.compiler.target>${java.version}</maven.compiler.target>
38 <maven-surefire-plugin.version>3.0.0-M5</maven-surefire-plugin.version> 38 <maven-surefire-plugin.version>3.0.0-M5</maven-surefire-plugin.version>
39 <maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version> 39 <maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version>
  40 + <flatten-maven-plugin.version>1.5.0</flatten-maven-plugin.version>
40 <!-- 看看咋放到 bom 里 --> 41 <!-- 看看咋放到 bom 里 -->
41 <lombok.version>1.18.28</lombok.version> 42 <lombok.version>1.18.28</lombok.version>
42 <spring.boot.version>2.7.14</spring.boot.version> 43 <spring.boot.version>2.7.14</spring.boot.version>
@@ -92,8 +93,41 @@ @@ -92,8 +93,41 @@
92 </annotationProcessorPaths> 93 </annotationProcessorPaths>
93 </configuration> 94 </configuration>
94 </plugin> 95 </plugin>
  96 + <plugin>
  97 + <groupId>org.codehaus.mojo</groupId>
  98 + <artifactId>flatten-maven-plugin</artifactId>
  99 + </plugin>
95 </plugins> 100 </plugins>
96 </pluginManagement> 101 </pluginManagement>
  102 +
  103 + <plugins>
  104 + <!-- 统一 revision 版本 -->
  105 + <plugin>
  106 + <groupId>org.codehaus.mojo</groupId>
  107 + <artifactId>flatten-maven-plugin</artifactId>
  108 + <version>${flatten-maven-plugin.version}</version>
  109 + <configuration>
  110 + <flattenMode>resolveCiFriendliesOnly</flattenMode>
  111 + <updatePomFile>true</updatePomFile>
  112 + </configuration>
  113 + <executions>
  114 + <execution>
  115 + <goals>
  116 + <goal>flatten</goal>
  117 + </goals>
  118 + <id>flatten</id>
  119 + <phase>process-resources</phase>
  120 + </execution>
  121 + <execution>
  122 + <goals>
  123 + <goal>clean</goal>
  124 + </goals>
  125 + <id>flatten.clean</id>
  126 + <phase>clean</phase>
  127 + </execution>
  128 + </executions>
  129 + </plugin>
  130 + </plugins>
97 </build> 131 </build>
98 132
99 <!-- 使用 huawei / aliyun 的 Maven 源,提升下载速度 --> 133 <!-- 使用 huawei / aliyun 的 Maven 源,提升下载速度 -->
sql/mysql/brokerage.sql 0 → 100644
  1 +-- 增加配置表
  2 +create table trade_config
  3 +(
  4 + id bigint auto_increment comment '自增主键' primary key,
  5 + brokerage_enabled bit default 1 not null comment '是否启用分佣',
  6 + brokerage_enabled_condition tinyint default 0 not null comment '分佣模式:0-人人分销 1-指定分销',
  7 + brokerage_bind_mode tinyint default 0 not null comment '分销关系绑定模式: 0-没有推广人,1-新用户',
  8 + brokerage_post_urls varchar(2000) default '' null comment '分销海报图地址数组',
  9 + brokerage_first_percent int default 0 not null comment '一级返佣比例',
  10 + brokerage_second_percent int default 0 not null comment '二级返佣比例',
  11 + brokerage_withdraw_min_price int default 0 not null comment '用户提现最低金额',
  12 + brokerage_bank_names varchar(200) default '' not null comment '提现银行(字典类型=brokerage_bank_name)',
  13 + brokerage_frozen_days int default 7 not null comment '佣金冻结时间(天)',
  14 + brokerage_withdraw_type varchar(32) default '1,2,3,4' not null comment '提现方式:1-钱包;2-银行卡;3-微信;4-支付宝',
  15 + creator varchar(64) collate utf8mb4_unicode_ci default '' null comment '创建者',
  16 + create_time datetime default CURRENT_TIMESTAMP not null comment '创建时间',
  17 + updater varchar(64) collate utf8mb4_unicode_ci default '' null comment '更新者',
  18 + update_time datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间',
  19 + deleted bit default b'0' not null comment '是否删除',
  20 + tenant_id bigint default 0 not null comment '租户编号'
  21 +) comment '交易中心配置';
  22 +
  23 +-- 增加分销用户扩展表
  24 +create table trade_brokerage_user
  25 +(
  26 + id bigint auto_increment comment '用户编号' primary key,
  27 + brokerage_user_id bigint not null comment '推广员编号',
  28 + brokerage_bind_time datetime null comment '推广员绑定时间',
  29 + brokerage_enabled bit default 1 not null comment '是否成为推广员',
  30 + brokerage_time datetime null comment '成为分销员时间',
  31 + brokerage_price int default 0 not null comment '可用佣金',
  32 + frozen_brokerage_price int default 0 not null comment '冻结佣金',
  33 + creator varchar(64) collate utf8mb4_unicode_ci default '' null comment '创建者',
  34 + create_time datetime default CURRENT_TIMESTAMP not null comment '创建时间',
  35 + updater varchar(64) collate utf8mb4_unicode_ci default '' null comment '更新者',
  36 + update_time datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间',
  37 + deleted bit default b'0' not null comment '是否删除',
  38 + tenant_id bigint default 0 not null comment '租户编号'
  39 +) comment '分销用户';
  40 +
  41 +create index idx_invite_user_id on trade_brokerage_user (brokerage_user_id) comment '推广员编号';
  42 +create index idx_agent on trade_brokerage_user (brokerage_enabled) comment '是否成为推广员';
  43 +
  44 +
  45 +create table trade_brokerage_record
  46 +(
  47 + id int auto_increment comment '编号'
  48 + primary key,
  49 + user_id bigint not null comment '用户编号',
  50 + biz_id varchar(64) default '' not null comment '业务编号',
  51 + biz_type tinyint default 0 not null comment '业务类型:0-订单,1-提现',
  52 + title varchar(64) default '' not null comment '标题',
  53 + price int default 0 not null comment '金额',
  54 + total_price int default 0 not null comment '当前总佣金',
  55 + description varchar(500) default '' not null comment '说明',
  56 + status tinyint default 0 not null comment '状态:0-待结算,1-已结算,2-已取消',
  57 + frozen_days int default 0 not null comment '冻结时间(天)',
  58 + unfreeze_time datetime null comment '解冻时间',
  59 + creator varchar(64) collate utf8mb4_general_ci default '' null comment '创建者',
  60 + create_time datetime default CURRENT_TIMESTAMP not null comment '创建时间',
  61 + updater varchar(64) collate utf8mb4_general_ci default '' null comment '更新者',
  62 + update_time datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间',
  63 + deleted bit default b'0' not null comment '是否删除',
  64 + tenant_id bigint default 0 not null comment '租户编号'
  65 +)
  66 + comment '佣金记录';
  67 +
  68 +create index idx_user_id on trade_brokerage_record (user_id) comment '用户编号';
  69 +create index idx_biz on trade_brokerage_record (biz_type, biz_id) comment '业务';
  70 +create index idx_status on trade_brokerage_record (status) comment '状态';
  71 +
  72 +
  73 +create table trade_brokerage_withdraw
  74 +(
  75 + id int auto_increment comment '编号'
  76 + primary key,
  77 + user_id bigint not null comment '用户编号',
  78 + price int default 0 not null comment '提现金额',
  79 + fee_price int default 0 not null comment '提现手续费',
  80 + total_price int default 0 not null comment '当前总佣金',
  81 + type tinyint default 0 not null comment '提现类型:1-钱包;2-银行卡;3-微信;4-支付宝',
  82 + name varchar(64) null comment '真实姓名',
  83 + account_no varchar(64) null comment '账号',
  84 + bank_name varchar(100) null comment '银行名称',
  85 + bank_address varchar(200) null comment '开户地址',
  86 + account_qr_code_url varchar(512) null comment '收款码',
  87 + status tinyint(2) default 0 not null comment '状态:0-审核中,10-审核通过 20-审核不通过;预留:11 - 提现成功;21-提现失败',
  88 + audit_reason varchar(128) null comment '审核驳回原因',
  89 + audit_time datetime null comment '审核时间',
  90 + remark varchar(500) null comment '备注',
  91 + creator varchar(64) collate utf8mb4_general_ci default '' null comment '创建者',
  92 + create_time datetime default CURRENT_TIMESTAMP not null comment '创建时间',
  93 + updater varchar(64) collate utf8mb4_general_ci default '' null comment '更新者',
  94 + update_time datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间',
  95 + deleted bit default b'0' not null comment '是否删除',
  96 + tenant_id bigint default 0 not null comment '租户编号'
  97 +)
  98 + comment '佣金提现';
  99 +
  100 +create index idx_user_id on trade_brokerage_withdraw (user_id) comment '用户编号';
  101 +create index idx_audit_status on trade_brokerage_withdraw (status) comment '状态';
  102 +
  103 +-- 增加字典
  104 +insert into system_dict_type(type, name)
  105 +values ('brokerage_enabled_condition', '分佣模式');
  106 +insert into system_dict_data(dict_type, label, value, sort, remark)
  107 +values ('brokerage_enabled_condition', '人人分销', 0, 0, '所有用户都可以分销'),
  108 + ('brokerage_enabled_condition', '指定分销', 1, 1, '仅可后台手动设置推广员');
  109 +
  110 +insert into system_dict_type(type, name)
  111 +values ('brokerage_bind_mode', '分销关系绑定模式');
  112 +insert into system_dict_data(dict_type, label, value, sort, remark)
  113 +values ('brokerage_bind_mode', '没有推广人', 0, 0, '只要用户没有推广人,随时都可以绑定推广关系'),
  114 + ('brokerage_bind_mode', '新用户', 1, 1, '仅新用户注册时才能绑定推广关系');
  115 +
  116 +insert into system_dict_type(type, name)
  117 +values ('brokerage_withdraw_type', '佣金提现类型');
  118 +insert into system_dict_data(dict_type, label, value, sort)
  119 +values ('brokerage_withdraw_type', '钱包', 1, 1),
  120 + ('brokerage_withdraw_type', '银行卡', 2, 2),
  121 + ('brokerage_withdraw_type', '微信', 3, 3),
  122 + ('brokerage_withdraw_type', '支付宝', 4, 4);
  123 +
  124 +insert into system_dict_type(type, name)
  125 +values ('brokerage_record_biz_type', '佣金记录业务类型');
  126 +insert into system_dict_data(dict_type, label, value, sort)
  127 +values ('brokerage_record_biz_type', '订单返佣', 0, 0),
  128 + ('brokerage_record_biz_type', '申请提现', 1, 1);
  129 +
  130 +insert into system_dict_type(type, name)
  131 +values ('brokerage_record_status', '佣金记录状态');
  132 +insert into system_dict_data(dict_type, label, value, sort)
  133 +values ('brokerage_record_status', '待结算', 0, 0),
  134 + ('brokerage_record_status', '已结算', 1, 1),
  135 + ('brokerage_record_status', '已取消', 2, 2);
  136 +
  137 +insert into system_dict_type(type, name)
  138 +values ('brokerage_withdraw_status', '佣金提现状态');
  139 +insert into system_dict_data(dict_type, label, value, sort)
  140 +values ('brokerage_withdraw_status', '审核中', 0, 0),
  141 + ('brokerage_withdraw_status', '审核通过', 10, 10),
  142 + ('brokerage_withdraw_status', '提现成功', 11, 11),
  143 + ('brokerage_withdraw_status', '审核不通过', 20, 20),
  144 + ('brokerage_withdraw_status', '提现失败', 21, 21);
  145 +
  146 +insert into system_dict_type(type, name)
  147 +values ('brokerage_bank_name', '佣金提现银行');
  148 +insert into system_dict_data(dict_type, label, value, sort)
  149 +values ('brokerage_bank_name', '工商银行', 0, 0),
  150 + ('brokerage_bank_name', '建设银行', 1, 1),
  151 + ('brokerage_bank_name', '农业银行', 2, 2),
  152 + ('brokerage_bank_name', '中国银行', 3, 3),
  153 + ('brokerage_bank_name', '交通银行', 4, 4),
  154 + ('brokerage_bank_name', '招商银行', 5, 5);
  155 +
  156 +
  157 +-- 交易中心配置:菜单 SQL
  158 +INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status, component_name)
  159 +VALUES ('交易中心配置', '', 2, 0, 2072, 'config', 'ep:setting', 'trade/config/index', 0, 'TradeConfig');
  160 +-- 按钮父菜单ID
  161 +-- 暂时只支持 MySQL。如果你是 Oracle、PostgreSQL、SQLServer 的话,需要手动修改 @parentId 的部分的代码
  162 +SELECT @parentId := LAST_INSERT_ID();
  163 +-- 按钮 SQL
  164 +INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status)
  165 +VALUES ('交易中心配置查询', 'trade:config:query', 3, 1, @parentId, '', '', '', 0);
  166 +INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status)
  167 +VALUES ('交易中心配置保存', 'trade:config:save', 3, 2, @parentId, '', '', '', 0);
  168 +
  169 +
  170 +-- 增加菜单:分销
  171 +INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status, component_name)
  172 +VALUES ('分销', '', 1, 5, 2072, 'brokerage', 'fa-solid:project-diagram', '', 0, '');
  173 +-- 按钮父菜单ID
  174 +SELECT @brokerageMenuId := LAST_INSERT_ID();
  175 +
  176 +-- 增加菜单:分销员
  177 +-- 菜单 SQL
  178 +INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status, component_name)
  179 +VALUES ('分销用户', '', 2, 0, @brokerageMenuId, 'brokerage-user', 'fa-solid:user-tie', 'trade/brokerage/user/index', 0,
  180 + 'TradeBrokerageUser');
  181 +-- 按钮父菜单ID
  182 +-- 暂时只支持 MySQL。如果你是 Oracle、PostgreSQL、SQLServer 的话,需要手动修改 @parentId 的部分的代码
  183 +SELECT @parentId := LAST_INSERT_ID();
  184 +-- 按钮 SQL
  185 +INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status)
  186 +VALUES ('分销用户查询', 'trade:brokerage-user:query', 3, 1, @parentId, '', '', '', 0);
  187 +INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status)
  188 +VALUES ('分销用户修改推广员', 'trade:brokerage-user:update-brokerage-user', 3, 2, @parentId, '', '', '', 0);
  189 +INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status)
  190 +VALUES ('分销用户清除推广员', 'trade:brokerage-user:clear-brokerage-user', 3, 3, @parentId, '', '', '', 0);
  191 +INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status)
  192 +VALUES ('分销用户修改推广资格', 'trade:brokerage-user:update-brokerage-enable', 3, 4, @parentId, '', '', '', 0);
  193 +
  194 +
  195 +-- 增加菜单:佣金记录
  196 +INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status, component_name)
  197 +VALUES ('佣金记录', '', 2, 1, @brokerageMenuId, 'brokerage-record', 'fa:money', 'trade/brokerage/record/index', 0,
  198 + 'TradeBrokerageRecord');
  199 +-- 按钮父菜单ID
  200 +-- 暂时只支持 MySQL。如果你是 Oracle、PostgreSQL、SQLServer 的话,需要手动修改 @parentId 的部分的代码
  201 +SELECT @parentId := LAST_INSERT_ID();
  202 +-- 按钮 SQL
  203 +INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status)
  204 +VALUES ('佣金记录查询', 'trade:brokerage-record:query', 3, 1, @parentId, '', '', '', 0);
  205 +
  206 +-- 增加菜单:佣金提现
  207 +INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status, component_name)
  208 +VALUES ('佣金提现', '', 2, 2, @brokerageMenuId, 'brokerage-withdraw', 'fa:credit-card',
  209 + 'trade/brokerage/withdraw/index', 0, 'TradeBrokerageWithdraw');
  210 +-- 按钮父菜单ID
  211 +-- 暂时只支持 MySQL。如果你是 Oracle、PostgreSQL、SQLServer 的话,需要手动修改 @parentId 的部分的代码
  212 +SELECT @parentId := LAST_INSERT_ID();
  213 +-- 按钮 SQL
  214 +INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status)
  215 +VALUES ('佣金提现查询', 'trade:brokerage-withdraw:query', 3, 1, @parentId, '', '', '', 0);
  216 +INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status)
  217 +VALUES ('佣金提现审核', 'trade:brokerage-withdraw:audit', 3, 2, @parentId, '', '', '', 0);
0 \ No newline at end of file 218 \ No newline at end of file
sql/mysql/pay_wallet.sql
1 -- ---------------------------- 1 -- ----------------------------
2 --- 支付-钱包表 2 +-- 会员钱包表
3 -- ---------------------------- 3 -- ----------------------------
4 DROP TABLE IF EXISTS `pay_wallet`; 4 DROP TABLE IF EXISTS `pay_wallet`;
5 CREATE TABLE `pay_wallet` 5 CREATE TABLE `pay_wallet`
@@ -17,28 +17,27 @@ CREATE TABLE `pay_wallet` @@ -17,28 +17,27 @@ CREATE TABLE `pay_wallet`
17 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', 17 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
18 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', 18 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
19 PRIMARY KEY (`id`) USING BTREE 19 PRIMARY KEY (`id`) USING BTREE
20 -) ENGINE=InnoDB COMMENT='支付钱包表'; 20 +) ENGINE=InnoDB COMMENT='会员钱包表';
21 21
22 -- ---------------------------- 22 -- ----------------------------
23 --- 支付- 钱包余额明细表 23 +-- 会员钱包流水表
24 -- ---------------------------- 24 -- ----------------------------
25 DROP TABLE IF EXISTS `pay_wallet_transaction`; 25 DROP TABLE IF EXISTS `pay_wallet_transaction`;
26 CREATE TABLE `pay_wallet_transaction` 26 CREATE TABLE `pay_wallet_transaction`
27 ( 27 (
28 - `id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',  
29 - `wallet_id` bigint NOT NULL COMMENT '会员钱包 id',  
30 - `biz_type` tinyint NOT NULL COMMENT '关联类型',  
31 - `biz_id` bigint NOT NULL COMMENT '关联业务编号',  
32 - `no` varchar(64) NOT NULL COMMENT '流水号',  
33 - `description` varchar(255) COMMENT '操作说明',  
34 - `amount` int NOT NULL COMMENT '交易金额, 单位分',  
35 - `balance` int NOT NULL COMMENT '余额, 单位分',  
36 - `transaction_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '交易时间',  
37 - `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者',  
38 - `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',  
39 - `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者',  
40 - `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',  
41 - `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',  
42 - `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', 28 + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
  29 + `wallet_id` bigint NOT NULL COMMENT '会员钱包 id',
  30 + `biz_type` tinyint NOT NULL COMMENT '关联类型',
  31 + `biz_id` varchar(64) NOT NULL COMMENT '关联业务编号',
  32 + `no` varchar(64) NOT NULL COMMENT '流水号',
  33 + `title` varchar(128) NOT NULL COMMENT '流水标题',
  34 + `price` int NOT NULL COMMENT '交易金额, 单位分',
  35 + `balance` int NOT NULL COMMENT '余额, 单位分',
  36 + `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者',
  37 + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  38 + `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者',
  39 + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  40 + `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
  41 + `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
43 PRIMARY KEY (`id`) USING BTREE 42 PRIMARY KEY (`id`) USING BTREE
44 -) ENGINE=InnoDB COMMENT='支付钱包余额明细表'; 43 +) ENGINE=InnoDB COMMENT='会员钱包流水表';
sql/mysql/ruoyi-vue-pro.sql
@@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@
11 Target Server Version : 80034 11 Target Server Version : 80034
12 File Encoding : 65001 12 File Encoding : 65001
13 13
14 - Date: 20/08/2023 19:42:16 14 + Date: 03/09/2023 19:13:55
15 */ 15 */
16 16
17 SET NAMES utf8mb4; 17 SET NAMES utf8mb4;
@@ -360,7 +360,7 @@ CREATE TABLE `infra_api_error_log` ( @@ -360,7 +360,7 @@ CREATE TABLE `infra_api_error_log` (
360 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', 360 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
361 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', 361 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
362 PRIMARY KEY (`id`) USING BTREE 362 PRIMARY KEY (`id`) USING BTREE
363 -) ENGINE = InnoDB AUTO_INCREMENT = 1453 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '系统异常日志'; 363 +) ENGINE = InnoDB AUTO_INCREMENT = 1497 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '系统异常日志';
364 364
365 -- ---------------------------- 365 -- ----------------------------
366 -- Records of infra_api_error_log 366 -- Records of infra_api_error_log
@@ -514,7 +514,7 @@ CREATE TABLE `infra_file` ( @@ -514,7 +514,7 @@ CREATE TABLE `infra_file` (
514 `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', 514 `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
515 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', 515 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
516 PRIMARY KEY (`id`) USING BTREE 516 PRIMARY KEY (`id`) USING BTREE
517 -) ENGINE = InnoDB AUTO_INCREMENT = 975 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '文件表'; 517 +) ENGINE = InnoDB AUTO_INCREMENT = 1054 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '文件表';
518 518
519 -- ---------------------------- 519 -- ----------------------------
520 -- Records of infra_file 520 -- Records of infra_file
@@ -568,7 +568,7 @@ CREATE TABLE `infra_file_content` ( @@ -568,7 +568,7 @@ CREATE TABLE `infra_file_content` (
568 `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', 568 `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
569 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', 569 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
570 PRIMARY KEY (`id`) USING BTREE 570 PRIMARY KEY (`id`) USING BTREE
571 -) ENGINE = InnoDB AUTO_INCREMENT = 66 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '文件表'; 571 +) ENGINE = InnoDB AUTO_INCREMENT = 145 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '文件表';
572 572
573 -- ---------------------------- 573 -- ----------------------------
574 -- Records of infra_file_content 574 -- Records of infra_file_content
@@ -694,6 +694,124 @@ INSERT INTO `member_address` (`id`, `user_id`, `name`, `mobile`, `area_id`, `det @@ -694,6 +694,124 @@ INSERT INTO `member_address` (`id`, `user_id`, `name`, `mobile`, `area_id`, `det
694 COMMIT; 694 COMMIT;
695 695
696 -- ---------------------------- 696 -- ----------------------------
  697 +-- Table structure for member_experience_record
  698 +-- ----------------------------
  699 +DROP TABLE IF EXISTS `member_experience_record`;
  700 +CREATE TABLE `member_experience_record` (
  701 + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
  702 + `user_id` bigint NOT NULL DEFAULT 0 COMMENT '用户编号',
  703 + `biz_id` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '业务编号',
  704 + `biz_type` tinyint NOT NULL DEFAULT 0 COMMENT '业务类型',
  705 + `title` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '标题',
  706 + `description` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '描述',
  707 + `experience` int NOT NULL DEFAULT 0 COMMENT '经验',
  708 + `total_experience` int NOT NULL DEFAULT 0 COMMENT '变更后的经验',
  709 + `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者',
  710 + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  711 + `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者',
  712 + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  713 + `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
  714 + `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
  715 + PRIMARY KEY (`id`) USING BTREE,
  716 + INDEX `idx_user_id`(`user_id` ASC) USING BTREE COMMENT '会员经验记录-用户编号',
  717 + INDEX `idx_user_biz_type`(`user_id` ASC, `biz_type` ASC) USING BTREE COMMENT '会员经验记录-用户业务类型'
  718 +) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '会员经验记录';
  719 +
  720 +-- ----------------------------
  721 +-- Records of member_experience_record
  722 +-- ----------------------------
  723 +BEGIN;
  724 +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 (1, 247, '0', 0, '管理员调整', '管理员调整获得100经验', 100, 100, '1', '2023-08-22 21:52:44', '1', '2023-08-22 21:52:44', b'0', 1);
  725 +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 (2, 247, '0', 0, '管理员调整', '管理员调整获得100经验', -50, 100, '1', '2023-08-22 21:52:44', '1', '2023-08-22 21:52:44', b'0', 1);
  726 +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 (3, 247, '78', 2, '下单奖励', '下单获得 27 经验', 27, 127, NULL, '2023-08-30 18:46:52', NULL, '2023-08-30 18:46:52', b'0', 1);
  727 +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 (4, 247, 'null', 3, '退单扣除', '退单获得 -6 经验', -6, 121, NULL, '2023-08-31 19:56:21', NULL, '2023-08-31 19:56:21', b'0', 1);
  728 +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 (5, 247, '80', 2, '下单奖励', '下单获得 699906 经验', 699906, 700027, NULL, '2023-08-31 23:43:29', NULL, '2023-08-31 23:43:29', b'0', 1);
  729 +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 (6, 247, '81', 2, '下单奖励', '下单获得 2799606 经验', 2799606, 3499633, NULL, '2023-08-31 23:46:17', NULL, '2023-08-31 23:46:17', b'0', 1);
  730 +COMMIT;
  731 +
  732 +-- ----------------------------
  733 +-- Table structure for member_group
  734 +-- ----------------------------
  735 +DROP TABLE IF EXISTS `member_group`;
  736 +CREATE TABLE `member_group` (
  737 + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
  738 + `name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '名称',
  739 + `status` tinyint NOT NULL DEFAULT 0 COMMENT '状态',
  740 + `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '备注',
  741 + `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者',
  742 + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  743 + `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者',
  744 + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  745 + `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
  746 + `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
  747 + PRIMARY KEY (`id`) USING BTREE
  748 +) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '用户分组';
  749 +
  750 +-- ----------------------------
  751 +-- Records of member_group
  752 +-- ----------------------------
  753 +BEGIN;
  754 +COMMIT;
  755 +
  756 +-- ----------------------------
  757 +-- Table structure for member_level
  758 +-- ----------------------------
  759 +DROP TABLE IF EXISTS `member_level`;
  760 +CREATE TABLE `member_level` (
  761 + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
  762 + `name` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '等级名称',
  763 + `level` int NOT NULL DEFAULT 0 COMMENT '等级',
  764 + `experience` int NOT NULL DEFAULT 0 COMMENT '升级经验',
  765 + `discount_percent` tinyint NOT NULL DEFAULT 100 COMMENT '享受折扣',
  766 + `icon` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '等级图标',
  767 + `background_url` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '等级背景图',
  768 + `status` tinyint NOT NULL DEFAULT 0 COMMENT '状态',
  769 + `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者',
  770 + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  771 + `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者',
  772 + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  773 + `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
  774 + `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
  775 + PRIMARY KEY (`id`) USING BTREE
  776 +) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '会员等级';
  777 +
  778 +-- ----------------------------
  779 +-- Records of member_level
  780 +-- ----------------------------
  781 +BEGIN;
  782 +COMMIT;
  783 +
  784 +-- ----------------------------
  785 +-- Table structure for member_level_record
  786 +-- ----------------------------
  787 +DROP TABLE IF EXISTS `member_level_record`;
  788 +CREATE TABLE `member_level_record` (
  789 + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
  790 + `user_id` bigint NOT NULL DEFAULT 0 COMMENT '用户编号',
  791 + `level_id` bigint NOT NULL DEFAULT 0 COMMENT '等级编号',
  792 + `level` int NOT NULL DEFAULT 0 COMMENT '会员等级',
  793 + `discount_percent` tinyint NOT NULL DEFAULT 100 COMMENT '享受折扣',
  794 + `experience` int NOT NULL DEFAULT 0 COMMENT '升级经验',
  795 + `user_experience` int NOT NULL DEFAULT 0 COMMENT '会员此时的经验',
  796 + `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '备注',
  797 + `description` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '描述',
  798 + `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者',
  799 + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  800 + `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者',
  801 + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  802 + `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
  803 + `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
  804 + PRIMARY KEY (`id`) USING BTREE,
  805 + INDEX `idx_user_id`(`user_id` ASC) USING BTREE COMMENT '会员等级记录-用户编号'
  806 +) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '会员等级记录';
  807 +
  808 +-- ----------------------------
  809 +-- Records of member_level_record
  810 +-- ----------------------------
  811 +BEGIN;
  812 +COMMIT;
  813 +
  814 +-- ----------------------------
697 -- Table structure for member_point_config 815 -- Table structure for member_point_config
698 -- ---------------------------- 816 -- ----------------------------
699 DROP TABLE IF EXISTS `member_point_config`; 817 DROP TABLE IF EXISTS `member_point_config`;
@@ -741,7 +859,7 @@ CREATE TABLE `member_point_record` ( @@ -741,7 +859,7 @@ CREATE TABLE `member_point_record` (
741 PRIMARY KEY (`id`) USING BTREE, 859 PRIMARY KEY (`id`) USING BTREE,
742 INDEX `index_userId`(`user_id` ASC) USING BTREE, 860 INDEX `index_userId`(`user_id` ASC) USING BTREE,
743 INDEX `index_title`(`title` ASC) USING BTREE 861 INDEX `index_title`(`title` ASC) USING BTREE
744 -) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '用户积分记录'; 862 +) ENGINE = InnoDB AUTO_INCREMENT = 8 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '用户积分记录';
745 863
746 -- ---------------------------- 864 -- ----------------------------
747 -- Records of member_point_record 865 -- Records of member_point_record
@@ -749,7 +867,11 @@ CREATE TABLE `member_point_record` ( @@ -749,7 +867,11 @@ CREATE TABLE `member_point_record` (
749 BEGIN; 867 BEGIN;
750 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 (1, 247, '1', 1, '12', NULL, 33, 12, '', '2023-07-02 14:50:23', '', '2023-08-20 11:03:01', b'0', 1); 868 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 (1, 247, '1', 1, '12', NULL, 33, 12, '', '2023-07-02 14:50:23', '', '2023-08-20 11:03:01', b'0', 1);
751 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 (2, 247, '12', 1, '123', NULL, 22, 130, '', '2023-07-02 14:50:23', '', '2023-08-20 11:03:00', b'0', 1); 869 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 (2, 247, '12', 1, '123', NULL, 22, 130, '', '2023-07-02 14:50:23', '', '2023-08-20 11:03:00', b'0', 1);
752 -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 (3, 247, '12', 1, '12', NULL, -12, 12, '', '2023-07-02 14:50:23', '', '2023-08-20 11:02:50', b'0', 1); 870 +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 (3, 247, '12', 1, '12', NULL, -12, 12, '', '2023-07-02 14:50:55', '', '2023-08-21 14:19:29', b'0', 1);
  871 +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 (4, 247, '78', 10, '订单消费', '下单获得 81 积分', 81, 91, NULL, '2023-08-30 18:46:52', NULL, '2023-08-30 18:46:52', b'0', 1);
  872 +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 (5, 247, 'null', 11, '订单取消', '退单获得 -18 积分', -18, 73, NULL, '2023-08-31 19:56:21', NULL, '2023-08-31 19:56:21', b'0', 1);
  873 +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 (6, 247, '80', 10, '订单消费', '下单获得 2099718 积分', 2099718, 2099791, NULL, '2023-08-31 23:43:29', NULL, '2023-08-31 23:43:29', b'0', 1);
  874 +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 (7, 247, '81', 10, '订单消费', '下单获得 8398818 积分', 8398818, 10498609, NULL, '2023-08-31 23:46:17', NULL, '2023-08-31 23:46:17', b'0', 1);
753 COMMIT; 875 COMMIT;
754 876
755 -- ---------------------------- 877 -- ----------------------------
@@ -768,7 +890,7 @@ CREATE TABLE `member_sign_in_config` ( @@ -768,7 +890,7 @@ CREATE TABLE `member_sign_in_config` (
768 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', 890 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
769 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', 891 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
770 PRIMARY KEY (`id`) USING BTREE 892 PRIMARY KEY (`id`) USING BTREE
771 -) ENGINE = InnoDB AUTO_INCREMENT = 8 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '签到规则'; 893 +) ENGINE = InnoDB AUTO_INCREMENT = 13 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = '签到规则';
772 894
773 -- ---------------------------- 895 -- ----------------------------
774 -- Records of member_sign_in_config 896 -- Records of member_sign_in_config
@@ -781,6 +903,11 @@ INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `status`, `creator`, @@ -781,6 +903,11 @@ INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `status`, `creator`,
781 INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (5, 2, 12, 0, '', '2023-08-20 01:38:56', '', '2023-08-20 01:38:56', b'0', 0); 903 INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (5, 2, 12, 0, '', '2023-08-20 01:38:56', '', '2023-08-20 01:38:56', b'0', 0);
782 INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6, 1, 10, 0, '1', '2023-08-20 19:20:42', '1', '2023-08-20 19:20:56', b'0', 1); 904 INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (6, 1, 10, 0, '1', '2023-08-20 19:20:42', '1', '2023-08-20 19:20:56', b'0', 1);
783 INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (7, 7, 22, 0, '1', '2023-08-20 19:20:48', '1', '2023-08-20 19:20:48', b'0', 1); 905 INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (7, 7, 22, 0, '1', '2023-08-20 19:20:48', '1', '2023-08-20 19:20:48', b'0', 1);
  906 +INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (8, 2, 3, 0, '1', '2023-08-21 20:22:44', '1', '2023-08-21 20:22:44', b'0', 1);
  907 +INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (9, 3, 4, 0, '1', '2023-08-21 20:22:48', '1', '2023-08-21 20:22:48', b'0', 1);
  908 +INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (10, 4, 5, 0, '1', '2023-08-21 20:22:51', '1', '2023-08-21 20:22:51', b'0', 1);
  909 +INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (11, 5, 6, 0, '1', '2023-08-21 20:22:56', '1', '2023-08-21 20:22:56', b'0', 1);
  910 +INSERT INTO `member_sign_in_config` (`id`, `day`, `point`, `status`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (12, 6, 7, 0, '1', '2023-08-21 20:22:59', '1', '2023-08-21 20:22:59', b'0', 1);
784 COMMIT; 911 COMMIT;
785 912
786 -- ---------------------------- 913 -- ----------------------------
@@ -822,7 +949,7 @@ CREATE TABLE `member_tag` ( @@ -822,7 +949,7 @@ CREATE TABLE `member_tag` (
822 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', 949 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
823 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', 950 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
824 PRIMARY KEY (`id`) USING BTREE 951 PRIMARY KEY (`id`) USING BTREE
825 -) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '会员标签'; 952 +) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '会员标签';
826 953
827 -- ---------------------------- 954 -- ----------------------------
828 -- Records of member_tag 955 -- Records of member_tag
@@ -853,6 +980,9 @@ CREATE TABLE `member_user` ( @@ -853,6 +980,9 @@ CREATE TABLE `member_user` (
853 `mark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '会员备注', 980 `mark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '会员备注',
854 `point` int NOT NULL DEFAULT 0 COMMENT '积分', 981 `point` int NOT NULL DEFAULT 0 COMMENT '积分',
855 `tag_ids` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用户标签编号列表,以逗号分隔', 982 `tag_ids` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用户标签编号列表,以逗号分隔',
  983 + `level_id` bigint NULL DEFAULT NULL COMMENT '等级编号',
  984 + `experience` int NOT NULL DEFAULT 0 COMMENT '经验',
  985 + `group_id` bigint NULL DEFAULT NULL COMMENT '用户分组编号',
856 `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '创建者', 986 `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '创建者',
857 `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', 987 `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
858 `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '更新者', 988 `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT '' COMMENT '更新者',
@@ -929,7 +1059,7 @@ CREATE TABLE `system_dict_data` ( @@ -929,7 +1059,7 @@ CREATE TABLE `system_dict_data` (
929 `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', 1059 `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
930 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', 1060 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
931 PRIMARY KEY (`id`) USING BTREE 1061 PRIMARY KEY (`id`) USING BTREE
932 -) ENGINE = InnoDB AUTO_INCREMENT = 1350 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '字典数据表'; 1062 +) ENGINE = InnoDB AUTO_INCREMENT = 1359 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '字典数据表';
933 1063
934 -- ---------------------------- 1064 -- ----------------------------
935 -- Records of system_dict_data 1065 -- Records of system_dict_data
@@ -1058,8 +1188,8 @@ INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `st @@ -1058,8 +1188,8 @@ INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `st
1058 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 (1166, 2, '折扣', '2', 'promotion_discount_type', 0, 'primary', '', '优惠类型 - 折扣', '1', '2022-11-01 12:46:51', '1', '2022-11-01 12:50:08', b'0'); 1188 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 (1166, 2, '折扣', '2', 'promotion_discount_type', 0, 'primary', '', '优惠类型 - 折扣', '1', '2022-11-01 12:46:51', '1', '2022-11-01 12:50:08', b'0');
1059 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 (1167, 1, '固定日期', '1', 'promotion_coupon_template_validity_type', 0, 'default', '', '优惠劵模板的有限期类型 - 固定日期', '1', '2022-11-02 00:07:34', '1', '2022-11-04 00:07:49', b'0'); 1189 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 (1167, 1, '固定日期', '1', 'promotion_coupon_template_validity_type', 0, 'default', '', '优惠劵模板的有限期类型 - 固定日期', '1', '2022-11-02 00:07:34', '1', '2022-11-04 00:07:49', b'0');
1060 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 (1168, 2, '领取之后', '2', 'promotion_coupon_template_validity_type', 0, 'default', '', '优惠劵模板的有限期类型 - 领取之后', '1', '2022-11-02 00:07:54', '1', '2022-11-04 00:07:52', b'0'); 1190 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 (1168, 2, '领取之后', '2', 'promotion_coupon_template_validity_type', 0, 'default', '', '优惠劵模板的有限期类型 - 领取之后', '1', '2022-11-02 00:07:54', '1', '2022-11-04 00:07:52', b'0');
1061 -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 (1169, 1, '全部商品参与', '1', 'promotion_product_scope', 0, 'default', '', '营销的商品范围 - 全部商品参与', '1', '2022-11-02 00:28:22', '1', '2022-11-02 00:28:22', b'0');  
1062 -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 (1170, 2, '指定商品参与', '2', 'promotion_product_scope', 0, 'default', '', '营销的商品范围 - 指定商品参与', '1', '2022-11-02 00:28:34', '1', '2022-11-02 00:28:40', b'0'); 1191 +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 (1169, 1, '通用卷', '1', 'promotion_product_scope', 0, 'default', '', '营销的商品范围 - 全部商品参与', '1', '2022-11-02 00:28:22', '1', '2023-09-01 23:42:49', b'0');
  1192 +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 (1170, 2, '商品卷', '2', 'promotion_product_scope', 0, 'default', '', '营销的商品范围 - 指定商品参与', '1', '2022-11-02 00:28:34', '1', '2023-09-01 23:42:54', b'0');
1063 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 (1171, 1, '已领取', '1', 'promotion_coupon_status', 0, 'primary', '', '优惠劵的状态 - 已领取', '1', '2022-11-04 00:15:08', '1', '2022-11-04 19:16:04', b'0'); 1193 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 (1171, 1, '已领取', '1', 'promotion_coupon_status', 0, 'primary', '', '优惠劵的状态 - 已领取', '1', '2022-11-04 00:15:08', '1', '2022-11-04 19:16:04', b'0');
1064 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 (1172, 2, '已使用', '2', 'promotion_coupon_status', 0, 'success', '', '优惠劵的状态 - 已使用', '1', '2022-11-04 00:15:21', '1', '2022-11-04 19:16:08', b'0'); 1194 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 (1172, 2, '已使用', '2', 'promotion_coupon_status', 0, 'success', '', '优惠劵的状态 - 已使用', '1', '2022-11-04 00:15:21', '1', '2022-11-04 19:16:08', b'0');
1065 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 (1173, 3, '已过期', '3', 'promotion_coupon_status', 0, 'info', '', '优惠劵的状态 - 已过期', '1', '2022-11-04 00:15:43', '1', '2022-11-04 19:16:12', b'0'); 1195 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 (1173, 3, '已过期', '3', 'promotion_coupon_status', 0, 'info', '', '优惠劵的状态 - 已过期', '1', '2022-11-04 00:15:43', '1', '2022-11-04 19:16:12', b'0');
@@ -1146,6 +1276,15 @@ INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `st @@ -1146,6 +1276,15 @@ INSERT INTO `system_dict_data` (`id`, `sort`, `label`, `value`, `dict_type`, `st
1146 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'); 1276 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');
1147 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'); 1277 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');
1148 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'); 1278 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');
  1279 +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');
  1280 +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');
  1281 +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');
  1282 +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');
  1283 +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');
  1284 +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');
  1285 +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');
  1286 +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 (1357, 2, '用户自提', '2', 'trade_delivery_type', 0, '', '', '', '1', '2023-08-23 00:05:05', '1', '2023-08-23 00:05:05', b'0');
  1287 +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 (1358, 3, '品类卷', '3', 'promotion_product_scope', 0, 'default', '', '', '1', '2023-09-01 23:43:07', '1', '2023-09-01 23:43:07', b'0');
1149 COMMIT; 1288 COMMIT;
1150 1289
1151 -- ---------------------------- 1290 -- ----------------------------
@@ -1166,7 +1305,7 @@ CREATE TABLE `system_dict_type` ( @@ -1166,7 +1305,7 @@ CREATE TABLE `system_dict_type` (
1166 `deleted_time` datetime NULL DEFAULT NULL COMMENT '删除时间', 1305 `deleted_time` datetime NULL DEFAULT NULL COMMENT '删除时间',
1167 PRIMARY KEY (`id`) USING BTREE, 1306 PRIMARY KEY (`id`) USING BTREE,
1168 UNIQUE INDEX `dict_type`(`type` ASC) USING BTREE 1307 UNIQUE INDEX `dict_type`(`type` ASC) USING BTREE
1169 -) ENGINE = InnoDB AUTO_INCREMENT = 174 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '字典类型表'; 1308 +) ENGINE = InnoDB AUTO_INCREMENT = 176 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '字典类型表';
1170 1309
1171 -- ---------------------------- 1310 -- ----------------------------
1172 -- Records of system_dict_type 1311 -- Records of system_dict_type
@@ -1229,6 +1368,8 @@ INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creat @@ -1229,6 +1368,8 @@ INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creat
1229 INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (170, '快递计费方式', 'trade_delivery_express_charge_mode', 0, '用于商城交易模块配送管理', '1', '2023-05-21 22:45:03', '1', '2023-05-21 22:45:03', b'0', '1970-01-01 00:00:00'); 1368 INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (170, '快递计费方式', 'trade_delivery_express_charge_mode', 0, '用于商城交易模块配送管理', '1', '2023-05-21 22:45:03', '1', '2023-05-21 22:45:03', b'0', '1970-01-01 00:00:00');
1230 INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (171, '积分业务类型', 'member_point_biz_type', 0, '', '1', '2023-06-10 12:15:00', '1', '2023-06-28 13:48:20', b'0', '1970-01-01 00:00:00'); 1369 INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (171, '积分业务类型', 'member_point_biz_type', 0, '', '1', '2023-06-10 12:15:00', '1', '2023-06-28 13:48:20', b'0', '1970-01-01 00:00:00');
1231 INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (173, '支付通知类型', 'pay_notify_type', 0, NULL, '1', '2023-07-20 12:23:03', '1', '2023-07-20 12:23:03', b'0', '1970-01-01 00:00:00'); 1370 INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (173, '支付通知类型', 'pay_notify_type', 0, NULL, '1', '2023-07-20 12:23:03', '1', '2023-07-20 12:23:03', b'0', '1970-01-01 00:00:00');
  1371 +INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (174, '会员经验业务类型', 'member_experience_biz_type', 0, NULL, '', '2023-08-22 12:41:01', '', '2023-08-22 12:41:01', b'0', NULL);
  1372 +INSERT INTO `system_dict_type` (`id`, `name`, `type`, `status`, `remark`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `deleted_time`) VALUES (175, '交易配送类型', 'trade_delivery_type', 0, '', '1', '2023-08-23 00:03:14', '1', '2023-08-23 00:03:14', b'0', '1970-01-01 00:00:00');
1232 COMMIT; 1373 COMMIT;
1233 1374
1234 -- ---------------------------- 1375 -- ----------------------------
@@ -1277,7 +1418,7 @@ CREATE TABLE `system_login_log` ( @@ -1277,7 +1418,7 @@ CREATE TABLE `system_login_log` (
1277 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', 1418 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
1278 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', 1419 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
1279 PRIMARY KEY (`id`) USING BTREE 1420 PRIMARY KEY (`id`) USING BTREE
1280 -) ENGINE = InnoDB AUTO_INCREMENT = 2303 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '系统访问记录'; 1421 +) ENGINE = InnoDB AUTO_INCREMENT = 2375 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '系统访问记录';
1281 1422
1282 -- ---------------------------- 1423 -- ----------------------------
1283 -- Records of system_login_log 1424 -- Records of system_login_log
@@ -1407,7 +1548,7 @@ CREATE TABLE `system_menu` ( @@ -1407,7 +1548,7 @@ CREATE TABLE `system_menu` (
1407 `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', 1548 `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
1408 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', 1549 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
1409 PRIMARY KEY (`id`) USING BTREE 1550 PRIMARY KEY (`id`) USING BTREE
1410 -) ENGINE = InnoDB AUTO_INCREMENT = 2325 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '菜单权限表'; 1551 +) ENGINE = InnoDB AUTO_INCREMENT = 2342 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '菜单权限表';
1411 1552
1412 -- ---------------------------- 1553 -- ----------------------------
1413 -- Records of system_menu 1554 -- Records of system_menu
@@ -1638,33 +1779,33 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i @@ -1638,33 +1779,33 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i
1638 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 (1267, '客户端删除', 'system:oauth2-client:delete', 3, 4, 1263, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-05-10 16:26:33', '1', '2022-05-11 00:31:33', b'0'); 1779 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 (1267, '客户端删除', 'system:oauth2-client:delete', 3, 4, 1263, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-05-10 16:26:33', '1', '2022-05-11 00:31:33', b'0');
1639 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 (1281, '报表管理', '', 1, 40, 0, '/report', 'chart', NULL, NULL, 0, b'1', b'1', b'1', '1', '2022-07-10 20:22:15', '1', '2023-02-07 17:16:40', b'0'); 1780 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 (1281, '报表管理', '', 1, 40, 0, '/report', 'chart', NULL, NULL, 0, b'1', b'1', b'1', '1', '2022-07-10 20:22:15', '1', '2023-02-07 17:16:40', b'0');
1640 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 (1282, '报表设计器', '', 2, 1, 1281, 'jimu-report', 'example', 'report/jmreport/index', 'GoView', 0, b'1', b'1', b'1', '1', '2022-07-10 20:26:36', '1', '2023-04-08 10:47:59', b'0'); 1781 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 (1282, '报表设计器', '', 2, 1, 1281, 'jimu-report', 'example', 'report/jmreport/index', 'GoView', 0, b'1', b'1', b'1', '1', '2022-07-10 20:26:36', '1', '2023-04-08 10:47:59', b'0');
1641 -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 (2000, '商品中心', '', 1, 60, 0, '/product', 'merchant', NULL, NULL, 0, b'1', b'1', b'1', '', '2022-07-29 15:53:53', '1', '2022-07-30 22:26:19', b'0');  
1642 -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 (2002, '商品分类', '', 2, 2, 2000, 'category', 'dict', 'mall/product/category/index', 'ProductCategory', 0, b'1', b'1', b'1', '', '2022-07-29 15:53:53', '1', '2023-04-08 11:34:59', b'0'); 1782 +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 (2000, '商品中心', '', 1, 60, 0, '/product', 'fa:product-hunt', NULL, NULL, 0, b'1', b'1', b'1', '', '2022-07-29 15:53:53', '1', '2023-08-21 10:26:51', b'0');
  1783 +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 (2002, '商品分类', '', 2, 2, 2000, 'category', 'ep:cellphone', 'mall/product/category/index', 'ProductCategory', 0, b'1', b'1', b'1', '', '2022-07-29 15:53:53', '1', '2023-08-21 10:27:15', b'0');
1643 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 (2003, '分类查询', 'product:category:query', 3, 1, 2002, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-07-29 15:53:53', '', '2022-07-29 15:53:53', b'0'); 1784 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 (2003, '分类查询', 'product:category:query', 3, 1, 2002, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-07-29 15:53:53', '', '2022-07-29 15:53:53', b'0');
1644 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 (2004, '分类创建', 'product:category:create', 3, 2, 2002, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-07-29 15:53:53', '', '2022-07-29 15:53:53', b'0'); 1785 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 (2004, '分类创建', 'product:category:create', 3, 2, 2002, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-07-29 15:53:53', '', '2022-07-29 15:53:53', b'0');
1645 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 (2005, '分类更新', 'product:category:update', 3, 3, 2002, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-07-29 15:53:53', '', '2022-07-29 15:53:53', b'0'); 1786 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 (2005, '分类更新', 'product:category:update', 3, 3, 2002, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-07-29 15:53:53', '', '2022-07-29 15:53:53', b'0');
1646 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 (2006, '分类删除', 'product:category:delete', 3, 4, 2002, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-07-29 15:53:53', '', '2022-07-29 15:53:53', b'0'); 1787 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 (2006, '分类删除', 'product:category:delete', 3, 4, 2002, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-07-29 15:53:53', '', '2022-07-29 15:53:53', b'0');
1647 -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 (2008, '商品品牌', '', 2, 3, 2000, 'brand', 'dashboard', 'mall/product/brand/index', 'ProductBrand', 0, b'1', b'1', b'1', '', '2022-07-30 13:52:44', '1', '2023-04-08 11:35:29', b'0'); 1788 +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 (2008, '商品品牌', '', 2, 3, 2000, 'brand', 'ep:chicken', 'mall/product/brand/index', 'ProductBrand', 0, b'1', b'1', b'1', '', '2022-07-30 13:52:44', '1', '2023-08-21 10:27:28', b'0');
1648 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 (2009, '品牌查询', 'product:brand:query', 3, 1, 2008, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-07-30 13:52:44', '', '2022-07-30 13:52:44', b'0'); 1789 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 (2009, '品牌查询', 'product:brand:query', 3, 1, 2008, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-07-30 13:52:44', '', '2022-07-30 13:52:44', b'0');
1649 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 (2010, '品牌创建', 'product:brand:create', 3, 2, 2008, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-07-30 13:52:44', '', '2022-07-30 13:52:44', b'0'); 1790 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 (2010, '品牌创建', 'product:brand:create', 3, 2, 2008, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-07-30 13:52:44', '', '2022-07-30 13:52:44', b'0');
1650 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 (2011, '品牌更新', 'product:brand:update', 3, 3, 2008, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-07-30 13:52:44', '', '2022-07-30 13:52:44', b'0'); 1791 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 (2011, '品牌更新', 'product:brand:update', 3, 3, 2008, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-07-30 13:52:44', '', '2022-07-30 13:52:44', b'0');
1651 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 (2012, '品牌删除', 'product:brand:delete', 3, 4, 2008, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-07-30 13:52:44', '', '2022-07-30 13:52:44', b'0'); 1792 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 (2012, '品牌删除', 'product:brand:delete', 3, 4, 2008, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-07-30 13:52:44', '', '2022-07-30 13:52:44', b'0');
1652 -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 (2014, '商品列表', '', 2, 1, 2000, 'spu', 'list', 'mall/product/spu/index', 'ProductSpu', 0, b'1', b'1', b'1', '', '2022-07-30 14:22:58', '1', '2023-04-08 11:34:47', b'0'); 1793 +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 (2014, '商品列表', '', 2, 1, 2000, 'spu', 'ep:apple', 'mall/product/spu/index', 'ProductSpu', 0, b'1', b'1', b'1', '', '2022-07-30 14:22:58', '1', '2023-08-21 10:27:01', b'0');
1653 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 (2015, '商品查询', 'product:spu:query', 3, 1, 2014, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-07-30 14:22:58', '', '2022-07-30 14:22:58', b'0'); 1794 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 (2015, '商品查询', 'product:spu:query', 3, 1, 2014, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-07-30 14:22:58', '', '2022-07-30 14:22:58', b'0');
1654 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 (2016, '商品创建', 'product:spu:create', 3, 2, 2014, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-07-30 14:22:58', '', '2022-07-30 14:22:58', b'0'); 1795 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 (2016, '商品创建', 'product:spu:create', 3, 2, 2014, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-07-30 14:22:58', '', '2022-07-30 14:22:58', b'0');
1655 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 (2017, '商品更新', 'product:spu:update', 3, 3, 2014, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-07-30 14:22:58', '', '2022-07-30 14:22:58', b'0'); 1796 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 (2017, '商品更新', 'product:spu:update', 3, 3, 2014, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-07-30 14:22:58', '', '2022-07-30 14:22:58', b'0');
1656 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 (2018, '商品删除', 'product:spu:delete', 3, 4, 2014, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-07-30 14:22:58', '', '2022-07-30 14:22:58', b'0'); 1797 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 (2018, '商品删除', 'product:spu:delete', 3, 4, 2014, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-07-30 14:22:58', '', '2022-07-30 14:22:58', b'0');
1657 -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 (2019, '商品属性', '', 2, 3, 2000, 'property', 'eye', 'mall/product/property/index', 'ProductProperty', 0, b'1', b'1', b'1', '', '2022-08-01 14:55:35', '1', '2023-04-08 11:35:15', b'0'); 1798 +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 (2019, '商品属性', '', 2, 4, 2000, 'property', 'ep:cold-drink', 'mall/product/property/index', 'ProductProperty', 0, b'1', b'1', b'1', '', '2022-08-01 14:55:35', '1', '2023-08-26 11:01:05', b'0');
1658 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 (2020, '规格查询', 'product:property:query', 3, 1, 2019, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-08-01 14:55:35', '', '2022-12-12 20:26:24', b'0'); 1799 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 (2020, '规格查询', 'product:property:query', 3, 1, 2019, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-08-01 14:55:35', '', '2022-12-12 20:26:24', b'0');
1659 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'); 1800 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');
1660 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'); 1801 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');
1661 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'); 1802 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');
1662 -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, 2000, 'banner', '', 'mall/market/banner/index', NULL, 0, b'1', b'1', b'1', '', '2022-08-01 14:56:14', '1', '2022-10-24 22:29:39', b'0'); 1803 +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');
1663 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'); 1804 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');
1664 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'); 1805 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');
1665 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'); 1806 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');
1666 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'); 1807 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');
1667 -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, 0, '/promotion', 'rate', NULL, NULL, 0, b'1', b'1', b'1', '1', '2022-10-31 21:25:09', '1', '2022-10-31 21:25:09', b'0'); 1808 +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, 0, '/promotion', 'ep:present', NULL, NULL, 0, b'1', b'1', b'1', '1', '2022-10-31 21:25:09', '1', '2023-08-31 15:49:31', b'0');
1668 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, 2030, 'coupon-template', 'ep:discount', 'mall/promotion/coupon/template/index', 'PromotionCouponTemplate', 0, b'1', b'1', b'1', '', '2022-10-31 22:27:14', '1', '2023-08-12 11:35:35', b'0'); 1809 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, 2030, 'coupon-template', 'ep:discount', 'mall/promotion/coupon/template/index', 'PromotionCouponTemplate', 0, b'1', b'1', b'1', '', '2022-10-31 22:27:14', '1', '2023-08-12 11:35:35', b'0');
1669 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'); 1810 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');
1670 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 (2034, '优惠劵模板创建', 'promotion:coupon-template:create', 3, 2, 2032, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-10-31 22:27:14', '', '2022-10-31 22:27:14', b'0'); 1811 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 (2034, '优惠劵模板创建', 'promotion:coupon-template:create', 3, 2, 2032, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-10-31 22:27:14', '', '2022-10-31 22:27:14', b'0');
@@ -1695,11 +1836,11 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i @@ -1695,11 +1836,11 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i
1695 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 (2068, '秒杀时段创建', 'promotion:seckill-config:create', 3, 2, 2066, '', '', '', '', 0, b'1', b'1', b'1', '', '2022-11-15 19:46:51', '1', '2023-06-24 17:48:39', b'0'); 1836 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 (2068, '秒杀时段创建', 'promotion:seckill-config:create', 3, 2, 2066, '', '', '', '', 0, b'1', b'1', b'1', '', '2022-11-15 19:46:51', '1', '2023-06-24 17:48:39', b'0');
1696 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 (2069, '秒杀时段更新', 'promotion:seckill-config:update', 3, 3, 2066, '', '', '', '', 0, b'1', b'1', b'1', '', '2022-11-15 19:46:51', '1', '2023-06-24 17:50:29', b'0'); 1837 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 (2069, '秒杀时段更新', 'promotion:seckill-config:update', 3, 3, 2066, '', '', '', '', 0, b'1', b'1', b'1', '', '2022-11-15 19:46:51', '1', '2023-06-24 17:50:29', b'0');
1697 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 (2070, '秒杀时段删除', 'promotion:seckill-config:delete', 3, 4, 2066, '', '', '', '', 0, b'1', b'1', b'1', '', '2022-11-15 19:46:51', '1', '2023-06-24 17:50:32', b'0'); 1838 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 (2070, '秒杀时段删除', 'promotion:seckill-config:delete', 3, 4, 2066, '', '', '', '', 0, b'1', b'1', b'1', '', '2022-11-15 19:46:51', '1', '2023-06-24 17:50:32', b'0');
1698 -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 (2072, '订单中心', '', 1, 65, 0, '/trade', 'order', NULL, NULL, 0, b'1', b'1', b'1', '1', '2022-11-19 18:57:19', '1', '2022-12-10 16:32:57', b'0');  
1699 -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 (2073, '售后退款', '', 2, 1, 2072, 'trade/after-sale', 'education', 'mall/trade/afterSale/index', 'TradeAfterSale', 0, b'1', b'1', b'1', '', '2022-11-19 20:15:32', '1', '2023-04-08 11:43:19', b'0'); 1839 +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 (2072, '订单中心', '', 1, 65, 0, '/trade', 'ep:eleme', NULL, NULL, 0, b'1', b'1', b'1', '1', '2022-11-19 18:57:19', '1', '2023-08-30 21:01:48', b'0');
  1840 +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 (2073, '售后退款', '', 2, 1, 2072, 'trade/after-sale', 'ep:refrigerator', 'mall/trade/afterSale/index', 'TradeAfterSale', 0, b'1', b'1', b'1', '', '2022-11-19 20:15:32', '1', '2023-08-30 21:02:16', b'0');
1700 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 (2074, '售后查询', 'trade:after-sale:query', 3, 1, 2073, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-11-19 20:15:33', '1', '2022-12-10 21:04:29', b'0'); 1841 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 (2074, '售后查询', 'trade:after-sale:query', 3, 1, 2073, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-11-19 20:15:33', '1', '2022-12-10 21:04:29', b'0');
1701 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 (2075, '秒杀活动关闭', 'promotion:sekill-activity:close', 3, 5, 2059, '', '', '', '', 0, b'1', b'1', b'1', '1', '2022-11-28 20:20:15', '1', '2023-08-12 17:53:02', b'0'); 1842 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 (2075, '秒杀活动关闭', 'promotion:sekill-activity:close', 3, 5, 2059, '', '', '', '', 0, b'1', b'1', b'1', '1', '2022-11-28 20:20:15', '1', '2023-08-12 17:53:02', b'0');
1702 -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 (2076, '订单列表', '', 2, 0, 2072, 'trade/order', 'list', 'mall/trade/order/index', 'TradeOrder', 0, b'1', b'1', b'1', '1', '2022-12-10 21:05:44', '1', '2023-04-08 11:42:23', b'0'); 1843 +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 (2076, '订单列表', '', 2, 0, 2072, 'trade/order', 'ep:list', 'mall/trade/order/index', 'TradeOrder', 0, b'1', b'1', b'1', '1', '2022-12-10 21:05:44', '1', '2023-08-30 21:02:00', b'0');
1703 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 (2083, '地区管理', '', 2, 14, 1, 'area', 'row', 'system/area/index', 'SystemArea', 0, b'1', b'1', b'1', '1', '2022-12-23 17:35:05', '1', '2023-04-08 09:01:37', b'0'); 1844 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 (2083, '地区管理', '', 2, 14, 1, 'area', 'row', 'system/area/index', 'SystemArea', 0, b'1', b'1', b'1', '1', '2022-12-23 17:35:05', '1', '2023-04-08 09:01:37', b'0');
1704 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 (2084, '公众号管理', '', 1, 100, 0, '/mp', 'wechat', NULL, NULL, 0, b'1', b'1', b'1', '1', '2023-01-01 20:11:04', '1', '2023-01-15 11:28:57', b'0'); 1845 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 (2084, '公众号管理', '', 1, 100, 0, '/mp', 'wechat', NULL, NULL, 0, b'1', b'1', b'1', '1', '2023-01-01 20:11:04', '1', '2023-01-15 11:28:57', b'0');
1705 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 (2085, '账号管理', '', 2, 1, 2084, 'account', 'phone', 'mp/account/index', 'MpAccount', 0, b'1', b'1', b'1', '1', '2023-01-01 20:13:31', '1', '2023-02-09 23:56:39', b'0'); 1846 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 (2085, '账号管理', '', 2, 1, 2084, 'account', 'phone', 'mp/account/index', 'MpAccount', 0, b'1', b'1', b'1', '1', '2023-01-01 20:13:31', '1', '2023-02-09 23:56:39', b'0');
@@ -1780,22 +1921,22 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i @@ -1780,22 +1921,22 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i
1780 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 (2160, 'Cloud 开发文档', '', 1, 2, 0, 'https://cloud.iocoder.cn', 'documentation', NULL, NULL, 0, b'1', b'1', b'1', '1', '2023-02-10 22:47:07', '1', '2023-02-10 22:47:07', b'0'); 1921 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 (2160, 'Cloud 开发文档', '', 1, 2, 0, 'https://cloud.iocoder.cn', 'documentation', NULL, NULL, 0, b'1', b'1', b'1', '1', '2023-02-10 22:47:07', '1', '2023-02-10 22:47:07', b'0');
1781 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 (2161, '接入示例', '', 2, 99, 1117, 'demo-order', 'drag', 'pay/demo/index', NULL, 0, b'1', b'1', b'1', '', '2023-02-11 14:21:42', '1', '2023-02-11 22:26:35', b'0'); 1922 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 (2161, '接入示例', '', 2, 99, 1117, 'demo-order', 'drag', 'pay/demo/index', NULL, 0, b'1', b'1', b'1', '', '2023-02-11 14:21:42', '1', '2023-02-11 22:26:35', b'0');
1782 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 (2162, '商品导出', 'product:spu:export', 3, 5, 2014, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-07-30 14:22:58', '', '2022-07-30 14:22:58', b'0'); 1923 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 (2162, '商品导出', 'product:spu:export', 3, 5, 2014, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2022-07-30 14:22:58', '', '2022-07-30 14:22:58', b'0');
1783 -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 (2164, '配送管理', '', 1, 2, 2072, 'delivery', '', '', '', 0, b'1', b'1', b'1', '1', '2023-05-18 09:18:02', '1', '2023-05-24 23:24:13', b'0');  
1784 -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 (2165, '快递发货', '', 1, 0, 2164, 'express', '', '', '', 0, b'1', b'1', b'1', '1', '2023-05-18 09:22:06', '1', '2023-05-18 09:22:06', b'0');  
1785 -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 (2166, '门店自提', '', 1, 1, 2164, 'pick-up-store', '', '', '', 0, b'1', b'1', b'1', '1', '2023-05-18 09:23:14', '1', '2023-05-18 09:23:14', b'0');  
1786 -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 (2167, '快递公司', '', 2, 0, 2165, 'express', '', 'mall/trade/delivery/express/index', 'Express', 0, b'1', b'1', b'1', '1', '2023-05-18 09:27:21', '1', '2023-05-18 22:11:14', b'0'); 1924 +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 (2164, '配送管理', '', 1, 2, 2072, 'delivery', 'ep:shopping-cart', '', '', 0, b'1', b'1', b'1', '1', '2023-05-18 09:18:02', '1', '2023-08-30 21:02:27', b'0');
  1925 +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 (2165, '快递发货', '', 1, 0, 2164, 'express', 'ep:bicycle', '', '', 0, b'1', b'1', b'1', '1', '2023-05-18 09:22:06', '1', '2023-08-30 21:02:49', b'0');
  1926 +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 (2166, '门店自提', '', 1, 1, 2164, 'pick-up-store', 'ep:add-location', '', '', 0, b'1', b'1', b'1', '1', '2023-05-18 09:23:14', '1', '2023-08-30 21:03:21', b'0');
  1927 +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 (2167, '快递公司', '', 2, 0, 2165, 'express', 'ep:compass', 'mall/trade/delivery/express/index', 'Express', 0, b'1', b'1', b'1', '1', '2023-05-18 09:27:21', '1', '2023-08-30 21:02:59', b'0');
1787 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 (2168, '快递公司查询', 'trade:delivery:express:query', 3, 1, 2167, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-18 09:37:53', '', '2023-05-18 09:37:53', b'0'); 1928 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 (2168, '快递公司查询', 'trade:delivery:express:query', 3, 1, 2167, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-18 09:37:53', '', '2023-05-18 09:37:53', b'0');
1788 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 (2169, '快递公司创建', 'trade:delivery:express:create', 3, 2, 2167, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-18 09:37:53', '', '2023-05-18 09:37:53', b'0'); 1929 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 (2169, '快递公司创建', 'trade:delivery:express:create', 3, 2, 2167, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-18 09:37:53', '', '2023-05-18 09:37:53', b'0');
1789 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 (2170, '快递公司更新', 'trade:delivery:express:update', 3, 3, 2167, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-18 09:37:53', '', '2023-05-18 09:37:53', b'0'); 1930 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 (2170, '快递公司更新', 'trade:delivery:express:update', 3, 3, 2167, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-18 09:37:53', '', '2023-05-18 09:37:53', b'0');
1790 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 (2171, '快递公司删除', 'trade:delivery:express:delete', 3, 4, 2167, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-18 09:37:53', '', '2023-05-18 09:37:53', b'0'); 1931 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 (2171, '快递公司删除', 'trade:delivery:express:delete', 3, 4, 2167, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-18 09:37:53', '', '2023-05-18 09:37:53', b'0');
1791 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 (2172, '快递公司导出', 'trade:delivery:express:export', 3, 5, 2167, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-18 09:37:53', '', '2023-05-18 09:37:53', b'0'); 1932 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 (2172, '快递公司导出', 'trade:delivery:express:export', 3, 5, 2167, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-18 09:37:53', '', '2023-05-18 09:37:53', b'0');
1792 -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 (2173, '运费模版', 'trade:delivery:express-template:query', 2, 1, 2165, 'express-template', '', 'mall/trade/delivery/expressTemplate/index', 'ExpressTemplate', 0, b'1', b'1', b'1', '1', '2023-05-20 06:48:10', '1', '2023-05-20 06:48:29', b'0'); 1933 +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 (2173, '运费模版', 'trade:delivery:express-template:query', 2, 1, 2165, 'express-template', 'ep:coordinate', 'mall/trade/delivery/expressTemplate/index', 'ExpressTemplate', 0, b'1', b'1', b'1', '1', '2023-05-20 06:48:10', '1', '2023-08-30 21:03:13', b'0');
1793 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 (2174, '快递运费模板查询', 'trade:delivery:express-template:query', 3, 1, 2173, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-20 06:49:53', '', '2023-05-20 06:49:53', b'0'); 1934 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 (2174, '快递运费模板查询', 'trade:delivery:express-template:query', 3, 1, 2173, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-20 06:49:53', '', '2023-05-20 06:49:53', b'0');
1794 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 (2175, '快递运费模板创建', 'trade:delivery:express-template:create', 3, 2, 2173, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-20 06:49:53', '', '2023-05-20 06:49:53', b'0'); 1935 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 (2175, '快递运费模板创建', 'trade:delivery:express-template:create', 3, 2, 2173, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-20 06:49:53', '', '2023-05-20 06:49:53', b'0');
1795 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 (2176, '快递运费模板更新', 'trade:delivery:express-template:update', 3, 3, 2173, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-20 06:49:53', '', '2023-05-20 06:49:53', b'0'); 1936 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 (2176, '快递运费模板更新', 'trade:delivery:express-template:update', 3, 3, 2173, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-20 06:49:53', '', '2023-05-20 06:49:53', b'0');
1796 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 (2177, '快递运费模板删除', 'trade:delivery:express-template:delete', 3, 4, 2173, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-20 06:49:53', '', '2023-05-20 06:49:53', b'0'); 1937 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 (2177, '快递运费模板删除', 'trade:delivery:express-template:delete', 3, 4, 2173, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-20 06:49:53', '', '2023-05-20 06:49:53', b'0');
1797 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 (2178, '快递运费模板导出', 'trade:delivery:express-template:export', 3, 5, 2173, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-20 06:49:53', '', '2023-05-20 06:49:53', b'0'); 1938 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 (2178, '快递运费模板导出', 'trade:delivery:express-template:export', 3, 5, 2173, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-20 06:49:53', '', '2023-05-20 06:49:53', b'0');
1798 -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 (2179, '门店管理', '', 2, 1, 2166, 'pick-up-store', '', 'mall/trade/delivery/pickUpStore/index', 'PickUpStore', 0, b'1', b'1', b'1', '1', '2023-05-25 10:50:00', '1', '2023-05-25 10:50:00', b'0'); 1939 +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 (2179, '门店管理', '', 2, 1, 2166, 'pick-up-store', 'ep:basketball', 'mall/trade/delivery/pickUpStore/index', 'PickUpStore', 0, b'1', b'1', b'1', '1', '2023-05-25 10:50:00', '1', '2023-08-30 21:03:28', b'0');
1799 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 (2180, '自提门店查询', 'trade:delivery:pick-up-store:query', 3, 1, 2179, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-25 10:53:29', '', '2023-05-25 10:53:29', b'0'); 1940 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 (2180, '自提门店查询', 'trade:delivery:pick-up-store:query', 3, 1, 2179, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-25 10:53:29', '', '2023-05-25 10:53:29', b'0');
1800 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 (2181, '自提门店创建', 'trade:delivery:pick-up-store:create', 3, 2, 2179, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-25 10:53:29', '', '2023-05-25 10:53:29', b'0'); 1941 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 (2181, '自提门店创建', 'trade:delivery:pick-up-store:create', 3, 2, 2179, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-25 10:53:29', '', '2023-05-25 10:53:29', b'0');
1801 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 (2182, '自提门店更新', 'trade:delivery:pick-up-store:update', 3, 3, 2179, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-25 10:53:29', '', '2023-05-25 10:53:29', b'0'); 1942 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 (2182, '自提门店更新', 'trade:delivery:pick-up-store:update', 3, 3, 2179, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-05-25 10:53:29', '', '2023-05-25 10:53:29', b'0');
@@ -1834,7 +1975,7 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i @@ -1834,7 +1975,7 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i
1834 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 (2314, '砍价活动更新', 'promotion:bargain-activity:update', 3, 3, 2311, '', '', '', '', 0, b'1', b'1', b'1', '1', '2023-08-13 00:32:55', '1', '2023-08-13 00:32:55', b'0'); 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 (2314, '砍价活动更新', 'promotion:bargain-activity:update', 3, 3, 2311, '', '', '', '', 0, b'1', b'1', b'1', '1', '2023-08-13 00:32:55', '1', '2023-08-13 00:32:55', b'0');
1835 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 (2315, '砍价活动删除', 'promotion:bargain-activity:delete', 3, 4, 2311, '', '', '', '', 0, b'1', b'1', b'1', '1', '2023-08-13 00:34:50', '1', '2023-08-13 00:34:50', 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 (2315, '砍价活动删除', 'promotion:bargain-activity:delete', 3, 4, 2311, '', '', '', '', 0, b'1', b'1', b'1', '1', '2023-08-13 00:34:50', '1', '2023-08-13 00:34:50', b'0');
1836 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 (2316, '砍价活动关闭', 'promotion:bargain-activity:close', 3, 5, 2311, '', '', '', '', 0, b'1', b'1', b'1', '1', '2023-08-13 00:35:02', '1', '2023-08-13 00:35:02', b'0'); 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 (2316, '砍价活动关闭', 'promotion:bargain-activity:close', 3, 5, 2311, '', '', '', '', 0, b'1', b'1', b'1', '1', '2023-08-13 00:35:02', '1', '2023-08-13 00:35:02', b'0');
1837 -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 (2317, '会员管理', '', 2, 0, 2262, 'user', 'ep:avatar', 'member/user/index', 'MemberUser', 0, b'1', b'1', b'1', '', '2023-08-19 04:12:15', '1', '2023-08-19 12:13:06', b'0'); 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 (2317, '会员管理', '', 2, 0, 2262, 'user', 'ep:avatar', 'member/user/index', 'MemberUser', 0, b'1', b'1', b'1', '', '2023-08-19 04:12:15', '1', '2023-08-24 00:50:55', b'0');
1838 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 (2318, '会员用户查询', 'member:user:query', 3, 1, 2317, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-08-19 04:12:15', '', '2023-08-19 04:12:15', b'0'); 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 (2318, '会员用户查询', 'member:user:query', 3, 1, 2317, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-08-19 04:12:15', '', '2023-08-19 04:12:15', b'0');
1839 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 (2319, '会员用户更新', 'member:user:update', 3, 3, 2317, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-08-19 04:12:15', '', '2023-08-19 04:12:15', b'0'); 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 (2319, '会员用户更新', 'member:user:update', 3, 3, 2317, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-08-19 04:12:15', '', '2023-08-19 04:12:15', b'0');
1840 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 (2320, '会员标签', '', 2, 1, 2262, 'tag', 'ep:collection-tag', 'member/tag/index', 'MemberTag', 0, b'1', b'1', b'1', '', '2023-08-20 01:03:08', '1', '2023-08-20 09:23:19', b'0'); 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 (2320, '会员标签', '', 2, 1, 2262, 'tag', 'ep:collection-tag', 'member/tag/index', 'MemberTag', 0, b'1', b'1', b'1', '', '2023-08-20 01:03:08', '1', '2023-08-20 09:23:19', b'0');
@@ -1842,6 +1983,23 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i @@ -1842,6 +1983,23 @@ INSERT INTO `system_menu` (`id`, `name`, `permission`, `type`, `sort`, `parent_i
1842 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 (2322, '会员标签创建', 'member:tag:create', 3, 2, 2320, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-08-20 01:03:08', '', '2023-08-20 01:03:08', b'0'); 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 (2322, '会员标签创建', 'member:tag:create', 3, 2, 2320, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-08-20 01:03:08', '', '2023-08-20 01:03:08', b'0');
1843 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 (2323, '会员标签更新', 'member:tag:update', 3, 3, 2320, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-08-20 01:03:08', '', '2023-08-20 01:03:08', b'0'); 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 (2323, '会员标签更新', 'member:tag:update', 3, 3, 2320, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-08-20 01:03:08', '', '2023-08-20 01:03:08', b'0');
1844 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 (2324, '会员标签删除', 'member:tag:delete', 3, 4, 2320, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-08-20 01:03:08', '', '2023-08-20 01:03:08', b'0'); 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 (2324, '会员标签删除', 'member:tag:delete', 3, 4, 2320, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-08-20 01:03:08', '', '2023-08-20 01:03:08', b'0');
  1986 +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 (2325, '会员等级', '', 2, 2, 2262, 'level', 'fa:level-up', 'member/level/index', 'MemberLevel', 0, b'1', b'1', b'1', '', '2023-08-22 12:41:01', '1', '2023-08-22 21:47:00', b'0');
  1987 +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 (2326, '会员等级查询', 'member:level:query', 3, 1, 2325, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-08-22 12:41:02', '', '2023-08-22 12:41:02', b'0');
  1988 +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 (2327, '会员等级创建', 'member:level:create', 3, 2, 2325, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-08-22 12:41:02', '', '2023-08-22 12:41:02', b'0');
  1989 +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 (2328, '会员等级更新', 'member:level:update', 3, 3, 2325, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-08-22 12:41:02', '', '2023-08-22 12:41:02', b'0');
  1990 +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 (2329, '会员等级删除', 'member:level:delete', 3, 4, 2325, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-08-22 12:41:02', '', '2023-08-22 12:41:02', b'0');
  1991 +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 (2330, '用户分组', '', 2, 3, 2262, 'group', 'fa:group', 'member/group/index', 'MemberGroup', 0, b'1', b'1', b'1', '', '2023-08-22 13:50:06', '1', '2023-08-22 21:57:47', b'0');
  1992 +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 (2331, '用户分组查询', 'member:group:query', 3, 1, 2330, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-08-22 13:50:06', '', '2023-08-22 13:50:06', b'0');
  1993 +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 (2332, '用户分组创建', 'member:group:create', 3, 2, 2330, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-08-22 13:50:06', '', '2023-08-22 13:50:06', b'0');
  1994 +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 (2333, '用户分组更新', 'member:group:update', 3, 3, 2330, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-08-22 13:50:06', '', '2023-08-22 13:50:06', b'0');
  1995 +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 (2334, '用户分组删除', 'member:group:delete', 3, 4, 2330, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-08-22 13:50:06', '', '2023-08-22 13:50:06', b'0');
  1996 +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 (2335, '用户等级修改', 'member:user:update-level', 3, 5, 2317, '', '', '', NULL, 0, b'1', b'1', b'1', '', '2023-08-23 16:49:05', '', '2023-08-23 16:50:48', b'0');
  1997 +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 (2336, '商品评论', '', 2, 5, 2000, 'comment', 'ep:comment', 'mall/product/comment/index', 'ProductComment', 0, b'1', b'1', b'1', '1', '2023-08-26 11:03:00', '1', '2023-08-26 11:03:38', b'0');
  1998 +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 (2337, '评论查询', 'product:comment:query', 3, 1, 2336, '', '', '', '', 0, b'1', b'1', b'1', '1', '2023-08-26 11:04:01', '1', '2023-08-26 11:04:01', b'0');
  1999 +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 (2338, '添加自评', 'product:comment:create', 3, 2, 2336, '', '', '', '', 0, b'1', b'1', b'1', '1', '2023-08-26 11:04:23', '1', '2023-08-26 11:08:18', b'0');
  2000 +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 (2339, '商家回复', 'product:comment:update', 3, 3, 2336, '', '', '', '', 0, b'1', b'1', b'1', '1', '2023-08-26 11:04:37', '1', '2023-08-26 11:04:37', b'0');
  2001 +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 (2340, '显隐评论', 'product:comment:update', 3, 4, 2336, '', '', '', '', 0, b'1', b'1', b'1', '1', '2023-08-26 11:04:55', '1', '2023-08-26 11:04:55', b'0');
  2002 +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 (2341, '优惠劵发送', 'promotion:coupon:send', 3, 2, 2038, '', '', '', '', 0, b'1', b'1', b'1', '1', '2023-09-02 00:03:14', '1', '2023-09-02 00:03:14', b'0');
1845 COMMIT; 2003 COMMIT;
1846 2004
1847 -- ---------------------------- 2005 -- ----------------------------
@@ -1958,7 +2116,7 @@ CREATE TABLE `system_oauth2_access_token` ( @@ -1958,7 +2116,7 @@ CREATE TABLE `system_oauth2_access_token` (
1958 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', 2116 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
1959 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', 2117 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
1960 PRIMARY KEY (`id`) USING BTREE 2118 PRIMARY KEY (`id`) USING BTREE
1961 -) ENGINE = InnoDB AUTO_INCREMENT = 2453 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'OAuth2 访问令牌'; 2119 +) ENGINE = InnoDB AUTO_INCREMENT = 2597 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'OAuth2 访问令牌';
1962 2120
1963 -- ---------------------------- 2121 -- ----------------------------
1964 -- Records of system_oauth2_access_token 2122 -- Records of system_oauth2_access_token
@@ -2080,7 +2238,7 @@ CREATE TABLE `system_oauth2_refresh_token` ( @@ -2080,7 +2238,7 @@ CREATE TABLE `system_oauth2_refresh_token` (
2080 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', 2238 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
2081 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', 2239 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
2082 PRIMARY KEY (`id`) USING BTREE 2240 PRIMARY KEY (`id`) USING BTREE
2083 -) ENGINE = InnoDB AUTO_INCREMENT = 850 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'OAuth2 刷新令牌'; 2241 +) ENGINE = InnoDB AUTO_INCREMENT = 896 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'OAuth2 刷新令牌';
2084 2242
2085 -- ---------------------------- 2243 -- ----------------------------
2086 -- Records of system_oauth2_refresh_token 2244 -- Records of system_oauth2_refresh_token
@@ -2120,7 +2278,7 @@ CREATE TABLE `system_operate_log` ( @@ -2120,7 +2278,7 @@ CREATE TABLE `system_operate_log` (
2120 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', 2278 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
2121 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', 2279 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
2122 PRIMARY KEY (`id`) USING BTREE 2280 PRIMARY KEY (`id`) USING BTREE
2123 -) ENGINE = InnoDB AUTO_INCREMENT = 8043 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '操作日志记录'; 2281 +) ENGINE = InnoDB AUTO_INCREMENT = 8321 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '操作日志记录';
2124 2282
2125 -- ---------------------------- 2283 -- ----------------------------
2126 -- Records of system_operate_log 2284 -- Records of system_operate_log
@@ -3128,7 +3286,7 @@ CREATE TABLE `system_sms_code` ( @@ -3128,7 +3286,7 @@ CREATE TABLE `system_sms_code` (
3128 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', 3286 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
3129 PRIMARY KEY (`id`) USING BTREE, 3287 PRIMARY KEY (`id`) USING BTREE,
3130 INDEX `idx_mobile`(`mobile` ASC) USING BTREE COMMENT '手机号' 3288 INDEX `idx_mobile`(`mobile` ASC) USING BTREE COMMENT '手机号'
3131 -) ENGINE = InnoDB AUTO_INCREMENT = 500 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '手机验证码'; 3289 +) ENGINE = InnoDB AUTO_INCREMENT = 501 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '手机验证码';
3132 3290
3133 -- ---------------------------- 3291 -- ----------------------------
3134 -- Records of system_sms_code 3292 -- Records of system_sms_code
@@ -3171,7 +3329,7 @@ CREATE TABLE `system_sms_log` ( @@ -3171,7 +3329,7 @@ CREATE TABLE `system_sms_log` (
3171 `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', 3329 `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
3172 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', 3330 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
3173 PRIMARY KEY (`id`) USING BTREE 3331 PRIMARY KEY (`id`) USING BTREE
3174 -) ENGINE = InnoDB AUTO_INCREMENT = 364 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '短信日志'; 3332 +) ENGINE = InnoDB AUTO_INCREMENT = 365 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '短信日志';
3175 3333
3176 -- ---------------------------- 3334 -- ----------------------------
3177 -- Records of system_sms_log 3335 -- Records of system_sms_log
@@ -3444,7 +3602,7 @@ CREATE TABLE `system_users` ( @@ -3444,7 +3602,7 @@ CREATE TABLE `system_users` (
3444 -- Records of system_users 3602 -- Records of system_users
3445 -- ---------------------------- 3603 -- ----------------------------
3446 BEGIN; 3604 BEGIN;
3447 -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-08-20 19:24:52', 'admin', '2021-01-05 17:03:47', NULL, '2023-08-20 19:24:52', b'0', 1); 3605 +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-09-02 00:03:37', 'admin', '2021-01-05 17:03:47', NULL, '2023-09-02 00:03:37', b'0', 1);
3448 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); 3606 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);
3449 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); 3607 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);
3450 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, '127.0.0.1', '2022-05-28 15:43:17', '', '2021-01-21 02:13:53', NULL, '2022-07-09 09:00:33', b'0', 1); 3608 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, '127.0.0.1', '2022-05-28 15:43:17', '', '2021-01-21 02:13:53', NULL, '2022-07-09 09:00:33', b'0', 1);
sql/postgresql/ruoyi-vue-pro.sql
@@ -2587,7 +2587,7 @@ INSERT INTO &quot;qrtz_job_details&quot; (&quot;sched_name&quot;, &quot;job_name&quot;, &quot;job_group&quot;, &quot;descript @@ -2587,7 +2587,7 @@ INSERT INTO &quot;qrtz_job_details&quot; (&quot;sched_name&quot;, &quot;job_name&quot;, &quot;job_group&quot;, &quot;descript
2587 "is_nonconcurrent", "is_update_data", "requests_recovery", "job_data") 2587 "is_nonconcurrent", "is_update_data", "requests_recovery", "job_data")
2588 VALUES ('schedulerName', 'userSessionTimeoutJob', 'DEFAULT', NULL, 2588 VALUES ('schedulerName', 'userSessionTimeoutJob', 'DEFAULT', NULL,
2589 'cn.iocoder.yudao.framework.quartz.core.handler.JobHandlerInvoker', 'f', 't', 't', 'f', 2589 'cn.iocoder.yudao.framework.quartz.core.handler.JobHandlerInvoker', 'f', 't', 't', 'f',
2590 - E '\254\355\000\005sr\000\025org.quartz.JobDataMap\237\260\203\350\277\251\260\313\002\000\000xr\000&org.quartz.utils.StringKeyDirtyFlagMap\202\010\350\303\373\305](\002\000\001Z\000\023allowsTransientDataxr\000\035org.quartz.utils.DirtyFlagMap\023\346.\255(v\012\316\002\000\002Z\000\005dirtyL\000\003mapt\000\017Ljava/util/Map;xp\001sr\000\021java.util.HashMap\005\007\332\301\303\026`\321\003\000\002F\000\012loadFactorI\000\011thresholdxp?@\000\000\000\000\000\014w\010\000\000\000\020\000\000\000\002t\000\006JOB_IDsr\000\016java.lang.Long;\213\344\220\314\217#\337\002\000\001J\000\005valuexr\000\020java.lang.Number\206\254\225\035\013\224\340\213\002\000\000xp\000\000\000\000\000\000\000\002t\000\020JOB_HANDLER_NAMEt\000\025userSessionTimeoutJobx\000'); 2590 + '\254\355\000\005sr\000\025org.quartz.JobDataMap\237\260\203\350\277\251\260\313\002\000\000xr\000&org.quartz.utils.StringKeyDirtyFlagMap\202\010\350\303\373\305](\002\000\001Z\000\023allowsTransientDataxr\000\035org.quartz.utils.DirtyFlagMap\023\346.\255(v\012\316\002\000\002Z\000\005dirtyL\000\003mapt\000\017Ljava/util/Map;xp\001sr\000\021java.util.HashMap\005\007\332\301\303\026`\321\003\000\002F\000\012loadFactorI\000\011thresholdxp?@\000\000\000\000\000\014w\010\000\000\000\020\000\000\000\002t\000\006JOB_IDsr\000\016java.lang.Long;\213\344\220\314\217#\337\002\000\001J\000\005valuexr\000\020java.lang.Number\206\254\225\035\013\224\340\213\002\000\000xp\000\000\000\000\000\000\000\002t\000\020JOB_HANDLER_NAMEt\000\025userSessionTimeoutJobx\000');
2591 COMMIT; 2591 COMMIT;
2592 2592
2593 -- ---------------------------- 2593 -- ----------------------------
@@ -2733,7 +2733,7 @@ INSERT INTO &quot;qrtz_triggers&quot; (&quot;sched_name&quot;, &quot;trigger_name&quot;, &quot;trigger_group&quot;, &quot;job @@ -2733,7 +2733,7 @@ INSERT INTO &quot;qrtz_triggers&quot; (&quot;sched_name&quot;, &quot;trigger_name&quot;, &quot;trigger_group&quot;, &quot;job
2733 "start_time", "end_time", "calendar_name", "misfire_instr", "job_data") 2733 "start_time", "end_time", "calendar_name", "misfire_instr", "job_data")
2734 VALUES ('schedulerName', 'userSessionTimeoutJob', 'DEFAULT', 'userSessionTimeoutJob', 'DEFAULT', NULL, 1651328700000, 2734 VALUES ('schedulerName', 'userSessionTimeoutJob', 'DEFAULT', 'userSessionTimeoutJob', 'DEFAULT', NULL, 1651328700000,
2735 1651328640000, 5, 'WAITING', 'CRON', 1651328526000, 0, NULL, 0, 2735 1651328640000, 5, 'WAITING', 'CRON', 1651328526000, 0, NULL, 0,
2736 - E '\254\355\000\005sr\000\025org.quartz.JobDataMap\237\260\203\350\277\251\260\313\002\000\000xr\000&org.quartz.utils.StringKeyDirtyFlagMap\202\010\350\303\373\305](\002\000\001Z\000\023allowsTransientDataxr\000\035org.quartz.utils.DirtyFlagMap\023\346.\255(v\012\316\002\000\002Z\000\005dirtyL\000\003mapt\000\017Ljava/util/Map;xp\001sr\000\021java.util.HashMap\005\007\332\301\303\026`\321\003\000\002F\000\012loadFactorI\000\011thresholdxp?@\000\000\000\000\000\014w\010\000\000\000\020\000\000\000\003t\000\021JOB_HANDLER_PARAMpt\000\022JOB_RETRY_INTERVALsr\000\021java.lang.Integer\022\342\240\244\367\201\2078\002\000\001I\000\005valuexr\000\020java.lang.Number\206\254\225\035\013\224\340\213\002\000\000xp\000\000\007\320t\000\017JOB_RETRY_COUNTsq\000~\000\011\000\000\000\003x\000'); 2736 + '\254\355\000\005sr\000\025org.quartz.JobDataMap\237\260\203\350\277\251\260\313\002\000\000xr\000&org.quartz.utils.StringKeyDirtyFlagMap\202\010\350\303\373\305](\002\000\001Z\000\023allowsTransientDataxr\000\035org.quartz.utils.DirtyFlagMap\023\346.\255(v\012\316\002\000\002Z\000\005dirtyL\000\003mapt\000\017Ljava/util/Map;xp\001sr\000\021java.util.HashMap\005\007\332\301\303\026`\321\003\000\002F\000\012loadFactorI\000\011thresholdxp?@\000\000\000\000\000\014w\010\000\000\000\020\000\000\000\003t\000\021JOB_HANDLER_PARAMpt\000\022JOB_RETRY_INTERVALsr\000\021java.lang.Integer\022\342\240\244\367\201\2078\002\000\001I\000\005valuexr\000\020java.lang.Number\206\254\225\035\013\224\340\213\002\000\000xp\000\000\007\320t\000\017JOB_RETRY_COUNTsq\000~\000\011\000\000\000\003x\000');
2737 COMMIT; 2737 COMMIT;
2738 2738
2739 -- ---------------------------- 2739 -- ----------------------------
yudao-dependencies/pom.xml
@@ -14,7 +14,8 @@ @@ -14,7 +14,8 @@
14 <url>https://github.com/YunaiV/ruoyi-vue-pro</url> 14 <url>https://github.com/YunaiV/ruoyi-vue-pro</url>
15 15
16 <properties> 16 <properties>
17 - <revision>1.8.0-snapshot</revision> 17 + <revision>1.8.1-snapshot</revision>
  18 + <flatten-maven-plugin.version>1.5.0</flatten-maven-plugin.version>
18 <!-- 统一依赖管理 --> 19 <!-- 统一依赖管理 -->
19 <spring.boot.version>2.7.14</spring.boot.version> 20 <spring.boot.version>2.7.14</spring.boot.version>
20 <!-- Web 相关 --> 21 <!-- Web 相关 -->
@@ -23,10 +24,10 @@ @@ -23,10 +24,10 @@
23 <servlet.versoin>2.5</servlet.versoin> 24 <servlet.versoin>2.5</servlet.versoin>
24 <!-- DB 相关 --> 25 <!-- DB 相关 -->
25 <druid.version>1.2.18</druid.version> 26 <druid.version>1.2.18</druid.version>
26 - <mybatis-plus.version>3.5.3.1</mybatis-plus.version>  
27 - <mybatis-plus-generator.version>3.5.3.1</mybatis-plus-generator.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>
28 <dynamic-datasource.version>3.6.1</dynamic-datasource.version> 29 <dynamic-datasource.version>3.6.1</dynamic-datasource.version>
29 - <mybatis-plus-join-boot-starter.version>1.4.5</mybatis-plus-join-boot-starter.version> 30 + <mybatis-plus-join.version>1.4.6</mybatis-plus-join.version>
30 <redisson.version>3.18.0</redisson.version> 31 <redisson.version>3.18.0</redisson.version>
31 <dm8.jdbc.version>8.1.2.141</dm8.jdbc.version> 32 <dm8.jdbc.version>8.1.2.141</dm8.jdbc.version>
32 <!-- 服务保障相关 --> 33 <!-- 服务保障相关 -->
@@ -219,7 +220,7 @@ @@ -219,7 +220,7 @@
219 <dependency> 220 <dependency>
220 <groupId>com.github.yulichang</groupId> 221 <groupId>com.github.yulichang</groupId>
221 <artifactId>mybatis-plus-join-boot-starter</artifactId> <!-- MyBatis 联表查询 --> 222 <artifactId>mybatis-plus-join-boot-starter</artifactId> <!-- MyBatis 联表查询 -->
222 - <version>${mybatis-plus-join-boot-starter.version}</version> 223 + <version>${mybatis-plus-join.version}</version>
223 </dependency> 224 </dependency>
224 225
225 <dependency> 226 <dependency>
@@ -645,4 +646,35 @@ @@ -645,4 +646,35 @@
645 </dependencies> 646 </dependencies>
646 </dependencyManagement> 647 </dependencyManagement>
647 648
  649 + <build>
  650 + <plugins>
  651 + <!-- 统一 revision 版本 -->
  652 + <plugin>
  653 + <groupId>org.codehaus.mojo</groupId>
  654 + <artifactId>flatten-maven-plugin</artifactId>
  655 + <version>${flatten-maven-plugin.version}</version>
  656 + <configuration>
  657 + <flattenMode>resolveCiFriendliesOnly</flattenMode>
  658 + <updatePomFile>true</updatePomFile>
  659 + </configuration>
  660 + <executions>
  661 + <execution>
  662 + <goals>
  663 + <goal>flatten</goal>
  664 + </goals>
  665 + <id>flatten</id>
  666 + <phase>process-resources</phase>
  667 + </execution>
  668 + <execution>
  669 + <goals>
  670 + <goal>clean</goal>
  671 + </goals>
  672 + <id>flatten.clean</id>
  673 + <phase>clean</phase>
  674 + </execution>
  675 + </executions>
  676 + </plugin>
  677 + </plugins>
  678 + </build>
  679 +
648 </project> 680 </project>
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/pojo/SortingField.java
1 package cn.iocoder.yudao.framework.common.pojo; 1 package cn.iocoder.yudao.framework.common.pojo;
2 2
  3 +import lombok.AllArgsConstructor;
  4 +import lombok.Data;
  5 +import lombok.NoArgsConstructor;
  6 +
3 import java.io.Serializable; 7 import java.io.Serializable;
4 8
5 /** 9 /**
@@ -7,6 +11,9 @@ import java.io.Serializable; @@ -7,6 +11,9 @@ import java.io.Serializable;
7 * 11 *
8 * 类名加了 ing 的原因是,避免和 ES SortField 重名。 12 * 类名加了 ing 的原因是,避免和 ES SortField 重名。
9 */ 13 */
  14 +@Data
  15 +@NoArgsConstructor
  16 +@AllArgsConstructor
10 public class SortingField implements Serializable { 17 public class SortingField implements Serializable {
11 18
12 /** 19 /**
@@ -27,30 +34,4 @@ public class SortingField implements Serializable { @@ -27,30 +34,4 @@ public class SortingField implements Serializable {
27 */ 34 */
28 private String order; 35 private String order;
29 36
30 - // 空构造方法,解决反序列化  
31 - public SortingField() {  
32 - }  
33 -  
34 - public SortingField(String field, String order) {  
35 - this.field = field;  
36 - this.order = order;  
37 - }  
38 -  
39 - public String getField() {  
40 - return field;  
41 - }  
42 -  
43 - public SortingField setField(String field) {  
44 - this.field = field;  
45 - return this;  
46 - }  
47 -  
48 - public String getOrder() {  
49 - return order;  
50 - }  
51 -  
52 - public SortingField setOrder(String order) {  
53 - this.order = order;  
54 - return this;  
55 - }  
56 } 37 }
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/DateUtils.java
@@ -36,6 +36,9 @@ public class DateUtils { @@ -36,6 +36,9 @@ public class DateUtils {
36 * @return LocalDateTime 36 * @return LocalDateTime
37 */ 37 */
38 public static Date of(LocalDateTime date) { 38 public static Date of(LocalDateTime date) {
  39 + if (date == null) {
  40 + return null;
  41 + }
39 // 将此日期时间与时区相结合以创建 ZonedDateTime 42 // 将此日期时间与时区相结合以创建 ZonedDateTime
40 ZonedDateTime zonedDateTime = date.atZone(ZoneId.systemDefault()); 43 ZonedDateTime zonedDateTime = date.atZone(ZoneId.systemDefault());
41 // 本地时间线 LocalDateTime 到即时时间线 Instant 时间戳 44 // 本地时间线 LocalDateTime 到即时时间线 Instant 时间戳
@@ -51,6 +54,9 @@ public class DateUtils { @@ -51,6 +54,9 @@ public class DateUtils {
51 * @return LocalDateTime 54 * @return LocalDateTime
52 */ 55 */
53 public static LocalDateTime of(Date date) { 56 public static LocalDateTime of(Date date) {
  57 + if (date == null) {
  58 + return null;
  59 + }
54 // 转为时间戳 60 // 转为时间戳
55 Instant instant = date.toInstant(); 61 Instant instant = date.toInstant();
56 // UTC时间(世界协调时间,UTC + 00:00)转北京(北京,UTC + 8:00)时间 62 // UTC时间(世界协调时间,UTC + 00:00)转北京(北京,UTC + 8:00)时间
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/validation/InEnum.java
@@ -17,7 +17,7 @@ import java.lang.annotation.*; @@ -17,7 +17,7 @@ import java.lang.annotation.*;
17 @Retention(RetentionPolicy.RUNTIME) 17 @Retention(RetentionPolicy.RUNTIME)
18 @Documented 18 @Documented
19 @Constraint( 19 @Constraint(
20 - validatedBy = InEnumValidator.class 20 + validatedBy = {InEnumValidator.class, InEnumCollectionValidator.class}
21 ) 21 )
22 public @interface InEnum { 22 public @interface InEnum {
23 23
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/validation/InEnumCollectionValidator.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.common.validation;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
  5 +
  6 +import javax.validation.ConstraintValidator;
  7 +import javax.validation.ConstraintValidatorContext;
  8 +import java.util.Arrays;
  9 +import java.util.Collection;
  10 +import java.util.Collections;
  11 +import java.util.List;
  12 +import java.util.stream.Collectors;
  13 +
  14 +public class InEnumCollectionValidator implements ConstraintValidator<InEnum, Collection<Integer>> {
  15 +
  16 + private List<Integer> values;
  17 +
  18 + @Override
  19 + public void initialize(InEnum annotation) {
  20 + IntArrayValuable[] values = annotation.value().getEnumConstants();
  21 + if (values.length == 0) {
  22 + this.values = Collections.emptyList();
  23 + } else {
  24 + this.values = Arrays.stream(values[0].array()).boxed().collect(Collectors.toList());
  25 + }
  26 + }
  27 +
  28 + @Override
  29 + public boolean isValid(Collection<Integer> list, ConstraintValidatorContext context) {
  30 + // 校验通过
  31 + if (CollUtil.containsAll(values, list)) {
  32 + return true;
  33 + }
  34 + // 校验不通过,自定义提示语句(因为,注解上的 value 是枚举类,无法获得枚举类的实际值)
  35 + context.disableDefaultConstraintViolation(); // 禁用默认的 message 的值
  36 + context.buildConstraintViolationWithTemplate(context.getDefaultConstraintMessageTemplate()
  37 + .replaceAll("\\{value}", CollUtil.join(list, ","))).addConstraintViolation(); // 重新添加错误提示语句
  38 + return false;
  39 + }
  40 +
  41 +}
  42 +
yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/core/db/DataPermissionDatabaseInterceptor.java
@@ -5,7 +5,6 @@ import cn.iocoder.yudao.framework.common.util.collection.SetUtils; @@ -5,7 +5,6 @@ import cn.iocoder.yudao.framework.common.util.collection.SetUtils;
5 import cn.iocoder.yudao.framework.datapermission.core.rule.DataPermissionRule; 5 import cn.iocoder.yudao.framework.datapermission.core.rule.DataPermissionRule;
6 import cn.iocoder.yudao.framework.datapermission.core.rule.DataPermissionRuleFactory; 6 import cn.iocoder.yudao.framework.datapermission.core.rule.DataPermissionRuleFactory;
7 import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils; 7 import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils;
8 -import com.alibaba.ttl.TransmittableThreadLocal;  
9 import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; 8 import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
10 import com.baomidou.mybatisplus.core.toolkit.PluginUtils; 9 import com.baomidou.mybatisplus.core.toolkit.PluginUtils;
11 import com.baomidou.mybatisplus.extension.parser.JsqlParserSupport; 10 import com.baomidou.mybatisplus.extension.parser.JsqlParserSupport;
@@ -508,6 +507,9 @@ public class DataPermissionDatabaseInterceptor extends JsqlParserSupport impleme @@ -508,6 +507,9 @@ public class DataPermissionDatabaseInterceptor extends JsqlParserSupport impleme
508 // 单条规则的条件 507 // 单条规则的条件
509 String tableName = MyBatisUtils.getTableName(table); 508 String tableName = MyBatisUtils.getTableName(table);
510 Expression oneExpress = rule.getExpression(tableName, table.getAlias()); 509 Expression oneExpress = rule.getExpression(tableName, table.getAlias());
  510 + if (oneExpress == null){
  511 + continue;
  512 + }
511 // 拼接到 allExpression 中 513 // 拼接到 allExpression 中
512 allExpression = allExpression == null ? oneExpress 514 allExpression = allExpression == null ? oneExpress
513 : new AndExpression(allExpression, oneExpress); 515 : new AndExpression(allExpression, oneExpress);
yudao-framework/yudao-spring-boot-starter-biz-data-permission/src/main/java/cn/iocoder/yudao/framework/datapermission/core/rule/dept/DeptDataPermissionRule.java
@@ -7,7 +7,6 @@ import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; @@ -7,7 +7,6 @@ import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
7 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; 7 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
8 import cn.iocoder.yudao.framework.common.util.json.JsonUtils; 8 import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
9 import cn.iocoder.yudao.framework.datapermission.core.rule.DataPermissionRule; 9 import cn.iocoder.yudao.framework.datapermission.core.rule.DataPermissionRule;
10 -import cn.iocoder.yudao.framework.expression.OrExpressionX;  
11 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; 10 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
12 import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils; 11 import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils;
13 import cn.iocoder.yudao.framework.security.core.LoginUser; 12 import cn.iocoder.yudao.framework.security.core.LoginUser;
@@ -17,10 +16,8 @@ import cn.iocoder.yudao.module.system.api.permission.dto.DeptDataPermissionRespD @@ -17,10 +16,8 @@ import cn.iocoder.yudao.module.system.api.permission.dto.DeptDataPermissionRespD
17 import com.baomidou.mybatisplus.core.metadata.TableInfoHelper; 16 import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
18 import lombok.AllArgsConstructor; 17 import lombok.AllArgsConstructor;
19 import lombok.extern.slf4j.Slf4j; 18 import lombok.extern.slf4j.Slf4j;
20 -import net.sf.jsqlparser.expression.Alias;  
21 -import net.sf.jsqlparser.expression.Expression;  
22 -import net.sf.jsqlparser.expression.LongValue;  
23 -import net.sf.jsqlparser.expression.NullValue; 19 +import net.sf.jsqlparser.expression.*;
  20 +import net.sf.jsqlparser.expression.operators.conditional.OrExpression;
24 import net.sf.jsqlparser.expression.operators.relational.EqualsTo; 21 import net.sf.jsqlparser.expression.operators.relational.EqualsTo;
25 import net.sf.jsqlparser.expression.operators.relational.ExpressionList; 22 import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
26 import net.sf.jsqlparser.expression.operators.relational.InExpression; 23 import net.sf.jsqlparser.expression.operators.relational.InExpression;
@@ -144,7 +141,7 @@ public class DeptDataPermissionRule implements DataPermissionRule { @@ -144,7 +141,7 @@ public class DeptDataPermissionRule implements DataPermissionRule {
144 return deptExpression; 141 return deptExpression;
145 } 142 }
146 // 目前,如果有指定部门 + 可查看自己,采用 OR 条件。即,WHERE (dept_id IN ? OR user_id = ?) 143 // 目前,如果有指定部门 + 可查看自己,采用 OR 条件。即,WHERE (dept_id IN ? OR user_id = ?)
147 - return new OrExpressionX(deptExpression, userExpression); 144 + return new Parenthesis(new OrExpression(deptExpression, userExpression));
148 } 145 }
149 146
150 private Expression buildDeptExpression(String tableName, Alias tableAlias, Set<Long> deptIds) { 147 private Expression buildDeptExpression(String tableName, Alias tableAlias, Set<Long> deptIds) {
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/delegate/DelegatePayClient.java deleted
1 -package cn.iocoder.yudao.framework.pay.core.client.impl.delegate;  
2 -  
3 -import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig;  
4 -import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;  
5 -import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;  
6 -import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO;  
7 -import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO;  
8 -import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient;  
9 -  
10 -import java.util.Map;  
11 -  
12 -// TODO @jason:其它模块,主要是无法 pay client 初始化存在问题,所以我感觉,是不是可以搞个 PayClientInitializer 接口。这样,PayClientFactory 去 get 这个支付模式对应的 PayClientInitializer,通过它来创建。具体注入的地方,可以在 PayChannel init 方法那;  
13 -/**  
14 - * 代理支付 Client 的抽象类。  
15 - *  
16 - * 用于支付 Client 由其它模块实现,例如钱包支付  
17 - *  
18 - * @author jason  
19 - */  
20 -public abstract class DelegatePayClient<Config extends PayClientConfig> extends AbstractPayClient<PayClientConfig> {  
21 -  
22 - private final DelegatePayClient<Config> delegate;  
23 -  
24 - public DelegatePayClient(Long channelId, String channelCode, PayClientConfig config) {  
25 - super(channelId, channelCode, config);  
26 - delegate = this;  
27 - }  
28 -  
29 - @Override  
30 - protected void doInit() {  
31 - delegate.doInit();  
32 - }  
33 -  
34 - @Override  
35 - protected PayOrderRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) {  
36 - return delegate.doUnifiedOrder(reqDTO);  
37 - }  
38 -  
39 - @Override  
40 - protected PayOrderRespDTO doGetOrder(String outTradeNo) {  
41 - return delegate.doGetOrder(outTradeNo);  
42 - }  
43 -  
44 - @Override  
45 - protected PayRefundRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) {  
46 - return delegate.doUnifiedRefund(reqDTO);  
47 - }  
48 -  
49 - @Override  
50 - protected PayRefundRespDTO doGetRefund(String outTradeNo, String outRefundNo) {  
51 - return delegate.doGetRefund(outTradeNo, outRefundNo);  
52 - }  
53 -  
54 - @Override  
55 - protected PayRefundRespDTO doParseRefundNotify(Map<String,String> params, String body) {  
56 - return delegate.doParseRefundNotify(params, body);  
57 - }  
58 -  
59 - @Override  
60 - protected PayOrderRespDTO doParseOrderNotify(Map<String,String> params, String body) {  
61 - return delegate.doParseOrderNotify(params, body);  
62 - }  
63 -}  
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/mock/MockPayClient.java
@@ -5,6 +5,7 @@ import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDT @@ -5,6 +5,7 @@ import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderUnifiedReqDT
5 import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO; 5 import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundRespDTO;
6 import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO; 6 import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReqDTO;
7 import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient; 7 import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient;
  8 +import cn.iocoder.yudao.framework.pay.core.client.impl.NonePayClientConfig;
8 import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum; 9 import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
9 10
10 import java.time.LocalDateTime; 11 import java.time.LocalDateTime;
@@ -17,11 +18,11 @@ import java.util.Map; @@ -17,11 +18,11 @@ import java.util.Map;
17 * 18 *
18 * @author jason 19 * @author jason
19 */ 20 */
20 -public class MockPayClient extends AbstractPayClient<MockPayClientConfig> { 21 +public class MockPayClient extends AbstractPayClient<NonePayClientConfig> {
21 22
22 private static final String MOCK_RESP_SUCCESS_DATA = "MOCK_SUCCESS"; 23 private static final String MOCK_RESP_SUCCESS_DATA = "MOCK_SUCCESS";
23 24
24 - public MockPayClient(Long channelId, MockPayClientConfig config) { 25 + public MockPayClient(Long channelId, NonePayClientConfig config) {
25 super(channelId, PayChannelEnum.MOCK.getCode(), config); 26 super(channelId, PayChannelEnum.MOCK.getCode(), config);
26 } 27 }
27 28
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/mock/MockPayClientConfig.java deleted
1 -package cn.iocoder.yudao.framework.pay.core.client.impl.mock;  
2 -  
3 -import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig;  
4 -import lombok.Data;  
5 -  
6 -import javax.validation.Validator;  
7 -  
8 -/**  
9 - * 模拟支付的 PayClientConfig 实现类  
10 - *  
11 - * @author jason  
12 - */  
13 -@Data  
14 -public class MockPayClientConfig implements PayClientConfig {  
15 -  
16 - /**  
17 - * 配置名称  
18 - *  
19 - * 如果不加任何属性,JsonUtils.parseObject2 解析会报错,所以暂时加个名称  
20 - */  
21 - private String name;  
22 -  
23 - @Override  
24 - public void validate(Validator validator) {  
25 - // 模拟支付配置无需校验  
26 - }  
27 -  
28 -}  
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/weixin/AbstractWxPayClient.java
@@ -56,7 +56,7 @@ public abstract class AbstractWxPayClient extends AbstractPayClient&lt;WxPayClientC @@ -56,7 +56,7 @@ public abstract class AbstractWxPayClient extends AbstractPayClient&lt;WxPayClientC
56 protected void doInit(String tradeType) { 56 protected void doInit(String tradeType) {
57 // 创建 config 配置 57 // 创建 config 配置
58 WxPayConfig payConfig = new WxPayConfig(); 58 WxPayConfig payConfig = new WxPayConfig();
59 - BeanUtil.copyProperties(config, payConfig, "keyContent"); 59 + BeanUtil.copyProperties(config, payConfig, "keyContent", "privateKeyContent", "privateCertContent");
60 payConfig.setTradeType(tradeType); 60 payConfig.setTradeType(tradeType);
61 // weixin-pay-java 无法设置内容,只允许读取文件,所以这里要创建临时文件来解决 61 // weixin-pay-java 无法设置内容,只允许读取文件,所以这里要创建临时文件来解决
62 if (Base64.isBase64(config.getKeyContent())) { 62 if (Base64.isBase64(config.getKeyContent())) {
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/channel/PayChannelEnum.java
@@ -4,7 +4,6 @@ import cn.hutool.core.util.ArrayUtil; @@ -4,7 +4,6 @@ import cn.hutool.core.util.ArrayUtil;
4 import cn.iocoder.yudao.framework.pay.core.client.impl.NonePayClientConfig; 4 import cn.iocoder.yudao.framework.pay.core.client.impl.NonePayClientConfig;
5 import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig; 5 import cn.iocoder.yudao.framework.pay.core.client.PayClientConfig;
6 import cn.iocoder.yudao.framework.pay.core.client.impl.alipay.AlipayPayClientConfig; 6 import cn.iocoder.yudao.framework.pay.core.client.impl.alipay.AlipayPayClientConfig;
7 -import cn.iocoder.yudao.framework.pay.core.client.impl.mock.MockPayClientConfig;  
8 import cn.iocoder.yudao.framework.pay.core.client.impl.weixin.WxPayClientConfig; 7 import cn.iocoder.yudao.framework.pay.core.client.impl.weixin.WxPayClientConfig;
9 import lombok.AllArgsConstructor; 8 import lombok.AllArgsConstructor;
10 import lombok.Getter; 9 import lombok.Getter;
@@ -30,7 +29,7 @@ public enum PayChannelEnum { @@ -30,7 +29,7 @@ public enum PayChannelEnum {
30 ALIPAY_QR("alipay_qr", "支付宝扫码支付", AlipayPayClientConfig.class), 29 ALIPAY_QR("alipay_qr", "支付宝扫码支付", AlipayPayClientConfig.class),
31 ALIPAY_BAR("alipay_bar", "支付宝条码支付", AlipayPayClientConfig.class), 30 ALIPAY_BAR("alipay_bar", "支付宝条码支付", AlipayPayClientConfig.class),
32 31
33 - MOCK("mock", "模拟支付", MockPayClientConfig.class), 32 + MOCK("mock", "模拟支付", NonePayClientConfig.class),
34 33
35 WALLET("wallet", "钱包支付", NonePayClientConfig.class); 34 WALLET("wallet", "钱包支付", NonePayClientConfig.class);
36 35
yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/expression/AndExpressionX.java deleted
1 -package cn.iocoder.yudao.framework.expression;  
2 -  
3 -import net.sf.jsqlparser.expression.Expression;  
4 -import net.sf.jsqlparser.expression.operators.conditional.AndExpression;  
5 -  
6 -/**  
7 - * AndExpression 的扩展类(会在原有表达式两端加上括号)  
8 - */  
9 -public class AndExpressionX extends AndExpression {  
10 -  
11 - public AndExpressionX() {  
12 - }  
13 -  
14 - public AndExpressionX(Expression leftExpression, Expression rightExpression) {  
15 - this.setLeftExpression(leftExpression);  
16 - this.setRightExpression(rightExpression);  
17 - }  
18 -  
19 - @Override  
20 - public String toString() {  
21 - return "(" + super.toString() + ")";  
22 - }  
23 -  
24 -}  
yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/expression/OrExpressionX.java deleted
1 -package cn.iocoder.yudao.framework.expression;  
2 -  
3 -import net.sf.jsqlparser.expression.Expression;  
4 -import net.sf.jsqlparser.expression.operators.conditional.OrExpression;  
5 -  
6 -/**  
7 - * OrExpression 的扩展类(会在原有表达式两端加上括号)  
8 - */  
9 -public class OrExpressionX extends OrExpression {  
10 -  
11 - public OrExpressionX() {  
12 - }  
13 -  
14 - public OrExpressionX(Expression leftExpression, Expression rightExpression) {  
15 - this.setLeftExpression(leftExpression);  
16 - this.setRightExpression(rightExpression);  
17 - }  
18 -  
19 - @Override  
20 - public String toString() {  
21 - return "(" + super.toString() + ")";  
22 - }  
23 -  
24 -}  
yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/mapper/BaseMapperX.java
1 package cn.iocoder.yudao.framework.mybatis.core.mapper; 1 package cn.iocoder.yudao.framework.mybatis.core.mapper;
2 2
  3 +import cn.hutool.core.collection.CollUtil;
3 import cn.iocoder.yudao.framework.common.pojo.PageParam; 4 import cn.iocoder.yudao.framework.common.pojo.PageParam;
4 import cn.iocoder.yudao.framework.common.pojo.PageResult; 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
5 import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils; 6 import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils;
@@ -10,6 +11,7 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; @@ -10,6 +11,7 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
10 import com.baomidou.mybatisplus.core.metadata.IPage; 11 import com.baomidou.mybatisplus.core.metadata.IPage;
11 import com.baomidou.mybatisplus.core.toolkit.support.SFunction; 12 import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
12 import com.baomidou.mybatisplus.extension.toolkit.Db; 13 import com.baomidou.mybatisplus.extension.toolkit.Db;
  14 +import com.github.yulichang.base.MPJBaseMapper;
13 import org.apache.ibatis.annotations.Param; 15 import org.apache.ibatis.annotations.Param;
14 16
15 import java.util.Collection; 17 import java.util.Collection;
@@ -17,8 +19,11 @@ import java.util.List; @@ -17,8 +19,11 @@ import java.util.List;
17 19
18 /** 20 /**
19 * 在 MyBatis Plus 的 BaseMapper 的基础上拓展,提供更多的能力 21 * 在 MyBatis Plus 的 BaseMapper 的基础上拓展,提供更多的能力
  22 + *
  23 + * 1. {@link BaseMapper} 为 MyBatis Plus 的基础接口,提供基础的 CRUD 能力
  24 + * 2. {@link MPJBaseMapper} 为 MyBatis Plus Join 的基础接口,提供连表 Join 能力
20 */ 25 */
21 -public interface BaseMapperX<T> extends BaseMapper<T> { 26 +public interface BaseMapperX<T> extends MPJBaseMapper<T> {
22 27
23 default PageResult<T> selectPage(PageParam pageParam, @Param("ew") Wrapper<T> queryWrapper) { 28 default PageResult<T> selectPage(PageParam pageParam, @Param("ew") Wrapper<T> queryWrapper) {
24 // MyBatis Plus 查询 29 // MyBatis Plus 查询
@@ -75,10 +80,16 @@ public interface BaseMapperX&lt;T&gt; extends BaseMapper&lt;T&gt; { @@ -75,10 +80,16 @@ public interface BaseMapperX&lt;T&gt; extends BaseMapper&lt;T&gt; {
75 } 80 }
76 81
77 default List<T> selectList(String field, Collection<?> values) { 82 default List<T> selectList(String field, Collection<?> values) {
  83 + if (CollUtil.isEmpty(values)) {
  84 + return CollUtil.newArrayList();
  85 + }
78 return selectList(new QueryWrapper<T>().in(field, values)); 86 return selectList(new QueryWrapper<T>().in(field, values));
79 } 87 }
80 88
81 default List<T> selectList(SFunction<T, ?> field, Collection<?> values) { 89 default List<T> selectList(SFunction<T, ?> field, Collection<?> values) {
  90 + if (CollUtil.isEmpty(values)) {
  91 + return CollUtil.newArrayList();
  92 + }
82 return selectList(new LambdaQueryWrapper<T>().in(field, values)); 93 return selectList(new LambdaQueryWrapper<T>().in(field, values));
83 } 94 }
84 95
yudao-framework/yudao-spring-boot-starter-web/src/main/java/cn/iocoder/yudao/framework/web/core/util/WebFrameworkUtils.java
1 package cn.iocoder.yudao.framework.web.core.util; 1 package cn.iocoder.yudao.framework.web.core.util;
2 2
3 import cn.hutool.core.util.NumberUtil; 3 import cn.hutool.core.util.NumberUtil;
4 -import cn.hutool.core.util.StrUtil;  
5 import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; 4 import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
6 import cn.iocoder.yudao.framework.common.pojo.CommonResult; 5 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
7 import cn.iocoder.yudao.framework.web.config.WebProperties; 6 import cn.iocoder.yudao.framework.web.config.WebProperties;
@@ -89,10 +88,10 @@ public class WebFrameworkUtils { @@ -89,10 +88,10 @@ public class WebFrameworkUtils {
89 return userType; 88 return userType;
90 } 89 }
91 // 2. 其次,基于 URL 前缀的约定 90 // 2. 其次,基于 URL 前缀的约定
92 - if (request.getRequestURI().startsWith(properties.getAdminApi().getPrefix())) { 91 + if (request.getServletPath().startsWith(properties.getAdminApi().getPrefix())) {
93 return UserTypeEnum.ADMIN.getValue(); 92 return UserTypeEnum.ADMIN.getValue();
94 } 93 }
95 - if (request.getRequestURI().startsWith(properties.getAppApi().getPrefix())) { 94 + if (request.getServletPath().startsWith(properties.getAppApi().getPrefix())) {
96 return UserTypeEnum.MEMBER.getValue(); 95 return UserTypeEnum.MEMBER.getValue();
97 } 96 }
98 return null; 97 return null;
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmActivityConvert.java
1 package cn.iocoder.yudao.module.bpm.convert.task; 1 package cn.iocoder.yudao.module.bpm.convert.task;
2 2
  3 +import cn.iocoder.yudao.framework.common.util.date.DateUtils;
3 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.activity.BpmActivityRespVO; 4 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.activity.BpmActivityRespVO;
4 import org.flowable.engine.history.HistoricActivityInstance; 5 import org.flowable.engine.history.HistoricActivityInstance;
5 import org.mapstruct.Mapper; 6 import org.mapstruct.Mapper;
@@ -14,7 +15,7 @@ import java.util.List; @@ -14,7 +15,7 @@ import java.util.List;
14 * 15 *
15 * @author 芋道源码 16 * @author 芋道源码
16 */ 17 */
17 -@Mapper 18 +@Mapper(uses = DateUtils.class)
18 public interface BpmActivityConvert { 19 public interface BpmActivityConvert {
19 20
20 BpmActivityConvert INSTANCE = Mappers.getMapper(BpmActivityConvert.class); 21 BpmActivityConvert INSTANCE = Mappers.getMapper(BpmActivityConvert.class);
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmProcessInstanceConvert.java
1 package cn.iocoder.yudao.module.bpm.convert.task; 1 package cn.iocoder.yudao.module.bpm.convert.task;
2 2
3 import cn.iocoder.yudao.framework.common.pojo.PageResult; 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.framework.common.util.date.DateUtils;
4 import cn.iocoder.yudao.framework.common.util.number.NumberUtils; 5 import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
5 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstancePageItemRespVO; 6 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstancePageItemRespVO;
6 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceRespVO; 7 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceRespVO;
@@ -28,7 +29,7 @@ import java.util.Map; @@ -28,7 +29,7 @@ import java.util.Map;
28 * 29 *
29 * @author 芋道源码 30 * @author 芋道源码
30 */ 31 */
31 -@Mapper 32 +@Mapper(uses = DateUtils.class)
32 public interface BpmProcessInstanceConvert { 33 public interface BpmProcessInstanceConvert {
33 34
34 BpmProcessInstanceConvert INSTANCE = Mappers.getMapper(BpmProcessInstanceConvert.class); 35 BpmProcessInstanceConvert INSTANCE = Mappers.getMapper(BpmProcessInstanceConvert.class);
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmTaskConvert.java
@@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.bpm.convert.task; @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.bpm.convert.task;
2 2
3 import cn.hutool.core.date.LocalDateTimeUtil; 3 import cn.hutool.core.date.LocalDateTimeUtil;
4 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; 4 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
  5 +import cn.iocoder.yudao.framework.common.util.date.DateUtils;
5 import cn.iocoder.yudao.framework.common.util.number.NumberUtils; 6 import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
6 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskDonePageItemRespVO; 7 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskDonePageItemRespVO;
7 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskRespVO; 8 import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskRespVO;
@@ -26,7 +27,7 @@ import java.util.Map; @@ -26,7 +27,7 @@ import java.util.Map;
26 * 27 *
27 * @author 芋道源码 28 * @author 芋道源码
28 */ 29 */
29 -@Mapper 30 +@Mapper(uses = DateUtils.class)
30 public interface BpmTaskConvert { 31 public interface BpmTaskConvert {
31 32
32 BpmTaskConvert INSTANCE = Mappers.getMapper(BpmTaskConvert.class); 33 BpmTaskConvert INSTANCE = Mappers.getMapper(BpmTaskConvert.class);
@@ -46,8 +47,6 @@ public interface BpmTaskConvert { @@ -46,8 +47,6 @@ public interface BpmTaskConvert {
46 } 47 }
47 48
48 @Mapping(source = "suspended", target = "suspensionState", qualifiedByName = "convertSuspendedToSuspensionState") 49 @Mapping(source = "suspended", target = "suspensionState", qualifiedByName = "convertSuspendedToSuspensionState")
49 - @Mapping(target = "claimTime", expression = "java(bean.getClaimTime()==null?null: LocalDateTime.ofInstant(bean.getClaimTime().toInstant(),ZoneId.systemDefault()))")  
50 - @Mapping(target = "createTime", expression = "java(bean.getCreateTime()==null?null:LocalDateTime.ofInstant(bean.getCreateTime().toInstant(),ZoneId.systemDefault()))")  
51 BpmTaskTodoPageItemRespVO convert1(Task bean); 50 BpmTaskTodoPageItemRespVO convert1(Task bean);
52 51
53 @Named("convertSuspendedToSuspensionState") 52 @Named("convertSuspendedToSuspensionState")
@@ -106,8 +105,6 @@ public interface BpmTaskConvert { @@ -106,8 +105,6 @@ public interface BpmTaskConvert {
106 } 105 }
107 106
108 @Mapping(source = "taskDefinitionKey", target = "definitionKey") 107 @Mapping(source = "taskDefinitionKey", target = "definitionKey")
109 - @Mapping(target = "createTime", expression = "java(bean.getCreateTime() == null ? null : LocalDateTime.ofInstant(bean.getCreateTime().toInstant(), ZoneId.systemDefault()))")  
110 - @Mapping(target = "endTime", expression = "java(bean.getEndTime() == null ? null : LocalDateTime.ofInstant(bean.getEndTime().toInstant(), ZoneId.systemDefault()))")  
111 BpmTaskRespVO convert3(HistoricTaskInstance bean); 108 BpmTaskRespVO convert3(HistoricTaskInstance bean);
112 109
113 BpmTaskRespVO.User convert3(AdminUserRespDTO bean); 110 BpmTaskRespVO.User convert3(AdminUserRespDTO bean);
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben/views/data.ts.vm
@@ -15,7 +15,7 @@ export const columns: BasicColumn[] = [ @@ -15,7 +15,7 @@ export const columns: BasicColumn[] = [
15 width: 180, 15 width: 180,
16 customRender: ({ text }) => { 16 customRender: ({ text }) => {
17 return useRender.renderDate(text) 17 return useRender.renderDate(text)
18 - } 18 + },
19 }, 19 },
20 #elseif("" != $column.dictType)## 数据字典 20 #elseif("" != $column.dictType)## 数据字典
21 { 21 {
@@ -24,13 +24,13 @@ export const columns: BasicColumn[] = [ @@ -24,13 +24,13 @@ export const columns: BasicColumn[] = [
24 width: 180, 24 width: 180,
25 customRender: ({ text }) => { 25 customRender: ({ text }) => {
26 return useRender.renderDict(text, DICT_TYPE.$dictType.toUpperCase()) 26 return useRender.renderDict(text, DICT_TYPE.$dictType.toUpperCase())
27 - } 27 + },
28 }, 28 },
29 #else 29 #else
30 { 30 {
31 title: '${comment}', 31 title: '${comment}',
32 dataIndex: '${javaField}', 32 dataIndex: '${javaField}',
33 - width: 160 33 + width: 160,
34 }, 34 },
35 #end 35 #end
36 #end 36 #end
@@ -53,15 +53,15 @@ export const searchFormSchema: FormSchema[] = [ @@ -53,15 +53,15 @@ export const searchFormSchema: FormSchema[] = [
53 component: 'Select', 53 component: 'Select',
54 componentProps: { 54 componentProps: {
55 #if ("" != $dictType)## 设置了 dictType 数据字典的情况 55 #if ("" != $dictType)## 设置了 dictType 数据字典的情况
56 - options: getDictOptions(DICT_TYPE.$dictType.toUpperCase()) 56 + options: getDictOptions(DICT_TYPE.$dictType.toUpperCase()),
57 #else## 未设置 dictType 数据字典的情况 57 #else## 未设置 dictType 数据字典的情况
58 - options: [] 58 + options: [],
59 #end 59 #end
60 }, 60 },
61 #elseif($column.htmlType == "datetime") 61 #elseif($column.htmlType == "datetime")
62 component: 'RangePicker', 62 component: 'RangePicker',
63 #end 63 #end
64 - colProps: { span: 8 } 64 + colProps: { span: 8 },
65 }, 65 },
66 #end 66 #end
67 #end 67 #end
@@ -72,7 +72,7 @@ export const createFormSchema: FormSchema[] = [ @@ -72,7 +72,7 @@ export const createFormSchema: FormSchema[] = [
72 label: '编号', 72 label: '编号',
73 field: 'id', 73 field: 'id',
74 show: false, 74 show: false,
75 - component: 'Input' 75 + component: 'Input',
76 }, 76 },
77 #foreach($column in $columns) 77 #foreach($column in $columns)
78 #if ($column.createOperation) 78 #if ($column.createOperation)
@@ -88,52 +88,52 @@ export const createFormSchema: FormSchema[] = [ @@ -88,52 +88,52 @@ export const createFormSchema: FormSchema[] = [
88 required: true, 88 required: true,
89 #end 89 #end
90 #if ($column.htmlType == "input") 90 #if ($column.htmlType == "input")
91 - component: 'Input' 91 + component: 'Input',
92 #elseif($column.htmlType == "imageUpload")## 图片上传 92 #elseif($column.htmlType == "imageUpload")## 图片上传
93 component: 'FileUpload', 93 component: 'FileUpload',
94 componentProps: { 94 componentProps: {
95 fileType: 'file', 95 fileType: 'file',
96 - maxCount: 1  
97 - } 96 + maxCount: 1,
  97 + },
98 #elseif($column.htmlType == "fileUpload")## 文件上传 98 #elseif($column.htmlType == "fileUpload")## 文件上传
99 component: 'FileUpload', 99 component: 'FileUpload',
100 componentProps: { 100 componentProps: {
101 fileType: 'image', 101 fileType: 'image',
102 - maxCount: 1  
103 - } 102 + maxCount: 1,
  103 + },
104 #elseif($column.htmlType == "editor")## 文本编辑器 104 #elseif($column.htmlType == "editor")## 文本编辑器
105 - component: 'Editor' 105 + component: 'Editor',
106 #elseif($column.htmlType == "select")## 下拉框 106 #elseif($column.htmlType == "select")## 下拉框
107 component: 'Select', 107 component: 'Select',
108 componentProps: { 108 componentProps: {
109 #if ("" != $dictType)## 有数据字典 109 #if ("" != $dictType)## 有数据字典
110 - options: getDictOptions(DICT_TYPE.$dictType.toUpperCase(), 'number') 110 + options: getDictOptions(DICT_TYPE.$dictType.toUpperCase(), 'number'),
111 #else##没数据字典 111 #else##没数据字典
112 - options:[] 112 + options:[],
113 #end 113 #end
114 - } 114 + },
115 #elseif($column.htmlType == "checkbox")## 多选框 115 #elseif($column.htmlType == "checkbox")## 多选框
116 component: 'Checkbox', 116 component: 'Checkbox',
117 componentProps: { 117 componentProps: {
118 #if ("" != $dictType)## 有数据字典 118 #if ("" != $dictType)## 有数据字典
119 - options: getDictOptions(DICT_TYPE.$dictType.toUpperCase(), 'number') 119 + options: getDictOptions(DICT_TYPE.$dictType.toUpperCase(), 'number'),
120 #else##没数据字典 120 #else##没数据字典
121 - options:[] 121 + options:[],
122 #end 122 #end
123 - } 123 + },
124 #elseif($column.htmlType == "radio")## 单选框 124 #elseif($column.htmlType == "radio")## 单选框
125 component: 'RadioButtonGroup', 125 component: 'RadioButtonGroup',
126 componentProps: { 126 componentProps: {
127 #if ("" != $dictType)## 有数据字典 127 #if ("" != $dictType)## 有数据字典
128 - options: getDictOptions(DICT_TYPE.$dictType.toUpperCase(), 'number') 128 + options: getDictOptions(DICT_TYPE.$dictType.toUpperCase(), 'number'),
129 #else##没数据字典 129 #else##没数据字典
130 - options:[] 130 + options:[],
131 #end 131 #end
132 - } 132 + },
133 #elseif($column.htmlType == "datetime")## 时间框 133 #elseif($column.htmlType == "datetime")## 时间框
134 - component: 'DatePicker' 134 + component: 'DatePicker',
135 #elseif($column.htmlType == "textarea")## 文本域 135 #elseif($column.htmlType == "textarea")## 文本域
136 - component: 'InputTextArea' 136 + component: 'InputTextArea',
137 #end 137 #end
138 }, 138 },
139 #end 139 #end
@@ -146,7 +146,7 @@ export const updateFormSchema: FormSchema[] = [ @@ -146,7 +146,7 @@ export const updateFormSchema: FormSchema[] = [
146 label: '编号', 146 label: '编号',
147 field: 'id', 147 field: 'id',
148 show: false, 148 show: false,
149 - component: 'Input' 149 + component: 'Input',
150 }, 150 },
151 #foreach($column in $columns) 151 #foreach($column in $columns)
152 #if ($column.updateOperation) 152 #if ($column.updateOperation)
@@ -162,44 +162,44 @@ export const updateFormSchema: FormSchema[] = [ @@ -162,44 +162,44 @@ export const updateFormSchema: FormSchema[] = [
162 required: true, 162 required: true,
163 #end 163 #end
164 #if ($column.htmlType == "input") 164 #if ($column.htmlType == "input")
165 - component: 'Input' 165 + component: 'Input',
166 #elseif($column.htmlType == "imageUpload")## 图片上传 166 #elseif($column.htmlType == "imageUpload")## 图片上传
167 - component: 'Upload' 167 + component: 'Upload',
168 #elseif($column.htmlType == "fileUpload")## 文件上传 168 #elseif($column.htmlType == "fileUpload")## 文件上传
169 - component: 'Upload' 169 + component: 'Upload',
170 #elseif($column.htmlType == "editor")## 文本编辑器 170 #elseif($column.htmlType == "editor")## 文本编辑器
171 - component: 'Editor' 171 + component: 'Editor',
172 #elseif($column.htmlType == "select")## 下拉框 172 #elseif($column.htmlType == "select")## 下拉框
173 component: 'Select', 173 component: 'Select',
174 componentProps: { 174 componentProps: {
175 #if ("" != $dictType)## 有数据字典 175 #if ("" != $dictType)## 有数据字典
176 - options: getDictOptions(DICT_TYPE.$dictType.toUpperCase(), 'number') 176 + options: getDictOptions(DICT_TYPE.$dictType.toUpperCase(), 'number'),
177 #else##没数据字典 177 #else##没数据字典
178 - options:[] 178 + options:[],
179 #end 179 #end
180 - } 180 + },
181 #elseif($column.htmlType == "checkbox")## 多选框 181 #elseif($column.htmlType == "checkbox")## 多选框
182 component: 'Checkbox', 182 component: 'Checkbox',
183 componentProps: { 183 componentProps: {
184 #if ("" != $dictType)## 有数据字典 184 #if ("" != $dictType)## 有数据字典
185 - options: getDictOptions(DICT_TYPE.$dictType.toUpperCase(), 'number') 185 + options: getDictOptions(DICT_TYPE.$dictType.toUpperCase(), 'number'),
186 #else##没数据字典 186 #else##没数据字典
187 - options:[] 187 + options:[],
188 #end 188 #end
189 - } 189 + },
190 #elseif($column.htmlType == "radio")## 单选框 190 #elseif($column.htmlType == "radio")## 单选框
191 component: 'RadioButtonGroup', 191 component: 'RadioButtonGroup',
192 componentProps: { 192 componentProps: {
193 #if ("" != $dictType)## 有数据字典 193 #if ("" != $dictType)## 有数据字典
194 - options: getDictOptions(DICT_TYPE.$dictType.toUpperCase(), 'number') 194 + options: getDictOptions(DICT_TYPE.$dictType.toUpperCase(), 'number'),
195 #else##没数据字典 195 #else##没数据字典
196 - options:[] 196 + options:[],
197 #end 197 #end
198 - } 198 + },
199 #elseif($column.htmlType == "datetime")## 时间框 199 #elseif($column.htmlType == "datetime")## 时间框
200 - component: 'DatePicker' 200 + component: 'DatePicker',
201 #elseif($column.htmlType == "textarea")## 文本域 201 #elseif($column.htmlType == "textarea")## 文本域
202 - component: 'InputTextArea' 202 + component: 'InputTextArea',
203 #end 203 #end
204 }, 204 },
205 #end 205 #end
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben/views/form.vue.vm
1 -<template>  
2 - <BasicModal v-bind="$attrs" @register="registerModal" :title="isUpdate ? t('action.edit') : t('action.create')" @ok="handleSubmit">  
3 - <BasicForm @register="registerForm" />  
4 - </BasicModal>  
5 -</template>  
6 <script lang="ts" setup> 1 <script lang="ts" setup>
7 import { ref, unref } from 'vue' 2 import { ref, unref } from 'vue'
  3 +import { createFormSchema, updateFormSchema } from './${classNameVar}.data'
8 import { useI18n } from '@/hooks/web/useI18n' 4 import { useI18n } from '@/hooks/web/useI18n'
9 import { useMessage } from '@/hooks/web/useMessage' 5 import { useMessage } from '@/hooks/web/useMessage'
10 import { BasicForm, useForm } from '@/components/Form' 6 import { BasicForm, useForm } from '@/components/Form'
11 import { BasicModal, useModalInner } from '@/components/Modal' 7 import { BasicModal, useModalInner } from '@/components/Modal'
12 -import { createFormSchema, updateFormSchema } from './${classNameVar}.data'  
13 import { create${simpleClassName}, get${simpleClassName}, update${simpleClassName} } from '@/api/${table.moduleName}/${classNameVar}' 8 import { create${simpleClassName}, get${simpleClassName}, update${simpleClassName} } from '@/api/${table.moduleName}/${classNameVar}'
14 9
15 defineOptions({ name: '${table.className}Modal' }) 10 defineOptions({ name: '${table.className}Modal' })
@@ -24,7 +19,7 @@ const [registerForm, { setFieldsValue, resetFields, resetSchema, validate }] = u @@ -24,7 +19,7 @@ const [registerForm, { setFieldsValue, resetFields, resetSchema, validate }] = u
24 baseColProps: { span: 24 }, 19 baseColProps: { span: 24 },
25 schemas: createFormSchema, 20 schemas: createFormSchema,
26 showActionButtonGroup: false, 21 showActionButtonGroup: false,
27 - actionColOptions: { span: 23 } 22 + actionColOptions: { span: 23 },
28 }) 23 })
29 24
30 const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => { 25 const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
@@ -55,3 +50,8 @@ async function handleSubmit() { @@ -55,3 +50,8 @@ async function handleSubmit() {
55 } 50 }
56 } 51 }
57 </script> 52 </script>
  53 +<template>
  54 + <BasicModal v-bind="$attrs" @register="registerModal" :title="isUpdate ? t('action.edit') : t('action.create')" @ok="handleSubmit">
  55 + <BasicForm @register="registerForm" />
  56 + </BasicModal>
  57 +</template>
58 \ No newline at end of file 58 \ No newline at end of file
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/vue3_vben/views/index.vue.vm
1 -<template>  
2 - <div>  
3 - <BasicTable @register="registerTable">  
4 - <template #toolbar>  
5 - <a-button type="primary" v-auth="['${permissionPrefix}:create']" :preIcon="IconEnum.ADD" @click="handleCreate">  
6 - {{ t('action.create') }}  
7 - </a-button>  
8 - <a-button type="warning" v-auth="['${permissionPrefix}:export']" :preIcon="IconEnum.EXPORT" @click="handleExport">  
9 - {{ t('action.export') }}  
10 - </a-button>  
11 - </template>  
12 - <template #bodyCell="{ column, record }">  
13 - <template v-if="column.key === 'action'">  
14 - <TableAction  
15 - :actions="[  
16 - { icon: IconEnum.EDIT, label: t('action.edit'), auth: '${permissionPrefix}:update', onClick: handleEdit.bind(null, record) },  
17 - {  
18 - icon: IconEnum.DELETE,  
19 - color: 'error',  
20 - label: t('action.delete'),  
21 - auth: '${permissionPrefix}:delete',  
22 - popConfirm: {  
23 - title: t('common.delMessage'),  
24 - placement: 'left',  
25 - confirm: handleDelete.bind(null, record)  
26 - }  
27 - }  
28 - ]"  
29 - />  
30 - </template>  
31 - </template>  
32 - </BasicTable>  
33 - <${simpleClassName}Modal @register="registerModal" @success="reload()" />  
34 - </div>  
35 -</template>  
36 <script lang="ts" setup> 1 <script lang="ts" setup>
  2 +import ${simpleClassName}Modal from './${simpleClassName}Modal.vue'
  3 +import { columns, searchFormSchema } from './${classNameVar}.data'
37 import { useI18n } from '@/hooks/web/useI18n' 4 import { useI18n } from '@/hooks/web/useI18n'
38 import { useMessage } from '@/hooks/web/useMessage' 5 import { useMessage } from '@/hooks/web/useMessage'
39 import { useModal } from '@/components/Modal' 6 import { useModal } from '@/components/Modal'
40 -import ${simpleClassName}Modal from './${simpleClassName}Modal.vue'  
41 import { IconEnum } from '@/enums/appEnum' 7 import { IconEnum } from '@/enums/appEnum'
42 import { BasicTable, useTable, TableAction } from '@/components/Table' 8 import { BasicTable, useTable, TableAction } from '@/components/Table'
43 import { delete${simpleClassName}, export${simpleClassName}, get${simpleClassName}Page } from '@/api/${table.moduleName}/${classNameVar}' 9 import { delete${simpleClassName}, export${simpleClassName}, get${simpleClassName}Page } from '@/api/${table.moduleName}/${classNameVar}'
44 -import { columns, searchFormSchema } from './${classNameVar}.data'  
45 10
46 defineOptions({ name: '${table.className}' }) 11 defineOptions({ name: '${table.className}' })
47 12
@@ -60,8 +25,8 @@ const [registerTable, { getForm, reload }] = useTable({ @@ -60,8 +25,8 @@ const [registerTable, { getForm, reload }] = useTable({
60 width: 140, 25 width: 140,
61 title: t('common.action'), 26 title: t('common.action'),
62 dataIndex: 'action', 27 dataIndex: 'action',
63 - fixed: 'right'  
64 - } 28 + fixed: 'right',
  29 + },
65 }) 30 })
66 31
67 function handleCreate() { 32 function handleCreate() {
@@ -80,7 +45,7 @@ async function handleExport() { @@ -80,7 +45,7 @@ async function handleExport() {
80 async onOk() { 45 async onOk() {
81 await export${simpleClassName}(getForm().getFieldsValue()) 46 await export${simpleClassName}(getForm().getFieldsValue())
82 createMessage.success(t('common.exportSuccessText')) 47 createMessage.success(t('common.exportSuccessText'))
83 - } 48 + },
84 }) 49 })
85 } 50 }
86 51
@@ -90,3 +55,38 @@ async function handleDelete(record: Recordable) { @@ -90,3 +55,38 @@ async function handleDelete(record: Recordable) {
90 reload() 55 reload()
91 } 56 }
92 </script> 57 </script>
  58 +<template>
  59 + <div>
  60 + <BasicTable @register="registerTable">
  61 + <template #toolbar>
  62 + <a-button type="primary" v-auth="['${permissionPrefix}:create']" :preIcon="IconEnum.ADD" @click="handleCreate">
  63 + {{ t('action.create') }}
  64 + </a-button>
  65 + <a-button type="warning" v-auth="['${permissionPrefix}:export']" :preIcon="IconEnum.EXPORT" @click="handleExport">
  66 + {{ t('action.export') }}
  67 + </a-button>
  68 + </template>
  69 + <template #bodyCell="{ column, record }">
  70 + <template v-if="column.key === 'action'">
  71 + <TableAction
  72 + :actions="[
  73 + { icon: IconEnum.EDIT, label: t('action.edit'), auth: '${permissionPrefix}:update', onClick: handleEdit.bind(null, record) },
  74 + {
  75 + icon: IconEnum.DELETE,
  76 + danger: true,
  77 + label: t('action.delete'),
  78 + auth: '${permissionPrefix}:delete',
  79 + popConfirm: {
  80 + title: t('common.delMessage'),
  81 + placement: 'left',
  82 + confirm: handleDelete.bind(null, record),
  83 + },
  84 + },
  85 + ]"
  86 + />
  87 + </template>
  88 + </template>
  89 + </BasicTable>
  90 + <${simpleClassName}Modal @register="registerModal" @success="reload()" />
  91 + </div>
  92 +</template>
93 \ No newline at end of file 93 \ No newline at end of file
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/dto/ProductSkuRespDTO.java
@@ -60,4 +60,14 @@ public class ProductSkuRespDTO { @@ -60,4 +60,14 @@ public class ProductSkuRespDTO {
60 */ 60 */
61 private Double volume; 61 private Double volume;
62 62
  63 + // TODO @puhui:这 2 字段,需要改下;firstBrokerageRecord、secondBrokerageRecord;和分佣保持一致;
  64 + /**
  65 + * 一级分销的佣金,单位:分
  66 + */
  67 + private Integer subCommissionFirstPrice;
  68 + /**
  69 + * 二级分销的佣金,单位:分
  70 + */
  71 + private Integer subCommissionSecondPrice;
  72 +
63 } 73 }
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/coupon/dto/CouponRespDTO.java
@@ -71,9 +71,9 @@ public class CouponRespDTO { @@ -71,9 +71,9 @@ public class CouponRespDTO {
71 */ 71 */
72 private Integer productScope; 72 private Integer productScope;
73 /** 73 /**
74 - * 商品 SPU 编号的数组 74 + * 商品范围编号的数组
75 */ 75 */
76 - private List<Long> productSpuIds; 76 + private List<Long> productScopeValues;
77 // ========== 使用规则 END ========== 77 // ========== 使用规则 END ==========
78 78
79 // ========== 使用效果 BEGIN ========== 79 // ========== 使用效果 BEGIN ==========
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/coupon/CouponBaseVO.java
@@ -67,8 +67,8 @@ public class CouponBaseVO { @@ -67,8 +67,8 @@ public class CouponBaseVO {
67 @InEnum(PromotionProductScopeEnum.class) 67 @InEnum(PromotionProductScopeEnum.class)
68 private Integer productScope; 68 private Integer productScope;
69 69
70 - @Schema(description = "商品 SPU 编号的数组", example = "1,3")  
71 - private List<Long> productSpuIds; 70 + @Schema(description = "商品范围编号的数组", example = "1,3")
  71 + private List<Long> productScopeValues;
72 // ========== 使用规则 END ========== 72 // ========== 使用规则 END ==========
73 73
74 // ========== 使用效果 BEGIN ========== 74 // ========== 使用效果 BEGIN ==========
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/coupon/vo/template/CouponTemplateBaseVO.java
@@ -54,8 +54,8 @@ public class CouponTemplateBaseVO { @@ -54,8 +54,8 @@ public class CouponTemplateBaseVO {
54 @InEnum(PromotionProductScopeEnum.class) 54 @InEnum(PromotionProductScopeEnum.class)
55 private Integer productScope; 55 private Integer productScope;
56 56
57 - @Schema(description = "商品 SPU 编号的数组", example = "1,3")  
58 - private List<Long> productSpuIds; 57 + @Schema(description = "商品范围编号的数组", example = "[1, 3]")
  58 + private List<Long> productScopeValues;
59 59
60 @Schema(description = "生效日期类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") 60 @Schema(description = "生效日期类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
61 @NotNull(message = "生效日期类型不能为空") 61 @NotNull(message = "生效日期类型不能为空")
@@ -95,11 +95,11 @@ public class CouponTemplateBaseVO { @@ -95,11 +95,11 @@ public class CouponTemplateBaseVO {
95 @Schema(description = "折扣上限", example = "100") // 单位:分,仅在 discountType 为 PERCENT 使用 95 @Schema(description = "折扣上限", example = "100") // 单位:分,仅在 discountType 为 PERCENT 使用
96 private Integer discountLimitPrice; 96 private Integer discountLimitPrice;
97 97
98 - @AssertTrue(message = "商品 SPU 编号的数组不能为空") 98 + @AssertTrue(message = "商品范围编号的数组不能为空")
99 @JsonIgnore 99 @JsonIgnore
100 - public boolean isProductSpuIdsValid() { 100 + public boolean isProductScopeValuesValid() {
101 return Objects.equals(productScope, PromotionProductScopeEnum.ALL.getScope()) // 全部范围时,可以为空 101 return Objects.equals(productScope, PromotionProductScopeEnum.ALL.getScope()) // 全部范围时,可以为空
102 - || CollUtil.isNotEmpty(productSpuIds); 102 + || CollUtil.isNotEmpty(productScopeValues);
103 } 103 }
104 104
105 @AssertTrue(message = "生效开始时间不能为空") 105 @AssertTrue(message = "生效开始时间不能为空")
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/AppCombinationRecordController.java
1 package cn.iocoder.yudao.module.promotion.controller.app.combination; 1 package cn.iocoder.yudao.module.promotion.controller.app.combination;
2 2
3 import cn.iocoder.yudao.framework.common.pojo.CommonResult; 3 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
4 -import cn.iocoder.yudao.framework.common.util.date.DateUtils; 4 +import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils;
5 import cn.iocoder.yudao.module.promotion.controller.app.combination.vo.record.AppCombinationRecordDetailRespVO; 5 import cn.iocoder.yudao.module.promotion.controller.app.combination.vo.record.AppCombinationRecordDetailRespVO;
6 import cn.iocoder.yudao.module.promotion.controller.app.combination.vo.record.AppCombinationRecordRespVO; 6 import cn.iocoder.yudao.module.promotion.controller.app.combination.vo.record.AppCombinationRecordRespVO;
7 import cn.iocoder.yudao.module.promotion.controller.app.combination.vo.record.AppCombinationRecordSummaryRespVO; 7 import cn.iocoder.yudao.module.promotion.controller.app.combination.vo.record.AppCombinationRecordSummaryRespVO;
@@ -16,8 +16,8 @@ import org.springframework.web.bind.annotation.RestController; @@ -16,8 +16,8 @@ import org.springframework.web.bind.annotation.RestController;
16 16
17 import javax.validation.constraints.Max; 17 import javax.validation.constraints.Max;
18 import java.time.Duration; 18 import java.time.Duration;
  19 +import java.time.LocalDateTime;
19 import java.util.ArrayList; 20 import java.util.ArrayList;
20 -import java.util.Date;  
21 import java.util.List; 21 import java.util.List;
22 22
23 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; 23 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@@ -58,7 +58,7 @@ public class AppCombinationRecordController { @@ -58,7 +58,7 @@ public class AppCombinationRecordController {
58 record.setId((long) i); 58 record.setId((long) i);
59 record.setNickname("用户" + i); 59 record.setNickname("用户" + i);
60 record.setAvatar("头像" + i); 60 record.setAvatar("头像" + i);
61 - record.setExpireTime(new Date()); 61 + record.setExpireTime(LocalDateTime.now());
62 record.setUserSize(10); 62 record.setUserSize(10);
63 record.setUserCount(i); 63 record.setUserCount(i);
64 record.setPicUrl("https://static.iocoder.cn/mall/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg"); 64 record.setPicUrl("https://static.iocoder.cn/mall/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg");
@@ -79,7 +79,7 @@ public class AppCombinationRecordController { @@ -79,7 +79,7 @@ public class AppCombinationRecordController {
79 headRecord.setId(1L); 79 headRecord.setId(1L);
80 headRecord.setNickname("用户" + 1); 80 headRecord.setNickname("用户" + 1);
81 headRecord.setAvatar("头像" + 1); 81 headRecord.setAvatar("头像" + 1);
82 - headRecord.setExpireTime(DateUtils.addTime(Duration.ofDays(1))); 82 + headRecord.setExpireTime(LocalDateTimeUtils.addTime(Duration.ofDays(1)));
83 headRecord.setUserSize(10); 83 headRecord.setUserSize(10);
84 headRecord.setUserCount(3); 84 headRecord.setUserCount(3);
85 headRecord.setStatus(1); 85 headRecord.setStatus(1);
@@ -94,7 +94,7 @@ public class AppCombinationRecordController { @@ -94,7 +94,7 @@ public class AppCombinationRecordController {
94 record.setId((long) i); 94 record.setId((long) i);
95 record.setNickname("用户" + i); 95 record.setNickname("用户" + i);
96 record.setAvatar("头像" + i); 96 record.setAvatar("头像" + i);
97 - record.setExpireTime(new Date()); 97 + record.setExpireTime(LocalDateTime.now());
98 record.setUserSize(10); 98 record.setUserSize(10);
99 record.setUserCount(i); 99 record.setUserCount(i);
100 record.setStatus(1); 100 record.setStatus(1);
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/combination/vo/record/AppCombinationRecordRespVO.java
@@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.promotion.controller.app.combination.vo.record; @@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.promotion.controller.app.combination.vo.record;
3 import io.swagger.v3.oas.annotations.media.Schema; 3 import io.swagger.v3.oas.annotations.media.Schema;
4 import lombok.Data; 4 import lombok.Data;
5 5
6 -import java.util.Date; 6 +import java.time.LocalDateTime;
7 7
8 @Schema(description = "用户 App - 拼团记录 Response VO") 8 @Schema(description = "用户 App - 拼团记录 Response VO")
9 @Data 9 @Data
@@ -22,7 +22,7 @@ public class AppCombinationRecordRespVO { @@ -22,7 +22,7 @@ public class AppCombinationRecordRespVO {
22 private String avatar; 22 private String avatar;
23 23
24 @Schema(description = "过期时间", requiredMode = Schema.RequiredMode.REQUIRED) 24 @Schema(description = "过期时间", requiredMode = Schema.RequiredMode.REQUIRED)
25 - private Date expireTime; 25 + private LocalDateTime expireTime;
26 26
27 @Schema(description = "可参团人数", requiredMode = Schema.RequiredMode.REQUIRED, example = "10") 27 @Schema(description = "可参团人数", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
28 private Integer userSize; 28 private Integer userSize;
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/coupon/vo/template/AppCouponTemplateRespVO.java
@@ -28,8 +28,8 @@ public class AppCouponTemplateRespVO { @@ -28,8 +28,8 @@ public class AppCouponTemplateRespVO {
28 // @InEnum(PromotionProductScopeEnum.class) 28 // @InEnum(PromotionProductScopeEnum.class)
29 // private Integer productScope; 29 // private Integer productScope;
30 // 30 //
31 -// @Schema(description = "商品 SPU 编号的数组", example = "1,3")  
32 -// private List<Long> productSpuIds; 31 +// @Schema(description = "商品范围编号的数组", example = "1,3")
  32 +// private List<Long> productScopeValues;
33 33
34 @Schema(description = "生效日期类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") 34 @Schema(description = "生效日期类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
35 private Integer validityType; 35 private Integer validityType;
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/coupon/CouponConvert.java
@@ -33,7 +33,7 @@ public interface CouponConvert { @@ -33,7 +33,7 @@ public interface CouponConvert {
33 .setTakeType(template.getTakeType()) 33 .setTakeType(template.getTakeType())
34 .setUsePrice(template.getUsePrice()) 34 .setUsePrice(template.getUsePrice())
35 .setProductScope(template.getProductScope()) 35 .setProductScope(template.getProductScope())
36 - .setProductSpuIds(template.getProductSpuIds()) 36 + .setProductScopeValues(template.getProductScopeValues())
37 .setDiscountType(template.getDiscountType()) 37 .setDiscountType(template.getDiscountType())
38 .setDiscountPercent(template.getDiscountPercent()) 38 .setDiscountPercent(template.getDiscountPercent())
39 .setDiscountPrice(template.getDiscountPrice()) 39 .setDiscountPrice(template.getDiscountPrice())
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/coupon/CouponDO.java
@@ -89,12 +89,12 @@ public class CouponDO extends BaseDO { @@ -89,12 +89,12 @@ public class CouponDO extends BaseDO {
89 */ 89 */
90 private Integer productScope; 90 private Integer productScope;
91 /** 91 /**
92 - * 商品 SPU 编号的数组 92 + * 商品范围编号的数组
93 * 93 *
94 - * 冗余 {@link CouponTemplateDO#getProductSpuIds()} 94 + * 冗余 {@link CouponTemplateDO#getProductScopeValues()}
95 */ 95 */
96 @TableField(typeHandler = LongListTypeHandler.class) 96 @TableField(typeHandler = LongListTypeHandler.class)
97 - private List<Long> productSpuIds; 97 + private List<Long> productScopeValues;
98 // ========== 使用规则 END ========== 98 // ========== 使用规则 END ==========
99 99
100 // ========== 使用效果 BEGIN ========== 100 // ========== 使用效果 BEGIN ==========
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/coupon/CouponTemplateDO.java
@@ -85,10 +85,10 @@ public class CouponTemplateDO extends BaseDO { @@ -85,10 +85,10 @@ public class CouponTemplateDO extends BaseDO {
85 */ 85 */
86 private Integer productScope; 86 private Integer productScope;
87 /** 87 /**
88 - * 商品 SPU 编号的数组 88 + * 商品范围编号的数组
89 */ 89 */
90 @TableField(typeHandler = LongListTypeHandler.class) 90 @TableField(typeHandler = LongListTypeHandler.class)
91 - private List<Long> productSpuIds; 91 + private List<Long> productScopeValues;
92 /** 92 /**
93 * 生效日期类型 93 * 生效日期类型
94 * 94 *
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/coupon/CouponServiceImpl.java
@@ -93,6 +93,7 @@ public class CouponServiceImpl implements CouponService { @@ -93,6 +93,7 @@ public class CouponServiceImpl implements CouponService {
93 public void useCoupon(Long id, Long userId, Long orderId) { 93 public void useCoupon(Long id, Long userId, Long orderId) {
94 // 校验优惠劵 94 // 校验优惠劵
95 validCoupon(id, userId); 95 validCoupon(id, userId);
  96 +
96 // 更新状态 97 // 更新状态
97 int updateCount = couponMapper.updateByIdAndStatus(id, CouponStatusEnum.UNUSED.getStatus(), 98 int updateCount = couponMapper.updateByIdAndStatus(id, CouponStatusEnum.UNUSED.getStatus(),
98 new CouponDO().setStatus(CouponStatusEnum.USED.getStatus()) 99 new CouponDO().setStatus(CouponStatusEnum.USED.getStatus())
@@ -115,12 +116,14 @@ public class CouponServiceImpl implements CouponService { @@ -115,12 +116,14 @@ public class CouponServiceImpl implements CouponService {
115 } 116 }
116 117
117 // 退还 118 // 退还
118 - // TODO @疯狂:最好 where status,避免可能存在的并发问题  
119 Integer status = LocalDateTimeUtils.beforeNow(coupon.getValidEndTime()) 119 Integer status = LocalDateTimeUtils.beforeNow(coupon.getValidEndTime())
120 - // 退还时可能已经过期了  
121 - ? CouponStatusEnum.EXPIRE.getStatus() 120 + ? CouponStatusEnum.EXPIRE.getStatus() // 退还时可能已经过期了
122 : CouponStatusEnum.UNUSED.getStatus(); 121 : CouponStatusEnum.UNUSED.getStatus();
123 - couponMapper.updateById(new CouponDO().setId(id).setStatus(status)); 122 + int updateCount = couponMapper.updateByIdAndStatus(id, CouponStatusEnum.UNUSED.getStatus(),
  123 + new CouponDO().setStatus(status));
  124 + if (updateCount == 0) {
  125 + throw exception(COUPON_STATUS_NOT_USED);
  126 + }
124 127
125 // TODO 增加优惠券变动记录? 128 // TODO 增加优惠券变动记录?
126 } 129 }
yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/ErrorCodeConstants.java
@@ -11,7 +11,7 @@ import cn.iocoder.yudao.framework.common.exception.ErrorCode; @@ -11,7 +11,7 @@ import cn.iocoder.yudao.framework.common.exception.ErrorCode;
11 */ 11 */
12 public interface ErrorCodeConstants { 12 public interface ErrorCodeConstants {
13 13
14 - // ========== Order 模块 1011000000 ========== 14 + // ========== Order 模块 1011000000 ==========
15 ErrorCode ORDER_CREATE_SKU_NOT_FOUND = new ErrorCode(1011000001, "商品 SKU 不存在"); 15 ErrorCode ORDER_CREATE_SKU_NOT_FOUND = new ErrorCode(1011000001, "商品 SKU 不存在");
16 ErrorCode ORDER_CREATE_SPU_NOT_SALE = new ErrorCode(1011000002, "商品 SPU 不可售卖"); 16 ErrorCode ORDER_CREATE_SPU_NOT_SALE = new ErrorCode(1011000002, "商品 SPU 不可售卖");
17 ErrorCode ORDER_CREATE_SKU_STOCK_NOT_ENOUGH = new ErrorCode(1011000004, "商品 SKU 库存不足"); 17 ErrorCode ORDER_CREATE_SKU_STOCK_NOT_ENOUGH = new ErrorCode(1011000004, "商品 SKU 库存不足");
@@ -35,7 +35,7 @@ public interface ErrorCodeConstants { @@ -35,7 +35,7 @@ public interface ErrorCodeConstants {
35 ErrorCode ORDER_DELIVERY_FAIL_DELIVERY_TYPE_NOT_EXPRESS = new ErrorCode(1011000024, "交易订单发货失败,发货类型不是快递"); 35 ErrorCode ORDER_DELIVERY_FAIL_DELIVERY_TYPE_NOT_EXPRESS = new ErrorCode(1011000024, "交易订单发货失败,发货类型不是快递");
36 ErrorCode ORDER_CANCEL_FAIL_STATUS_NOT_UNPAID = new ErrorCode(1011000025, "交易订单取消失败,订单不是【待支付】状态"); 36 ErrorCode ORDER_CANCEL_FAIL_STATUS_NOT_UNPAID = new ErrorCode(1011000025, "交易订单取消失败,订单不是【待支付】状态");
37 37
38 - // ========== After Sale 模块 1011000100 ========== 38 + // ========== After Sale 模块 1011000100 ==========
39 ErrorCode AFTER_SALE_NOT_FOUND = new ErrorCode(1011000100, "售后单不存在"); 39 ErrorCode AFTER_SALE_NOT_FOUND = new ErrorCode(1011000100, "售后单不存在");
40 ErrorCode AFTER_SALE_CREATE_FAIL_REFUND_PRICE_ERROR = new ErrorCode(1011000101, "申请退款金额错误"); 40 ErrorCode AFTER_SALE_CREATE_FAIL_REFUND_PRICE_ERROR = new ErrorCode(1011000101, "申请退款金额错误");
41 ErrorCode AFTER_SALE_CREATE_FAIL_ORDER_STATUS_CANCELED = new ErrorCode(1011000102, "订单已关闭,无法申请售后"); 41 ErrorCode AFTER_SALE_CREATE_FAIL_ORDER_STATUS_CANCELED = new ErrorCode(1011000102, "订单已关闭,无法申请售后");
@@ -50,7 +50,7 @@ public interface ErrorCodeConstants { @@ -50,7 +50,7 @@ public interface ErrorCodeConstants {
50 ErrorCode AFTER_SALE_CANCEL_FAIL_STATUS_NOT_APPLY_OR_AGREE_OR_BUYER_DELIVERY = 50 ErrorCode AFTER_SALE_CANCEL_FAIL_STATUS_NOT_APPLY_OR_AGREE_OR_BUYER_DELIVERY =
51 new ErrorCode(1011000111, "取消售后单失败,售后单状态不是【待审核】或【卖家同意】或【商家待收货】"); 51 new ErrorCode(1011000111, "取消售后单失败,售后单状态不是【待审核】或【卖家同意】或【商家待收货】");
52 52
53 - // ========== Cart 模块 1011002000 ========== 53 + // ========== Cart 模块 1011002000 ==========
54 ErrorCode CARD_ITEM_NOT_FOUND = new ErrorCode(1011002000, "购物车项不存在"); 54 ErrorCode CARD_ITEM_NOT_FOUND = new ErrorCode(1011002000, "购物车项不存在");
55 55
56 // ========== Price 相关 1011003000 ============ 56 // ========== Price 相关 1011003000 ============
@@ -58,7 +58,7 @@ public interface ErrorCodeConstants { @@ -58,7 +58,7 @@ public interface ErrorCodeConstants {
58 ErrorCode PRICE_CALCULATE_DELIVERY_PRICE_USER_ADDR_IS_EMPTY = new ErrorCode(1011003001, "计算快递运费异常,收件人地址编号为空"); 58 ErrorCode PRICE_CALCULATE_DELIVERY_PRICE_USER_ADDR_IS_EMPTY = new ErrorCode(1011003001, "计算快递运费异常,收件人地址编号为空");
59 ErrorCode PRICE_CALCULATE_DELIVERY_PRICE_TEMPLATE_NOT_FOUND = new ErrorCode(1011003002, "计算快递运费异常,找不到对应的运费模板"); 59 ErrorCode PRICE_CALCULATE_DELIVERY_PRICE_TEMPLATE_NOT_FOUND = new ErrorCode(1011003002, "计算快递运费异常,找不到对应的运费模板");
60 60
61 - // ========== 物流 Express 模块 1011004000 ========== 61 + // ========== 物流 Express 模块 1011004000 ==========
62 ErrorCode EXPRESS_NOT_EXISTS = new ErrorCode(1011004000, "快递公司不存在"); 62 ErrorCode EXPRESS_NOT_EXISTS = new ErrorCode(1011004000, "快递公司不存在");
63 ErrorCode EXPRESS_CODE_DUPLICATE = new ErrorCode(1011004001, "已经存在该编码的快递公司"); 63 ErrorCode EXPRESS_CODE_DUPLICATE = new ErrorCode(1011004001, "已经存在该编码的快递公司");
64 ErrorCode EXPRESS_CLIENT_NOT_PROVIDE = new ErrorCode(1011004002, "需要接入快递服务商,比如【快递100】"); 64 ErrorCode EXPRESS_CLIENT_NOT_PROVIDE = new ErrorCode(1011004002, "需要接入快递服务商,比如【快递100】");
@@ -67,11 +67,15 @@ public interface ErrorCodeConstants { @@ -67,11 +67,15 @@ public interface ErrorCodeConstants {
67 ErrorCode EXPRESS_API_QUERY_ERROR = new ErrorCode(1011004101, "快递查询接口异常"); 67 ErrorCode EXPRESS_API_QUERY_ERROR = new ErrorCode(1011004101, "快递查询接口异常");
68 ErrorCode EXPRESS_API_QUERY_FAILED = new ErrorCode(1011004102, "快递查询返回失败,原因:{}"); 68 ErrorCode EXPRESS_API_QUERY_FAILED = new ErrorCode(1011004102, "快递查询返回失败,原因:{}");
69 69
70 - // ========== 物流 Template 模块 1011005000 ========== 70 + // ========== 物流 Template 模块 1011005000 ==========
71 ErrorCode EXPRESS_TEMPLATE_NAME_DUPLICATE = new ErrorCode(1011005000, "已经存在该运费模板名"); 71 ErrorCode EXPRESS_TEMPLATE_NAME_DUPLICATE = new ErrorCode(1011005000, "已经存在该运费模板名");
72 ErrorCode EXPRESS_TEMPLATE_NOT_EXISTS = new ErrorCode(1011005001, "运费模板不存在"); 72 ErrorCode EXPRESS_TEMPLATE_NOT_EXISTS = new ErrorCode(1011005001, "运费模板不存在");
73 73
74 - // ========== 物流 PICK_UP 模块 1011006000 ========== 74 + // ========== 物流 PICK_UP 模块 1011006000 ==========
75 ErrorCode PICK_UP_STORE_NOT_EXISTS = new ErrorCode(1011006000, "自提门店不存在"); 75 ErrorCode PICK_UP_STORE_NOT_EXISTS = new ErrorCode(1011006000, "自提门店不存在");
76 76
  77 +
  78 + // ========== 分销用户 模块 1011007000 ==========
  79 + ErrorCode BROKERAGE_USER_NOT_EXISTS = new ErrorCode(1011007000, "分销用户不存在");
  80 +
77 } 81 }
yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/brokerage/BrokerageBindModeEnum.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.enums.brokerage;
  2 +
  3 +import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
  4 +import lombok.AllArgsConstructor;
  5 +import lombok.Getter;
  6 +
  7 +import java.util.Arrays;
  8 +
  9 +/**
  10 + * 分销关系绑定模式枚举
  11 + *
  12 + * @author owen
  13 + */
  14 +@AllArgsConstructor
  15 +@Getter
  16 +public enum BrokerageBindModeEnum implements IntArrayValuable {
  17 +
  18 + // TODO @疯狂:要不从 1 开始?
  19 + /**
  20 + * 只要用户没有推广人,随时都可以绑定分销关系
  21 + */
  22 + ANYTIME(0, "没有推广人"),
  23 + /**
  24 + * 仅新用户注册时才能绑定推广关系
  25 + */
  26 + REGISTER(1, "新用户"),
  27 + // TODO @疯狂:要加个 2,每次扫码都覆盖
  28 + ;
  29 +
  30 + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(BrokerageBindModeEnum::getMode).toArray();
  31 +
  32 + /**
  33 + * 模式
  34 + */
  35 + private final Integer mode;
  36 + /**
  37 + * 名字
  38 + */
  39 + private final String name;
  40 +
  41 + @Override
  42 + public int[] array() {
  43 + return ARRAYS;
  44 + }
  45 +
  46 +}
yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/brokerage/BrokerageEnabledConditionEnum.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.enums.brokerage;
  2 +
  3 +import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
  4 +import lombok.AllArgsConstructor;
  5 +import lombok.Getter;
  6 +
  7 +import java.util.Arrays;
  8 +
  9 +/**
  10 + * 分佣模式枚举
  11 + *
  12 + * @author owen
  13 + */
  14 +@AllArgsConstructor
  15 +@Getter
  16 +public enum BrokerageEnabledConditionEnum implements IntArrayValuable {
  17 +
  18 + // TODO @疯狂:这个也从 1 开始哇
  19 + /**
  20 + * 所有用户都可以分销
  21 + */
  22 + ALL(0, "人人分销"),
  23 + /**
  24 + * 仅可后台手动设置推广员
  25 + */
  26 + ADMIN(1, "指定分销"),
  27 + ;
  28 +
  29 + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(BrokerageEnabledConditionEnum::getCondition).toArray();
  30 +
  31 + /**
  32 + * 模式
  33 + */
  34 + private final Integer condition;
  35 + /**
  36 + * 名字
  37 + */
  38 + private final String name;
  39 +
  40 + @Override
  41 + public int[] array() {
  42 + return ARRAYS;
  43 + }
  44 +
  45 +}
yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/brokerage/BrokerageRecordBizTypeEnum.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.enums.brokerage;
  2 +
  3 +import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
  4 +import lombok.AllArgsConstructor;
  5 +import lombok.Getter;
  6 +
  7 +import java.util.Arrays;
  8 +
  9 +/**
  10 + * 佣金记录业务类型枚举
  11 + *
  12 + * @author owen
  13 + */
  14 +@AllArgsConstructor
  15 +@Getter
  16 +public enum BrokerageRecordBizTypeEnum implements IntArrayValuable {
  17 +
  18 + // TODO @疯狂:这个也从 1 开始哇
  19 + ORDER(0, "获得推广佣金", "获得推广佣金 {}", true),
  20 + WITHDRAW(1, "提现申请", "提现申请扣除佣金 {}", false),
  21 + ;
  22 +
  23 + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(BrokerageRecordBizTypeEnum::getType).toArray();
  24 +
  25 + /**
  26 + * 类型
  27 + */
  28 + private final Integer type;
  29 + /**
  30 + * 标题
  31 + */
  32 + private final String title;
  33 + /**
  34 + * 描述
  35 + */
  36 + private final String description;
  37 + /**
  38 + * 是否为增加佣金
  39 + */
  40 + private final boolean add;
  41 +
  42 + @Override
  43 + public int[] array() {
  44 + return ARRAYS;
  45 + }
  46 +
  47 +}
yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/brokerage/BrokerageRecordStatusEnum.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.enums.brokerage;
  2 +
  3 +import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
  4 +import lombok.AllArgsConstructor;
  5 +import lombok.Getter;
  6 +
  7 +import java.util.Arrays;
  8 +
  9 +/**
  10 + * 佣金记录状态枚举
  11 + *
  12 + * @author owen
  13 + */
  14 +@AllArgsConstructor
  15 +@Getter
  16 +public enum BrokerageRecordStatusEnum implements IntArrayValuable {
  17 +
  18 + WAIT_SETTLEMENT(0, "待结算"),
  19 + SETTLEMENT(1, "已结算"),
  20 + CANCEL(2, "已取消"),
  21 + ;
  22 +
  23 + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(BrokerageRecordStatusEnum::getStatus).toArray();
  24 +
  25 + /**
  26 + * 状态
  27 + */
  28 + private final Integer status;
  29 + /**
  30 + * 名字
  31 + */
  32 + private final String name;
  33 +
  34 + @Override
  35 + public int[] array() {
  36 + return ARRAYS;
  37 + }
  38 +
  39 +}
yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/brokerage/BrokerageWithdrawStatusEnum.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.enums.brokerage;
  2 +
  3 +import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
  4 +import lombok.AllArgsConstructor;
  5 +import lombok.Getter;
  6 +
  7 +import java.util.Arrays;
  8 +
  9 +/**
  10 + * 佣金提现状态枚举
  11 + *
  12 + * @author owen
  13 + */
  14 +@AllArgsConstructor
  15 +@Getter
  16 +public enum BrokerageWithdrawStatusEnum implements IntArrayValuable {
  17 +
  18 + AUDITING(0, "审核中"),
  19 + AUDIT_SUCCESS(10, "审核通过"),
  20 + WITHDRAW_SUCCESS(11, "提现成功"),
  21 + AUDIT_FAIL(20, "审核不通过"),
  22 + WITHDRAW_FAIL(21, "提现失败"),
  23 + ;
  24 +
  25 + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(BrokerageWithdrawStatusEnum::getStatus).toArray();
  26 +
  27 + /**
  28 + * 状态
  29 + */
  30 + private final Integer status;
  31 + /**
  32 + * 名字
  33 + */
  34 + private final String name;
  35 +
  36 + @Override
  37 + public int[] array() {
  38 + return ARRAYS;
  39 + }
  40 +
  41 +}
yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/brokerage/BrokerageWithdrawTypeEnum.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.enums.brokerage;
  2 +
  3 +import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
  4 +import lombok.AllArgsConstructor;
  5 +import lombok.Getter;
  6 +
  7 +import java.util.Arrays;
  8 +
  9 +/**
  10 + * 佣金提现类型枚举
  11 + *
  12 + * @author owen
  13 + */
  14 +@AllArgsConstructor
  15 +@Getter
  16 +public enum BrokerageWithdrawTypeEnum implements IntArrayValuable {
  17 +
  18 + WALLET(1, "钱包"),
  19 + BANK(2, "银行卡"),
  20 + WECHAT(3, "微信"),
  21 + ALIPAY(4, "支付宝"),
  22 + ;
  23 +
  24 + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(BrokerageWithdrawTypeEnum::getType).toArray();
  25 +
  26 + /**
  27 + * 类型
  28 + */
  29 + private final Integer type;
  30 + /**
  31 + * 名字
  32 + */
  33 + private final String name;
  34 +
  35 + @Override
  36 + public int[] array() {
  37 + return ARRAYS;
  38 + }
  39 +
  40 +}
yudao-module-mall/yudao-module-trade-biz/pom.xml
@@ -56,6 +56,10 @@ @@ -56,6 +56,10 @@
56 </dependency> 56 </dependency>
57 <dependency> 57 <dependency>
58 <groupId>cn.iocoder.boot</groupId> 58 <groupId>cn.iocoder.boot</groupId>
  59 + <artifactId>yudao-spring-boot-starter-biz-tenant</artifactId>
  60 + </dependency>
  61 + <dependency>
  62 + <groupId>cn.iocoder.boot</groupId>
59 <artifactId>yudao-spring-boot-starter-biz-ip</artifactId> 63 <artifactId>yudao-spring-boot-starter-biz-ip</artifactId>
60 </dependency> 64 </dependency>
61 65
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/record/TradeBrokerageRecordController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.controller.admin.brokerage.record;
  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.trade.controller.admin.brokerage.record.vo.TradeBrokerageRecordPageReqVO;
  6 +import cn.iocoder.yudao.module.trade.controller.admin.brokerage.record.vo.TradeBrokerageRecordRespVO;
  7 +import cn.iocoder.yudao.module.trade.convert.brokerage.record.TradeBrokerageRecordConvert;
  8 +import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.record.TradeBrokerageRecordDO;
  9 +import cn.iocoder.yudao.module.trade.service.brokerage.record.TradeBrokerageRecordService;
  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.GetMapping;
  16 +import org.springframework.web.bind.annotation.RequestMapping;
  17 +import org.springframework.web.bind.annotation.RequestParam;
  18 +import org.springframework.web.bind.annotation.RestController;
  19 +
  20 +import javax.annotation.Resource;
  21 +import javax.validation.Valid;
  22 +
  23 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  24 +
  25 +@Tag(name = "管理后台 - 佣金记录")
  26 +@RestController
  27 +@RequestMapping("/trade/brokerage-record")
  28 +@Validated
  29 +public class TradeBrokerageRecordController {
  30 +
  31 + @Resource
  32 + private TradeBrokerageRecordService tradeBrokerageRecordService;
  33 +
  34 + @GetMapping("/get")
  35 + @Operation(summary = "获得佣金记录")
  36 + @Parameter(name = "id", description = "编号", required = true, example = "1024")
  37 + @PreAuthorize("@ss.hasPermission('trade:brokerage-record:query')")
  38 + public CommonResult<TradeBrokerageRecordRespVO> getBrokerageRecord(@RequestParam("id") Integer id) {
  39 + TradeBrokerageRecordDO tradeBrokerageRecord = tradeBrokerageRecordService.getBrokerageRecord(id);
  40 + return success(TradeBrokerageRecordConvert.INSTANCE.convert(tradeBrokerageRecord));
  41 + }
  42 +
  43 + @GetMapping("/page")
  44 + @Operation(summary = "获得佣金记录分页")
  45 + @PreAuthorize("@ss.hasPermission('trade:brokerage-record:query')")
  46 + public CommonResult<PageResult<TradeBrokerageRecordRespVO>> getBrokerageRecordPage(@Valid TradeBrokerageRecordPageReqVO pageVO) {
  47 + PageResult<TradeBrokerageRecordDO> pageResult = tradeBrokerageRecordService.getBrokerageRecordPage(pageVO);
  48 + return success(TradeBrokerageRecordConvert.INSTANCE.convertPage(pageResult));
  49 + }
  50 +
  51 +}
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/record/vo/TradeBrokerageRecordBaseVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.controller.admin.brokerage.record.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +import org.springframework.format.annotation.DateTimeFormat;
  6 +
  7 +import javax.validation.constraints.NotEmpty;
  8 +import javax.validation.constraints.NotNull;
  9 +import java.time.LocalDateTime;
  10 +
  11 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  12 +
  13 +/**
  14 + * 佣金记录 Base VO,提供给添加、修改、详细的子 VO 使用
  15 + * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
  16 + */
  17 +@Data
  18 +public class TradeBrokerageRecordBaseVO {
  19 +
  20 + @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "25973")
  21 + @NotNull(message = "用户编号不能为空")
  22 + private Long userId;
  23 +
  24 + @Schema(description = "业务编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "23353")
  25 + @NotEmpty(message = "业务编号不能为空")
  26 + private String bizId;
  27 +
  28 + @Schema(description = "业务类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  29 + @NotNull(message = "业务类型不能为空")
  30 + private Integer bizType;
  31 +
  32 + @Schema(description = "标题", requiredMode = Schema.RequiredMode.REQUIRED)
  33 + @NotEmpty(message = "标题不能为空")
  34 + private String title;
  35 +
  36 + @Schema(description = "金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "28731")
  37 + @NotNull(message = "金额不能为空")
  38 + private Integer price;
  39 +
  40 + @Schema(description = "当前总佣金", requiredMode = Schema.RequiredMode.REQUIRED, example = "13226")
  41 + @NotNull(message = "当前总佣金不能为空")
  42 + private Integer totalPrice;
  43 +
  44 + @Schema(description = "说明", requiredMode = Schema.RequiredMode.REQUIRED, example = "你说的对")
  45 + @NotNull(message = "说明不能为空")
  46 + private String description;
  47 +
  48 + @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  49 + @NotNull(message = "状态不能为空")
  50 + private Integer status;
  51 +
  52 + @Schema(description = "冻结时间(天)", requiredMode = Schema.RequiredMode.REQUIRED)
  53 + @NotNull(message = "冻结时间(天)不能为空")
  54 + private Integer frozenDays;
  55 +
  56 + @Schema(description = "解冻时间")
  57 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  58 + private LocalDateTime unfreezeTime;
  59 +
  60 +}
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/record/vo/TradeBrokerageRecordPageReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.controller.admin.brokerage.record.vo;
  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 TradeBrokerageRecordPageReqVO extends PageParam {
  19 +
  20 + @Schema(description = "用户编号", example = "25973")
  21 + private Long userId;
  22 +
  23 + @Schema(description = "业务类型", example = "1")
  24 + private Integer bizType;
  25 +
  26 + @Schema(description = "状态", example = "1")
  27 + private Integer status;
  28 +
  29 + @Schema(description = "创建时间")
  30 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  31 + private LocalDateTime[] createTime;
  32 +
  33 +}
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/record/vo/TradeBrokerageRecordRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.controller.admin.brokerage.record.vo;
  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 TradeBrokerageRecordRespVO extends TradeBrokerageRecordBaseVO {
  15 +
  16 + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "28896")
  17 + private Integer id;
  18 +
  19 + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
  20 + private LocalDateTime createTime;
  21 +
  22 +}
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/user/TradeBrokerageUserController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.controller.admin.brokerage.user;
  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.trade.controller.admin.brokerage.user.vo.*;
  6 +import cn.iocoder.yudao.module.trade.convert.brokerage.user.TradeBrokerageUserConvert;
  7 +import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.user.TradeBrokerageUserDO;
  8 +import cn.iocoder.yudao.module.trade.service.brokerage.user.TradeBrokerageUserService;
  9 +import io.swagger.v3.oas.annotations.Operation;
  10 +import io.swagger.v3.oas.annotations.Parameter;
  11 +import io.swagger.v3.oas.annotations.tags.Tag;
  12 +import org.springframework.security.access.prepost.PreAuthorize;
  13 +import org.springframework.validation.annotation.Validated;
  14 +import org.springframework.web.bind.annotation.*;
  15 +
  16 +import javax.annotation.Resource;
  17 +import javax.validation.Valid;
  18 +
  19 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  20 +
  21 +@Tag(name = "管理后台 - 分销用户")
  22 +@RestController
  23 +@RequestMapping("/trade/brokerage-user")
  24 +@Validated
  25 +public class TradeBrokerageUserController {
  26 +
  27 + @Resource
  28 + private TradeBrokerageUserService brokerageUserService;
  29 +
  30 + @PutMapping("/update-brokerage-user")
  31 + @Operation(summary = "修改推广员")
  32 + @PreAuthorize("@ss.hasPermission('trade:brokerage-user:update-brokerage-user')")
  33 + public CommonResult<Boolean> updateBrokerageUser(@Valid @RequestBody TradeBrokerageUserUpdateBrokerageUserReqVO updateReqVO) {
  34 + brokerageUserService.updateBrokerageUserId(updateReqVO.getId(), updateReqVO.getBrokerageUserId());
  35 + return success(true);
  36 + }
  37 +
  38 + @PutMapping("/clear-brokerage-user")
  39 + @Operation(summary = "清除推广员")
  40 + @PreAuthorize("@ss.hasPermission('trade:brokerage-user:clear-brokerage-user')")
  41 + public CommonResult<Boolean> clearBrokerageUser(@Valid @RequestBody TradeBrokerageUserClearBrokerageUserReqVO updateReqVO) {
  42 + brokerageUserService.updateBrokerageUserId(updateReqVO.getId(), null);
  43 + return success(true);
  44 + }
  45 +
  46 + @PutMapping("/update-brokerage-enable")
  47 + @Operation(summary = "修改推广资格")
  48 + @PreAuthorize("@ss.hasPermission('trade:brokerage-user:update-brokerage-enable')")
  49 + public CommonResult<Boolean> updateBrokerageEnabled(@Valid @RequestBody TradeBrokerageUserUpdateBrokerageEnabledReqVO updateReqVO) {
  50 + brokerageUserService.updateBrokerageEnabled(updateReqVO.getId(), updateReqVO.getBrokerageEnabled());
  51 + return success(true);
  52 + }
  53 +
  54 + @GetMapping("/get")
  55 + @Operation(summary = "获得分销用户")
  56 + @Parameter(name = "id", description = "编号", required = true, example = "1024")
  57 + @PreAuthorize("@ss.hasPermission('trade:brokerage-user:query')")
  58 + public CommonResult<TradeBrokerageUserRespVO> getBrokerageUser(@RequestParam("id") Long id) {
  59 + TradeBrokerageUserDO brokerageUser = brokerageUserService.getBrokerageUser(id);
  60 + return success(TradeBrokerageUserConvert.INSTANCE.convert(brokerageUser));
  61 + }
  62 +
  63 + @GetMapping("/page")
  64 + @Operation(summary = "获得分销用户分页")
  65 + @PreAuthorize("@ss.hasPermission('trade:brokerage-user:query')")
  66 + public CommonResult<PageResult<TradeBrokerageUserRespVO>> getBrokerageUserPage(@Valid TradeBrokerageUserPageReqVO pageVO) {
  67 + PageResult<TradeBrokerageUserDO> pageResult = brokerageUserService.getBrokerageUserPage(pageVO);
  68 + return success(TradeBrokerageUserConvert.INSTANCE.convertPage(pageResult));
  69 + }
  70 +
  71 +}
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/user/vo/TradeBrokerageUserBaseVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.controller.admin.brokerage.user.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +import org.springframework.format.annotation.DateTimeFormat;
  6 +
  7 +import javax.validation.constraints.NotNull;
  8 +import java.time.LocalDateTime;
  9 +
  10 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  11 +
  12 +/**
  13 + * 分销用户 Base VO,提供给添加、修改、详细的子 VO 使用
  14 + * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
  15 + */
  16 +@Data
  17 +public class TradeBrokerageUserBaseVO {
  18 +
  19 + @Schema(description = "推广员编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "4587")
  20 + @NotNull(message = "推广员编号不能为空")
  21 + private Long brokerageUserId;
  22 +
  23 + @Schema(description = "推广员绑定时间")
  24 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  25 + private LocalDateTime brokerageBindTime;
  26 +
  27 + @Schema(description = "推广资格", requiredMode = Schema.RequiredMode.REQUIRED)
  28 + @NotNull(message = "推广资格不能为空")
  29 + private Boolean brokerageEnabled;
  30 +
  31 + @Schema(description = "成为分销员时间")
  32 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  33 + private LocalDateTime brokerageTime;
  34 +
  35 + @Schema(description = "可用佣金", requiredMode = Schema.RequiredMode.REQUIRED, example = "11089")
  36 + @NotNull(message = "可用佣金不能为空")
  37 + private Integer brokeragePrice;
  38 +
  39 + @Schema(description = "冻结佣金", requiredMode = Schema.RequiredMode.REQUIRED, example = "30916")
  40 + @NotNull(message = "冻结佣金不能为空")
  41 + private Integer frozenBrokeragePrice;
  42 +
  43 +}
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/user/vo/TradeBrokerageUserClearBrokerageUserReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.controller.admin.brokerage.user.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +import lombok.ToString;
  6 +
  7 +import javax.validation.constraints.NotNull;
  8 +
  9 +@Schema(description = "管理后台 - 分销用户 - 清除推广员 Request VO")
  10 +@Data
  11 +@ToString(callSuper = true)
  12 +public class TradeBrokerageUserClearBrokerageUserReqVO {
  13 +
  14 + @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "20019")
  15 + @NotNull(message = "用户编号不能为空")
  16 + private Long id;
  17 +
  18 +}
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/user/vo/TradeBrokerageUserPageReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.controller.admin.brokerage.user.vo;
  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 TradeBrokerageUserPageReqVO extends PageParam {
  19 +
  20 + @Schema(description = "推广员编号", example = "4587")
  21 + private Long brokerageUserId;
  22 +
  23 + @Schema(description = "推广资格")
  24 + private Boolean brokerageEnabled;
  25 +
  26 + @Schema(description = "创建时间")
  27 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  28 + private LocalDateTime[] createTime;
  29 +
  30 +}
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/user/vo/TradeBrokerageUserRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.controller.admin.brokerage.user.vo;
  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 TradeBrokerageUserRespVO extends TradeBrokerageUserBaseVO {
  15 +
  16 + @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "20019")
  17 + private Long id;
  18 +
  19 + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
  20 + private LocalDateTime createTime;
  21 +
  22 +}
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/user/vo/TradeBrokerageUserUpdateBrokerageEnabledReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.controller.admin.brokerage.user.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +import lombok.ToString;
  6 +
  7 +import javax.validation.constraints.NotNull;
  8 +
  9 +@Schema(description = "管理后台 - 分销用户 - 修改推广员 Request VO")
  10 +@Data
  11 +@ToString(callSuper = true)
  12 +public class TradeBrokerageUserUpdateBrokerageEnabledReqVO {
  13 +
  14 + @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "20019")
  15 + @NotNull(message = "用户编号不能为空")
  16 + private Long id;
  17 +
  18 + // TODO @疯狂:是不是这个字段,可以改成 enabled
  19 +
  20 + @Schema(description = "推广资格", requiredMode = Schema.RequiredMode.REQUIRED)
  21 + @NotNull(message = "推广资格不能为空")
  22 + private Boolean brokerageEnabled;
  23 +
  24 +}
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/user/vo/TradeBrokerageUserUpdateBrokerageUserReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.controller.admin.brokerage.user.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +import lombok.ToString;
  6 +
  7 +import javax.validation.constraints.NotNull;
  8 +
  9 +@Schema(description = "管理后台 - 分销用户 - 修改推广员 Request VO")
  10 +@Data
  11 +@ToString(callSuper = true)
  12 +public class TradeBrokerageUserUpdateBrokerageUserReqVO {
  13 +
  14 + @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "20019")
  15 + @NotNull(message = "用户编号不能为空")
  16 + private Long id;
  17 +
  18 + @Schema(description = "推广员编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "4587")
  19 + @NotNull(message = "推广员编号不能为空")
  20 + private Long brokerageUserId;
  21 +
  22 +}
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/config/TradeConfigController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.controller.admin.config;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.module.trade.controller.admin.config.vo.TradeConfigRespVO;
  5 +import cn.iocoder.yudao.module.trade.controller.admin.config.vo.TradeConfigSaveReqVO;
  6 +import cn.iocoder.yudao.module.trade.convert.config.TradeConfigConvert;
  7 +import cn.iocoder.yudao.module.trade.dal.dataobject.config.TradeConfigDO;
  8 +import cn.iocoder.yudao.module.trade.service.config.TradeConfigService;
  9 +import io.swagger.v3.oas.annotations.Operation;
  10 +import io.swagger.v3.oas.annotations.tags.Tag;
  11 +import org.springframework.security.access.prepost.PreAuthorize;
  12 +import org.springframework.validation.annotation.Validated;
  13 +import org.springframework.web.bind.annotation.*;
  14 +
  15 +import javax.annotation.Resource;
  16 +import javax.validation.Valid;
  17 +
  18 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  19 +
  20 +@Tag(name = "管理后台 - 交易中心配置")
  21 +@RestController
  22 +@RequestMapping("/trade/config")
  23 +@Validated
  24 +public class TradeConfigController {
  25 +
  26 + @Resource
  27 + private TradeConfigService tradeConfigService;
  28 +
  29 + @PutMapping("/save")
  30 + @Operation(summary = "更新交易中心配置")
  31 + @PreAuthorize("@ss.hasPermission('trade:config:save')")
  32 + public CommonResult<Boolean> updateConfig(@Valid @RequestBody TradeConfigSaveReqVO updateReqVO) {
  33 + tradeConfigService.saveTradeConfig(updateReqVO);
  34 + return success(true);
  35 + }
  36 +
  37 + @GetMapping("/get")
  38 + @Operation(summary = "获得交易中心配置")
  39 + @PreAuthorize("@ss.hasPermission('trade:config:query')")
  40 + public CommonResult<TradeConfigRespVO> getConfig() {
  41 + TradeConfigDO config = tradeConfigService.getTradeConfig();
  42 + return success(TradeConfigConvert.INSTANCE.convert(config));
  43 + }
  44 +
  45 +}
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/config/vo/TradeConfigBaseVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.controller.admin.config.vo;
  2 +
  3 +import cn.iocoder.yudao.framework.common.validation.InEnum;
  4 +import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageBindModeEnum;
  5 +import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageEnabledConditionEnum;
  6 +import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageWithdrawTypeEnum;
  7 +import io.swagger.v3.oas.annotations.media.Schema;
  8 +import lombok.Data;
  9 +import org.hibernate.validator.constraints.Range;
  10 +
  11 +import javax.validation.constraints.NotEmpty;
  12 +import javax.validation.constraints.NotNull;
  13 +import javax.validation.constraints.PositiveOrZero;
  14 +import java.util.List;
  15 +
  16 +/**
  17 + * 交易中心配置 Base VO,提供给添加、修改、详细的子 VO 使用
  18 + * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
  19 + */
  20 +@Data
  21 +public class TradeConfigBaseVO {
  22 +
  23 + // ========== 分销相关 ==========
  24 +
  25 + @Schema(description = "是否启用分佣", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
  26 + @NotNull(message = "是否启用分佣不能为空")
  27 + private Boolean brokerageEnabled;
  28 +
  29 + @Schema(description = "分佣模式", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
  30 + @NotNull(message = "分佣模式不能为空")
  31 + @InEnum(value = BrokerageEnabledConditionEnum.class, message = "分佣模式必须是 {value}")
  32 + private Integer brokerageEnabledCondition;
  33 +
  34 + @Schema(description = "分销关系绑定模式", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
  35 + @NotNull(message = "分销关系绑定模式不能为空")
  36 + @InEnum(value = BrokerageBindModeEnum.class, message = "分销关系绑定模式必须是 {value}")
  37 + private Integer brokerageBindMode;
  38 +
  39 + @Schema(description = "分销海报图地址数组", requiredMode = Schema.RequiredMode.REQUIRED, example = "[https://www.iocoder.cn/yudao.jpg]")
  40 + private List<String> brokeragePostUrls;
  41 +
  42 + @Schema(description = "一级返佣比例", requiredMode = Schema.RequiredMode.REQUIRED, example = "5")
  43 + @NotNull(message = "一级返佣比例不能为空")
  44 + @Range(min = 0, max = 100, message = "一级返佣比例必须在 0 - 100 之间")
  45 + private Integer brokerageFirstPercent;
  46 +
  47 + @Schema(description = "二级返佣比例", requiredMode = Schema.RequiredMode.REQUIRED, example = "5")
  48 + @NotNull(message = "二级返佣比例不能为空")
  49 + @Range(min = 0, max = 100, message = "二级返佣比例必须在 0 - 100 之间")
  50 + private Integer brokerageSecondPercent;
  51 +
  52 + @Schema(description = "用户提现最低金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "1000")
  53 + @NotNull(message = "用户提现最低金额不能为空")
  54 + @PositiveOrZero(message = "用户提现最低金额不能是负数")
  55 + private Integer brokerageWithdrawMinPrice;
  56 +
  57 + // TODO @疯狂:要不要做成字典?按道理都可以体现对哇?感觉是全局的配置哈;
  58 + @Schema(description = "提现银行", requiredMode = Schema.RequiredMode.REQUIRED, example = "[0, 1]")
  59 + @NotEmpty(message = "提现银行不能为空")
  60 + private List<Integer> brokerageBankNames;
  61 +
  62 + @Schema(description = "佣金冻结时间(天)", requiredMode = Schema.RequiredMode.REQUIRED, example = "7")
  63 + @NotNull(message = "佣金冻结时间(天)不能为空")
  64 + @PositiveOrZero(message = "佣金冻结时间不能是负数")
  65 + private Integer brokerageFrozenDays;
  66 +
  67 + @Schema(description = "提现方式", requiredMode = Schema.RequiredMode.REQUIRED, example = "[0, 1]")
  68 + @NotNull(message = "提现方式不能为空")
  69 + @InEnum(value = BrokerageWithdrawTypeEnum.class, message = "提现方式必须是 {value}")
  70 + private List<Integer> brokerageWithdrawType;
  71 +
  72 +}
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/config/vo/TradeConfigRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.controller.admin.config.vo;
  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 = "管理后台 - 交易中心配置 Response VO")
  9 +@Data
  10 +@EqualsAndHashCode(callSuper = true)
  11 +@ToString(callSuper = true)
  12 +public class TradeConfigRespVO extends TradeConfigBaseVO {
  13 +
  14 + @Schema(description = "自增主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  15 + private Long id;
  16 +
  17 +}
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/config/vo/TradeConfigSaveReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.controller.admin.config.vo;
  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 TradeConfigSaveReqVO extends TradeConfigBaseVO {
  13 +
  14 +}
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/AppBrokerageRecordController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.controller.app.brokerage;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  5 +import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated;
  6 +import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.record.AppBrokerageRecordPageReqVO;
  7 +import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.record.AppBrokerageRecordRespVO;
  8 +import io.swagger.v3.oas.annotations.Operation;
  9 +import io.swagger.v3.oas.annotations.tags.Tag;
  10 +import lombok.extern.slf4j.Slf4j;
  11 +import org.springframework.validation.annotation.Validated;
  12 +import org.springframework.web.bind.annotation.GetMapping;
  13 +import org.springframework.web.bind.annotation.RequestMapping;
  14 +import org.springframework.web.bind.annotation.RestController;
  15 +
  16 +import javax.validation.Valid;
  17 +import java.time.LocalDateTime;
  18 +
  19 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  20 +import static java.util.Arrays.asList;
  21 +
  22 +@Tag(name = "用户 APP - 分销用户")
  23 +@RestController
  24 +@RequestMapping("/trade/brokerage-record")
  25 +@Validated
  26 +@Slf4j
  27 +public class AppBrokerageRecordController {
  28 +
  29 + // TODO 芋艿:临时 mock =>
  30 + @GetMapping("/page")
  31 + @Operation(summary = "获得分销记录分页")
  32 + @PreAuthenticated
  33 + public CommonResult<PageResult<AppBrokerageRecordRespVO>> getBrokerageRecordPage(@Valid AppBrokerageRecordPageReqVO pageReqVO) {
  34 + AppBrokerageRecordRespVO vo1 = new AppBrokerageRecordRespVO()
  35 + .setId(1L).setPrice(10).setTitle("收到钱").setCreateTime(LocalDateTime.now())
  36 + .setFinishTime(LocalDateTime.now());
  37 + AppBrokerageRecordRespVO vo2 = new AppBrokerageRecordRespVO()
  38 + .setId(2L).setPrice(-20).setTitle("提现钱").setCreateTime(LocalDateTime.now())
  39 + .setFinishTime(LocalDateTime.now());
  40 + return success(new PageResult<>(asList(vo1, vo2), 10L));
  41 + }
  42 +
  43 +}
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/AppBrokerageUserController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.controller.app.brokerage;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  5 +import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated;
  6 +import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user.*;
  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 +import lombok.extern.slf4j.Slf4j;
  11 +import org.springframework.format.annotation.DateTimeFormat;
  12 +import org.springframework.validation.annotation.Validated;
  13 +import org.springframework.web.bind.annotation.GetMapping;
  14 +import org.springframework.web.bind.annotation.RequestMapping;
  15 +import org.springframework.web.bind.annotation.RequestParam;
  16 +import org.springframework.web.bind.annotation.RestController;
  17 +
  18 +import java.time.LocalDateTime;
  19 +
  20 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  21 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  22 +import static java.util.Arrays.asList;
  23 +
  24 +@Tag(name = "用户 APP - 分销用户")
  25 +@RestController
  26 +@RequestMapping("/trade/brokerage-user")
  27 +@Validated
  28 +@Slf4j
  29 +public class AppBrokerageUserController {
  30 +
  31 + // TODO 芋艿:临时 mock =>
  32 + @GetMapping("/get")
  33 + @Operation(summary = "获得个人分销信息")
  34 + @PreAuthenticated
  35 + public CommonResult<AppBrokerageUserRespVO> getBrokerageUser() {
  36 + AppBrokerageUserRespVO respVO = new AppBrokerageUserRespVO()
  37 + .setBrokeragePrice(2000)
  38 + .setFrozenBrokeragePrice(3000);
  39 + return success(respVO);
  40 + }
  41 +
  42 + // TODO 芋艿:临时 mock =>
  43 + @GetMapping("/get-summary")
  44 + @Operation(summary = "获得个人分销统计")
  45 + @PreAuthenticated
  46 + public CommonResult<AppBrokerageUserMySummaryRespVO> getBrokerageUserSummary() {
  47 + AppBrokerageUserMySummaryRespVO respVO = new AppBrokerageUserMySummaryRespVO()
  48 + .setYesterdayBrokeragePrice(1)
  49 + .setBrokeragePrice(2)
  50 + .setFrozenBrokeragePrice(3)
  51 + .setWithdrawBrokeragePrice(4)
  52 + .setFirstBrokerageUserCount(166)
  53 + .setSecondBrokerageUserCount(233);
  54 + return success(respVO);
  55 + }
  56 +
  57 + // TODO 芋艿:临时 mock =>
  58 + @GetMapping("/rank-page-by-user-count")
  59 + @Operation(summary = "获得分销用户排行分页(基于用户量)")
  60 + @PreAuthenticated
  61 + public CommonResult<PageResult<AppBrokerageUserRankByUserCountRespVO>> getBrokerageUserRankPageByUserCount(AppBrokerageUserRankPageReqVO pageReqVO) {
  62 + AppBrokerageUserRankByUserCountRespVO vo1 = new AppBrokerageUserRankByUserCountRespVO()
  63 + .setId(1L).setNickname("芋1**艿").setAvatar("http://www.iocoder.cn/images/common/wechat_mp_2017_07_31_bak.jpg")
  64 + .setBrokerageUserCount(10);
  65 + AppBrokerageUserRankByUserCountRespVO vo2 = new AppBrokerageUserRankByUserCountRespVO()
  66 + .setId(2L).setNickname("芋2**艿").setAvatar("http://www.iocoder.cn/images/common/wechat_mp_2017_07_31_bak.jpg")
  67 + .setBrokerageUserCount(6);
  68 + AppBrokerageUserRankByUserCountRespVO vo3 = new AppBrokerageUserRankByUserCountRespVO()
  69 + .setId(3L).setNickname("芋3**艿").setAvatar("http://www.iocoder.cn/images/common/wechat_mp_2017_07_31_bak.jpg")
  70 + .setBrokerageUserCount(4);
  71 + AppBrokerageUserRankByUserCountRespVO vo4 = new AppBrokerageUserRankByUserCountRespVO()
  72 + .setId(3L).setNickname("芋3**艿").setAvatar("http://www.iocoder.cn/images/common/wechat_mp_2017_07_31_bak.jpg")
  73 + .setBrokerageUserCount(4);
  74 + return success(new PageResult<>(asList(vo1, vo2, vo3, vo4), 10L));
  75 + }
  76 +
  77 + // TODO 芋艿:临时 mock =>
  78 + @GetMapping("/rank-page-by-price")
  79 + @Operation(summary = "获得分销用户排行分页(基于佣金)")
  80 + @PreAuthenticated
  81 + public CommonResult<PageResult<AppBrokerageUserRankByPriceRespVO>> getBrokerageUserChildSummaryPageByPrice(AppBrokerageUserRankPageReqVO pageReqVO) {
  82 + AppBrokerageUserRankByPriceRespVO vo1 = new AppBrokerageUserRankByPriceRespVO()
  83 + .setId(1L).setNickname("芋1**艿").setAvatar("http://www.iocoder.cn/images/common/wechat_mp_2017_07_31_bak.jpg")
  84 + .setBrokeragePrice(10);
  85 + AppBrokerageUserRankByPriceRespVO vo2 = new AppBrokerageUserRankByPriceRespVO()
  86 + .setId(2L).setNickname("芋2**艿").setAvatar("http://www.iocoder.cn/images/common/wechat_mp_2017_07_31_bak.jpg")
  87 + .setBrokeragePrice(6);
  88 + AppBrokerageUserRankByPriceRespVO vo3 = new AppBrokerageUserRankByPriceRespVO()
  89 + .setId(3L).setNickname("芋3**艿").setAvatar("http://www.iocoder.cn/images/common/wechat_mp_2017_07_31_bak.jpg")
  90 + .setBrokeragePrice(4);
  91 + AppBrokerageUserRankByPriceRespVO vo4 = new AppBrokerageUserRankByPriceRespVO()
  92 + .setId(3L).setNickname("芋3**艿").setAvatar("http://www.iocoder.cn/images/common/wechat_mp_2017_07_31_bak.jpg")
  93 + .setBrokeragePrice(4);
  94 + return success(new PageResult<>(asList(vo1, vo2, vo3, vo4), 10L));
  95 + }
  96 +
  97 + // TODO 芋艿:临时 mock =>
  98 + @GetMapping("/child-summary-page")
  99 + @Operation(summary = "获得下级分销统计分页")
  100 + @PreAuthenticated
  101 + public CommonResult<PageResult<AppBrokerageUserChildSummaryRespVO>> getBrokerageUserChildSummaryPage(
  102 + AppBrokerageUserChildSummaryPageReqVO pageReqVO) {
  103 + AppBrokerageUserChildSummaryRespVO vo1 = new AppBrokerageUserChildSummaryRespVO()
  104 + .setId(1L).setNickname("芋1**艿").setAvatar("http://www.iocoder.cn/images/common/wechat_mp_2017_07_31_bak.jpg")
  105 + .setBrokeragePrice(10).setBrokeragePrice(20).setBrokerageOrderCount(30)
  106 + .setBrokerageTime(LocalDateTime.now());
  107 + AppBrokerageUserChildSummaryRespVO vo2 = new AppBrokerageUserChildSummaryRespVO()
  108 + .setId(1L).setNickname("芋2**艿").setAvatar("http://www.iocoder.cn/images/common/wechat_mp_2017_07_31_bak.jpg")
  109 + .setBrokeragePrice(20).setBrokeragePrice(30).setBrokerageOrderCount(40)
  110 + .setBrokerageTime(LocalDateTime.now());
  111 + return success(new PageResult<>(asList(vo1, vo2), 10L));
  112 + }
  113 +
  114 + // TODO 芋艿:临时 mock =>
  115 + @GetMapping("/get-rank-by-price")
  116 + @Operation(summary = "获得分销用户排行(基于佣金)")
  117 + @Parameter(name = "times", description = "时间段", required = true)
  118 + public CommonResult<Integer> getBrokerageUserRankByPrice(
  119 + @RequestParam("times") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) LocalDateTime[] times) {
  120 + return success(1);
  121 + }
  122 +
  123 +}
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/AppBrokerageWithdrawController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.controller.app.brokerage;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  5 +import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated;
  6 +import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.withdraw.AppBrokerageWithdrawCreateReqVO;
  7 +import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.withdraw.AppBrokerageWithdrawRespVO;
  8 +import io.swagger.v3.oas.annotations.Operation;
  9 +import io.swagger.v3.oas.annotations.tags.Tag;
  10 +import lombok.extern.slf4j.Slf4j;
  11 +import org.springframework.validation.annotation.Validated;
  12 +import org.springframework.web.bind.annotation.*;
  13 +
  14 +import javax.validation.Valid;
  15 +import java.time.LocalDateTime;
  16 +
  17 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  18 +import static java.util.Arrays.asList;
  19 +
  20 +@Tag(name = "用户 APP - 分销提现")
  21 +@RestController
  22 +@RequestMapping("/trade/brokerage-withdraw")
  23 +@Validated
  24 +@Slf4j
  25 +public class AppBrokerageWithdrawController {
  26 +
  27 + // TODO 芋艿:临时 mock =>
  28 + @GetMapping("/page")
  29 + @Operation(summary = "获得分销提现分页")
  30 + @PreAuthenticated
  31 + public CommonResult<PageResult<AppBrokerageWithdrawRespVO>> getBrokerageWithdrawPage() {
  32 + AppBrokerageWithdrawRespVO vo1 = new AppBrokerageWithdrawRespVO()
  33 + .setId(1L).setStatus(10).setPrice(10).setStatusName("审批通过").setCreateTime(LocalDateTime.now());
  34 + AppBrokerageWithdrawRespVO vo2 = new AppBrokerageWithdrawRespVO()
  35 + .setId(2L).setStatus(0).setPrice(20).setStatusName("审批中").setCreateTime(LocalDateTime.now());
  36 + return success(new PageResult<>(asList(vo1, vo2), 10L));
  37 + }
  38 +
  39 + // TODO 芋艿:临时 mock =>
  40 + @PostMapping("/create")
  41 + @Operation(summary = "创建分销提现")
  42 + @PreAuthenticated
  43 + public CommonResult<Long> createBrokerageWithdraw(@RequestBody @Valid AppBrokerageWithdrawCreateReqVO createReqVO) {
  44 + return success(1L);
  45 + }
  46 +
  47 +}
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/record/AppBrokerageRecordPageReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.record;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  4 +import io.swagger.v3.oas.annotations.media.Schema;
  5 +import lombok.Data;
  6 +
  7 +@Schema(description = "应用 App - 分销记录分页 Request VO")
  8 +@Data
  9 +public class AppBrokerageRecordPageReqVO extends PageParam {
  10 +
  11 + // TODO @疯狂:要加下枚举校验
  12 +
  13 + @Schema(description = "业务类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  14 + private Integer bizType;
  15 +
  16 + @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  17 + private Integer status;
  18 +
  19 +}
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/record/AppBrokerageRecordRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.record;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +import java.time.LocalDateTime;
  7 +
  8 +@Schema(description = "用户 App - 分销记录 Response VO")
  9 +@Data
  10 +public class AppBrokerageRecordRespVO {
  11 +
  12 + @Schema(description = "记录编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
  13 + private Long id;
  14 +
  15 + @Schema(description = "分销标题", requiredMode = Schema.RequiredMode.REQUIRED, example = "用户下单")
  16 + private String title;
  17 +
  18 + @Schema(description = "分销金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "1000")
  19 + private Integer price;
  20 +
  21 + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
  22 + private LocalDateTime createTime;
  23 +
  24 + @Schema(description = "完成时间", requiredMode = Schema.RequiredMode.REQUIRED)
  25 + private LocalDateTime finishTime;
  26 +
  27 +}
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/user/AppBrokerageUserChildSummaryPageReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  4 +import cn.iocoder.yudao.framework.common.pojo.SortingField;
  5 +import io.swagger.v3.oas.annotations.media.Schema;
  6 +import lombok.Data;
  7 +
  8 +@Schema(description = "用户 App - 下级分销统计分页 Request VO")
  9 +@Data
  10 +public class AppBrokerageUserChildSummaryPageReqVO extends PageParam {
  11 +
  12 + public static final String SORT_FIELD_USER_COUNT = "userCount";
  13 + public static final String SORT_FIELD_ORDER_COUNT = "orderCount";
  14 + public static final String SORT_FIELD_PRICE = "price";
  15 +
  16 + @Schema(description = "用户昵称", example = "李") // 模糊匹配
  17 + private String nickname;
  18 +
  19 + @Schema(description = "排序字段", example = "userCount")
  20 + private SortingField sortingField;
  21 +
  22 + @Schema(description = "下级的级别", example = "1") // 1 - 直接下级;2 - 间接下级
  23 + private Integer level;
  24 +
  25 +}
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/user/AppBrokerageUserChildSummaryRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +import java.time.LocalDateTime;
  7 +
  8 +@Schema(description = "用户 App - 下级分销统计 Response VO")
  9 +@Data
  10 +public class AppBrokerageUserChildSummaryRespVO {
  11 +
  12 + @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
  13 + private Long id;
  14 +
  15 + @Schema(description = "用户昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "小王")
  16 + private String nickname;
  17 +
  18 + @Schema(description = "用户头像", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/xxx.jpg")
  19 + private String avatar;
  20 +
  21 + @Schema(description = "佣金金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
  22 + private Integer brokeragePrice;
  23 +
  24 + @Schema(description = "分销订单数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "20")
  25 + private Integer brokerageOrderCount;
  26 +
  27 + @Schema(description = "分销用户数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "30")
  28 + private Integer brokerageUserCount;
  29 +
  30 + @Schema(description = "成为分销员时间", requiredMode = Schema.RequiredMode.REQUIRED)
  31 + private LocalDateTime brokerageTime;
  32 +
  33 +}
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/user/AppBrokerageUserMySummaryRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +@Schema(description = "用户 App - 个人分销统计 Response VO")
  7 +@Data
  8 +public class AppBrokerageUserMySummaryRespVO {
  9 +
  10 + @Schema(description = "昨天的佣金,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
  11 + private Integer yesterdayBrokeragePrice;
  12 +
  13 + @Schema(description = "提现的佣金,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  14 + private Integer withdrawBrokeragePrice;
  15 +
  16 + @Schema(description = "可用的佣金,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "2408")
  17 + private Integer brokeragePrice;
  18 +
  19 + @Schema(description = "冻结的佣金,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "234")
  20 + private Integer frozenBrokeragePrice;
  21 +
  22 + @Schema(description = "分销用户数量(一级)", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
  23 + private Integer firstBrokerageUserCount;
  24 +
  25 + @Schema(description = "分销用户数量(二级)", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
  26 + private Integer secondBrokerageUserCount;
  27 +
  28 +}
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/user/AppBrokerageUserRankByPriceRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +@Schema(description = "用户 App - 分销排行用户(基于用户量) Response VO")
  7 +@Data
  8 +public class AppBrokerageUserRankByPriceRespVO {
  9 +
  10 + @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
  11 + private Long id;
  12 +
  13 + @Schema(description = "用户昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "小王")
  14 + private String nickname;
  15 +
  16 + @Schema(description = "用户头像", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/xxx.jpg")
  17 + private String avatar;
  18 +
  19 + @Schema(description = "佣金金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
  20 + private Integer brokeragePrice;
  21 +
  22 +}
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/user/AppBrokerageUserRankByUserCountRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +@Schema(description = "用户 App - 分销排行用户(基于用户量) Response VO")
  7 +@Data
  8 +public class AppBrokerageUserRankByUserCountRespVO {
  9 +
  10 + @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
  11 + private Long id;
  12 +
  13 + @Schema(description = "用户昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "小王")
  14 + private String nickname;
  15 +
  16 + @Schema(description = "用户头像", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn/xxx.jpg")
  17 + private String avatar;
  18 +
  19 + @Schema(description = "邀请用户数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
  20 + private Integer brokerageUserCount;
  21 +
  22 +}
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/user/AppBrokerageUserRankPageReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user;
  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 org.springframework.format.annotation.DateTimeFormat;
  7 +
  8 +import javax.validation.constraints.NotEmpty;
  9 +import java.time.LocalDateTime;
  10 +
  11 +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
  12 +
  13 +@Schema(description = "应用 App - 分销用户排行 Request VO")
  14 +@Data
  15 +public class AppBrokerageUserRankPageReqVO extends PageParam {
  16 +
  17 + @Schema(description = "开始 + 结束时间", requiredMode = Schema.RequiredMode.REQUIRED)
  18 + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
  19 + @NotEmpty(message = "时间不能为空")
  20 + private LocalDateTime[] times;
  21 +
  22 +}
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/user/AppBrokerageUserRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.user;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +@Schema(description = "用户 App - 分销用户信息 Response VO")
  7 +@Data
  8 +public class AppBrokerageUserRespVO {
  9 +
  10 + @Schema(description = "可用的佣金,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "2408")
  11 + private Integer brokeragePrice;
  12 +
  13 + @Schema(description = "冻结的佣金,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "234")
  14 + private Integer frozenBrokeragePrice;
  15 +
  16 +}
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/withdraw/AppBrokerageWithdrawCreateReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.withdraw;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +import org.hibernate.validator.constraints.URL;
  6 +
  7 +import javax.validation.constraints.Min;
  8 +
  9 +@Schema(description = "用户 App - 分销提现创建 Request VO")
  10 +@Data
  11 +public class AppBrokerageWithdrawCreateReqVO {
  12 +
  13 + // TODO @疯狂:参数校验逻辑,需要根据 type 进行不同的校验;感觉可以通过分组?
  14 +
  15 + @Schema(description = "提现方式", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
  16 + private Integer type;
  17 +
  18 + @Schema(description = "提现账号", requiredMode = Schema.RequiredMode.REQUIRED, example = "123456789") // 银行卡号/微信账号/支付宝账号
  19 + private String accountNo;
  20 +
  21 + @Schema(description = "收款码的图片", example = "https://www.iocoder.cn/1.png")
  22 + @URL(message = "收款码的图片,必须是一个 URL")
  23 + private String accountQrCodeUrl;
  24 +
  25 + @Schema(description = "提现金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "1000")
  26 + @Min(value = 1, message = "提现金额必须大于 1")
  27 + private Integer price;
  28 +
  29 +}
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/withdraw/AppBrokerageWithdrawRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.withdraw;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +import java.time.LocalDateTime;
  7 +
  8 +@Schema(description = "用户 App - 分销提现 Response VO")
  9 +@Data
  10 +public class AppBrokerageWithdrawRespVO {
  11 +
  12 + @Schema(description = "提现编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
  13 + private Long id;
  14 +
  15 + @Schema(description = "提现状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
  16 + private Integer status;
  17 +
  18 + @Schema(description = "提现状态名", requiredMode = Schema.RequiredMode.REQUIRED, example = "审核中")
  19 + private String statusName;
  20 +
  21 + @Schema(description = "提现金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "1000")
  22 + private Integer price;
  23 +
  24 + @Schema(description = "提现时间", requiredMode = Schema.RequiredMode.REQUIRED)
  25 + private LocalDateTime createTime;
  26 +
  27 +}
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/config/AppTradeConfigController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.controller.app.config;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.module.trade.controller.app.config.vo.AppTradeConfigRespVO;
  5 +import io.swagger.v3.oas.annotations.tags.Tag;
  6 +import lombok.RequiredArgsConstructor;
  7 +import lombok.extern.slf4j.Slf4j;
  8 +import org.springframework.validation.annotation.Validated;
  9 +import org.springframework.web.bind.annotation.GetMapping;
  10 +import org.springframework.web.bind.annotation.RequestMapping;
  11 +import org.springframework.web.bind.annotation.RestController;
  12 +
  13 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  14 +import static java.util.Arrays.asList;
  15 +
  16 +@Tag(name = "用户 App - 交易配置")
  17 +@RestController
  18 +@RequestMapping("/trade/config")
  19 +@RequiredArgsConstructor
  20 +@Validated
  21 +@Slf4j
  22 +public class AppTradeConfigController {
  23 +
  24 + @GetMapping("/get")
  25 + public CommonResult<AppTradeConfigRespVO> getTradeConfig() {
  26 + AppTradeConfigRespVO respVO = new AppTradeConfigRespVO();
  27 + respVO.setBrokeragePosterUrls(asList(
  28 + "https://api.java.crmeb.net/crmebimage/product/2020/08/03/755bf516b1ca4b6db3bfeaa4dd5901cdh71kob20re.jpg",
  29 + "https://api.java.crmeb.net/crmebimage/maintain/2021/03/01/406d729b84ed4ec9a2171bfcf6fd0634ughzbz9kfi.jpg",
  30 + "https://api.java.crmeb.net/crmebimage/maintain/2021/03/01/efb1e4e7fe604fe1988b4213ce08cb11tdsyijtd2r.jpg"
  31 + ));
  32 + respVO.setBrokerageFrozenDays(10);
  33 + respVO.setBrokerageWithdrawMinPrice(100);
  34 + return success(respVO);
  35 + }
  36 +
  37 +}
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/config/vo/AppTradeConfigRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.controller.app.config.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +import java.util.List;
  7 +
  8 +@Schema(description = "用户 App - 交易配置 Response VO")
  9 +@Data
  10 +public class AppTradeConfigRespVO {
  11 +
  12 + @Schema(description = "分销海报地址数组", requiredMode = Schema.RequiredMode.REQUIRED)
  13 + private List<String> brokeragePosterUrls;
  14 +
  15 + @Schema(description = "佣金冻结时间(天)", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
  16 + private Integer brokerageFrozenDays;
  17 +
  18 + @Schema(description = "佣金提现最小金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
  19 + private Integer brokerageWithdrawMinPrice;
  20 +
  21 +}
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/delivery/vo/config/AppDeliveryConfigRespVO.java
@@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.trade.controller.app.delivery.vo.config; @@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.trade.controller.app.delivery.vo.config;
3 import io.swagger.v3.oas.annotations.media.Schema; 3 import io.swagger.v3.oas.annotations.media.Schema;
4 import lombok.Data; 4 import lombok.Data;
5 5
6 -// TODO 芋艿:后续要实现下,配送配置 6 +// TODO 芋艿:后续要实现下,配送配置;后续融合到 AppTradeConfigRespVO 中
7 @Schema(description = "用户 App - 配送配置 Response VO") 7 @Schema(description = "用户 App - 配送配置 Response VO")
8 @Data 8 @Data
9 public class AppDeliveryConfigRespVO { 9 public class AppDeliveryConfigRespVO {
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderDetailRespVO.java
@@ -21,7 +21,7 @@ public class AppTradeOrderDetailRespVO { @@ -21,7 +21,7 @@ public class AppTradeOrderDetailRespVO {
21 private String no; 21 private String no;
22 22
23 @Schema(description = "下单时间", requiredMode = Schema.RequiredMode.REQUIRED) 23 @Schema(description = "下单时间", requiredMode = Schema.RequiredMode.REQUIRED)
24 - private Date createTime; 24 + private LocalDateTime createTime;
25 25
26 @Schema(description = "用户备注", requiredMode = Schema.RequiredMode.REQUIRED, example = "你猜") 26 @Schema(description = "用户备注", requiredMode = Schema.RequiredMode.REQUIRED, example = "你猜")
27 private String userRemark; 27 private String userRemark;
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderPageItemRespVO.java
@@ -4,7 +4,7 @@ import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderI @@ -4,7 +4,7 @@ import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderI
4 import io.swagger.v3.oas.annotations.media.Schema; 4 import io.swagger.v3.oas.annotations.media.Schema;
5 import lombok.Data; 5 import lombok.Data;
6 6
7 -import java.util.Date; 7 +import java.time.LocalDateTime;
8 import java.util.List; 8 import java.util.List;
9 9
10 @Schema(description = "用户 App - 订单交易的分页项 Response VO") 10 @Schema(description = "用户 App - 订单交易的分页项 Response VO")
@@ -30,7 +30,7 @@ public class AppTradeOrderPageItemRespVO { @@ -30,7 +30,7 @@ public class AppTradeOrderPageItemRespVO {
30 private Boolean commentStatus; 30 private Boolean commentStatus;
31 31
32 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) 32 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
33 - private Date createTime; 33 + private LocalDateTime createTime;
34 34
35 // ========== 价格 + 支付基本信息 ========== 35 // ========== 价格 + 支付基本信息 ==========
36 36
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/brokerage/record/TradeBrokerageRecordConvert.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.convert.brokerage.record;
  2 +
  3 +import cn.hutool.core.util.StrUtil;
  4 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  5 +import cn.iocoder.yudao.module.trade.controller.admin.brokerage.record.vo.TradeBrokerageRecordRespVO;
  6 +import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.record.TradeBrokerageRecordDO;
  7 +import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.user.TradeBrokerageUserDO;
  8 +import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordBizTypeEnum;
  9 +import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordStatusEnum;
  10 +import org.mapstruct.Mapper;
  11 +import org.mapstruct.factory.Mappers;
  12 +
  13 +import java.time.LocalDateTime;
  14 +import java.util.List;
  15 +
  16 +/**
  17 + * 佣金记录 Convert
  18 + *
  19 + * @author owen
  20 + */
  21 +@Mapper
  22 +public interface TradeBrokerageRecordConvert {
  23 +
  24 + TradeBrokerageRecordConvert INSTANCE = Mappers.getMapper(TradeBrokerageRecordConvert.class);
  25 +
  26 + TradeBrokerageRecordRespVO convert(TradeBrokerageRecordDO bean);
  27 +
  28 + List<TradeBrokerageRecordRespVO> convertList(List<TradeBrokerageRecordDO> list);
  29 +
  30 + PageResult<TradeBrokerageRecordRespVO> convertPage(PageResult<TradeBrokerageRecordDO> page);
  31 +
  32 + default TradeBrokerageRecordDO convert(TradeBrokerageUserDO user, String bizId, int brokerageFrozenDays, int brokerage, LocalDateTime unfreezeTime) {
  33 + // 不冻结时,佣金直接就是结算状态
  34 + Integer status = brokerageFrozenDays > 0
  35 + ? BrokerageRecordStatusEnum.WAIT_SETTLEMENT.getStatus()
  36 + : BrokerageRecordStatusEnum.SETTLEMENT.getStatus();
  37 + return new TradeBrokerageRecordDO()
  38 + .setUserId(user.getId())
  39 + .setBizType(BrokerageRecordBizTypeEnum.ORDER.getType())
  40 + .setBizId(bizId)
  41 + .setPrice(brokerage)
  42 + .setTotalPrice(user.getBrokeragePrice())
  43 + .setTitle(BrokerageRecordBizTypeEnum.ORDER.getTitle()) // TODO @疯狂:可能 title 不是很固化,会存在类似:沐晴成功购买《XXX JVM 实战》
  44 + .setDescription(StrUtil.format(BrokerageRecordBizTypeEnum.ORDER.getDescription(), String.valueOf(brokerage / 100.0)))
  45 + .setStatus(status)
  46 + .setFrozenDays(brokerageFrozenDays)
  47 + .setUnfreezeTime(unfreezeTime);
  48 + }
  49 +
  50 +}
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/brokerage/user/TradeBrokerageUserConvert.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.convert.brokerage.user;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.module.trade.controller.admin.brokerage.user.vo.TradeBrokerageUserRespVO;
  5 +import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.user.TradeBrokerageUserDO;
  6 +import org.mapstruct.Mapper;
  7 +import org.mapstruct.factory.Mappers;
  8 +
  9 +import java.util.List;
  10 +
  11 +/**
  12 + * 分销用户 Convert
  13 + *
  14 + * @author owen
  15 + */
  16 +@Mapper
  17 +public interface TradeBrokerageUserConvert {
  18 +
  19 + TradeBrokerageUserConvert INSTANCE = Mappers.getMapper(TradeBrokerageUserConvert.class);
  20 +
  21 + TradeBrokerageUserRespVO convert(TradeBrokerageUserDO bean);
  22 +
  23 + List<TradeBrokerageUserRespVO> convertList(List<TradeBrokerageUserDO> list);
  24 +
  25 + PageResult<TradeBrokerageUserRespVO> convertPage(PageResult<TradeBrokerageUserDO> page);
  26 +
  27 +}
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/config/TradeConfigConvert.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.convert.config;
  2 +
  3 +import cn.iocoder.yudao.module.trade.controller.admin.config.vo.TradeConfigRespVO;
  4 +import cn.iocoder.yudao.module.trade.controller.admin.config.vo.TradeConfigSaveReqVO;
  5 +import cn.iocoder.yudao.module.trade.dal.dataobject.config.TradeConfigDO;
  6 +import org.mapstruct.Mapper;
  7 +import org.mapstruct.factory.Mappers;
  8 +
  9 +/**
  10 + * 交易中心配置 Convert
  11 + *
  12 + * @author owen
  13 + */
  14 +@Mapper
  15 +public interface TradeConfigConvert {
  16 +
  17 + TradeConfigConvert INSTANCE = Mappers.getMapper(TradeConfigConvert.class);
  18 +
  19 + TradeConfigDO convert(TradeConfigSaveReqVO bean);
  20 +
  21 + TradeConfigRespVO convert(TradeConfigDO bean);
  22 +
  23 +}
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java
@@ -7,11 +7,13 @@ import cn.iocoder.yudao.framework.common.util.string.StrUtils; @@ -7,11 +7,13 @@ import cn.iocoder.yudao.framework.common.util.string.StrUtils;
7 import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils; 7 import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils;
8 import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils; 8 import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils;
9 import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO; 9 import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO;
  10 +import cn.iocoder.yudao.module.trade.service.brokerage.record.bo.BrokerageAddReqBO;
10 import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; 11 import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
11 import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO; 12 import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO;
12 import cn.iocoder.yudao.module.pay.enums.DictTypeConstants; 13 import cn.iocoder.yudao.module.pay.enums.DictTypeConstants;
13 import cn.iocoder.yudao.module.product.api.comment.dto.ProductCommentCreateReqDTO; 14 import cn.iocoder.yudao.module.product.api.comment.dto.ProductCommentCreateReqDTO;
14 import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO; 15 import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO;
  16 +import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO;
15 import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO; 17 import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO;
16 import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO; 18 import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO;
17 import cn.iocoder.yudao.module.trade.api.order.dto.TradeOrderRespDTO; 19 import cn.iocoder.yudao.module.trade.api.order.dto.TradeOrderRespDTO;
@@ -275,4 +277,10 @@ public interface TradeOrderConvert { @@ -275,4 +277,10 @@ public interface TradeOrderConvert {
275 277
276 TradeOrderDO convert(TradeOrderRemarkReqVO reqVO); 278 TradeOrderDO convert(TradeOrderRemarkReqVO reqVO);
277 279
  280 + default BrokerageAddReqBO convert(TradeOrderItemDO item, ProductSkuRespDTO sku) {
  281 + return new BrokerageAddReqBO().setBizId(String.valueOf(item.getId()))
  282 + .setPayPrice(item.getPayPrice()).setCount(item.getCount())
  283 + .setSkuFirstBrokeragePrice(sku.getSubCommissionFirstPrice())
  284 + .setSkuSecondBrokeragePrice(sku.getSubCommissionSecondPrice());
  285 + }
278 } 286 }
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/brokerage/record/TradeBrokerageRecordDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.record;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordBizTypeEnum;
  5 +import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordStatusEnum;
  6 +import com.baomidou.mybatisplus.annotation.KeySequence;
  7 +import com.baomidou.mybatisplus.annotation.TableId;
  8 +import com.baomidou.mybatisplus.annotation.TableName;
  9 +import lombok.*;
  10 +
  11 +import java.time.LocalDateTime;
  12 +
  13 +/**
  14 + * 佣金记录 DO
  15 + *
  16 + * @author owen
  17 + */
  18 +@TableName("trade_brokerage_record")
  19 +@KeySequence("trade_brokerage_record_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
  20 +@Data
  21 +@EqualsAndHashCode(callSuper = true)
  22 +@ToString(callSuper = true)
  23 +@Builder
  24 +@NoArgsConstructor
  25 +@AllArgsConstructor
  26 +public class TradeBrokerageRecordDO extends BaseDO {
  27 +
  28 + /**
  29 + * 编号
  30 + */
  31 + @TableId
  32 + private Integer id;
  33 + /**
  34 + * 用户编号
  35 + */
  36 + private Long userId;
  37 + /**
  38 + * 业务编号
  39 + */
  40 + private String bizId;
  41 + /**
  42 + * 业务类型
  43 + * <p>
  44 + * 枚举 {@link BrokerageRecordBizTypeEnum}
  45 + */
  46 + private Integer bizType;
  47 +
  48 + /**
  49 + * 标题
  50 + */
  51 + private String title;
  52 + /**
  53 + * 说明
  54 + */
  55 + private String description;
  56 +
  57 + /**
  58 + * 金额
  59 + */
  60 + private Integer price;
  61 + /**
  62 + * 当前总佣金
  63 + */
  64 + private Integer totalPrice;
  65 +
  66 + /**
  67 + * 状态
  68 + * <p>
  69 + * 枚举 {@link BrokerageRecordStatusEnum}
  70 + */
  71 + private Integer status;
  72 +
  73 + /**
  74 + * 冻结时间(天)
  75 + */
  76 + private Integer frozenDays;
  77 + /**
  78 + * 解冻时间
  79 + */
  80 + private LocalDateTime unfreezeTime;
  81 +
  82 +}
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/brokerage/user/TradeBrokerageUserDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.user;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import com.baomidou.mybatisplus.annotation.KeySequence;
  5 +import com.baomidou.mybatisplus.annotation.TableId;
  6 +import com.baomidou.mybatisplus.annotation.TableName;
  7 +import lombok.*;
  8 +
  9 +import java.time.LocalDateTime;
  10 +
  11 +// TODO @疯狂:因为独立了表,是不是可以把字段的 brokerage 去掉了哈?
  12 +/**
  13 + * 分销用户 DO
  14 + *
  15 + * @author owen
  16 + */
  17 +@TableName("trade_brokerage_user")
  18 +@KeySequence("trade_brokerage_user_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
  19 +@Data
  20 +@EqualsAndHashCode(callSuper = true)
  21 +@ToString(callSuper = true)
  22 +@Builder
  23 +@NoArgsConstructor
  24 +@AllArgsConstructor
  25 +public class TradeBrokerageUserDO extends BaseDO {
  26 +
  27 + /**
  28 + * 用户编号
  29 + */
  30 + @TableId
  31 + private Long id;
  32 +
  33 + // TODO @疯狂:貌似改成 bindUserId,更明确?
  34 + /**
  35 + * 推广员编号
  36 + *
  37 + * 关联 MemberUserDO 的 id 字段
  38 + */
  39 + private Long brokerageUserId;
  40 + /**
  41 + * 推广员绑定时间
  42 + */
  43 + private LocalDateTime brokerageBindTime;
  44 +
  45 + /**
  46 + * 推广资格
  47 + */
  48 + private Boolean brokerageEnabled;
  49 + /**
  50 + * 成为分销员时间
  51 + */
  52 + private LocalDateTime brokerageTime;
  53 +
  54 + /**
  55 + * 可用佣金
  56 + */
  57 + private Integer brokeragePrice;
  58 + /**
  59 + * 冻结佣金
  60 + */
  61 + private Integer frozenBrokeragePrice;
  62 +
  63 +}
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/config/TradeConfigDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.dal.dataobject.config;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import cn.iocoder.yudao.framework.mybatis.core.type.IntegerListTypeHandler;
  5 +import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageBindModeEnum;
  6 +import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageEnabledConditionEnum;
  7 +import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageWithdrawTypeEnum;
  8 +import com.baomidou.mybatisplus.annotation.KeySequence;
  9 +import com.baomidou.mybatisplus.annotation.TableField;
  10 +import com.baomidou.mybatisplus.annotation.TableId;
  11 +import com.baomidou.mybatisplus.annotation.TableName;
  12 +import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
  13 +import lombok.*;
  14 +
  15 +import java.util.List;
  16 +
  17 +/**
  18 + * 交易中心配置 DO
  19 + *
  20 + * @author owen
  21 + */
  22 +@TableName(value = "trade_config", autoResultMap = true)
  23 +@KeySequence("trade_config_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
  24 +@Data
  25 +@EqualsAndHashCode(callSuper = true)
  26 +@ToString(callSuper = true)
  27 +@Builder
  28 +@NoArgsConstructor
  29 +@AllArgsConstructor
  30 +public class TradeConfigDO extends BaseDO {
  31 +
  32 + /**
  33 + * 自增主键
  34 + */
  35 + @TableId
  36 + private Long id;
  37 +
  38 + // ========== 分销相关 ==========
  39 +
  40 + /**
  41 + * 是否启用分佣
  42 + */
  43 + private Boolean brokerageEnabled;
  44 + /**
  45 + * 分佣模式
  46 + * <p>
  47 + * 枚举 {@link BrokerageEnabledConditionEnum 对应的类}
  48 + */
  49 + private Integer brokerageEnabledCondition;
  50 + /**
  51 + * 分销关系绑定模式
  52 + * <p>
  53 + * 枚举 {@link BrokerageBindModeEnum 对应的类}
  54 + */
  55 + private Integer brokerageBindMode;
  56 + /**
  57 + * 分销海报图地址数组
  58 + */
  59 + @TableField(typeHandler = JacksonTypeHandler.class)
  60 + private List<String> brokeragePostUrls;
  61 + /**
  62 + * 一级返佣比例
  63 + */
  64 + private Integer brokerageFirstPercent;
  65 + /**
  66 + * 二级返佣比例
  67 + */
  68 + private Integer brokerageSecondPercent;
  69 + /**
  70 + * 用户提现最低金额
  71 + */
  72 + private Integer brokerageWithdrawMinPrice;
  73 + /**
  74 + * 提现银行
  75 + */
  76 + @TableField(typeHandler = IntegerListTypeHandler.class)
  77 + private List<Integer> brokerageBankNames;
  78 + /**
  79 + * 佣金冻结时间(天)
  80 + */
  81 + private Integer brokerageFrozenDays;
  82 + /**
  83 + * 提现方式
  84 + * <p>
  85 + * 枚举 {@link BrokerageWithdrawTypeEnum 对应的类}
  86 + */
  87 + @TableField(typeHandler = IntegerListTypeHandler.class)
  88 + private List<Integer> brokerageWithdrawType;
  89 +
  90 +}
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/record/TradeBrokerageRecordMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.dal.mysql.brokerage.record;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  5 +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
  6 +import cn.iocoder.yudao.module.trade.controller.admin.brokerage.record.vo.TradeBrokerageRecordPageReqVO;
  7 +import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.record.TradeBrokerageRecordDO;
  8 +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  9 +import org.apache.ibatis.annotations.Mapper;
  10 +
  11 +import java.time.LocalDateTime;
  12 +import java.util.List;
  13 +
  14 +/**
  15 + * 佣金记录 Mapper
  16 + *
  17 + * @author owen
  18 + */
  19 +@Mapper
  20 +public interface TradeBrokerageRecordMapper extends BaseMapperX<TradeBrokerageRecordDO> {
  21 +
  22 + default PageResult<TradeBrokerageRecordDO> selectPage(TradeBrokerageRecordPageReqVO reqVO) {
  23 + return selectPage(reqVO, new LambdaQueryWrapperX<TradeBrokerageRecordDO>()
  24 + .eqIfPresent(TradeBrokerageRecordDO::getUserId, reqVO.getUserId())
  25 + .eqIfPresent(TradeBrokerageRecordDO::getBizType, reqVO.getBizType())
  26 + .eqIfPresent(TradeBrokerageRecordDO::getStatus, reqVO.getStatus())
  27 + .betweenIfPresent(TradeBrokerageRecordDO::getCreateTime, reqVO.getCreateTime())
  28 + .orderByDesc(TradeBrokerageRecordDO::getId));
  29 + }
  30 +
  31 + default List<TradeBrokerageRecordDO> selectListByStatusAndUnfreezeTimeLt(Integer status, LocalDateTime unfreezeTime) {
  32 + return selectList(new LambdaQueryWrapper<TradeBrokerageRecordDO>()
  33 + .eq(TradeBrokerageRecordDO::getStatus, status)
  34 + .lt(TradeBrokerageRecordDO::getUnfreezeTime, unfreezeTime));
  35 + }
  36 +
  37 + default int updateByIdAndStatus(Integer id, Integer status, TradeBrokerageRecordDO updateObj) {
  38 + return update(updateObj, new LambdaQueryWrapper<TradeBrokerageRecordDO>()
  39 + .eq(TradeBrokerageRecordDO::getId, id)
  40 + .eq(TradeBrokerageRecordDO::getStatus, status));
  41 + }
  42 +
  43 + // TODO @疯狂:userId???
  44 + default TradeBrokerageRecordDO selectByUserIdAndBizTypeAndBizId(Integer bizType, String bizId) {
  45 + return selectOne(TradeBrokerageRecordDO::getBizType, bizType,
  46 + TradeBrokerageRecordDO::getBizId, bizId);
  47 + }
  48 +
  49 +}
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/user/TradeBrokerageUserMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.dal.mysql.brokerage.user;
  2 +
  3 +import cn.hutool.core.lang.Assert;
  4 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  5 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  6 +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
  7 +import cn.iocoder.yudao.module.trade.controller.admin.brokerage.user.vo.TradeBrokerageUserPageReqVO;
  8 +import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.user.TradeBrokerageUserDO;
  9 +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
  10 +import org.apache.ibatis.annotations.Mapper;
  11 +
  12 +/**
  13 + * 分销用户 Mapper
  14 + *
  15 + * @author owen
  16 + */
  17 +@Mapper
  18 +public interface TradeBrokerageUserMapper extends BaseMapperX<TradeBrokerageUserDO> {
  19 +
  20 + default PageResult<TradeBrokerageUserDO> selectPage(TradeBrokerageUserPageReqVO reqVO) {
  21 + return selectPage(reqVO, new LambdaQueryWrapperX<TradeBrokerageUserDO>()
  22 + .eqIfPresent(TradeBrokerageUserDO::getBrokerageUserId, reqVO.getBrokerageUserId())
  23 + .eqIfPresent(TradeBrokerageUserDO::getBrokerageEnabled, reqVO.getBrokerageEnabled())
  24 + .betweenIfPresent(TradeBrokerageUserDO::getCreateTime, reqVO.getCreateTime())
  25 + .orderByDesc(TradeBrokerageUserDO::getId));
  26 + }
  27 +
  28 + /**
  29 + * 更新用户可用佣金(增加)
  30 + *
  31 + * @param id 用户编号
  32 + * @param incrCount 增加佣金(正数)
  33 + */
  34 + default void updateBrokeragePriceIncr(Long id, int incrCount) {
  35 + Assert.isTrue(incrCount > 0);
  36 + LambdaUpdateWrapper<TradeBrokerageUserDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<TradeBrokerageUserDO>()
  37 + .setSql(" brokerage_price = brokerage_price + " + incrCount)
  38 + .eq(TradeBrokerageUserDO::getId, id);
  39 + update(null, lambdaUpdateWrapper);
  40 + }
  41 +
  42 + /**
  43 + * 更新用户可用佣金(减少)
  44 + * 注意:理论上佣金可能已经提现,这时会扣出负数,确保平台不会造成损失
  45 + *
  46 + * @param id 用户编号
  47 + * @param incrCount 增加佣金(负数)
  48 + */
  49 + default void updateBrokeragePriceDecr(Long id, int incrCount) {
  50 + Assert.isTrue(incrCount < 0);
  51 + LambdaUpdateWrapper<TradeBrokerageUserDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<TradeBrokerageUserDO>()
  52 + .setSql(" brokerage_price = brokerage_price + " + incrCount) // 负数,所以使用 + 号
  53 + .eq(TradeBrokerageUserDO::getId, id);
  54 + update(null, lambdaUpdateWrapper);
  55 + }
  56 +
  57 + /**
  58 + * 更新用户冻结佣金(增加)
  59 + *
  60 + * @param id 用户编号
  61 + * @param incrCount 增加冻结佣金(正数)
  62 + */
  63 + default void updateFrozenBrokeragePriceIncr(Long id, int incrCount) {
  64 + Assert.isTrue(incrCount > 0);
  65 + LambdaUpdateWrapper<TradeBrokerageUserDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<TradeBrokerageUserDO>()
  66 + .setSql(" frozen_brokerage_price = frozen_brokerage_price + " + incrCount)
  67 + .eq(TradeBrokerageUserDO::getId, id);
  68 + update(null, lambdaUpdateWrapper);
  69 + }
  70 +
  71 + /**
  72 + * 更新用户冻结佣金(减少)
  73 + * 注意:理论上冻结佣金可能已经解冻,这时会扣出负数,确保平台不会造成损失
  74 + *
  75 + * @param id 用户编号
  76 + * @param incrCount 减少冻结佣金(负数)
  77 + */
  78 + default void updateFrozenBrokeragePriceDecr(Long id, int incrCount) {
  79 + Assert.isTrue(incrCount < 0);
  80 + LambdaUpdateWrapper<TradeBrokerageUserDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<TradeBrokerageUserDO>()
  81 + .setSql(" frozen_brokerage_price = frozen_brokerage_price + " + incrCount) // 负数,所以使用 + 号
  82 + .eq(TradeBrokerageUserDO::getId, id);
  83 + update(null, lambdaUpdateWrapper);
  84 + }
  85 +
  86 + /**
  87 + * 更新用户冻结佣金(减少), 更新用户佣金(增加)
  88 + *
  89 + * @param id 用户编号
  90 + * @param incrCount 减少冻结佣金(负数)
  91 + * @return 更新条数
  92 + */
  93 + default int updateFrozenBrokeragePriceDecrAndBrokeragePriceIncr(Long id, int incrCount) {
  94 + Assert.isTrue(incrCount < 0);
  95 + LambdaUpdateWrapper<TradeBrokerageUserDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<TradeBrokerageUserDO>()
  96 + .setSql(" frozen_brokerage_price = frozen_brokerage_price + " + incrCount + // 负数,所以使用 + 号
  97 + ", brokerage_price = brokerage_price + " + -incrCount) // 负数,所以使用 - 号
  98 + .eq(TradeBrokerageUserDO::getId, id)
  99 + .ge(TradeBrokerageUserDO::getFrozenBrokeragePrice, -incrCount); // cas 逻辑
  100 + return update(null, lambdaUpdateWrapper);
  101 + }
  102 +
  103 +}
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/config/TradeConfigMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.dal.mysql.config;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  4 +import cn.iocoder.yudao.module.trade.dal.dataobject.config.TradeConfigDO;
  5 +import org.apache.ibatis.annotations.Mapper;
  6 +
  7 +/**
  8 + * 交易中心配置 Mapper
  9 + *
  10 + * @author owen
  11 + */
  12 +@Mapper
  13 +public interface TradeConfigMapper extends BaseMapperX<TradeConfigDO> {
  14 +
  15 +}
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/job/brokerage/TradeBrokerageRecordUnfreezeJob.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.job.brokerage;
  2 +
  3 +import cn.hutool.core.util.StrUtil;
  4 +import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler;
  5 +import cn.iocoder.yudao.framework.tenant.core.job.TenantJob;
  6 +import cn.iocoder.yudao.module.trade.service.brokerage.record.TradeBrokerageRecordService;
  7 +import org.springframework.stereotype.Component;
  8 +
  9 +import javax.annotation.Resource;
  10 +
  11 +/**
  12 + * 佣金解冻 Job
  13 + *
  14 + * @author owen
  15 + */
  16 +@Component
  17 +@TenantJob
  18 +public class TradeBrokerageRecordUnfreezeJob implements JobHandler {
  19 +
  20 + @Resource
  21 + private TradeBrokerageRecordService tradeBrokerageRecordService;
  22 +
  23 + @Override
  24 + public String execute(String param) {
  25 + int count = tradeBrokerageRecordService.unfreezeRecord();
  26 + return StrUtil.format("解冻佣金 {} 个", count);
  27 + }
  28 +
  29 +}
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/job/package-info.java 0 → 100644
  1 +/**
  2 + * 占位文件,无特殊用途
  3 + */
  4 +package cn.iocoder.yudao.module.trade.job;
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/record/TradeBrokerageRecordService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.service.brokerage.record;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.record.TradeBrokerageRecordDO;
  5 +import cn.iocoder.yudao.module.trade.service.brokerage.record.bo.BrokerageAddReqBO;
  6 +import cn.iocoder.yudao.module.trade.controller.admin.brokerage.record.vo.TradeBrokerageRecordPageReqVO;
  7 +
  8 +import java.util.List;
  9 +
  10 +/**
  11 + * 佣金记录 Service 接口
  12 + *
  13 + * @author owen
  14 + */
  15 +public interface TradeBrokerageRecordService {
  16 +
  17 + /**
  18 + * 获得佣金记录
  19 + *
  20 + * @param id 编号
  21 + * @return 佣金记录
  22 + */
  23 + TradeBrokerageRecordDO getBrokerageRecord(Integer id);
  24 +
  25 + /**
  26 + * 获得佣金记录分页
  27 + *
  28 + * @param pageReqVO 分页查询
  29 + * @return 佣金记录分页
  30 + */
  31 + PageResult<TradeBrokerageRecordDO> getBrokerageRecordPage(TradeBrokerageRecordPageReqVO pageReqVO);
  32 +
  33 + // TODO @疯狂:是不是 bizType 得加下?方便未来拓展哈;
  34 + /**
  35 + * 增加佣金
  36 + *
  37 + * @param userId 会员编号
  38 + * @param list 请求参数列表
  39 + */
  40 + void addBrokerage(Long userId, List<BrokerageAddReqBO> list);
  41 +
  42 + // TODO @疯狂:是不是 bizType 得加下?方便未来拓展哈;
  43 + /**
  44 + * 取消佣金:将佣金记录,状态修改为已失效
  45 + *
  46 + * @param userId 会员编号
  47 + * @param bizId 业务编号
  48 + */
  49 + void cancelBrokerage(Long userId, String bizId);
  50 +
  51 + /**
  52 + * 解冻佣金:将待结算的佣金记录,状态修改为已结算
  53 + *
  54 + * @return 解冻佣金的数量
  55 + */
  56 + int unfreezeRecord();
  57 +
  58 +}
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/record/TradeBrokerageRecordServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.service.brokerage.record;
  2 +
  3 +import cn.hutool.core.collection.CollUtil;
  4 +import cn.hutool.core.util.BooleanUtil;
  5 +import cn.hutool.core.util.NumberUtil;
  6 +import cn.hutool.core.util.ObjectUtil;
  7 +import cn.hutool.extra.spring.SpringUtil;
  8 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  9 +import cn.iocoder.yudao.module.trade.controller.admin.brokerage.record.vo.TradeBrokerageRecordPageReqVO;
  10 +import cn.iocoder.yudao.module.trade.convert.brokerage.record.TradeBrokerageRecordConvert;
  11 +import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.record.TradeBrokerageRecordDO;
  12 +import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.user.TradeBrokerageUserDO;
  13 +import cn.iocoder.yudao.module.trade.dal.dataobject.config.TradeConfigDO;
  14 +import cn.iocoder.yudao.module.trade.dal.mysql.brokerage.record.TradeBrokerageRecordMapper;
  15 +import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordBizTypeEnum;
  16 +import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordStatusEnum;
  17 +import cn.iocoder.yudao.module.trade.service.brokerage.record.bo.BrokerageAddReqBO;
  18 +import cn.iocoder.yudao.module.trade.service.brokerage.user.TradeBrokerageUserService;
  19 +import cn.iocoder.yudao.module.trade.service.config.TradeConfigService;
  20 +import lombok.extern.slf4j.Slf4j;
  21 +import org.springframework.stereotype.Service;
  22 +import org.springframework.transaction.annotation.Transactional;
  23 +import org.springframework.validation.annotation.Validated;
  24 +
  25 +import javax.annotation.Resource;
  26 +import java.math.RoundingMode;
  27 +import java.time.LocalDateTime;
  28 +import java.util.ArrayList;
  29 +import java.util.List;
  30 +import java.util.function.Function;
  31 +
  32 +/**
  33 + * 佣金记录 Service 实现类
  34 + *
  35 + * @author owen
  36 + */
  37 +@Slf4j
  38 +@Service
  39 +@Validated
  40 +public class TradeBrokerageRecordServiceImpl implements TradeBrokerageRecordService {
  41 +
  42 + @Resource
  43 + private TradeBrokerageRecordMapper tradeBrokerageRecordMapper;
  44 + @Resource
  45 + private TradeConfigService tradeConfigService;
  46 + @Resource
  47 + private TradeBrokerageUserService tradeBrokerageUserService;
  48 +
  49 + @Override
  50 + public TradeBrokerageRecordDO getBrokerageRecord(Integer id) {
  51 + return tradeBrokerageRecordMapper.selectById(id);
  52 + }
  53 +
  54 + @Override
  55 + public PageResult<TradeBrokerageRecordDO> getBrokerageRecordPage(TradeBrokerageRecordPageReqVO pageReqVO) {
  56 + return tradeBrokerageRecordMapper.selectPage(pageReqVO);
  57 + }
  58 +
  59 + // TODO @疯狂:buyerId 要不要统一改成 userId 哈;
  60 + @Override
  61 + @Transactional(rollbackFor = Exception.class)
  62 + public void addBrokerage(Long buyerId, List<BrokerageAddReqBO> list) {
  63 + TradeConfigDO memberConfig = tradeConfigService.getTradeConfig();
  64 + // 0 未启用分销功能
  65 + // TODO @疯狂:BooleanUtil.isFalse();逻辑里,尽量不做 !取反,这样要多思考一层;
  66 + if (memberConfig == null || !BooleanUtil.isTrue(memberConfig.getBrokerageEnabled())) {
  67 + log.warn("[addBrokerage][增加佣金失败:brokerageEnabled 未配置,buyerId({})", buyerId);
  68 + return;
  69 + }
  70 +
  71 + // 1.1 获得一级推广人
  72 + TradeBrokerageUserDO firstUser = tradeBrokerageUserService.getInviteBrokerageUser(buyerId);
  73 + if (firstUser == null || !BooleanUtil.isTrue(firstUser.getBrokerageEnabled())) {
  74 + return;
  75 + }
  76 +
  77 + // 1.2 计算一级分佣 // TODO 疯狂:类似 1.1 和 1.2 的空行,可以去掉;一般在代码里的空行,是为了逻辑分块;但是分块如果太多,就会导致代码里都是空行哈;
  78 + addBrokerage(firstUser, list, memberConfig.getBrokerageFrozenDays(), memberConfig.getBrokerageFirstPercent(), BrokerageAddReqBO::getSkuFirstBrokeragePrice);
  79 +
  80 + // 2.1 获得二级推广员
  81 + // TODO @疯狂:这里可以加个 firstUser.getBrokerageUserId() 为空的判断 return
  82 + TradeBrokerageUserDO secondUser = tradeBrokerageUserService.getBrokerageUser(firstUser.getBrokerageUserId());
  83 + if (secondUser == null || !BooleanUtil.isTrue(secondUser.getBrokerageEnabled())) {
  84 + return;
  85 + }
  86 +
  87 + // 2.2 计算二级分佣
  88 + addBrokerage(secondUser, list, memberConfig.getBrokerageFrozenDays(), memberConfig.getBrokerageSecondPercent(), BrokerageAddReqBO::getSkuSecondBrokeragePrice);
  89 + }
  90 +
  91 + @Override
  92 + @Transactional(rollbackFor = Exception.class)
  93 + public void cancelBrokerage(Long userId, String bizId) {
  94 + TradeBrokerageRecordDO record = tradeBrokerageRecordMapper.selectByUserIdAndBizTypeAndBizId(BrokerageRecordBizTypeEnum.ORDER.getType(), bizId);
  95 + if (record == null || ObjectUtil.notEqual(record.getUserId(), userId)) {
  96 + log.error("[cancelBrokerage][userId({})][bizId({}) 更新为已失效失败:记录不存在]", userId, bizId);
  97 + return;
  98 + }
  99 +
  100 + // 1. 更新佣金记录为已失效
  101 + TradeBrokerageRecordDO updateObj = new TradeBrokerageRecordDO().setStatus(BrokerageRecordStatusEnum.CANCEL.getStatus());
  102 + int updateRows = tradeBrokerageRecordMapper.updateByIdAndStatus(record.getId(), record.getStatus(), updateObj);
  103 + if (updateRows == 0) {
  104 + log.error("[cancelBrokerage][record({}) 更新为已失效失败]", record.getId());
  105 + return;
  106 + }
  107 +
  108 + // 2. 更新用户的佣金
  109 + if (BrokerageRecordStatusEnum.WAIT_SETTLEMENT.getStatus().equals(record.getStatus())) {
  110 + tradeBrokerageUserService.updateUserFrozenBrokeragePrice(userId, -record.getPrice());
  111 + } else if (BrokerageRecordStatusEnum.SETTLEMENT.getStatus().equals(record.getStatus())) {
  112 + tradeBrokerageUserService.updateUserBrokeragePrice(userId, -record.getPrice());
  113 + }
  114 + }
  115 +
  116 + // TODO @疯狂:是不是 calculateBrokeragePrice
  117 + /**
  118 + * 计算佣金
  119 + *
  120 + * @param payPrice 订单支付金额
  121 + * @param percent 商品 SKU 设置的佣金
  122 + * @param skuBrokeragePrice 商品的佣金
  123 + * @return 佣金
  124 + */
  125 + int calculateBrokerage(Integer payPrice, Integer percent, Integer skuBrokeragePrice) {
  126 + // 1. 优先使用商品 SKU 设置的佣金
  127 + if (skuBrokeragePrice != null && skuBrokeragePrice > 0) {
  128 + return ObjectUtil.defaultIfNull(skuBrokeragePrice, 0);
  129 + }
  130 + // 2. 根据订单支付金额计算佣金
  131 + // TODO @疯狂:要不要把 MoneyUtils 抽到 common 里,然后这里也使用这个类的方法;
  132 + if (payPrice != null && payPrice > 0 && percent != null && percent > 0) {
  133 + return NumberUtil.div(NumberUtil.mul(payPrice, percent), 100, 0, RoundingMode.DOWN).intValue();
  134 + }
  135 + return 0;
  136 + }
  137 +
  138 + /**
  139 + * 增加用户佣金
  140 + *
  141 + * @param user 用户
  142 + * @param list 佣金增加参数列表
  143 + * @param brokerageFrozenDays 冻结天数
  144 + * @param brokeragePercent 佣金比例
  145 + * @param skuBrokeragePriceFun 商品 SKU 设置的佣金
  146 + */
  147 + private void addBrokerage(TradeBrokerageUserDO user, List<BrokerageAddReqBO> list, Integer brokerageFrozenDays,
  148 + Integer brokeragePercent, Function<BrokerageAddReqBO, Integer> skuBrokeragePriceFun) {
  149 + // 1.1 处理冻结时间
  150 + // TODO @疯狂:是不是 brokerageFrozenDays != null && brokerageFrozenDays > 0 ?然后计算;更简洁一点;
  151 + brokerageFrozenDays = ObjectUtil.defaultIfNull(brokerageFrozenDays, 0);
  152 + LocalDateTime unfreezeTime = null;
  153 + if (brokerageFrozenDays > 0) {
  154 + unfreezeTime = LocalDateTime.now().plusDays(brokerageFrozenDays);
  155 + }
  156 + // 1.2 计算分佣
  157 + int totalBrokerage = 0;
  158 + List<TradeBrokerageRecordDO> records = new ArrayList<>();
  159 + for (BrokerageAddReqBO item : list) {
  160 + int brokeragePerItem = calculateBrokerage(item.getPayPrice(), brokeragePercent, skuBrokeragePriceFun.apply(item));
  161 + // TODO @疯狂:其实可以 brokeragePerItem <= 0 ,continue;这样 { 层级更少;代码更简洁;}
  162 + if (brokeragePerItem > 0) {
  163 + int brokerage = brokeragePerItem * item.getCount();
  164 + records.add(TradeBrokerageRecordConvert.INSTANCE.convert(user, item.getBizId(), brokerageFrozenDays, brokerage, unfreezeTime));
  165 + totalBrokerage += brokerage;
  166 + }
  167 + }
  168 + if (CollUtil.isEmpty(records)) {
  169 + return;
  170 + }
  171 + // 1.3 保存佣金记录
  172 + tradeBrokerageRecordMapper.insertBatch(records);
  173 +
  174 + // 2. 更新用户佣金
  175 + if (brokerageFrozenDays > 0) { // 更新用户冻结佣金
  176 + tradeBrokerageUserService.updateUserFrozenBrokeragePrice(user.getId(), totalBrokerage);
  177 + } else { // 更新用户可用佣金
  178 + tradeBrokerageUserService.updateUserBrokeragePrice(user.getId(), totalBrokerage);
  179 + }
  180 + }
  181 +
  182 + @Override
  183 + public int unfreezeRecord() {
  184 + // 1. 查询待结算的佣金记录
  185 + List<TradeBrokerageRecordDO> records = tradeBrokerageRecordMapper.selectListByStatusAndUnfreezeTimeLt(
  186 + BrokerageRecordStatusEnum.WAIT_SETTLEMENT.getStatus(), LocalDateTime.now());
  187 + if (CollUtil.isEmpty(records)) {
  188 + return 0;
  189 + }
  190 +
  191 + // 2. 遍历执行
  192 + int count = 0;
  193 + for (TradeBrokerageRecordDO record : records) {
  194 + try {
  195 + boolean success = getSelf().unfreezeRecord(record);
  196 + if (success) {
  197 + count++;
  198 + }
  199 + } catch (Exception e) {
  200 + log.error("[unfreezeRecord][record({}) 更新为已结算失败]", record.getId(), e);
  201 + }
  202 + }
  203 + return count;
  204 + }
  205 +
  206 + @Transactional(rollbackFor = Exception.class)
  207 + public boolean unfreezeRecord(TradeBrokerageRecordDO record) {
  208 + // 更新记录状态
  209 + TradeBrokerageRecordDO updateObj = new TradeBrokerageRecordDO()
  210 + .setStatus(BrokerageRecordStatusEnum.SETTLEMENT.getStatus())
  211 + .setUnfreezeTime(LocalDateTime.now());
  212 + int updateRows = tradeBrokerageRecordMapper.updateByIdAndStatus(record.getId(), record.getStatus(), updateObj);
  213 + if (updateRows == 0) {
  214 + log.error("[unfreezeRecord][record({}) 更新为已结算失败]", record.getId());
  215 + return false;
  216 + }
  217 +
  218 + // 更新用户冻结佣金
  219 + tradeBrokerageUserService.updateFrozenBrokeragePriceDecrAndBrokeragePriceIncr(record.getUserId(), -record.getPrice());
  220 + log.info("[unfreezeRecord][record({}) 更新为已结算成功]", record.getId());
  221 + return true;
  222 + }
  223 +
  224 + /**
  225 + * 获得自身的代理对象,解决 AOP 生效问题
  226 + *
  227 + * @return 自己
  228 + */
  229 + private TradeBrokerageRecordServiceImpl getSelf() {
  230 + return SpringUtil.getBean(getClass());
  231 + }
  232 +
  233 +}
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/record/bo/BrokerageAddReqBO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.service.brokerage.record.bo;
  2 +
  3 +import lombok.AllArgsConstructor;
  4 +import lombok.Data;
  5 +import lombok.NoArgsConstructor;
  6 +
  7 +// TODO @疯狂:要不要 service 还是拍平;就是都放在 brokerage 包下,然后 bo 里面,稍微分分;
  8 +/**
  9 + * 佣金 增加 Request BO
  10 + *
  11 + * @author owen
  12 + */
  13 +@Data
  14 +@NoArgsConstructor
  15 +@AllArgsConstructor
  16 +public class BrokerageAddReqBO {
  17 +
  18 + // TODO @疯狂:bo 的话,也可以考虑加下 @Validated 注解,校验下参数;防御性下哈,虽然不一定用的到
  19 +
  20 + /**
  21 + * 业务ID
  22 + */
  23 + private String bizId;
  24 + // TODO @疯狂:不需要 payPrice 和 count,计算成 price 就好啦;
  25 + /**
  26 + * 商品支付价格
  27 + */
  28 + private Integer payPrice;
  29 + // TODO @疯狂:可以去掉 sku 哈,更抽象一点;
  30 + /**
  31 + * SKU 一级佣金
  32 + */
  33 + private Integer skuFirstBrokeragePrice;
  34 + /**
  35 + * SKU 二级佣金
  36 + */
  37 + private Integer skuSecondBrokeragePrice;
  38 + /**
  39 + * 购买数量
  40 + */
  41 + private Integer count;
  42 +
  43 +}
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/user/TradeBrokerageUserService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.service.brokerage.user;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.module.trade.controller.admin.brokerage.user.vo.TradeBrokerageUserPageReqVO;
  5 +import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.user.TradeBrokerageUserDO;
  6 +
  7 +import java.util.Collection;
  8 +import java.util.List;
  9 +
  10 +// TODO @疯狂:要不去掉 Trade 前缀哈;交易这块,我准备除了 tradeorder 保持下,类似 aftersale,都要取消前缀了;tradeorder 保持的原因,是避免 payorder 和它重复
  11 +/**
  12 + * 分销用户 Service 接口
  13 + *
  14 + * @author owen
  15 + */
  16 +public interface TradeBrokerageUserService {
  17 +
  18 + /**
  19 + * 获得分销用户
  20 + *
  21 + * @param id 编号
  22 + * @return 分销用户
  23 + */
  24 + TradeBrokerageUserDO getBrokerageUser(Long id);
  25 +
  26 + /**
  27 + * 获得分销用户列表
  28 + *
  29 + * @param ids 编号
  30 + * @return 分销用户列表
  31 + */
  32 + List<TradeBrokerageUserDO> getBrokerageUserList(Collection<Long> ids);
  33 +
  34 + /**
  35 + * 获得分销用户分页
  36 + *
  37 + * @param pageReqVO 分页查询
  38 + * @return 分销用户分页
  39 + */
  40 + PageResult<TradeBrokerageUserDO> getBrokerageUserPage(TradeBrokerageUserPageReqVO pageReqVO);
  41 +
  42 + /**
  43 + * 修改推广员编号
  44 + *
  45 + * @param id 用户编号
  46 + * @param brokerageUserId 推广员编号
  47 + */
  48 + void updateBrokerageUserId(Long id, Long brokerageUserId);
  49 +
  50 + /**
  51 + * 修改推广资格
  52 + *
  53 + * @param id 用户编号
  54 + * @param brokerageEnabled 推广资格
  55 + */
  56 + void updateBrokerageEnabled(Long id, Boolean brokerageEnabled);
  57 +
  58 + /**
  59 + * 获得用户的推广人
  60 + *
  61 + * @param id 用户编号
  62 + * @return 用户的推广人
  63 + */
  64 + TradeBrokerageUserDO getInviteBrokerageUser(Long id);
  65 +
  66 + /**
  67 + * 更新用户佣金
  68 + *
  69 + * @param id 用户编号
  70 + * @param brokeragePrice 用户可用佣金
  71 + */
  72 + void updateUserBrokeragePrice(Long id, int brokeragePrice);
  73 +
  74 + // TODO @疯狂:int 类型一般不用哈;尽量都用封装类型;不差这点内存哈;
  75 + /**
  76 + * 更新用户冻结佣金
  77 + *
  78 + * @param id 用户编号
  79 + * @param frozenBrokeragePrice 用户冻结佣金
  80 + */
  81 + void updateUserFrozenBrokeragePrice(Long id, int frozenBrokeragePrice);
  82 +
  83 + /**
  84 + * 更新用户冻结佣金(减少), 更新用户佣金(增加)
  85 + *
  86 + * @param id 用户编号
  87 + * @param frozenBrokeragePrice 减少冻结佣金(负数)
  88 + */
  89 + void updateFrozenBrokeragePriceDecrAndBrokeragePriceIncr(Long id, int frozenBrokeragePrice);
  90 +
  91 +}
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/user/TradeBrokerageUserServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.service.brokerage.user;
  2 +
  3 +import cn.hutool.core.lang.Assert;
  4 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  5 +import cn.iocoder.yudao.module.trade.controller.admin.brokerage.user.vo.TradeBrokerageUserPageReqVO;
  6 +import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.user.TradeBrokerageUserDO;
  7 +import cn.iocoder.yudao.module.trade.dal.mysql.brokerage.user.TradeBrokerageUserMapper;
  8 +import org.springframework.stereotype.Service;
  9 +import org.springframework.transaction.annotation.Transactional;
  10 +import org.springframework.validation.annotation.Validated;
  11 +
  12 +import javax.annotation.Resource;
  13 +import java.util.Collection;
  14 +import java.util.List;
  15 +import java.util.Optional;
  16 +
  17 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  18 +import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.MEMBER_FROZEN_BROKERAGE_PRICE_NOT_ENOUGH;
  19 +import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.BROKERAGE_USER_NOT_EXISTS;
  20 +
  21 +/**
  22 + * 分销用户 Service 实现类
  23 + *
  24 + * @author owen
  25 + */
  26 +@Service
  27 +@Validated
  28 +public class TradeBrokerageUserServiceImpl implements TradeBrokerageUserService {
  29 +
  30 + @Resource
  31 + private TradeBrokerageUserMapper brokerageUserMapper;
  32 +
  33 + @Override
  34 + public TradeBrokerageUserDO getBrokerageUser(Long id) {
  35 + return brokerageUserMapper.selectById(id);
  36 + }
  37 +
  38 + @Override
  39 + public List<TradeBrokerageUserDO> getBrokerageUserList(Collection<Long> ids) {
  40 + return brokerageUserMapper.selectBatchIds(ids);
  41 + }
  42 +
  43 + @Override
  44 + public PageResult<TradeBrokerageUserDO> getBrokerageUserPage(TradeBrokerageUserPageReqVO pageReqVO) {
  45 + return brokerageUserMapper.selectPage(pageReqVO);
  46 + }
  47 +
  48 + @Override
  49 + public void updateBrokerageUserId(Long id, Long brokerageUserId) {
  50 + // 校验存在
  51 + validateBrokerageUserExists(id);
  52 + // TODO @疯狂:貌似没实现完
  53 + }
  54 +
  55 + @Override
  56 + public void updateBrokerageEnabled(Long id, Boolean brokerageEnabled) {
  57 + // 校验存在
  58 + validateBrokerageUserExists(id);
  59 + // TODO @疯狂:貌似没实现完
  60 + }
  61 +
  62 + private void validateBrokerageUserExists(Long id) {
  63 + if (brokerageUserMapper.selectById(id) == null) {
  64 + throw exception(BROKERAGE_USER_NOT_EXISTS);
  65 + }
  66 + }
  67 +
  68 + // TODO @疯狂:getBindBrokerageUser 会不会好点,因为统一使用 Bind 替代了 Invite
  69 + @Override
  70 + public TradeBrokerageUserDO getInviteBrokerageUser(Long id) {
  71 + return Optional.ofNullable(id)
  72 + .map(this::getBrokerageUser)
  73 + .map(TradeBrokerageUserDO::getBrokerageUserId)
  74 + .map(this::getBrokerageUser)
  75 + .orElse(null);
  76 + }
  77 +
  78 + // TODO @疯狂:单个更新,不用事务哈;
  79 + @Override
  80 + @Transactional(rollbackFor = Exception.class)
  81 + public void updateUserBrokeragePrice(Long id, int brokeragePrice) {
  82 + if (brokeragePrice > 0) {
  83 + brokerageUserMapper.updateBrokeragePriceIncr(id, brokeragePrice);
  84 + } else if (brokeragePrice < 0) {
  85 + brokerageUserMapper.updateBrokeragePriceDecr(id, brokeragePrice);
  86 + }
  87 + }
  88 +
  89 + // TODO @疯狂:单个更新,不用事务哈;
  90 + @Override
  91 + @Transactional(rollbackFor = Exception.class)
  92 + public void updateUserFrozenBrokeragePrice(Long id, int frozenBrokeragePrice) {
  93 + if (frozenBrokeragePrice > 0) {
  94 + brokerageUserMapper.updateFrozenBrokeragePriceIncr(id, frozenBrokeragePrice);
  95 + } else if (frozenBrokeragePrice < 0) {
  96 + brokerageUserMapper.updateFrozenBrokeragePriceDecr(id, frozenBrokeragePrice);
  97 + }
  98 + }
  99 +
  100 + // TODO @疯狂:单个更新,不用事务哈;
  101 + @Override
  102 + @Transactional(rollbackFor = Exception.class)
  103 + public void updateFrozenBrokeragePriceDecrAndBrokeragePriceIncr(Long id, int frozenBrokeragePrice) {
  104 + Assert.isTrue(frozenBrokeragePrice < 0);
  105 + int updateRows = brokerageUserMapper.updateFrozenBrokeragePriceDecrAndBrokeragePriceIncr(id, frozenBrokeragePrice);
  106 + if (updateRows == 0) {
  107 + // TODO @疯狂:挪到 trade 这变的错误码哈;
  108 + throw exception(MEMBER_FROZEN_BROKERAGE_PRICE_NOT_ENOUGH);
  109 + }
  110 + }
  111 +
  112 +}
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/config/TradeConfigService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.service.config;
  2 +
  3 +import cn.iocoder.yudao.module.trade.controller.admin.config.vo.TradeConfigSaveReqVO;
  4 +import cn.iocoder.yudao.module.trade.dal.dataobject.config.TradeConfigDO;
  5 +
  6 +import javax.validation.Valid;
  7 +
  8 +/**
  9 + * 交易中心配置 Service 接口
  10 + *
  11 + * @author owen
  12 + */
  13 +public interface TradeConfigService {
  14 +
  15 + /**
  16 + * 更新交易中心配置
  17 + *
  18 + * @param updateReqVO 更新信息
  19 + */
  20 + void saveTradeConfig(@Valid TradeConfigSaveReqVO updateReqVO);
  21 +
  22 + /**
  23 + * 获得交易中心配置
  24 + *
  25 + * @return 交易中心配置
  26 + */
  27 + TradeConfigDO getTradeConfig();
  28 +
  29 +}
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/config/TradeConfigServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.service.config;
  2 +
  3 +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
  4 +import cn.iocoder.yudao.module.trade.controller.admin.config.vo.TradeConfigSaveReqVO;
  5 +import cn.iocoder.yudao.module.trade.convert.config.TradeConfigConvert;
  6 +import cn.iocoder.yudao.module.trade.dal.dataobject.config.TradeConfigDO;
  7 +import cn.iocoder.yudao.module.trade.dal.mysql.config.TradeConfigMapper;
  8 +import org.springframework.stereotype.Service;
  9 +import org.springframework.validation.annotation.Validated;
  10 +
  11 +import javax.annotation.Resource;
  12 +import java.util.List;
  13 +
  14 +/**
  15 + * 交易中心配置 Service 实现类
  16 + *
  17 + * @author owen
  18 + */
  19 +@Service
  20 +@Validated
  21 +public class TradeConfigServiceImpl implements TradeConfigService {
  22 +
  23 + @Resource
  24 + private TradeConfigMapper tradeConfigMapper;
  25 +
  26 + @Override
  27 + public void saveTradeConfig(TradeConfigSaveReqVO saveReqVO) {
  28 + // 存在,则进行更新
  29 + TradeConfigDO dbConfig = getTradeConfig();
  30 + if (dbConfig != null) {
  31 + tradeConfigMapper.updateById(TradeConfigConvert.INSTANCE.convert(saveReqVO).setId(dbConfig.getId()));
  32 + return;
  33 + }
  34 + // 不存在,则进行插入
  35 + tradeConfigMapper.insert(TradeConfigConvert.INSTANCE.convert(saveReqVO));
  36 + }
  37 +
  38 + @Override
  39 + public TradeConfigDO getTradeConfig() {
  40 + List<TradeConfigDO> list = tradeConfigMapper.selectList();
  41 + return CollectionUtils.getFirst(list);
  42 + }
  43 +
  44 +}
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java
@@ -11,6 +11,8 @@ import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; @@ -11,6 +11,8 @@ import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
11 import cn.iocoder.yudao.framework.common.util.json.JsonUtils; 11 import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
12 import cn.iocoder.yudao.module.member.api.address.AddressApi; 12 import cn.iocoder.yudao.module.member.api.address.AddressApi;
13 import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO; 13 import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO;
  14 +import cn.iocoder.yudao.module.trade.service.brokerage.record.TradeBrokerageRecordService;
  15 +import cn.iocoder.yudao.module.trade.service.brokerage.record.bo.BrokerageAddReqBO;
14 import cn.iocoder.yudao.module.member.api.level.MemberLevelApi; 16 import cn.iocoder.yudao.module.member.api.level.MemberLevelApi;
15 import cn.iocoder.yudao.module.member.api.point.MemberPointApi; 17 import cn.iocoder.yudao.module.member.api.point.MemberPointApi;
16 import cn.iocoder.yudao.module.member.api.user.MemberUserApi; 18 import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
@@ -126,6 +128,8 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { @@ -126,6 +128,8 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
126 @Resource 128 @Resource
127 private MemberPointApi memberPointApi; 129 private MemberPointApi memberPointApi;
128 @Resource 130 @Resource
  131 + private TradeBrokerageRecordService tradeBrokerageRecordService;
  132 + @Resource
129 private ProductCommentApi productCommentApi; 133 private ProductCommentApi productCommentApi;
130 134
131 @Resource 135 @Resource
@@ -389,6 +393,8 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { @@ -389,6 +393,8 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
389 getSelf().addUserPointAsync(order.getUserId(), order.getPayPrice(), order.getId()); 393 getSelf().addUserPointAsync(order.getUserId(), order.getPayPrice(), order.getId());
390 // 增加用户经验 394 // 增加用户经验
391 getSelf().addUserExperienceAsync(order.getUserId(), order.getPayPrice(), order.getId()); 395 getSelf().addUserExperienceAsync(order.getUserId(), order.getPayPrice(), order.getId());
  396 + // 增加用户佣金
  397 + getSelf().addBrokerageAsync(order.getUserId(), order.getId());
392 } 398 }
393 399
394 /** 400 /**
@@ -659,12 +665,12 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { @@ -659,12 +665,12 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
659 .setRefundStatus(TradeOrderRefundStatusEnum.PART.getStatus()).setRefundPrice(orderRefundPrice)); 665 .setRefundStatus(TradeOrderRefundStatusEnum.PART.getStatus()).setRefundPrice(orderRefundPrice));
660 } 666 }
661 667
662 - // TODO 芋艿:未来如果有分佣,需要更新相关分佣订单为已失效  
663 -  
664 // 扣减用户积分 668 // 扣减用户积分
665 getSelf().reduceUserPointAsync(order.getUserId(), orderRefundPrice, afterSaleId); 669 getSelf().reduceUserPointAsync(order.getUserId(), orderRefundPrice, afterSaleId);
666 // 扣减用户经验 670 // 扣减用户经验
667 getSelf().reduceUserExperienceAsync(order.getUserId(), orderRefundPrice, afterSaleId); 671 getSelf().reduceUserExperienceAsync(order.getUserId(), orderRefundPrice, afterSaleId);
  672 + // 更新分佣记录为已失效
  673 + getSelf().cancelBrokerageAsync(order.getUserId(), id);
668 } 674 }
669 675
670 @Override 676 @Override
@@ -772,6 +778,20 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { @@ -772,6 +778,20 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
772 memberPointApi.addPoint(userId, -refundPrice, bizType, String.valueOf(afterSaleId)); 778 memberPointApi.addPoint(userId, -refundPrice, bizType, String.valueOf(afterSaleId));
773 } 779 }
774 780
  781 +
  782 + @Async
  783 + protected void addBrokerageAsync(Long userId, Long orderId) {
  784 + List<TradeOrderItemDO> orderItems = tradeOrderItemMapper.selectListByOrderId(orderId);
  785 + List<BrokerageAddReqBO> list = convertList(orderItems,
  786 + item -> TradeOrderConvert.INSTANCE.convert(item, productSkuApi.getSku(item.getSkuId())));
  787 + tradeBrokerageRecordService.addBrokerage(userId, list);
  788 + }
  789 +
  790 + @Async
  791 + protected void cancelBrokerageAsync(Long userId, Long orderItemId) {
  792 + tradeBrokerageRecordService.cancelBrokerage(userId, String.valueOf(orderItemId));
  793 + }
  794 +
775 /** 795 /**
776 * 获得自身的代理对象,解决 AOP 生效问题 796 * 获得自身的代理对象,解决 AOP 生效问题
777 * 797 *
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeCouponPriceCalculator.java
@@ -102,7 +102,10 @@ public class TradeCouponPriceCalculator implements TradePriceCalculator { @@ -102,7 +102,10 @@ public class TradeCouponPriceCalculator implements TradePriceCalculator {
102 Predicate<TradePriceCalculateRespBO.OrderItem> matchPredicate = TradePriceCalculateRespBO.OrderItem::getSelected; 102 Predicate<TradePriceCalculateRespBO.OrderItem> matchPredicate = TradePriceCalculateRespBO.OrderItem::getSelected;
103 if (PromotionProductScopeEnum.SPU.getScope().equals(coupon.getProductScope())) { 103 if (PromotionProductScopeEnum.SPU.getScope().equals(coupon.getProductScope())) {
104 matchPredicate = matchPredicate // 额外加如下条件 104 matchPredicate = matchPredicate // 额外加如下条件
105 - .and(orderItem -> coupon.getProductSpuIds().contains(orderItem.getSpuId())); 105 + .and(orderItem -> coupon.getProductScopeValues().contains(orderItem.getSpuId()));
  106 + } else if (PromotionProductScopeEnum.CATEGORY.getScope().equals(coupon.getProductScope())) {
  107 + matchPredicate = matchPredicate // 额外加如下条件
  108 + .and(orderItem -> coupon.getProductScopeValues().contains(orderItem.getCategoryId()));
106 } 109 }
107 return filterList(result.getItems(), matchPredicate); 110 return filterList(result.getItems(), matchPredicate);
108 } 111 }
yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/brokerage/record/TradeBrokerageRecordServiceImplTest.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.service.brokerage.record;
  2 +
  3 +import cn.hutool.core.util.NumberUtil;
  4 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  5 +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
  6 +import cn.iocoder.yudao.module.trade.controller.admin.brokerage.record.vo.TradeBrokerageRecordPageReqVO;
  7 +import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.record.TradeBrokerageRecordDO;
  8 +import cn.iocoder.yudao.module.trade.dal.mysql.brokerage.record.TradeBrokerageRecordMapper;
  9 +import cn.iocoder.yudao.module.trade.service.brokerage.user.TradeBrokerageUserService;
  10 +import cn.iocoder.yudao.module.trade.service.config.TradeConfigService;
  11 +import org.junit.jupiter.api.Disabled;
  12 +import org.junit.jupiter.api.Test;
  13 +import org.springframework.boot.test.mock.mockito.MockBean;
  14 +import org.springframework.context.annotation.Import;
  15 +
  16 +import javax.annotation.Resource;
  17 +import java.math.RoundingMode;
  18 +
  19 +import static cn.hutool.core.util.RandomUtil.randomEle;
  20 +import static cn.hutool.core.util.RandomUtil.randomInt;
  21 +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime;
  22 +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
  23 +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
  24 +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomInteger;
  25 +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
  26 +import static org.junit.jupiter.api.Assertions.assertEquals;
  27 +
  28 +// TODO @芋艿:单测后续看看
  29 +/**
  30 + * {@link TradeBrokerageRecordServiceImpl} 的单元测试类
  31 + *
  32 + * @author owen
  33 + */
  34 +@Import(TradeBrokerageRecordServiceImpl.class)
  35 +public class TradeBrokerageRecordServiceImplTest extends BaseDbUnitTest {
  36 +
  37 + @Resource
  38 + private TradeBrokerageRecordServiceImpl tradeBrokerageRecordService;
  39 + @Resource
  40 + private TradeBrokerageRecordMapper tradeBrokerageRecordMapper;
  41 +
  42 + @MockBean
  43 + private TradeConfigService tradeConfigService;
  44 + @MockBean
  45 + private TradeBrokerageUserService tradeBrokerageUserService;
  46 +
  47 + @Test
  48 + @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
  49 + public void testGetBrokerageRecordPage() {
  50 + // mock 数据
  51 + TradeBrokerageRecordDO dbBrokerageRecord = randomPojo(TradeBrokerageRecordDO.class, o -> { // 等会查询到
  52 + o.setUserId(null);
  53 + o.setBizType(null);
  54 + o.setStatus(null);
  55 + o.setCreateTime(null);
  56 + });
  57 + tradeBrokerageRecordMapper.insert(dbBrokerageRecord);
  58 + // 测试 userId 不匹配
  59 + tradeBrokerageRecordMapper.insert(cloneIgnoreId(dbBrokerageRecord, o -> o.setUserId(null)));
  60 + // 测试 bizType 不匹配
  61 + tradeBrokerageRecordMapper.insert(cloneIgnoreId(dbBrokerageRecord, o -> o.setBizType(null)));
  62 + // 测试 status 不匹配
  63 + tradeBrokerageRecordMapper.insert(cloneIgnoreId(dbBrokerageRecord, o -> o.setStatus(null)));
  64 + // 测试 createTime 不匹配
  65 + tradeBrokerageRecordMapper.insert(cloneIgnoreId(dbBrokerageRecord, o -> o.setCreateTime(null)));
  66 + // 准备参数
  67 + TradeBrokerageRecordPageReqVO reqVO = new TradeBrokerageRecordPageReqVO();
  68 + reqVO.setUserId(null);
  69 + reqVO.setBizType(null);
  70 + reqVO.setStatus(null);
  71 + reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
  72 +
  73 + // 调用
  74 + PageResult<TradeBrokerageRecordDO> pageResult = tradeBrokerageRecordService.getBrokerageRecordPage(reqVO);
  75 + // 断言
  76 + assertEquals(1, pageResult.getTotal());
  77 + assertEquals(1, pageResult.getList().size());
  78 + assertPojoEquals(dbBrokerageRecord, pageResult.getList().get(0));
  79 + }
  80 +
  81 + @Test
  82 + public void testCalculateBrokerage_useSkuBrokeragePrice() {
  83 + // mock 数据
  84 + Integer payPrice = randomInteger();
  85 + Integer percent = randomInt(1, 101);
  86 + Integer skuBrokeragePrice = randomInt();
  87 + // 调用
  88 + int brokerage = tradeBrokerageRecordService.calculateBrokerage(payPrice, percent, skuBrokeragePrice);
  89 + // 断言
  90 + assertEquals(brokerage, skuBrokeragePrice);
  91 + }
  92 +
  93 + @Test
  94 + public void testCalculateBrokerage_usePercent() {
  95 + // mock 数据
  96 + Integer payPrice = randomInteger();
  97 + Integer percent = randomInt(1, 101);
  98 + Integer skuBrokeragePrice = randomEle(new Integer[]{0, null});
  99 + System.out.println("skuBrokeragePrice=" + skuBrokeragePrice);
  100 + // 调用
  101 + int brokerage = tradeBrokerageRecordService.calculateBrokerage(payPrice, percent, skuBrokeragePrice);
  102 + // 断言
  103 + assertEquals(brokerage, NumberUtil.div(NumberUtil.mul(payPrice, percent), 100, 0, RoundingMode.DOWN).intValue());
  104 + }
  105 +
  106 + @Test
  107 + public void testCalculateBrokerage_equalsZero() {
  108 + // mock 数据
  109 + Integer payPrice = null;
  110 + Integer percent = null;
  111 + Integer skuBrokeragePrice = null;
  112 + // 调用
  113 + int brokerage = tradeBrokerageRecordService.calculateBrokerage(payPrice, percent, skuBrokeragePrice);
  114 + // 断言
  115 + assertEquals(brokerage, 0);
  116 + }
  117 +}
yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/brokerage/user/TradeBrokerageUserServiceImplTest.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.service.brokerage.user;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
  5 +import cn.iocoder.yudao.module.trade.controller.admin.brokerage.user.vo.TradeBrokerageUserPageReqVO;
  6 +import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.user.TradeBrokerageUserDO;
  7 +import cn.iocoder.yudao.module.trade.dal.mysql.brokerage.user.TradeBrokerageUserMapper;
  8 +import org.junit.jupiter.api.Disabled;
  9 +import org.junit.jupiter.api.Test;
  10 +import org.springframework.context.annotation.Import;
  11 +
  12 +import javax.annotation.Resource;
  13 +
  14 +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime;
  15 +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
  16 +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
  17 +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
  18 +import static org.junit.jupiter.api.Assertions.assertEquals;
  19 +
  20 +// TODO @芋艿:单测后续看看
  21 +/**
  22 + * {@link TradeBrokerageUserServiceImpl} 的单元测试类
  23 + *
  24 + * @author owen
  25 + */
  26 +@Import(TradeBrokerageUserServiceImpl.class)
  27 +public class TradeBrokerageUserServiceImplTest extends BaseDbUnitTest {
  28 +
  29 + @Resource
  30 + private TradeBrokerageUserServiceImpl brokerageUserService;
  31 +
  32 + @Resource
  33 + private TradeBrokerageUserMapper brokerageUserMapper;
  34 +
  35 + @Test
  36 + @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解
  37 + public void testGetBrokerageUserPage() {
  38 + // mock 数据
  39 + TradeBrokerageUserDO dbBrokerageUser = randomPojo(TradeBrokerageUserDO.class, o -> { // 等会查询到
  40 + o.setBrokerageUserId(null);
  41 + o.setBrokerageEnabled(null);
  42 + o.setCreateTime(null);
  43 + });
  44 + brokerageUserMapper.insert(dbBrokerageUser);
  45 + // 测试 brokerageUserId 不匹配
  46 + brokerageUserMapper.insert(cloneIgnoreId(dbBrokerageUser, o -> o.setBrokerageUserId(null)));
  47 + // 测试 brokerageEnabled 不匹配
  48 + brokerageUserMapper.insert(cloneIgnoreId(dbBrokerageUser, o -> o.setBrokerageEnabled(null)));
  49 + // 测试 createTime 不匹配
  50 + brokerageUserMapper.insert(cloneIgnoreId(dbBrokerageUser, o -> o.setCreateTime(null)));
  51 + // 准备参数
  52 + TradeBrokerageUserPageReqVO reqVO = new TradeBrokerageUserPageReqVO();
  53 + reqVO.setBrokerageUserId(null);
  54 + reqVO.setBrokerageEnabled(null);
  55 + reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28));
  56 +
  57 + // 调用
  58 + PageResult<TradeBrokerageUserDO> pageResult = brokerageUserService.getBrokerageUserPage(reqVO);
  59 + // 断言
  60 + assertEquals(1, pageResult.getTotal());
  61 + assertEquals(1, pageResult.getList().size());
  62 + assertPojoEquals(dbBrokerageUser, pageResult.getList().get(0));
  63 + }
  64 +
  65 +}
yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeCouponPriceCalculatorTest.java
@@ -65,7 +65,7 @@ public class TradeCouponPriceCalculatorTest extends BaseMockitoUnitTest { @@ -65,7 +65,7 @@ public class TradeCouponPriceCalculatorTest extends BaseMockitoUnitTest {
65 65
66 // mock 方法(优惠劵 Coupon 信息) 66 // mock 方法(优惠劵 Coupon 信息)
67 CouponRespDTO coupon = randomPojo(CouponRespDTO.class, o -> o.setId(1024L).setName("程序员节") 67 CouponRespDTO coupon = randomPojo(CouponRespDTO.class, o -> o.setId(1024L).setName("程序员节")
68 - .setProductScope(PromotionProductScopeEnum.SPU.getScope()).setProductSpuIds(asList(1L, 2L)) 68 + .setProductScope(PromotionProductScopeEnum.SPU.getScope()).setProductScopeValues(asList(1L, 2L))
69 .setUsePrice(350).setDiscountType(PromotionDiscountTypeEnum.PERCENT.getType()) 69 .setUsePrice(350).setDiscountType(PromotionDiscountTypeEnum.PERCENT.getType())
70 .setDiscountPercent(50).setDiscountLimitPrice(70)); 70 .setDiscountPercent(50).setDiscountLimitPrice(70));
71 when(couponApi.validateCoupon(eq(new CouponValidReqDTO().setId(1024L).setUserId(233L)))).thenReturn(coupon); 71 when(couponApi.validateCoupon(eq(new CouponValidReqDTO().setId(1024L).setUserId(233L)))).thenReturn(coupon);
yudao-module-mall/yudao-module-trade-biz/src/test/resources/sql/clean.sql
@@ -2,3 +2,5 @@ DELETE FROM trade_order; @@ -2,3 +2,5 @@ DELETE FROM trade_order;
2 DELETE FROM trade_order_item; 2 DELETE FROM trade_order_item;
3 DELETE FROM trade_after_sale; 3 DELETE FROM trade_after_sale;
4 DELETE FROM trade_after_sale_log; 4 DELETE FROM trade_after_sale_log;
  5 +DELETE FROM trade_brokerage_user;
  6 +DELETE FROM trade_brokerage_record;
yudao-module-mall/yudao-module-trade-biz/src/test/resources/sql/create_tables.sql
@@ -125,3 +125,42 @@ CREATE TABLE IF NOT EXISTS &quot;trade_after_sale_log&quot; ( @@ -125,3 +125,42 @@ CREATE TABLE IF NOT EXISTS &quot;trade_after_sale_log&quot; (
125 "deleted" bit NOT NULL DEFAULT FALSE, 125 "deleted" bit NOT NULL DEFAULT FALSE,
126 PRIMARY KEY ("id") 126 PRIMARY KEY ("id")
127 ) COMMENT '交易售后日志'; 127 ) COMMENT '交易售后日志';
  128 +
  129 +CREATE TABLE IF NOT EXISTS "trade_brokerage_user"
  130 +(
  131 + "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
  132 + "brokerage_user_id" bigint NOT NULL,
  133 + "brokerage_bind_time" varchar,
  134 + "brokerage_enabled" bit NOT NULL,
  135 + "brokerage_time" varchar,
  136 + "brokerage_price" int NOT NULL,
  137 + "frozen_brokerage_price" int NOT NULL,
  138 + "creator" varchar DEFAULT '',
  139 + "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  140 + "updater" varchar DEFAULT '',
  141 + "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  142 + "deleted" bit NOT NULL DEFAULT FALSE,
  143 + "tenant_id" bigint NOT NULL DEFAULT '0',
  144 + PRIMARY KEY ("id")
  145 +) COMMENT '分销用户';
  146 +CREATE TABLE IF NOT EXISTS "trade_brokerage_record"
  147 +(
  148 + "id" int NOT NULL GENERATED BY DEFAULT AS IDENTITY,
  149 + "user_id" bigint NOT NULL,
  150 + "biz_id" varchar NOT NULL,
  151 + "biz_type" varchar NOT NULL,
  152 + "title" varchar NOT NULL,
  153 + "price" int NOT NULL,
  154 + "total_price" int NOT NULL,
  155 + "description" varchar NOT NULL,
  156 + "status" varchar NOT NULL,
  157 + "frozen_days" int NOT NULL,
  158 + "unfreeze_time" varchar,
  159 + "creator" varchar DEFAULT '',
  160 + "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  161 + "updater" varchar DEFAULT '',
  162 + "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  163 + "deleted" bit NOT NULL DEFAULT FALSE,
  164 + "tenant_id" bigint not null default '0',
  165 + PRIMARY KEY ("id")
  166 +) COMMENT '佣金记录';
128 \ No newline at end of file 167 \ No newline at end of file
yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/ErrorCodeConstants.java
@@ -9,10 +9,11 @@ import cn.iocoder.yudao.framework.common.exception.ErrorCode; @@ -9,10 +9,11 @@ import cn.iocoder.yudao.framework.common.exception.ErrorCode;
9 */ 9 */
10 public interface ErrorCodeConstants { 10 public interface ErrorCodeConstants {
11 11
12 - // ========== 用户相关 1004001000============ 12 + // ========== 用户相关 1004001000============
13 ErrorCode USER_NOT_EXISTS = new ErrorCode(1004001000, "用户不存在"); 13 ErrorCode USER_NOT_EXISTS = new ErrorCode(1004001000, "用户不存在");
14 ErrorCode USER_MOBILE_NOT_EXISTS = new ErrorCode(1004001001, "手机号未注册用户"); 14 ErrorCode USER_MOBILE_NOT_EXISTS = new ErrorCode(1004001001, "手机号未注册用户");
15 ErrorCode USER_MOBILE_USED = new ErrorCode(1004001002, "修改手机失败,该手机号({})已经被使用"); 15 ErrorCode USER_MOBILE_USED = new ErrorCode(1004001002, "修改手机失败,该手机号({})已经被使用");
  16 + ErrorCode MEMBER_FROZEN_BROKERAGE_PRICE_NOT_ENOUGH = new ErrorCode(1004001003, "用户冻结佣金({})数量不足");
16 17
17 // ========== AUTH 模块 1004003000 ========== 18 // ========== AUTH 模块 1004003000 ==========
18 ErrorCode AUTH_LOGIN_BAD_CREDENTIALS = new ErrorCode(1004003000, "登录失败,账号密码不正确"); 19 ErrorCode AUTH_LOGIN_BAD_CREDENTIALS = new ErrorCode(1004003000, "登录失败,账号密码不正确");
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/AppMemberUserController.java
@@ -39,7 +39,9 @@ public class AppMemberUserController { @@ -39,7 +39,9 @@ public class AppMemberUserController {
39 public CommonResult<AppMemberUserInfoRespVO> getUserInfo() { 39 public CommonResult<AppMemberUserInfoRespVO> getUserInfo() {
40 MemberUserDO user = userService.getUser(getLoginUserId()); 40 MemberUserDO user = userService.getUser(getLoginUserId());
41 MemberLevelDO level = levelService.getLevel(user.getLevelId()); 41 MemberLevelDO level = levelService.getLevel(user.getLevelId());
42 - return success(MemberUserConvert.INSTANCE.convert(user, level)); 42 + return success(MemberUserConvert.INSTANCE.convert(user, level)
  43 + .setBrokerageEnabled(true) // TODO @疯狂:这里我先写死,后面改成 db 返回;
  44 + );
43 } 45 }
44 46
45 @PutMapping("/update") 47 @PutMapping("/update")
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/user/vo/AppMemberUserInfoRespVO.java
@@ -29,6 +29,9 @@ public class AppMemberUserInfoRespVO { @@ -29,6 +29,9 @@ public class AppMemberUserInfoRespVO {
29 @Schema(description = "用户等级") 29 @Schema(description = "用户等级")
30 private Level level; 30 private Level level;
31 31
  32 + @Schema(description = "是否成为推广员", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
  33 + private Boolean brokerageEnabled;
  34 +
32 @Schema(description = "用户 App - 会员等级") 35 @Schema(description = "用户 App - 会员等级")
33 @Data 36 @Data
34 public static class Level { 37 public static class Level {
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/point/MemberPointConfigDO.java
@@ -6,14 +6,12 @@ import com.baomidou.mybatisplus.annotation.TableId; @@ -6,14 +6,12 @@ import com.baomidou.mybatisplus.annotation.TableId;
6 import com.baomidou.mybatisplus.annotation.TableName; 6 import com.baomidou.mybatisplus.annotation.TableName;
7 import lombok.*; 7 import lombok.*;
8 8
9 -import java.math.BigDecimal;  
10 -  
11 /** 9 /**
12 * 会员积分配置 DO 10 * 会员积分配置 DO
13 * 11 *
14 * @author QingX 12 * @author QingX
15 */ 13 */
16 -@TableName("member_point_config") 14 +@TableName(value = "member_point_config", autoResultMap = true)
17 @KeySequence("member_point_config_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 15 @KeySequence("member_point_config_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
18 @Data 16 @Data
19 @EqualsAndHashCode(callSuper = true) 17 @EqualsAndHashCode(callSuper = true)
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/dataobject/user/MemberUserDO.java
@@ -136,4 +136,38 @@ public class MemberUserDO extends TenantBaseDO { @@ -136,4 +136,38 @@ public class MemberUserDO extends TenantBaseDO {
136 */ 136 */
137 private Long groupId; 137 private Long groupId;
138 138
  139 + // TODO @疯狂:看看要不要删除掉哈
  140 + // ========== 分销相关 ==========
  141 +
  142 + /**
  143 + * 推广员编号
  144 + */
  145 + @TableField(exist = false) // TODO 芋艿:避免报错
  146 + private Long brokerageUserId;
  147 + /**
  148 + * 推广员绑定时间
  149 + */
  150 + @TableField(exist = false) // TODO 芋艿:避免报错
  151 + private LocalDateTime brokerageBindTime;
  152 + /**
  153 + * 是否成为推广员
  154 + */
  155 + @TableField(exist = false) // TODO 芋艿:避免报错
  156 + private Boolean brokerageEnabled;
  157 + /**
  158 + * 成为分销员时间
  159 + */
  160 + @TableField(exist = false) // TODO 芋艿:避免报错
  161 + private LocalDateTime brokerageTime;
  162 + /**
  163 + * 可用佣金
  164 + */
  165 + @TableField(exist = false) // TODO 芋艿:避免报错
  166 + private Integer brokeragePrice;
  167 + /**
  168 + * 冻结佣金
  169 + */
  170 + @TableField(exist = false) // TODO 芋艿:避免报错
  171 + private Integer frozenBrokeragePrice;
  172 +
139 } 173 }
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/address/AddressMapper.java renamed to yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/address/MemberAddressMapper.java
@@ -8,7 +8,7 @@ import org.apache.ibatis.annotations.Mapper; @@ -8,7 +8,7 @@ import org.apache.ibatis.annotations.Mapper;
8 import java.util.List; 8 import java.util.List;
9 9
10 @Mapper 10 @Mapper
11 -public interface AddressMapper extends BaseMapperX<MemberAddressDO> { 11 +public interface MemberAddressMapper extends BaseMapperX<MemberAddressDO> {
12 12
13 default MemberAddressDO selectByIdAndUserId(Long id, Long userId) { 13 default MemberAddressDO selectByIdAndUserId(Long id, Long userId) {
14 return selectOne(MemberAddressDO::getId, id, MemberAddressDO::getUserId, userId); 14 return selectOne(MemberAddressDO::getId, id, MemberAddressDO::getUserId, userId);
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/address/AddressServiceImpl.java
@@ -5,7 +5,7 @@ import cn.iocoder.yudao.module.member.controller.app.address.vo.AppAddressCreate @@ -5,7 +5,7 @@ import cn.iocoder.yudao.module.member.controller.app.address.vo.AppAddressCreate
5 import cn.iocoder.yudao.module.member.controller.app.address.vo.AppAddressUpdateReqVO; 5 import cn.iocoder.yudao.module.member.controller.app.address.vo.AppAddressUpdateReqVO;
6 import cn.iocoder.yudao.module.member.convert.address.AddressConvert; 6 import cn.iocoder.yudao.module.member.convert.address.AddressConvert;
7 import cn.iocoder.yudao.module.member.dal.dataobject.address.MemberAddressDO; 7 import cn.iocoder.yudao.module.member.dal.dataobject.address.MemberAddressDO;
8 -import cn.iocoder.yudao.module.member.dal.mysql.address.AddressMapper; 8 +import cn.iocoder.yudao.module.member.dal.mysql.address.MemberAddressMapper;
9 import org.springframework.stereotype.Service; 9 import org.springframework.stereotype.Service;
10 import org.springframework.transaction.annotation.Transactional; 10 import org.springframework.transaction.annotation.Transactional;
11 import org.springframework.validation.annotation.Validated; 11 import org.springframework.validation.annotation.Validated;
@@ -26,21 +26,21 @@ import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.ADDRESS_NO @@ -26,21 +26,21 @@ import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.ADDRESS_NO
26 public class AddressServiceImpl implements AddressService { 26 public class AddressServiceImpl implements AddressService {
27 27
28 @Resource 28 @Resource
29 - private AddressMapper addressMapper; 29 + private MemberAddressMapper memberAddressMapper;
30 30
31 @Override 31 @Override
32 @Transactional(rollbackFor = Exception.class) 32 @Transactional(rollbackFor = Exception.class)
33 public Long createAddress(Long userId, AppAddressCreateReqVO createReqVO) { 33 public Long createAddress(Long userId, AppAddressCreateReqVO createReqVO) {
34 // 如果添加的是默认收件地址,则将原默认地址修改为非默认 34 // 如果添加的是默认收件地址,则将原默认地址修改为非默认
35 if (Boolean.TRUE.equals(createReqVO.getDefaultStatus())) { 35 if (Boolean.TRUE.equals(createReqVO.getDefaultStatus())) {
36 - List<MemberAddressDO> addresses = addressMapper.selectListByUserIdAndDefaulted(userId, true);  
37 - addresses.forEach(address -> addressMapper.updateById(new MemberAddressDO().setId(address.getId()).setDefaultStatus(false))); 36 + List<MemberAddressDO> addresses = memberAddressMapper.selectListByUserIdAndDefaulted(userId, true);
  37 + addresses.forEach(address -> memberAddressMapper.updateById(new MemberAddressDO().setId(address.getId()).setDefaultStatus(false)));
38 } 38 }
39 39
40 // 插入 40 // 插入
41 MemberAddressDO address = AddressConvert.INSTANCE.convert(createReqVO); 41 MemberAddressDO address = AddressConvert.INSTANCE.convert(createReqVO);
42 address.setUserId(userId); 42 address.setUserId(userId);
43 - addressMapper.insert(address); 43 + memberAddressMapper.insert(address);
44 // 返回 44 // 返回
45 return address.getId(); 45 return address.getId();
46 } 46 }
@@ -53,14 +53,14 @@ public class AddressServiceImpl implements AddressService { @@ -53,14 +53,14 @@ public class AddressServiceImpl implements AddressService {
53 53
54 // 如果修改的是默认收件地址,则将原默认地址修改为非默认 54 // 如果修改的是默认收件地址,则将原默认地址修改为非默认
55 if (Boolean.TRUE.equals(updateReqVO.getDefaultStatus())) { 55 if (Boolean.TRUE.equals(updateReqVO.getDefaultStatus())) {
56 - List<MemberAddressDO> addresses = addressMapper.selectListByUserIdAndDefaulted(userId, true); 56 + List<MemberAddressDO> addresses = memberAddressMapper.selectListByUserIdAndDefaulted(userId, true);
57 addresses.stream().filter(u -> !u.getId().equals(updateReqVO.getId())) // 排除自己 57 addresses.stream().filter(u -> !u.getId().equals(updateReqVO.getId())) // 排除自己
58 - .forEach(address -> addressMapper.updateById(new MemberAddressDO().setId(address.getId()).setDefaultStatus(false))); 58 + .forEach(address -> memberAddressMapper.updateById(new MemberAddressDO().setId(address.getId()).setDefaultStatus(false)));
59 } 59 }
60 60
61 // 更新 61 // 更新
62 MemberAddressDO updateObj = AddressConvert.INSTANCE.convert(updateReqVO); 62 MemberAddressDO updateObj = AddressConvert.INSTANCE.convert(updateReqVO);
63 - addressMapper.updateById(updateObj); 63 + memberAddressMapper.updateById(updateObj);
64 } 64 }
65 65
66 @Override 66 @Override
@@ -68,7 +68,7 @@ public class AddressServiceImpl implements AddressService { @@ -68,7 +68,7 @@ public class AddressServiceImpl implements AddressService {
68 // 校验存在,校验是否能够操作 68 // 校验存在,校验是否能够操作
69 validAddressExists(userId, id); 69 validAddressExists(userId, id);
70 // 删除 70 // 删除
71 - addressMapper.deleteById(id); 71 + memberAddressMapper.deleteById(id);
72 } 72 }
73 73
74 private void validAddressExists(Long userId, Long id) { 74 private void validAddressExists(Long userId, Long id) {
@@ -80,17 +80,17 @@ public class AddressServiceImpl implements AddressService { @@ -80,17 +80,17 @@ public class AddressServiceImpl implements AddressService {
80 80
81 @Override 81 @Override
82 public MemberAddressDO getAddress(Long userId, Long id) { 82 public MemberAddressDO getAddress(Long userId, Long id) {
83 - return addressMapper.selectByIdAndUserId(id, userId); 83 + return memberAddressMapper.selectByIdAndUserId(id, userId);
84 } 84 }
85 85
86 @Override 86 @Override
87 public List<MemberAddressDO> getAddressList(Long userId) { 87 public List<MemberAddressDO> getAddressList(Long userId) {
88 - return addressMapper.selectListByUserIdAndDefaulted(userId, null); 88 + return memberAddressMapper.selectListByUserIdAndDefaulted(userId, null);
89 } 89 }
90 90
91 @Override 91 @Override
92 public MemberAddressDO getDefaultUserAddress(Long userId) { 92 public MemberAddressDO getDefaultUserAddress(Long userId) {
93 - List<MemberAddressDO> addresses = addressMapper.selectListByUserIdAndDefaulted(userId, true); 93 + List<MemberAddressDO> addresses = memberAddressMapper.selectListByUserIdAndDefaulted(userId, true);
94 return CollUtil.getFirst(addresses); 94 return CollUtil.getFirst(addresses);
95 } 95 }
96 96
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/group/MemberGroupServiceImpl.java
@@ -31,7 +31,8 @@ import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.GROUP_NOT_ @@ -31,7 +31,8 @@ import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.GROUP_NOT_
31 public class MemberGroupServiceImpl implements MemberGroupService { 31 public class MemberGroupServiceImpl implements MemberGroupService {
32 32
33 @Resource 33 @Resource
34 - private MemberGroupMapper groupMapper; 34 + private MemberGroupMapper memberGroupMapper;
  35 +
35 @Resource 36 @Resource
36 private MemberUserService memberUserService; 37 private MemberUserService memberUserService;
37 38
@@ -39,7 +40,7 @@ public class MemberGroupServiceImpl implements MemberGroupService { @@ -39,7 +40,7 @@ public class MemberGroupServiceImpl implements MemberGroupService {
39 public Long createGroup(MemberGroupCreateReqVO createReqVO) { 40 public Long createGroup(MemberGroupCreateReqVO createReqVO) {
40 // 插入 41 // 插入
41 MemberGroupDO group = MemberGroupConvert.INSTANCE.convert(createReqVO); 42 MemberGroupDO group = MemberGroupConvert.INSTANCE.convert(createReqVO);
42 - groupMapper.insert(group); 43 + memberGroupMapper.insert(group);
43 // 返回 44 // 返回
44 return group.getId(); 45 return group.getId();
45 } 46 }
@@ -50,7 +51,7 @@ public class MemberGroupServiceImpl implements MemberGroupService { @@ -50,7 +51,7 @@ public class MemberGroupServiceImpl implements MemberGroupService {
50 validateGroupExists(updateReqVO.getId()); 51 validateGroupExists(updateReqVO.getId());
51 // 更新 52 // 更新
52 MemberGroupDO updateObj = MemberGroupConvert.INSTANCE.convert(updateReqVO); 53 MemberGroupDO updateObj = MemberGroupConvert.INSTANCE.convert(updateReqVO);
53 - groupMapper.updateById(updateObj); 54 + memberGroupMapper.updateById(updateObj);
54 } 55 }
55 56
56 @Override 57 @Override
@@ -60,11 +61,11 @@ public class MemberGroupServiceImpl implements MemberGroupService { @@ -60,11 +61,11 @@ public class MemberGroupServiceImpl implements MemberGroupService {
60 // 校验分组下是否有用户 61 // 校验分组下是否有用户
61 validateGroupHasUser(id); 62 validateGroupHasUser(id);
62 // 删除 63 // 删除
63 - groupMapper.deleteById(id); 64 + memberGroupMapper.deleteById(id);
64 } 65 }
65 66
66 void validateGroupExists(Long id) { 67 void validateGroupExists(Long id) {
67 - if (groupMapper.selectById(id) == null) { 68 + if (memberGroupMapper.selectById(id) == null) {
68 throw exception(GROUP_NOT_EXISTS); 69 throw exception(GROUP_NOT_EXISTS);
69 } 70 }
70 } 71 }
@@ -78,7 +79,7 @@ public class MemberGroupServiceImpl implements MemberGroupService { @@ -78,7 +79,7 @@ public class MemberGroupServiceImpl implements MemberGroupService {
78 79
79 @Override 80 @Override
80 public MemberGroupDO getGroup(Long id) { 81 public MemberGroupDO getGroup(Long id) {
81 - return groupMapper.selectById(id); 82 + return memberGroupMapper.selectById(id);
82 } 83 }
83 84
84 @Override 85 @Override
@@ -86,17 +87,17 @@ public class MemberGroupServiceImpl implements MemberGroupService { @@ -86,17 +87,17 @@ public class MemberGroupServiceImpl implements MemberGroupService {
86 if (CollUtil.isEmpty(ids)) { 87 if (CollUtil.isEmpty(ids)) {
87 return ListUtil.empty(); 88 return ListUtil.empty();
88 } 89 }
89 - return groupMapper.selectBatchIds(ids); 90 + return memberGroupMapper.selectBatchIds(ids);
90 } 91 }
91 92
92 @Override 93 @Override
93 public PageResult<MemberGroupDO> getGroupPage(MemberGroupPageReqVO pageReqVO) { 94 public PageResult<MemberGroupDO> getGroupPage(MemberGroupPageReqVO pageReqVO) {
94 - return groupMapper.selectPage(pageReqVO); 95 + return memberGroupMapper.selectPage(pageReqVO);
95 } 96 }
96 97
97 @Override 98 @Override
98 public List<MemberGroupDO> getGroupListByStatus(Integer status) { 99 public List<MemberGroupDO> getGroupListByStatus(Integer status) {
99 - return groupMapper.selectListByStatus(status); 100 + return memberGroupMapper.selectListByStatus(status);
100 } 101 }
101 102
102 } 103 }
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/level/MemberLevelServiceImpl.java
@@ -42,7 +42,8 @@ import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.*; @@ -42,7 +42,8 @@ import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.*;
42 public class MemberLevelServiceImpl implements MemberLevelService { 42 public class MemberLevelServiceImpl implements MemberLevelService {
43 43
44 @Resource 44 @Resource
45 - private MemberLevelMapper levelMapper; 45 + private MemberLevelMapper memberLevelMapper;
  46 +
46 @Resource 47 @Resource
47 private MemberLevelRecordService memberLevelRecordService; 48 private MemberLevelRecordService memberLevelRecordService;
48 @Resource 49 @Resource
@@ -57,7 +58,7 @@ public class MemberLevelServiceImpl implements MemberLevelService { @@ -57,7 +58,7 @@ public class MemberLevelServiceImpl implements MemberLevelService {
57 58
58 // 插入 59 // 插入
59 MemberLevelDO level = MemberLevelConvert.INSTANCE.convert(createReqVO); 60 MemberLevelDO level = MemberLevelConvert.INSTANCE.convert(createReqVO);
60 - levelMapper.insert(level); 61 + memberLevelMapper.insert(level);
61 // 返回 62 // 返回
62 return level.getId(); 63 return level.getId();
63 } 64 }
@@ -71,7 +72,7 @@ public class MemberLevelServiceImpl implements MemberLevelService { @@ -71,7 +72,7 @@ public class MemberLevelServiceImpl implements MemberLevelService {
71 72
72 // 更新 73 // 更新
73 MemberLevelDO updateObj = MemberLevelConvert.INSTANCE.convert(updateReqVO); 74 MemberLevelDO updateObj = MemberLevelConvert.INSTANCE.convert(updateReqVO);
74 - levelMapper.updateById(updateObj); 75 + memberLevelMapper.updateById(updateObj);
75 } 76 }
76 77
77 @Override 78 @Override
@@ -81,12 +82,12 @@ public class MemberLevelServiceImpl implements MemberLevelService { @@ -81,12 +82,12 @@ public class MemberLevelServiceImpl implements MemberLevelService {
81 // 校验分组下是否有用户 82 // 校验分组下是否有用户
82 validateLevelHasUser(id); 83 validateLevelHasUser(id);
83 // 删除 84 // 删除
84 - levelMapper.deleteById(id); 85 + memberLevelMapper.deleteById(id);
85 } 86 }
86 87
87 @VisibleForTesting 88 @VisibleForTesting
88 MemberLevelDO validateLevelExists(Long id) { 89 MemberLevelDO validateLevelExists(Long id) {
89 - MemberLevelDO levelDO = levelMapper.selectById(id); 90 + MemberLevelDO levelDO = memberLevelMapper.selectById(id);
90 if (levelDO == null) { 91 if (levelDO == null) {
91 throw exception(LEVEL_NOT_EXISTS); 92 throw exception(LEVEL_NOT_EXISTS);
92 } 93 }
@@ -141,7 +142,7 @@ public class MemberLevelServiceImpl implements MemberLevelService { @@ -141,7 +142,7 @@ public class MemberLevelServiceImpl implements MemberLevelService {
141 142
142 @VisibleForTesting 143 @VisibleForTesting
143 void validateConfigValid(Long id, String name, Integer level, Integer experience) { 144 void validateConfigValid(Long id, String name, Integer level, Integer experience) {
144 - List<MemberLevelDO> list = levelMapper.selectList(); 145 + List<MemberLevelDO> list = memberLevelMapper.selectList();
145 // 校验名称唯一 146 // 校验名称唯一
146 validateNameUnique(list, id, name); 147 validateNameUnique(list, id, name);
147 // 校验等级唯一 148 // 校验等级唯一
@@ -160,7 +161,7 @@ public class MemberLevelServiceImpl implements MemberLevelService { @@ -160,7 +161,7 @@ public class MemberLevelServiceImpl implements MemberLevelService {
160 161
161 @Override 162 @Override
162 public MemberLevelDO getLevel(Long id) { 163 public MemberLevelDO getLevel(Long id) {
163 - return id != null && id > 0 ? levelMapper.selectById(id) : null; 164 + return id != null && id > 0 ? memberLevelMapper.selectById(id) : null;
164 } 165 }
165 166
166 @Override 167 @Override
@@ -168,17 +169,17 @@ public class MemberLevelServiceImpl implements MemberLevelService { @@ -168,17 +169,17 @@ public class MemberLevelServiceImpl implements MemberLevelService {
168 if (CollUtil.isEmpty(ids)) { 169 if (CollUtil.isEmpty(ids)) {
169 return Collections.emptyList(); 170 return Collections.emptyList();
170 } 171 }
171 - return levelMapper.selectBatchIds(ids); 172 + return memberLevelMapper.selectBatchIds(ids);
172 } 173 }
173 174
174 @Override 175 @Override
175 public List<MemberLevelDO> getLevelList(MemberLevelListReqVO listReqVO) { 176 public List<MemberLevelDO> getLevelList(MemberLevelListReqVO listReqVO) {
176 - return levelMapper.selectList(listReqVO); 177 + return memberLevelMapper.selectList(listReqVO);
177 } 178 }
178 179
179 @Override 180 @Override
180 public List<MemberLevelDO> getLevelListByStatus(Integer status) { 181 public List<MemberLevelDO> getLevelListByStatus(Integer status) {
181 - return levelMapper.selectListByStatus(status); 182 + return memberLevelMapper.selectListByStatus(status);
182 } 183 }
183 184
184 @Override 185 @Override
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/point/MemberPointConfigServiceImpl.java
@@ -21,23 +21,23 @@ import java.util.List; @@ -21,23 +21,23 @@ import java.util.List;
21 public class MemberPointConfigServiceImpl implements MemberPointConfigService { 21 public class MemberPointConfigServiceImpl implements MemberPointConfigService {
22 22
23 @Resource 23 @Resource
24 - private MemberPointConfigMapper pointConfigMapper; 24 + private MemberPointConfigMapper memberPointConfigMapper;
25 25
26 @Override 26 @Override
27 public void savePointConfig(MemberPointConfigSaveReqVO saveReqVO) { 27 public void savePointConfig(MemberPointConfigSaveReqVO saveReqVO) {
28 // 存在,则进行更新 28 // 存在,则进行更新
29 MemberPointConfigDO dbConfig = getPointConfig(); 29 MemberPointConfigDO dbConfig = getPointConfig();
30 if (dbConfig != null) { 30 if (dbConfig != null) {
31 - pointConfigMapper.updateById(MemberPointConfigConvert.INSTANCE.convert(saveReqVO).setId(dbConfig.getId())); 31 + memberPointConfigMapper.updateById(MemberPointConfigConvert.INSTANCE.convert(saveReqVO).setId(dbConfig.getId()));
32 return; 32 return;
33 } 33 }
34 // 不存在,则进行插入 34 // 不存在,则进行插入
35 - pointConfigMapper.insert(MemberPointConfigConvert.INSTANCE.convert(saveReqVO)); 35 + memberPointConfigMapper.insert(MemberPointConfigConvert.INSTANCE.convert(saveReqVO));
36 } 36 }
37 37
38 @Override 38 @Override
39 public MemberPointConfigDO getPointConfig() { 39 public MemberPointConfigDO getPointConfig() {
40 - List<MemberPointConfigDO> list = pointConfigMapper.selectList(); 40 + List<MemberPointConfigDO> list = memberPointConfigMapper.selectList();
41 return CollectionUtils.getFirst(list); 41 return CollectionUtils.getFirst(list);
42 } 42 }
43 43
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/point/MemberPointRecordServiceImpl.java
@@ -35,7 +35,7 @@ import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils. @@ -35,7 +35,7 @@ import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.
35 public class MemberPointRecordServiceImpl implements MemberPointRecordService { 35 public class MemberPointRecordServiceImpl implements MemberPointRecordService {
36 36
37 @Resource 37 @Resource
38 - private MemberPointRecordMapper recordMapper; 38 + private MemberPointRecordMapper memberPointRecordMapper;
39 @Resource 39 @Resource
40 private MemberPointConfigService memberPointConfigService; 40 private MemberPointConfigService memberPointConfigService;
41 41
@@ -55,12 +55,12 @@ public class MemberPointRecordServiceImpl implements MemberPointRecordService { @@ -55,12 +55,12 @@ public class MemberPointRecordServiceImpl implements MemberPointRecordService {
55 userIds = convertSet(users, MemberUserDO::getId); 55 userIds = convertSet(users, MemberUserDO::getId);
56 } 56 }
57 // 执行查询 57 // 执行查询
58 - return recordMapper.selectPage(pageReqVO, userIds); 58 + return memberPointRecordMapper.selectPage(pageReqVO, userIds);
59 } 59 }
60 60
61 @Override 61 @Override
62 public PageResult<MemberPointRecordDO> getPointRecordPage(Long userId, PageParam pageVO) { 62 public PageResult<MemberPointRecordDO> getPointRecordPage(Long userId, PageParam pageVO) {
63 - return recordMapper.selectPage(userId, pageVO); 63 + return memberPointRecordMapper.selectPage(userId, pageVO);
64 } 64 }
65 65
66 @Override 66 @Override
@@ -86,7 +86,7 @@ public class MemberPointRecordServiceImpl implements MemberPointRecordService { @@ -86,7 +86,7 @@ public class MemberPointRecordServiceImpl implements MemberPointRecordService {
86 .setUserId(userId).setBizId(bizId).setBizType(bizType.getType()) 86 .setUserId(userId).setBizId(bizId).setBizType(bizType.getType())
87 .setTitle(bizType.getName()).setDescription(StrUtil.format(bizType.getDescription(), point)) 87 .setTitle(bizType.getName()).setDescription(StrUtil.format(bizType.getDescription(), point))
88 .setPoint(point).setTotalPoint(totalPoint); 88 .setPoint(point).setTotalPoint(totalPoint);
89 - recordMapper.insert(record); 89 + memberPointRecordMapper.insert(record);
90 90
91 // 3. 更新用户积分 91 // 3. 更新用户积分
92 memberUserService.updateUserPoint(userId, totalPoint); 92 memberUserService.updateUserPoint(userId, totalPoint);
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/signin/MemberSignInConfigServiceImpl.java
@@ -26,7 +26,7 @@ import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.SIGN_IN_CO @@ -26,7 +26,7 @@ import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.SIGN_IN_CO
26 public class MemberSignInConfigServiceImpl implements MemberSignInConfigService { 26 public class MemberSignInConfigServiceImpl implements MemberSignInConfigService {
27 27
28 @Resource 28 @Resource
29 - private MemberSignInConfigMapper signInConfigMapper; 29 + private MemberSignInConfigMapper memberSignInConfigMapper;
30 30
31 @Override 31 @Override
32 public Long createSignInConfig(MemberSignInConfigCreateReqVO createReqVO) { 32 public Long createSignInConfig(MemberSignInConfigCreateReqVO createReqVO) {
@@ -35,7 +35,7 @@ public class MemberSignInConfigServiceImpl implements MemberSignInConfigService @@ -35,7 +35,7 @@ public class MemberSignInConfigServiceImpl implements MemberSignInConfigService
35 35
36 // 插入 36 // 插入
37 MemberSignInConfigDO signInConfig = MemberSignInConfigConvert.INSTANCE.convert(createReqVO); 37 MemberSignInConfigDO signInConfig = MemberSignInConfigConvert.INSTANCE.convert(createReqVO);
38 - signInConfigMapper.insert(signInConfig); 38 + memberSignInConfigMapper.insert(signInConfig);
39 // 返回 39 // 返回
40 return signInConfig.getId(); 40 return signInConfig.getId();
41 } 41 }
@@ -49,7 +49,7 @@ public class MemberSignInConfigServiceImpl implements MemberSignInConfigService @@ -49,7 +49,7 @@ public class MemberSignInConfigServiceImpl implements MemberSignInConfigService
49 49
50 // 判断更新 50 // 判断更新
51 MemberSignInConfigDO updateObj = MemberSignInConfigConvert.INSTANCE.convert(updateReqVO); 51 MemberSignInConfigDO updateObj = MemberSignInConfigConvert.INSTANCE.convert(updateReqVO);
52 - signInConfigMapper.updateById(updateObj); 52 + memberSignInConfigMapper.updateById(updateObj);
53 } 53 }
54 54
55 @Override 55 @Override
@@ -57,11 +57,11 @@ public class MemberSignInConfigServiceImpl implements MemberSignInConfigService @@ -57,11 +57,11 @@ public class MemberSignInConfigServiceImpl implements MemberSignInConfigService
57 // 校验存在 57 // 校验存在
58 validateSignInConfigExists(id); 58 validateSignInConfigExists(id);
59 // 删除 59 // 删除
60 - signInConfigMapper.deleteById(id); 60 + memberSignInConfigMapper.deleteById(id);
61 } 61 }
62 62
63 private void validateSignInConfigExists(Long id) { 63 private void validateSignInConfigExists(Long id) {
64 - if (signInConfigMapper.selectById(id) == null) { 64 + if (memberSignInConfigMapper.selectById(id) == null) {
65 throw exception(SIGN_IN_CONFIG_NOT_EXISTS); 65 throw exception(SIGN_IN_CONFIG_NOT_EXISTS);
66 } 66 }
67 } 67 }
@@ -73,7 +73,7 @@ public class MemberSignInConfigServiceImpl implements MemberSignInConfigService @@ -73,7 +73,7 @@ public class MemberSignInConfigServiceImpl implements MemberSignInConfigService
73 * @param id 编号,只有更新的时候会传递 73 * @param id 编号,只有更新的时候会传递
74 */ 74 */
75 private void validateSignInConfigDayDuplicate(Integer day, Long id) { 75 private void validateSignInConfigDayDuplicate(Integer day, Long id) {
76 - MemberSignInConfigDO config = signInConfigMapper.selectByDay(day); 76 + MemberSignInConfigDO config = memberSignInConfigMapper.selectByDay(day);
77 // 1. 新增时,config 非空,则说明重复 77 // 1. 新增时,config 非空,则说明重复
78 if (id == null && config != null) { 78 if (id == null && config != null) {
79 throw exception(SIGN_IN_CONFIG_EXISTS); 79 throw exception(SIGN_IN_CONFIG_EXISTS);
@@ -86,19 +86,19 @@ public class MemberSignInConfigServiceImpl implements MemberSignInConfigService @@ -86,19 +86,19 @@ public class MemberSignInConfigServiceImpl implements MemberSignInConfigService
86 86
87 @Override 87 @Override
88 public MemberSignInConfigDO getSignInConfig(Long id) { 88 public MemberSignInConfigDO getSignInConfig(Long id) {
89 - return signInConfigMapper.selectById(id); 89 + return memberSignInConfigMapper.selectById(id);
90 } 90 }
91 91
92 @Override 92 @Override
93 public List <MemberSignInConfigDO> getSignInConfigList() { 93 public List <MemberSignInConfigDO> getSignInConfigList() {
94 - List<MemberSignInConfigDO> list = signInConfigMapper.selectList(); 94 + List<MemberSignInConfigDO> list = memberSignInConfigMapper.selectList();
95 list.sort(Comparator.comparing(MemberSignInConfigDO::getDay)); 95 list.sort(Comparator.comparing(MemberSignInConfigDO::getDay));
96 return list; 96 return list;
97 } 97 }
98 98
99 @Override 99 @Override
100 public List<MemberSignInConfigDO> getSignInConfigList(Integer status) { 100 public List<MemberSignInConfigDO> getSignInConfigList(Integer status) {
101 - List<MemberSignInConfigDO> list = signInConfigMapper.selectListByStatus(status); 101 + List<MemberSignInConfigDO> list = memberSignInConfigMapper.selectListByStatus(status);
102 list.sort(Comparator.comparing(MemberSignInConfigDO::getDay)); 102 list.sort(Comparator.comparing(MemberSignInConfigDO::getDay));
103 return list; 103 return list;
104 } 104 }
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/signin/MemberSignInRecordServiceImpl.java
@@ -28,7 +28,7 @@ import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils. @@ -28,7 +28,7 @@ import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.
28 public class MemberSignInRecordServiceImpl implements MemberSignInRecordService { 28 public class MemberSignInRecordServiceImpl implements MemberSignInRecordService {
29 29
30 @Resource 30 @Resource
31 - private MemberSignInRecordMapper signInRecordMapper; 31 + private MemberSignInRecordMapper memberSignInRecordMapper;
32 32
33 @Resource 33 @Resource
34 private MemberUserApi memberUserApi; 34 private MemberUserApi memberUserApi;
@@ -46,12 +46,12 @@ public class MemberSignInRecordServiceImpl implements MemberSignInRecordService @@ -46,12 +46,12 @@ public class MemberSignInRecordServiceImpl implements MemberSignInRecordService
46 userIds = convertSet(users, MemberUserRespDTO::getId); 46 userIds = convertSet(users, MemberUserRespDTO::getId);
47 } 47 }
48 // 分页查询 48 // 分页查询
49 - return signInRecordMapper.selectPage(pageReqVO, userIds); 49 + return memberSignInRecordMapper.selectPage(pageReqVO, userIds);
50 } 50 }
51 51
52 @Override 52 @Override
53 public PageResult<MemberSignInRecordDO> getSignRecordPage(Long userId, PageParam pageParam) { 53 public PageResult<MemberSignInRecordDO> getSignRecordPage(Long userId, PageParam pageParam) {
54 - return signInRecordMapper.selectPage(userId, pageParam); 54 + return memberSignInRecordMapper.selectPage(userId, pageParam);
55 } 55 }
56 56
57 } 57 }
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/tag/MemberTagServiceImpl.java
@@ -31,7 +31,8 @@ import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.*; @@ -31,7 +31,8 @@ import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.*;
31 public class MemberTagServiceImpl implements MemberTagService { 31 public class MemberTagServiceImpl implements MemberTagService {
32 32
33 @Resource 33 @Resource
34 - private MemberTagMapper tagMapper; 34 + private MemberTagMapper memberTagMapper;
  35 +
35 @Resource 36 @Resource
36 private MemberUserService memberUserService; 37 private MemberUserService memberUserService;
37 38
@@ -41,7 +42,7 @@ public class MemberTagServiceImpl implements MemberTagService { @@ -41,7 +42,7 @@ public class MemberTagServiceImpl implements MemberTagService {
41 validateTagNameUnique(null, createReqVO.getName()); 42 validateTagNameUnique(null, createReqVO.getName());
42 // 插入 43 // 插入
43 MemberTagDO tag = MemberTagConvert.INSTANCE.convert(createReqVO); 44 MemberTagDO tag = MemberTagConvert.INSTANCE.convert(createReqVO);
44 - tagMapper.insert(tag); 45 + memberTagMapper.insert(tag);
45 // 返回 46 // 返回
46 return tag.getId(); 47 return tag.getId();
47 } 48 }
@@ -54,7 +55,7 @@ public class MemberTagServiceImpl implements MemberTagService { @@ -54,7 +55,7 @@ public class MemberTagServiceImpl implements MemberTagService {
54 validateTagNameUnique(updateReqVO.getId(), updateReqVO.getName()); 55 validateTagNameUnique(updateReqVO.getId(), updateReqVO.getName());
55 // 更新 56 // 更新
56 MemberTagDO updateObj = MemberTagConvert.INSTANCE.convert(updateReqVO); 57 MemberTagDO updateObj = MemberTagConvert.INSTANCE.convert(updateReqVO);
57 - tagMapper.updateById(updateObj); 58 + memberTagMapper.updateById(updateObj);
58 } 59 }
59 60
60 @Override 61 @Override
@@ -64,11 +65,11 @@ public class MemberTagServiceImpl implements MemberTagService { @@ -64,11 +65,11 @@ public class MemberTagServiceImpl implements MemberTagService {
64 // 校验标签下是否有用户 65 // 校验标签下是否有用户
65 validateTagHasUser(id); 66 validateTagHasUser(id);
66 // 删除 67 // 删除
67 - tagMapper.deleteById(id); 68 + memberTagMapper.deleteById(id);
68 } 69 }
69 70
70 private void validateTagExists(Long id) { 71 private void validateTagExists(Long id) {
71 - if (tagMapper.selectById(id) == null) { 72 + if (memberTagMapper.selectById(id) == null) {
72 throw exception(TAG_NOT_EXISTS); 73 throw exception(TAG_NOT_EXISTS);
73 } 74 }
74 } 75 }
@@ -77,7 +78,7 @@ public class MemberTagServiceImpl implements MemberTagService { @@ -77,7 +78,7 @@ public class MemberTagServiceImpl implements MemberTagService {
77 if (StrUtil.isBlank(name)) { 78 if (StrUtil.isBlank(name)) {
78 return; 79 return;
79 } 80 }
80 - MemberTagDO tag = tagMapper.selelctByName(name); 81 + MemberTagDO tag = memberTagMapper.selelctByName(name);
81 if (tag == null) { 82 if (tag == null) {
82 return; 83 return;
83 } 84 }
@@ -100,7 +101,7 @@ public class MemberTagServiceImpl implements MemberTagService { @@ -100,7 +101,7 @@ public class MemberTagServiceImpl implements MemberTagService {
100 101
101 @Override 102 @Override
102 public MemberTagDO getTag(Long id) { 103 public MemberTagDO getTag(Long id) {
103 - return tagMapper.selectById(id); 104 + return memberTagMapper.selectById(id);
104 } 105 }
105 106
106 @Override 107 @Override
@@ -108,17 +109,17 @@ public class MemberTagServiceImpl implements MemberTagService { @@ -108,17 +109,17 @@ public class MemberTagServiceImpl implements MemberTagService {
108 if (CollUtil.isEmpty(ids)) { 109 if (CollUtil.isEmpty(ids)) {
109 return ListUtil.empty(); 110 return ListUtil.empty();
110 } 111 }
111 - return tagMapper.selectBatchIds(ids); 112 + return memberTagMapper.selectBatchIds(ids);
112 } 113 }
113 114
114 @Override 115 @Override
115 public PageResult<MemberTagDO> getTagPage(MemberTagPageReqVO pageReqVO) { 116 public PageResult<MemberTagDO> getTagPage(MemberTagPageReqVO pageReqVO) {
116 - return tagMapper.selectPage(pageReqVO); 117 + return memberTagMapper.selectPage(pageReqVO);
117 } 118 }
118 119
119 @Override 120 @Override
120 public List<MemberTagDO> getTagList() { 121 public List<MemberTagDO> getTagList() {
121 - return tagMapper.selectList(); 122 + return memberTagMapper.selectList();
122 } 123 }
123 124
124 } 125 }
yudao-module-member/yudao-module-member-biz/src/test/java/cn/iocoder/yudao/module/member/service/address/AddressServiceImplTest.java
@@ -4,7 +4,7 @@ import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; @@ -4,7 +4,7 @@ import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
4 import cn.iocoder.yudao.module.member.controller.app.address.vo.AppAddressCreateReqVO; 4 import cn.iocoder.yudao.module.member.controller.app.address.vo.AppAddressCreateReqVO;
5 import cn.iocoder.yudao.module.member.controller.app.address.vo.AppAddressUpdateReqVO; 5 import cn.iocoder.yudao.module.member.controller.app.address.vo.AppAddressUpdateReqVO;
6 import cn.iocoder.yudao.module.member.dal.dataobject.address.MemberAddressDO; 6 import cn.iocoder.yudao.module.member.dal.dataobject.address.MemberAddressDO;
7 -import cn.iocoder.yudao.module.member.dal.mysql.address.AddressMapper; 7 +import cn.iocoder.yudao.module.member.dal.mysql.address.MemberAddressMapper;
8 import org.junit.jupiter.api.Test; 8 import org.junit.jupiter.api.Test;
9 import org.springframework.context.annotation.Import; 9 import org.springframework.context.annotation.Import;
10 10
@@ -30,7 +30,7 @@ public class AddressServiceImplTest extends BaseDbUnitTest { @@ -30,7 +30,7 @@ public class AddressServiceImplTest extends BaseDbUnitTest {
30 private AddressServiceImpl addressService; 30 private AddressServiceImpl addressService;
31 31
32 @Resource 32 @Resource
33 - private AddressMapper addressMapper; 33 + private MemberAddressMapper addressMapper;
34 34
35 @Test 35 @Test
36 public void testCreateAddress_success() { 36 public void testCreateAddress_success() {
yudao-module-member/yudao-module-member-biz/src/test/java/cn/iocoder/yudao/module/member/service/group/MemberGroupServiceImplTest.java
1 package cn.iocoder.yudao.module.member.service.group; 1 package cn.iocoder.yudao.module.member.service.group;
2 2
3 -import cn.hutool.core.util.RandomUtil;  
4 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; 3 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
5 import cn.iocoder.yudao.framework.common.pojo.PageResult; 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
6 import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; 5 import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
@@ -8,11 +7,10 @@ import cn.iocoder.yudao.module.member.controller.admin.group.vo.MemberGroupCreat @@ -8,11 +7,10 @@ import cn.iocoder.yudao.module.member.controller.admin.group.vo.MemberGroupCreat
8 import cn.iocoder.yudao.module.member.controller.admin.group.vo.MemberGroupPageReqVO; 7 import cn.iocoder.yudao.module.member.controller.admin.group.vo.MemberGroupPageReqVO;
9 import cn.iocoder.yudao.module.member.controller.admin.group.vo.MemberGroupUpdateReqVO; 8 import cn.iocoder.yudao.module.member.controller.admin.group.vo.MemberGroupUpdateReqVO;
10 import cn.iocoder.yudao.module.member.dal.dataobject.group.MemberGroupDO; 9 import cn.iocoder.yudao.module.member.dal.dataobject.group.MemberGroupDO;
11 -import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;  
12 import cn.iocoder.yudao.module.member.dal.mysql.group.MemberGroupMapper; 10 import cn.iocoder.yudao.module.member.dal.mysql.group.MemberGroupMapper;
13 -import cn.iocoder.yudao.module.member.dal.mysql.user.MemberUserMapper;  
14 -import cn.iocoder.yudao.module.system.enums.common.SexEnum; 11 +import cn.iocoder.yudao.module.member.service.user.MemberUserService;
15 import org.junit.jupiter.api.Test; 12 import org.junit.jupiter.api.Test;
  13 +import org.springframework.boot.test.mock.mockito.MockBean;
16 import org.springframework.context.annotation.Import; 14 import org.springframework.context.annotation.Import;
17 15
18 import javax.annotation.Resource; 16 import javax.annotation.Resource;
@@ -26,7 +24,10 @@ import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*; @@ -26,7 +24,10 @@ import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
26 import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.GROUP_HAS_USER; 24 import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.GROUP_HAS_USER;
27 import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.GROUP_NOT_EXISTS; 25 import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.GROUP_NOT_EXISTS;
28 import static org.junit.jupiter.api.Assertions.*; 26 import static org.junit.jupiter.api.Assertions.*;
  27 +import static org.mockito.ArgumentMatchers.eq;
  28 +import static org.mockito.Mockito.when;
29 29
  30 +// TODO 芋艿:完全 review 完,在去 review 单测
30 /** 31 /**
31 * {@link MemberGroupServiceImpl} 的单元测试类 32 * {@link MemberGroupServiceImpl} 的单元测试类
32 * 33 *
@@ -40,13 +41,15 @@ public class MemberGroupServiceImplTest extends BaseDbUnitTest { @@ -40,13 +41,15 @@ public class MemberGroupServiceImplTest extends BaseDbUnitTest {
40 41
41 @Resource 42 @Resource
42 private MemberGroupMapper groupMapper; 43 private MemberGroupMapper groupMapper;
43 - @Resource  
44 - private MemberUserMapper memberUserMapper; 44 +
  45 + @MockBean
  46 + private MemberUserService memberUserService;
45 47
46 @Test 48 @Test
47 public void testCreateGroup_success() { 49 public void testCreateGroup_success() {
48 // 准备参数 50 // 准备参数
49 - MemberGroupCreateReqVO reqVO = randomPojo(MemberGroupCreateReqVO.class); 51 + MemberGroupCreateReqVO reqVO = randomPojo(MemberGroupCreateReqVO.class,
  52 + o -> o.setStatus(randomCommonStatus()));
50 53
51 // 调用 54 // 调用
52 Long groupId = groupService.createGroup(reqVO); 55 Long groupId = groupService.createGroup(reqVO);
@@ -65,6 +68,7 @@ public class MemberGroupServiceImplTest extends BaseDbUnitTest { @@ -65,6 +68,7 @@ public class MemberGroupServiceImplTest extends BaseDbUnitTest {
65 // 准备参数 68 // 准备参数
66 MemberGroupUpdateReqVO reqVO = randomPojo(MemberGroupUpdateReqVO.class, o -> { 69 MemberGroupUpdateReqVO reqVO = randomPojo(MemberGroupUpdateReqVO.class, o -> {
67 o.setId(dbGroup.getId()); // 设置更新的 ID 70 o.setId(dbGroup.getId()); // 设置更新的 ID
  71 + o.setStatus(randomCommonStatus());
68 }); 72 });
69 73
70 // 调用 74 // 调用
@@ -115,11 +119,7 @@ public class MemberGroupServiceImplTest extends BaseDbUnitTest { @@ -115,11 +119,7 @@ public class MemberGroupServiceImplTest extends BaseDbUnitTest {
115 Long id = dbGroup.getId(); 119 Long id = dbGroup.getId();
116 120
117 // mock 会员数据 121 // mock 会员数据
118 - MemberUserDO dbUser = randomPojo(MemberUserDO.class, o -> {  
119 - o.setGroupId(id);  
120 - o.setSex(RandomUtil.randomEle(SexEnum.values()).getSex());  
121 - });  
122 - memberUserMapper.insert(dbUser); 122 + when(memberUserService.getUserCountByGroupId(eq(id))).thenReturn(1L);
123 123
124 // 调用, 并断言异常 124 // 调用, 并断言异常
125 assertServiceException(() -> groupService.deleteGroup(id), GROUP_HAS_USER); 125 assertServiceException(() -> groupService.deleteGroup(id), GROUP_HAS_USER);
yudao-module-member/yudao-module-member-biz/src/test/java/cn/iocoder/yudao/module/member/service/level/MemberLevelServiceImplTest.java
1 package cn.iocoder.yudao.module.member.service.level; 1 package cn.iocoder.yudao.module.member.service.level;
2 2
3 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; 3 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
4 -import cn.iocoder.yudao.framework.common.pojo.PageResult;  
5 import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils; 4 import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils;
6 import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; 5 import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
7 import cn.iocoder.yudao.module.member.controller.admin.level.vo.level.MemberLevelCreateReqVO; 6 import cn.iocoder.yudao.module.member.controller.admin.level.vo.level.MemberLevelCreateReqVO;
@@ -9,6 +8,7 @@ import cn.iocoder.yudao.module.member.controller.admin.level.vo.level.MemberLeve @@ -9,6 +8,7 @@ import cn.iocoder.yudao.module.member.controller.admin.level.vo.level.MemberLeve
9 import cn.iocoder.yudao.module.member.controller.admin.level.vo.level.MemberLevelUpdateReqVO; 8 import cn.iocoder.yudao.module.member.controller.admin.level.vo.level.MemberLevelUpdateReqVO;
10 import cn.iocoder.yudao.module.member.dal.dataobject.level.MemberLevelDO; 9 import cn.iocoder.yudao.module.member.dal.dataobject.level.MemberLevelDO;
11 import cn.iocoder.yudao.module.member.dal.mysql.level.MemberLevelMapper; 10 import cn.iocoder.yudao.module.member.dal.mysql.level.MemberLevelMapper;
  11 +import cn.iocoder.yudao.module.member.service.user.MemberUserService;
12 import org.junit.jupiter.api.Test; 12 import org.junit.jupiter.api.Test;
13 import org.springframework.boot.test.mock.mockito.MockBean; 13 import org.springframework.boot.test.mock.mockito.MockBean;
14 import org.springframework.context.annotation.Import; 14 import org.springframework.context.annotation.Import;
@@ -38,12 +38,14 @@ public class MemberLevelServiceImplTest extends BaseDbUnitTest { @@ -38,12 +38,14 @@ public class MemberLevelServiceImplTest extends BaseDbUnitTest {
38 private MemberLevelServiceImpl levelService; 38 private MemberLevelServiceImpl levelService;
39 39
40 @Resource 40 @Resource
41 - private MemberLevelMapper levelMapper; 41 + private MemberLevelMapper memberlevelMapper;
42 42
43 @MockBean 43 @MockBean
44 private MemberLevelRecordService memberLevelRecordService; 44 private MemberLevelRecordService memberLevelRecordService;
45 @MockBean 45 @MockBean
46 private MemberExperienceRecordService memberExperienceRecordService; 46 private MemberExperienceRecordService memberExperienceRecordService;
  47 + @MockBean
  48 + private MemberUserService memberUserService;
47 49
48 @Test 50 @Test
49 public void testCreateLevel_success() { 51 public void testCreateLevel_success() {
@@ -52,6 +54,7 @@ public class MemberLevelServiceImplTest extends BaseDbUnitTest { @@ -52,6 +54,7 @@ public class MemberLevelServiceImplTest extends BaseDbUnitTest {
52 o.setDiscountPercent(randomInt()); 54 o.setDiscountPercent(randomInt());
53 o.setIcon(randomURL()); 55 o.setIcon(randomURL());
54 o.setBackgroundUrl(randomURL()); 56 o.setBackgroundUrl(randomURL());
  57 + o.setStatus(randomCommonStatus());
55 }); 58 });
56 59
57 // 调用 60 // 调用
@@ -59,7 +62,7 @@ public class MemberLevelServiceImplTest extends BaseDbUnitTest { @@ -59,7 +62,7 @@ public class MemberLevelServiceImplTest extends BaseDbUnitTest {
59 // 断言 62 // 断言
60 assertNotNull(levelId); 63 assertNotNull(levelId);
61 // 校验记录的属性是否正确 64 // 校验记录的属性是否正确
62 - MemberLevelDO level = levelMapper.selectById(levelId); 65 + MemberLevelDO level = memberlevelMapper.selectById(levelId);
63 assertPojoEquals(reqVO, level); 66 assertPojoEquals(reqVO, level);
64 } 67 }
65 68
@@ -67,7 +70,7 @@ public class MemberLevelServiceImplTest extends BaseDbUnitTest { @@ -67,7 +70,7 @@ public class MemberLevelServiceImplTest extends BaseDbUnitTest {
67 public void testUpdateLevel_success() { 70 public void testUpdateLevel_success() {
68 // mock 数据 71 // mock 数据
69 MemberLevelDO dbLevel = randomPojo(MemberLevelDO.class); 72 MemberLevelDO dbLevel = randomPojo(MemberLevelDO.class);
70 - levelMapper.insert(dbLevel);// @Sql: 先插入出一条存在的数据 73 + memberlevelMapper.insert(dbLevel);// @Sql: 先插入出一条存在的数据
71 // 准备参数 74 // 准备参数
72 MemberLevelUpdateReqVO reqVO = randomPojo(MemberLevelUpdateReqVO.class, o -> { 75 MemberLevelUpdateReqVO reqVO = randomPojo(MemberLevelUpdateReqVO.class, o -> {
73 o.setId(dbLevel.getId()); // 设置更新的 ID 76 o.setId(dbLevel.getId()); // 设置更新的 ID
@@ -79,12 +82,13 @@ public class MemberLevelServiceImplTest extends BaseDbUnitTest { @@ -79,12 +82,13 @@ public class MemberLevelServiceImplTest extends BaseDbUnitTest {
79 o.setDiscountPercent(randomInt()); 82 o.setDiscountPercent(randomInt());
80 o.setIcon(randomURL()); 83 o.setIcon(randomURL());
81 o.setBackgroundUrl(randomURL()); 84 o.setBackgroundUrl(randomURL());
  85 + o.setStatus(randomCommonStatus());
82 }); 86 });
83 87
84 // 调用 88 // 调用
85 levelService.updateLevel(reqVO); 89 levelService.updateLevel(reqVO);
86 // 校验是否更新正确 90 // 校验是否更新正确
87 - MemberLevelDO level = levelMapper.selectById(reqVO.getId()); // 获取最新的 91 + MemberLevelDO level = memberlevelMapper.selectById(reqVO.getId()); // 获取最新的
88 assertPojoEquals(reqVO, level); 92 assertPojoEquals(reqVO, level);
89 } 93 }
90 94
@@ -101,14 +105,14 @@ public class MemberLevelServiceImplTest extends BaseDbUnitTest { @@ -101,14 +105,14 @@ public class MemberLevelServiceImplTest extends BaseDbUnitTest {
101 public void testDeleteLevel_success() { 105 public void testDeleteLevel_success() {
102 // mock 数据 106 // mock 数据
103 MemberLevelDO dbLevel = randomPojo(MemberLevelDO.class); 107 MemberLevelDO dbLevel = randomPojo(MemberLevelDO.class);
104 - levelMapper.insert(dbLevel);// @Sql: 先插入出一条存在的数据 108 + memberlevelMapper.insert(dbLevel);// @Sql: 先插入出一条存在的数据
105 // 准备参数 109 // 准备参数
106 Long id = dbLevel.getId(); 110 Long id = dbLevel.getId();
107 111
108 // 调用 112 // 调用
109 levelService.deleteLevel(id); 113 levelService.deleteLevel(id);
110 // 校验数据不存在了 114 // 校验数据不存在了
111 - assertNull(levelMapper.selectById(id)); 115 + assertNull(memberlevelMapper.selectById(id));
112 } 116 }
113 117
114 @Test 118 @Test
@@ -127,11 +131,11 @@ public class MemberLevelServiceImplTest extends BaseDbUnitTest { @@ -127,11 +131,11 @@ public class MemberLevelServiceImplTest extends BaseDbUnitTest {
127 o.setName("黄金会员"); 131 o.setName("黄金会员");
128 o.setStatus(1); 132 o.setStatus(1);
129 }); 133 });
130 - levelMapper.insert(dbLevel); 134 + memberlevelMapper.insert(dbLevel);
131 // 测试 name 不匹配 135 // 测试 name 不匹配
132 - levelMapper.insert(cloneIgnoreId(dbLevel, o -> o.setName(""))); 136 + memberlevelMapper.insert(cloneIgnoreId(dbLevel, o -> o.setName("")));
133 // 测试 status 不匹配 137 // 测试 status 不匹配
134 - levelMapper.insert(cloneIgnoreId(dbLevel, o -> o.setStatus(0))); 138 + memberlevelMapper.insert(cloneIgnoreId(dbLevel, o -> o.setStatus(0)));
135 // 准备参数 139 // 准备参数
136 MemberLevelListReqVO reqVO = new MemberLevelListReqVO(); 140 MemberLevelListReqVO reqVO = new MemberLevelListReqVO();
137 reqVO.setName("黄金会员"); 141 reqVO.setName("黄金会员");
@@ -150,10 +154,10 @@ public class MemberLevelServiceImplTest extends BaseDbUnitTest { @@ -150,10 +154,10 @@ public class MemberLevelServiceImplTest extends BaseDbUnitTest {
150 String name = randomString(); 154 String name = randomString();
151 155
152 // mock 数据 156 // mock 数据
153 - levelMapper.insert(randomLevelDO(o -> o.setName(name))); 157 + memberlevelMapper.insert(randomLevelDO(o -> o.setName(name)));
154 158
155 // 调用,校验异常 159 // 调用,校验异常
156 - List<MemberLevelDO> list = levelMapper.selectList(); 160 + List<MemberLevelDO> list = memberlevelMapper.selectList();
157 assertServiceException(() -> levelService.validateNameUnique(list, null, name), LEVEL_NAME_EXISTS, name); 161 assertServiceException(() -> levelService.validateNameUnique(list, null, name), LEVEL_NAME_EXISTS, name);
158 } 162 }
159 163
@@ -164,10 +168,10 @@ public class MemberLevelServiceImplTest extends BaseDbUnitTest { @@ -164,10 +168,10 @@ public class MemberLevelServiceImplTest extends BaseDbUnitTest {
164 String name = randomString(); 168 String name = randomString();
165 169
166 // mock 数据 170 // mock 数据
167 - levelMapper.insert(randomLevelDO(o -> o.setName(name))); 171 + memberlevelMapper.insert(randomLevelDO(o -> o.setName(name)));
168 172
169 // 调用,校验异常 173 // 调用,校验异常
170 - List<MemberLevelDO> list = levelMapper.selectList(); 174 + List<MemberLevelDO> list = memberlevelMapper.selectList();
171 assertServiceException(() -> levelService.validateNameUnique(list, id, name), LEVEL_NAME_EXISTS, name); 175 assertServiceException(() -> levelService.validateNameUnique(list, id, name), LEVEL_NAME_EXISTS, name);
172 } 176 }
173 177
@@ -178,13 +182,13 @@ public class MemberLevelServiceImplTest extends BaseDbUnitTest { @@ -178,13 +182,13 @@ public class MemberLevelServiceImplTest extends BaseDbUnitTest {
178 String name = randomString(); 182 String name = randomString();
179 183
180 // mock 数据 184 // mock 数据
181 - levelMapper.insert(randomLevelDO(o -> { 185 + memberlevelMapper.insert(randomLevelDO(o -> {
182 o.setLevel(level); 186 o.setLevel(level);
183 o.setName(name); 187 o.setName(name);
184 })); 188 }));
185 189
186 // 调用,校验异常 190 // 调用,校验异常
187 - List<MemberLevelDO> list = levelMapper.selectList(); 191 + List<MemberLevelDO> list = memberlevelMapper.selectList();
188 assertServiceException(() -> levelService.validateLevelUnique(list, null, level), LEVEL_VALUE_EXISTS, level, name); 192 assertServiceException(() -> levelService.validateLevelUnique(list, null, level), LEVEL_VALUE_EXISTS, level, name);
189 } 193 }
190 194
@@ -196,13 +200,13 @@ public class MemberLevelServiceImplTest extends BaseDbUnitTest { @@ -196,13 +200,13 @@ public class MemberLevelServiceImplTest extends BaseDbUnitTest {
196 String name = randomString(); 200 String name = randomString();
197 201
198 // mock 数据 202 // mock 数据
199 - levelMapper.insert(randomLevelDO(o -> { 203 + memberlevelMapper.insert(randomLevelDO(o -> {
200 o.setLevel(level); 204 o.setLevel(level);
201 o.setName(name); 205 o.setName(name);
202 })); 206 }));
203 207
204 // 调用,校验异常 208 // 调用,校验异常
205 - List<MemberLevelDO> list = levelMapper.selectList(); 209 + List<MemberLevelDO> list = memberlevelMapper.selectList();
206 assertServiceException(() -> levelService.validateLevelUnique(list, id, level), LEVEL_VALUE_EXISTS, level, name); 210 assertServiceException(() -> levelService.validateLevelUnique(list, id, level), LEVEL_VALUE_EXISTS, level, name);
207 } 211 }
208 212
@@ -214,12 +218,12 @@ public class MemberLevelServiceImplTest extends BaseDbUnitTest { @@ -214,12 +218,12 @@ public class MemberLevelServiceImplTest extends BaseDbUnitTest {
214 String name = randomString(); 218 String name = randomString();
215 219
216 // mock 数据 220 // mock 数据
217 - levelMapper.insert(randomLevelDO(o -> { 221 + memberlevelMapper.insert(randomLevelDO(o -> {
218 o.setLevel(level); 222 o.setLevel(level);
219 o.setExperience(experience); 223 o.setExperience(experience);
220 o.setName(name); 224 o.setName(name);
221 })); 225 }));
222 - List<MemberLevelDO> list = levelMapper.selectList(); 226 + List<MemberLevelDO> list = memberlevelMapper.selectList();
223 227
224 // 调用,校验异常 228 // 调用,校验异常
225 assertServiceException(() -> levelService.validateExperienceOutRange(list, null, level + 1, experience - 1), LEVEL_EXPERIENCE_MIN, name, level); 229 assertServiceException(() -> levelService.validateExperienceOutRange(list, null, level + 1, experience - 1), LEVEL_EXPERIENCE_MIN, name, level);
@@ -236,12 +240,12 @@ public class MemberLevelServiceImplTest extends BaseDbUnitTest { @@ -236,12 +240,12 @@ public class MemberLevelServiceImplTest extends BaseDbUnitTest {
236 String name = randomString(); 240 String name = randomString();
237 241
238 // mock 数据 242 // mock 数据
239 - levelMapper.insert(randomLevelDO(o -> { 243 + memberlevelMapper.insert(randomLevelDO(o -> {
240 o.setLevel(level); 244 o.setLevel(level);
241 o.setExperience(experience); 245 o.setExperience(experience);
242 o.setName(name); 246 o.setName(name);
243 })); 247 }));
244 - List<MemberLevelDO> list = levelMapper.selectList(); 248 + List<MemberLevelDO> list = memberlevelMapper.selectList();
245 249
246 // 调用,校验异常 250 // 调用,校验异常
247 assertServiceException(() -> levelService.validateExperienceOutRange(list, id, level + 1, experience - 1), LEVEL_EXPERIENCE_MIN, name, level); 251 assertServiceException(() -> levelService.validateExperienceOutRange(list, id, level + 1, experience - 1), LEVEL_EXPERIENCE_MIN, name, level);
yudao-module-member/yudao-module-member-biz/src/test/java/cn/iocoder/yudao/module/member/service/tag/MemberTagServiceImplTest.java
@@ -7,7 +7,9 @@ import cn.iocoder.yudao.module.member.controller.admin.tag.vo.MemberTagPageReqVO @@ -7,7 +7,9 @@ import cn.iocoder.yudao.module.member.controller.admin.tag.vo.MemberTagPageReqVO
7 import cn.iocoder.yudao.module.member.controller.admin.tag.vo.MemberTagUpdateReqVO; 7 import cn.iocoder.yudao.module.member.controller.admin.tag.vo.MemberTagUpdateReqVO;
8 import cn.iocoder.yudao.module.member.dal.dataobject.tag.MemberTagDO; 8 import cn.iocoder.yudao.module.member.dal.dataobject.tag.MemberTagDO;
9 import cn.iocoder.yudao.module.member.dal.mysql.tag.MemberTagMapper; 9 import cn.iocoder.yudao.module.member.dal.mysql.tag.MemberTagMapper;
  10 +import cn.iocoder.yudao.module.member.service.user.MemberUserService;
10 import org.junit.jupiter.api.Test; 11 import org.junit.jupiter.api.Test;
  12 +import org.springframework.boot.test.mock.mockito.MockBean;
11 import org.springframework.context.annotation.Import; 13 import org.springframework.context.annotation.Import;
12 14
13 import javax.annotation.Resource; 15 import javax.annotation.Resource;
@@ -22,6 +24,7 @@ import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; @@ -22,6 +24,7 @@ import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
22 import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.TAG_NOT_EXISTS; 24 import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.TAG_NOT_EXISTS;
23 import static org.junit.jupiter.api.Assertions.*; 25 import static org.junit.jupiter.api.Assertions.*;
24 26
  27 +// TODO 芋艿:完全 review 完,在去 review 单测
25 /** 28 /**
26 * {@link MemberTagServiceImpl} 的单元测试类 29 * {@link MemberTagServiceImpl} 的单元测试类
27 * 30 *
@@ -36,6 +39,9 @@ public class MemberTagServiceImplTest extends BaseDbUnitTest { @@ -36,6 +39,9 @@ public class MemberTagServiceImplTest extends BaseDbUnitTest {
36 @Resource 39 @Resource
37 private MemberTagMapper tagMapper; 40 private MemberTagMapper tagMapper;
38 41
  42 + @MockBean
  43 + private MemberUserService memberUserService;
  44 +
39 @Test 45 @Test
40 public void testCreateTag_success() { 46 public void testCreateTag_success() {
41 // 准备参数 47 // 准备参数
yudao-module-member/yudao-module-member-biz/src/test/java/cn/iocoder/yudao/module/member/service/user/MemberUserServiceImplTest.java
@@ -11,6 +11,7 @@ import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO; @@ -11,6 +11,7 @@ import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
11 import cn.iocoder.yudao.module.member.dal.mysql.user.MemberUserMapper; 11 import cn.iocoder.yudao.module.member.dal.mysql.user.MemberUserMapper;
12 import cn.iocoder.yudao.module.member.service.auth.MemberAuthServiceImpl; 12 import cn.iocoder.yudao.module.member.service.auth.MemberAuthServiceImpl;
13 import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi; 13 import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi;
  14 +import org.junit.jupiter.api.Disabled;
14 import org.junit.jupiter.api.Test; 15 import org.junit.jupiter.api.Test;
15 import org.springframework.boot.test.mock.mockito.MockBean; 16 import org.springframework.boot.test.mock.mockito.MockBean;
16 import org.springframework.context.annotation.Import; 17 import org.springframework.context.annotation.Import;
@@ -92,6 +93,7 @@ public class MemberUserServiceImplTest extends BaseDbAndRedisUnitTest { @@ -92,6 +93,7 @@ public class MemberUserServiceImplTest extends BaseDbAndRedisUnitTest {
92 // } 93 // }
93 94
94 @Test 95 @Test
  96 + @Disabled // TODO 芋艿:后续再修复
95 public void updateMobile_success(){ 97 public void updateMobile_success(){
96 // mock数据 98 // mock数据
97 String oldMobile = randomNumbers(11); 99 String oldMobile = randomNumbers(11);
yudao-module-member/yudao-module-member-biz/src/test/resources/sql/create_tables.sql
@@ -63,7 +63,7 @@ CREATE TABLE IF NOT EXISTS &quot;member_level&quot; @@ -63,7 +63,7 @@ CREATE TABLE IF NOT EXISTS &quot;member_level&quot;
63 "name" varchar NOT NULL, 63 "name" varchar NOT NULL,
64 "experience" int NOT NULL, 64 "experience" int NOT NULL,
65 "level" int NOT NULL, 65 "level" int NOT NULL,
66 - "discount" int NOT NULL, 66 + "discount_percent" int NOT NULL,
67 "icon" varchar NOT NULL, 67 "icon" varchar NOT NULL,
68 "background_url" varchar NOT NULL, 68 "background_url" varchar NOT NULL,
69 "creator" varchar DEFAULT '', 69 "creator" varchar DEFAULT '',
@@ -72,7 +72,7 @@ CREATE TABLE IF NOT EXISTS &quot;member_level&quot; @@ -72,7 +72,7 @@ CREATE TABLE IF NOT EXISTS &quot;member_level&quot;
72 "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, 72 "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
73 "deleted" bit NOT NULL DEFAULT FALSE, 73 "deleted" bit NOT NULL DEFAULT FALSE,
74 "tenant_id" bigint not null default '0', 74 "tenant_id" bigint not null default '0',
75 - "status" int NOT NULL, 75 + "status" tinyint NOT NULL DEFAULT '0',
76 PRIMARY KEY ("id") 76 PRIMARY KEY ("id")
77 ) COMMENT '会员等级'; 77 ) COMMENT '会员等级';
78 78
@@ -81,7 +81,7 @@ CREATE TABLE IF NOT EXISTS &quot;member_group&quot; @@ -81,7 +81,7 @@ CREATE TABLE IF NOT EXISTS &quot;member_group&quot;
81 "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY, 81 "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
82 "name" varchar NOT NULL, 82 "name" varchar NOT NULL,
83 "remark" varchar NOT NULL, 83 "remark" varchar NOT NULL,
84 - "status" varchar NOT NULL, 84 + "status" tinyint NOT NULL DEFAULT '0',
85 "creator" varchar DEFAULT '', 85 "creator" varchar DEFAULT '',
86 "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, 86 "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
87 "updater" varchar DEFAULT '', 87 "updater" varchar DEFAULT '',
@@ -89,4 +89,25 @@ CREATE TABLE IF NOT EXISTS &quot;member_group&quot; @@ -89,4 +89,25 @@ CREATE TABLE IF NOT EXISTS &quot;member_group&quot;
89 "deleted" bit NOT NULL DEFAULT FALSE, 89 "deleted" bit NOT NULL DEFAULT FALSE,
90 "tenant_id" bigint not null default '0', 90 "tenant_id" bigint not null default '0',
91 PRIMARY KEY ("id") 91 PRIMARY KEY ("id")
92 -) COMMENT '用户分组';  
93 \ No newline at end of file 92 \ No newline at end of file
  93 +) COMMENT '用户分组';
  94 +CREATE TABLE IF NOT EXISTS "member_brokerage_record"
  95 +(
  96 + "id" int NOT NULL GENERATED BY DEFAULT AS IDENTITY,
  97 + "user_id" bigint NOT NULL,
  98 + "biz_id" varchar NOT NULL,
  99 + "biz_type" varchar NOT NULL,
  100 + "title" varchar NOT NULL,
  101 + "price" int NOT NULL,
  102 + "total_price" int NOT NULL,
  103 + "description" varchar NOT NULL,
  104 + "status" varchar NOT NULL,
  105 + "frozen_days" int NOT NULL,
  106 + "unfreeze_time" varchar,
  107 + "creator" varchar DEFAULT '',
  108 + "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  109 + "updater" varchar DEFAULT '',
  110 + "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  111 + "deleted" bit NOT NULL DEFAULT FALSE,
  112 + "tenant_id" bigint not null default '0',
  113 + PRIMARY KEY ("id")
  114 +) COMMENT '佣金记录';
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/account/vo/MpAccountRespVO.java
@@ -5,7 +5,7 @@ import lombok.Data; @@ -5,7 +5,7 @@ import lombok.Data;
5 import lombok.EqualsAndHashCode; 5 import lombok.EqualsAndHashCode;
6 import lombok.ToString; 6 import lombok.ToString;
7 7
8 -import java.util.Date; 8 +import java.time.LocalDateTime;
9 9
10 @Schema(description = "管理后台 - 公众号账号 Response VO") 10 @Schema(description = "管理后台 - 公众号账号 Response VO")
11 @Data 11 @Data
@@ -20,6 +20,6 @@ public class MpAccountRespVO extends MpAccountBaseVO { @@ -20,6 +20,6 @@ public class MpAccountRespVO extends MpAccountBaseVO {
20 private String qrCodeUrl; 20 private String qrCodeUrl;
21 21
22 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) 22 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
23 - private Date createTime; 23 + private LocalDateTime createTime;
24 24
25 } 25 }
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/material/vo/MpMaterialRespVO.java
@@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.mp.controller.admin.material.vo; @@ -3,7 +3,7 @@ package cn.iocoder.yudao.module.mp.controller.admin.material.vo;
3 import io.swagger.v3.oas.annotations.media.Schema; 3 import io.swagger.v3.oas.annotations.media.Schema;
4 import lombok.Data; 4 import lombok.Data;
5 5
6 -import java.util.Date; 6 +import java.time.LocalDateTime;
7 7
8 @Schema(description = "管理后台 - 公众号素材 Response VO") 8 @Schema(description = "管理后台 - 公众号素材 Response VO")
9 @Data 9 @Data
@@ -42,6 +42,6 @@ public class MpMaterialRespVO { @@ -42,6 +42,6 @@ public class MpMaterialRespVO {
42 private String introduction; 42 private String introduction;
43 43
44 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) 44 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
45 - private Date createTime; 45 + private LocalDateTime createTime;
46 46
47 } 47 }
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/menu/vo/MpMenuRespVO.java
@@ -5,7 +5,7 @@ import lombok.Data; @@ -5,7 +5,7 @@ import lombok.Data;
5 import lombok.EqualsAndHashCode; 5 import lombok.EqualsAndHashCode;
6 import lombok.ToString; 6 import lombok.ToString;
7 7
8 -import java.util.Date; 8 +import java.time.LocalDateTime;
9 9
10 @Schema(description = "管理后台 - 公众号菜单 Response VO") 10 @Schema(description = "管理后台 - 公众号菜单 Response VO")
11 @Data 11 @Data
@@ -23,6 +23,6 @@ public class MpMenuRespVO extends MpMenuBaseVO { @@ -23,6 +23,6 @@ public class MpMenuRespVO extends MpMenuBaseVO {
23 private String appId; 23 private String appId;
24 24
25 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) 25 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
26 - private Date createTime; 26 + private LocalDateTime createTime;
27 27
28 } 28 }
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/message/vo/autoreply/MpAutoReplyRespVO.java
@@ -5,7 +5,7 @@ import lombok.Data; @@ -5,7 +5,7 @@ import lombok.Data;
5 import lombok.EqualsAndHashCode; 5 import lombok.EqualsAndHashCode;
6 import lombok.ToString; 6 import lombok.ToString;
7 7
8 -import java.util.Date; 8 +import java.time.LocalDateTime;
9 9
10 @Schema(description = "管理后台 - 公众号自动回复 Response VO") 10 @Schema(description = "管理后台 - 公众号自动回复 Response VO")
11 @Data 11 @Data
@@ -22,6 +22,6 @@ public class MpAutoReplyRespVO extends MpAutoReplyBaseVO { @@ -22,6 +22,6 @@ public class MpAutoReplyRespVO extends MpAutoReplyBaseVO {
22 private String appId; 22 private String appId;
23 23
24 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) 24 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
25 - private Date createTime; 25 + private LocalDateTime createTime;
26 26
27 } 27 }
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/message/vo/message/MpMessageRespVO.java
@@ -6,6 +6,7 @@ import io.swagger.v3.oas.annotations.media.Schema; @@ -6,6 +6,7 @@ import io.swagger.v3.oas.annotations.media.Schema;
6 import lombok.Data; 6 import lombok.Data;
7 import me.chanjar.weixin.common.api.WxConsts; 7 import me.chanjar.weixin.common.api.WxConsts;
8 8
  9 +import java.time.LocalDateTime;
9 import java.util.Date; 10 import java.util.Date;
10 import java.util.List; 11 import java.util.List;
11 12
@@ -96,6 +97,6 @@ public class MpMessageRespVO { @@ -96,6 +97,6 @@ public class MpMessageRespVO {
96 private String eventKey; 97 private String eventKey;
97 98
98 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) 99 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
99 - private Date createTime; 100 + private LocalDateTime createTime;
100 101
101 } 102 }
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/statistics/vo/MpStatisticsInterfaceSummaryRespVO.java
@@ -3,14 +3,14 @@ package cn.iocoder.yudao.module.mp.controller.admin.statistics.vo; @@ -3,14 +3,14 @@ package cn.iocoder.yudao.module.mp.controller.admin.statistics.vo;
3 import io.swagger.v3.oas.annotations.media.Schema; 3 import io.swagger.v3.oas.annotations.media.Schema;
4 import lombok.Data; 4 import lombok.Data;
5 5
6 -import java.util.Date; 6 +import java.time.LocalDateTime;
7 7
8 @Schema(description = "管理后台 - 某一天的接口分析数据 Response VO") 8 @Schema(description = "管理后台 - 某一天的接口分析数据 Response VO")
9 @Data 9 @Data
10 public class MpStatisticsInterfaceSummaryRespVO { 10 public class MpStatisticsInterfaceSummaryRespVO {
11 11
12 @Schema(description = "日期", requiredMode = Schema.RequiredMode.REQUIRED) 12 @Schema(description = "日期", requiredMode = Schema.RequiredMode.REQUIRED)
13 - private Date refDate; 13 + private LocalDateTime refDate;
14 14
15 @Schema(description = "通过服务器配置地址获得消息后,被动回复粉丝消息的次数", requiredMode = Schema.RequiredMode.REQUIRED, example = "10") 15 @Schema(description = "通过服务器配置地址获得消息后,被动回复粉丝消息的次数", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
16 private Integer callbackCount; 16 private Integer callbackCount;
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/statistics/vo/MpStatisticsUpstreamMessageRespVO.java
@@ -3,14 +3,14 @@ package cn.iocoder.yudao.module.mp.controller.admin.statistics.vo; @@ -3,14 +3,14 @@ package cn.iocoder.yudao.module.mp.controller.admin.statistics.vo;
3 import io.swagger.v3.oas.annotations.media.Schema; 3 import io.swagger.v3.oas.annotations.media.Schema;
4 import lombok.Data; 4 import lombok.Data;
5 5
6 -import java.util.Date; 6 +import java.time.LocalDateTime;
7 7
8 @Schema(description = "管理后台 - 某一天的粉丝增减数据 Response VO") 8 @Schema(description = "管理后台 - 某一天的粉丝增减数据 Response VO")
9 @Data 9 @Data
10 public class MpStatisticsUpstreamMessageRespVO { 10 public class MpStatisticsUpstreamMessageRespVO {
11 11
12 @Schema(description = "日期", requiredMode = Schema.RequiredMode.REQUIRED) 12 @Schema(description = "日期", requiredMode = Schema.RequiredMode.REQUIRED)
13 - private Date refDate; 13 + private LocalDateTime refDate;
14 14
15 @Schema(description = "上行发送了(向公众号发送了)消息的粉丝数", requiredMode = Schema.RequiredMode.REQUIRED, example = "10") 15 @Schema(description = "上行发送了(向公众号发送了)消息的粉丝数", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
16 private Integer messageUser; 16 private Integer messageUser;
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/statistics/vo/MpStatisticsUserCumulateRespVO.java
@@ -3,14 +3,14 @@ package cn.iocoder.yudao.module.mp.controller.admin.statistics.vo; @@ -3,14 +3,14 @@ package cn.iocoder.yudao.module.mp.controller.admin.statistics.vo;
3 import io.swagger.v3.oas.annotations.media.Schema; 3 import io.swagger.v3.oas.annotations.media.Schema;
4 import lombok.Data; 4 import lombok.Data;
5 5
6 -import java.util.Date; 6 +import java.time.LocalDateTime;
7 7
8 @Schema(description = "管理后台 - 某一天的消息发送概况数据 Response VO") 8 @Schema(description = "管理后台 - 某一天的消息发送概况数据 Response VO")
9 @Data 9 @Data
10 public class MpStatisticsUserCumulateRespVO { 10 public class MpStatisticsUserCumulateRespVO {
11 11
12 @Schema(description = "日期", requiredMode = Schema.RequiredMode.REQUIRED) 12 @Schema(description = "日期", requiredMode = Schema.RequiredMode.REQUIRED)
13 - private Date refDate; 13 + private LocalDateTime refDate;
14 14
15 @Schema(description = "累计粉丝量", requiredMode = Schema.RequiredMode.REQUIRED, example = "10") 15 @Schema(description = "累计粉丝量", requiredMode = Schema.RequiredMode.REQUIRED, example = "10")
16 private Integer cumulateUser; 16 private Integer cumulateUser;
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/statistics/vo/MpStatisticsUserSummaryRespVO.java
@@ -3,14 +3,14 @@ package cn.iocoder.yudao.module.mp.controller.admin.statistics.vo; @@ -3,14 +3,14 @@ package cn.iocoder.yudao.module.mp.controller.admin.statistics.vo;
3 import io.swagger.v3.oas.annotations.media.Schema; 3 import io.swagger.v3.oas.annotations.media.Schema;
4 import lombok.Data; 4 import lombok.Data;
5 5
6 -import java.util.Date; 6 +import java.time.LocalDateTime;
7 7
8 @Schema(description = "管理后台 - 某一天的粉丝增减数据 Response VO") 8 @Schema(description = "管理后台 - 某一天的粉丝增减数据 Response VO")
9 @Data 9 @Data
10 public class MpStatisticsUserSummaryRespVO { 10 public class MpStatisticsUserSummaryRespVO {
11 11
12 @Schema(description = "日期", requiredMode = Schema.RequiredMode.REQUIRED) 12 @Schema(description = "日期", requiredMode = Schema.RequiredMode.REQUIRED)
13 - private Date refDate; 13 + private LocalDateTime refDate;
14 14
15 @Schema(description = "粉丝来源", requiredMode = Schema.RequiredMode.REQUIRED, example = "0") 15 @Schema(description = "粉丝来源", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
16 private Integer userSource; 16 private Integer userSource;
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/tag/vo/MpTagRespVO.java
@@ -5,7 +5,7 @@ import lombok.Data; @@ -5,7 +5,7 @@ import lombok.Data;
5 import lombok.EqualsAndHashCode; 5 import lombok.EqualsAndHashCode;
6 import lombok.ToString; 6 import lombok.ToString;
7 7
8 -import java.util.Date; 8 +import java.time.LocalDateTime;
9 9
10 @Schema(description = "管理后台 - 公众号标签 Response VO") 10 @Schema(description = "管理后台 - 公众号标签 Response VO")
11 @Data 11 @Data
@@ -20,6 +20,6 @@ public class MpTagRespVO extends MpTagBaseVO { @@ -20,6 +20,6 @@ public class MpTagRespVO extends MpTagBaseVO {
20 private Integer count; 20 private Integer count;
21 21
22 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) 22 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
23 - private Date createTime; 23 + private LocalDateTime createTime;
24 24
25 } 25 }
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/user/vo/MpUserRespVO.java
@@ -48,6 +48,6 @@ public class MpUserRespVO { @@ -48,6 +48,6 @@ public class MpUserRespVO {
48 private String appId; 48 private String appId;
49 49
50 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) 50 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
51 - private Date createTime; 51 + private LocalDateTime createTime;
52 52
53 } 53 }
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/convert/menu/MpMenuConvert.java
@@ -40,6 +40,8 @@ public interface MpMenuConvert { @@ -40,6 +40,8 @@ public interface MpMenuConvert {
40 @Mappings({ 40 @Mappings({
41 @Mapping(source = "menuKey", target = "key"), 41 @Mapping(source = "menuKey", target = "key"),
42 @Mapping(source = "children", target = "subButtons"), 42 @Mapping(source = "children", target = "subButtons"),
  43 + @Mapping(source = "miniProgramAppId", target = "appId"),
  44 + @Mapping(source = "miniProgramPagePath", target = "pagePath"),
43 }) 45 })
44 WxMenuButton convert(MpMenuSaveReqVO.Menu bean); 46 WxMenuButton convert(MpMenuSaveReqVO.Menu bean);
45 47
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/order/PayOrderController.java
@@ -5,6 +5,8 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult; @@ -5,6 +5,8 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult;
5 import cn.iocoder.yudao.framework.common.pojo.PageResult; 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
6 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; 6 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
7 import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; 7 import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
  8 +import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
  9 +import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
8 import cn.iocoder.yudao.module.pay.controller.admin.order.vo.*; 10 import cn.iocoder.yudao.module.pay.controller.admin.order.vo.*;
9 import cn.iocoder.yudao.module.pay.convert.order.PayOrderConvert; 11 import cn.iocoder.yudao.module.pay.convert.order.PayOrderConvert;
10 import cn.iocoder.yudao.module.pay.dal.dataobject.app.PayAppDO; 12 import cn.iocoder.yudao.module.pay.dal.dataobject.app.PayAppDO;
@@ -23,9 +25,7 @@ import javax.annotation.Resource; @@ -23,9 +25,7 @@ import javax.annotation.Resource;
23 import javax.servlet.http.HttpServletResponse; 25 import javax.servlet.http.HttpServletResponse;
24 import javax.validation.Valid; 26 import javax.validation.Valid;
25 import java.io.IOException; 27 import java.io.IOException;
26 -import java.util.ArrayList;  
27 -import java.util.List;  
28 -import java.util.Map; 28 +import java.util.*;
29 29
30 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; 30 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
31 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; 31 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
@@ -70,6 +70,13 @@ public class PayOrderController { @@ -70,6 +70,13 @@ public class PayOrderController {
70 @PostMapping("/submit") 70 @PostMapping("/submit")
71 @Operation(summary = "提交支付订单") 71 @Operation(summary = "提交支付订单")
72 public CommonResult<PayOrderSubmitRespVO> submitPayOrder(@RequestBody PayOrderSubmitReqVO reqVO) { 72 public CommonResult<PayOrderSubmitRespVO> submitPayOrder(@RequestBody PayOrderSubmitReqVO reqVO) {
  73 + // 钱包支付需要 额外传 user_id 和 user_type
  74 + if (Objects.equals(reqVO.getChannelCode(), PayChannelEnum.WALLET.getCode())) {
  75 + Map<String, String> channelExtras = reqVO.getChannelExtras() == null ? new HashMap<>(8) : reqVO.getChannelExtras();
  76 + channelExtras.put("user_id", String.valueOf(WebFrameworkUtils.getLoginUserId()));
  77 + channelExtras.put("user_type", String.valueOf(WebFrameworkUtils.getLoginUserType()));
  78 + reqVO.setChannelExtras(channelExtras);
  79 + }
73 PayOrderSubmitRespVO respVO = orderService.submitOrder(reqVO, getClientIP()); 80 PayOrderSubmitRespVO respVO = orderService.submitOrder(reqVO, getClientIP());
74 return success(respVO); 81 return success(respVO);
75 } 82 }
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/AppPayWalletController.java
@@ -37,7 +37,7 @@ public class AppPayWalletController { @@ -37,7 +37,7 @@ public class AppPayWalletController {
37 @Operation(summary = "获取钱包") 37 @Operation(summary = "获取钱包")
38 @PreAuthenticated 38 @PreAuthenticated
39 public CommonResult<AppPayWalletRespVO> getPayWallet() { 39 public CommonResult<AppPayWalletRespVO> getPayWallet() {
40 - PayWalletDO wallet = payWalletService.getPayWallet(getLoginUserId(), UserTypeEnum.MEMBER.getValue()); 40 + PayWalletDO wallet = payWalletService.getOrCreatePayWallet(getLoginUserId(), UserTypeEnum.MEMBER.getValue());
41 return success(PayWalletConvert.INSTANCE.convert(wallet)); 41 return success(PayWalletConvert.INSTANCE.convert(wallet));
42 } 42 }
43 43
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/vo/transaction/AppPayWalletTransactionRespVO.java
@@ -15,9 +15,6 @@ public class AppPayWalletTransactionRespVO { @@ -15,9 +15,6 @@ public class AppPayWalletTransactionRespVO {
15 @Schema(description = "业务分类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") 15 @Schema(description = "业务分类", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
16 private Integer bizType; 16 private Integer bizType;
17 17
18 - @Schema(description = "交易时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")  
19 - private LocalDateTime transactionTime;  
20 -  
21 @Schema(description = "交易金额,单位分", requiredMode = Schema.RequiredMode.REQUIRED, example = "100") 18 @Schema(description = "交易金额,单位分", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
22 private Long price; 19 private Long price;
23 20
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/wallet/PayWalletTransactionDO.java
@@ -7,8 +7,6 @@ import com.baomidou.mybatisplus.annotation.TableId; @@ -7,8 +7,6 @@ import com.baomidou.mybatisplus.annotation.TableId;
7 import com.baomidou.mybatisplus.annotation.TableName; 7 import com.baomidou.mybatisplus.annotation.TableName;
8 import lombok.Data; 8 import lombok.Data;
9 9
10 -import java.time.LocalDateTime;  
11 -  
12 /** 10 /**
13 * 会员钱包流水 DO 11 * 会员钱包流水 DO
14 * 12 *
@@ -24,6 +22,7 @@ public class PayWalletTransactionDO extends BaseDO { @@ -24,6 +22,7 @@ public class PayWalletTransactionDO extends BaseDO {
24 */ 22 */
25 @TableId 23 @TableId
26 private Long id; 24 private Long id;
  25 +
27 /** 26 /**
28 * 流水号 27 * 流水号
29 */ 28 */
@@ -42,34 +41,26 @@ public class PayWalletTransactionDO extends BaseDO { @@ -42,34 +41,26 @@ public class PayWalletTransactionDO extends BaseDO {
42 * 枚举 {@link PayWalletBizTypeEnum#getType()} 41 * 枚举 {@link PayWalletBizTypeEnum#getType()}
43 */ 42 */
44 private Integer bizType; 43 private Integer bizType;
45 - // TODO @jason:使用 string;因为可能有业务是 string 接入哈。 44 +
46 /** 45 /**
47 * 关联业务编号 46 * 关联业务编号
48 */ 47 */
49 - private Long bizId; 48 + private String bizId;
50 49
51 - // TODO @jason:想了下,改成 title;流水标题;因为账户明细那,会看到这个;  
52 /** 50 /**
53 - * 附加说明 51 + * 流水说明
54 */ 52 */
55 - private String description; 53 + private String title;
56 54
57 - // TODO @jason:使用 price 哈。项目里,金额都是用这个为主;  
58 /** 55 /**
59 * 交易金额,单位分 56 * 交易金额,单位分
60 * 57 *
61 * 正值表示余额增加,负值表示余额减少 58 * 正值表示余额增加,负值表示余额减少
62 */ 59 */
63 - private Integer amount; 60 + private Integer price;
  61 +
64 /** 62 /**
65 * 交易后余额,单位分 63 * 交易后余额,单位分
66 */ 64 */
67 private Integer balance; 65 private Integer balance;
68 -  
69 - // TODO @jason:使用 createTime 就够啦  
70 - /**  
71 - * 交易时间  
72 - */  
73 - private LocalDateTime transactionTime;  
74 -  
75 } 66 }
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/wallet/PayWalletMapper.java
@@ -3,6 +3,8 @@ package cn.iocoder.yudao.module.pay.dal.mysql.wallet; @@ -3,6 +3,8 @@ package cn.iocoder.yudao.module.pay.dal.mysql.wallet;
3 3
4 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; 4 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
5 import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO; 5 import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO;
  6 +import cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum;
  7 +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
6 import org.apache.ibatis.annotations.Mapper; 8 import org.apache.ibatis.annotations.Mapper;
7 9
8 @Mapper 10 @Mapper
@@ -12,6 +14,55 @@ public interface PayWalletMapper extends BaseMapperX&lt;PayWalletDO&gt; { @@ -12,6 +14,55 @@ public interface PayWalletMapper extends BaseMapperX&lt;PayWalletDO&gt; {
12 return selectOne(PayWalletDO::getUserId, userId, 14 return selectOne(PayWalletDO::getUserId, userId,
13 PayWalletDO::getUserType, userType); 15 PayWalletDO::getUserType, userType);
14 } 16 }
  17 +
  18 + /**
  19 + * 当余额减少时候更新
  20 + *
  21 + * @param bizType 业务类型
  22 + * @param balance 当前余额
  23 + * @param totalRecharge 当前累计充值
  24 + * @param totalExpense 当前累计支出
  25 + * @param price 支出的金额
  26 + * @param id 钱包 id
  27 + */
  28 + default int updateWhenDecBalance(PayWalletBizTypeEnum bizType, Integer balance, Long totalRecharge,
  29 + Long totalExpense, Integer price, Long id) {
  30 + PayWalletDO updateDO = new PayWalletDO().setBalance(balance - price);
  31 + if(bizType == PayWalletBizTypeEnum.PAYMENT){
  32 + updateDO.setTotalExpense(totalExpense + price);
  33 + }
  34 + if (bizType == PayWalletBizTypeEnum.RECHARGE_REFUND) {
  35 + updateDO.setTotalRecharge(totalRecharge - price);
  36 + }
  37 + return update(updateDO,
  38 + new LambdaQueryWrapper<PayWalletDO>().eq(PayWalletDO::getId, id)
  39 + .eq(PayWalletDO::getBalance, balance)
  40 + .ge(PayWalletDO::getBalance, price));
  41 + }
  42 +
  43 + /**
  44 + * 当余额增加时候更新
  45 + *
  46 + * @param bizType 业务类型
  47 + * @param balance 当前余额
  48 + * @param totalRecharge 当前累计充值
  49 + * @param totalExpense 当前累计支出
  50 + * @param price 金额
  51 + * @param id 钱包 id
  52 + */
  53 + default int updateWhenIncBalance(PayWalletBizTypeEnum bizType, Integer balance, Long totalRecharge,
  54 + Long totalExpense, Integer price, Long id) {
  55 + PayWalletDO updateDO = new PayWalletDO().setBalance(balance + price);
  56 + if (bizType == PayWalletBizTypeEnum.PAYMENT_REFUND) {
  57 + updateDO.setTotalExpense(totalExpense - price);
  58 + }
  59 + if (bizType == PayWalletBizTypeEnum.RECHARGE) {
  60 + updateDO.setTotalExpense(totalRecharge + price);
  61 + }
  62 + return update(updateDO,
  63 + new LambdaQueryWrapper<PayWalletDO>().eq(PayWalletDO::getId, id)
  64 + .eq(PayWalletDO::getBalance, balance));
  65 + }
15 } 66 }
16 67
17 68
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/wallet/PayWalletTransactionMapper.java
@@ -18,9 +18,9 @@ public interface PayWalletTransactionMapper extends BaseMapperX&lt;PayWalletTransac @@ -18,9 +18,9 @@ public interface PayWalletTransactionMapper extends BaseMapperX&lt;PayWalletTransac
18 LambdaQueryWrapperX<PayWalletTransactionDO> query = new LambdaQueryWrapperX<PayWalletTransactionDO>() 18 LambdaQueryWrapperX<PayWalletTransactionDO> query = new LambdaQueryWrapperX<PayWalletTransactionDO>()
19 .eq(PayWalletTransactionDO::getWalletId, walletId); 19 .eq(PayWalletTransactionDO::getWalletId, walletId);
20 if (Objects.equals(pageReqVO.getType(), AppPayWalletTransactionPageReqVO.TYPE_INCOME)) { 20 if (Objects.equals(pageReqVO.getType(), AppPayWalletTransactionPageReqVO.TYPE_INCOME)) {
21 - query.gt(PayWalletTransactionDO::getAmount, 0); 21 + query.gt(PayWalletTransactionDO::getPrice, 0);
22 } else if (Objects.equals(pageReqVO.getType(), AppPayWalletTransactionPageReqVO.TYPE_EXPENSE)) { 22 } else if (Objects.equals(pageReqVO.getType(), AppPayWalletTransactionPageReqVO.TYPE_EXPENSE)) {
23 - query.lt(PayWalletTransactionDO::getAmount, 0); 23 + query.lt(PayWalletTransactionDO::getPrice, 0);
24 } 24 }
25 query.orderByDesc(PayWalletTransactionDO::getId); 25 query.orderByDesc(PayWalletTransactionDO::getId);
26 return selectPage(pageReqVO, query); 26 return selectPage(pageReqVO, query);
@@ -30,9 +30,8 @@ public interface PayWalletTransactionMapper extends BaseMapperX&lt;PayWalletTransac @@ -30,9 +30,8 @@ public interface PayWalletTransactionMapper extends BaseMapperX&lt;PayWalletTransac
30 return selectOne(PayWalletTransactionDO::getNo, no); 30 return selectOne(PayWalletTransactionDO::getNo, no);
31 } 31 }
32 32
33 - default PayWalletTransactionDO selectByWalletIdAndBiz(Long walletId, Long bizId, Integer bizType) {  
34 - return selectOne(PayWalletTransactionDO::getWalletId, walletId,  
35 - PayWalletTransactionDO::getBizId, bizId, 33 + default PayWalletTransactionDO selectByBiz(String bizId, Integer bizType) {
  34 + return selectOne(PayWalletTransactionDO::getBizId, bizId,
36 PayWalletTransactionDO::getBizType, bizType); 35 PayWalletTransactionDO::getBizType, bizType);
37 } 36 }
38 37
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/framework/pay/wallet/WalletPayClient.java
1 package cn.iocoder.yudao.module.pay.framework.pay.wallet; 1 package cn.iocoder.yudao.module.pay.framework.pay.wallet;
2 2
  3 +import cn.hutool.core.lang.Assert;
  4 +import cn.hutool.core.map.MapUtil;
3 import cn.hutool.extra.spring.SpringUtil; 5 import cn.hutool.extra.spring.SpringUtil;
4 import cn.iocoder.yudao.framework.common.exception.ServiceException; 6 import cn.iocoder.yudao.framework.common.exception.ServiceException;
5 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO; 7 import cn.iocoder.yudao.framework.pay.core.client.dto.order.PayOrderRespDTO;
@@ -9,13 +11,23 @@ import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReq @@ -9,13 +11,23 @@ import cn.iocoder.yudao.framework.pay.core.client.dto.refund.PayRefundUnifiedReq
9 import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient; 11 import cn.iocoder.yudao.framework.pay.core.client.impl.AbstractPayClient;
10 import cn.iocoder.yudao.framework.pay.core.client.impl.NonePayClientConfig; 12 import cn.iocoder.yudao.framework.pay.core.client.impl.NonePayClientConfig;
11 import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum; 13 import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum;
  14 +import cn.iocoder.yudao.framework.pay.core.enums.refund.PayRefundStatusRespEnum;
  15 +import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderExtensionDO;
  16 +import cn.iocoder.yudao.module.pay.dal.dataobject.refund.PayRefundDO;
12 import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO; 17 import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO;
  18 +import cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum;
  19 +import cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum;
  20 +import cn.iocoder.yudao.module.pay.service.order.PayOrderService;
  21 +import cn.iocoder.yudao.module.pay.service.refund.PayRefundService;
13 import cn.iocoder.yudao.module.pay.service.wallet.PayWalletService; 22 import cn.iocoder.yudao.module.pay.service.wallet.PayWalletService;
  23 +import cn.iocoder.yudao.module.pay.service.wallet.PayWalletTransactionService;
14 import lombok.extern.slf4j.Slf4j; 24 import lombok.extern.slf4j.Slf4j;
15 25
16 import java.util.Map; 26 import java.util.Map;
17 27
18 import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR; 28 import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR;
  29 +import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.ORDER_EXTENSION_NOT_FOUND;
  30 +import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.REFUND_NOT_FOUND;
19 31
20 /** 32 /**
21 * 钱包支付的 PayClient 实现类 33 * 钱包支付的 PayClient 实现类
@@ -27,6 +39,12 @@ public class WalletPayClient extends AbstractPayClient&lt;NonePayClientConfig&gt; { @@ -27,6 +39,12 @@ public class WalletPayClient extends AbstractPayClient&lt;NonePayClientConfig&gt; {
27 39
28 private PayWalletService wallService; 40 private PayWalletService wallService;
29 41
  42 + private PayWalletTransactionService walletTransactionService;
  43 +
  44 + private PayOrderService payOrderService;
  45 +
  46 + private PayRefundService payRefundService;
  47 +
30 public WalletPayClient(Long channelId, NonePayClientConfig config) { 48 public WalletPayClient(Long channelId, NonePayClientConfig config) {
31 super(channelId, PayChannelEnum.WALLET.getCode(), config); 49 super(channelId, PayChannelEnum.WALLET.getCode(), config);
32 } 50 }
@@ -36,14 +54,22 @@ public class WalletPayClient extends AbstractPayClient&lt;NonePayClientConfig&gt; { @@ -36,14 +54,22 @@ public class WalletPayClient extends AbstractPayClient&lt;NonePayClientConfig&gt; {
36 if (wallService == null) { 54 if (wallService == null) {
37 wallService = SpringUtil.getBean(PayWalletService.class); 55 wallService = SpringUtil.getBean(PayWalletService.class);
38 } 56 }
  57 + if (walletTransactionService == null) {
  58 + walletTransactionService = SpringUtil.getBean(PayWalletTransactionService.class);
  59 + }
39 } 60 }
40 61
41 @Override 62 @Override
42 protected PayOrderRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) { 63 protected PayOrderRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) {
43 try { 64 try {
44 - PayWalletTransactionDO transaction = wallService.pay(reqDTO.getOutTradeNo(), reqDTO.getPrice()); 65 + String userId = MapUtil.getStr(reqDTO.getChannelExtras(), "user_id");
  66 + String userType = MapUtil.getStr(reqDTO.getChannelExtras(), "user_type");
  67 + Assert.notEmpty(userId, "用户 id 不能为空");
  68 + Assert.notEmpty(userType, "用户类型不能为空");
  69 + PayWalletTransactionDO transaction = wallService.orderPay(Long.valueOf(userId), Integer.valueOf(userType),
  70 + reqDTO.getOutTradeNo(), reqDTO.getPrice());
45 return PayOrderRespDTO.successOf(transaction.getNo(), transaction.getCreator(), 71 return PayOrderRespDTO.successOf(transaction.getNo(), transaction.getCreator(),
46 - transaction.getTransactionTime(), 72 + transaction.getCreateTime(),
47 reqDTO.getOutTradeNo(), transaction); 73 reqDTO.getOutTradeNo(), transaction);
48 } catch (Throwable ex) { 74 } catch (Throwable ex) {
49 log.error("[doUnifiedOrder] 失败", ex); 75 log.error("[doUnifiedOrder] 失败", ex);
@@ -66,15 +92,39 @@ public class WalletPayClient extends AbstractPayClient&lt;NonePayClientConfig&gt; { @@ -66,15 +92,39 @@ public class WalletPayClient extends AbstractPayClient&lt;NonePayClientConfig&gt; {
66 92
67 @Override 93 @Override
68 protected PayOrderRespDTO doGetOrder(String outTradeNo) { 94 protected PayOrderRespDTO doGetOrder(String outTradeNo) {
69 - throw new UnsupportedOperationException("待实现"); 95 + if (payOrderService == null) {
  96 + payOrderService = SpringUtil.getBean(PayOrderService.class);
  97 + }
  98 + PayOrderExtensionDO orderExtension = payOrderService.getOrderExtensionByNo(outTradeNo);
  99 + // 支付交易拓展单不存在, 返回关闭状态
  100 + if (orderExtension == null) {
  101 + return PayOrderRespDTO.closedOf(String.valueOf(ORDER_EXTENSION_NOT_FOUND.getCode()),
  102 + ORDER_EXTENSION_NOT_FOUND.getMsg(), outTradeNo, "");
  103 + }
  104 + // 关闭状态
  105 + if (PayOrderStatusEnum.isClosed(orderExtension.getStatus())) {
  106 + return PayOrderRespDTO.closedOf(orderExtension.getChannelErrorCode(),
  107 + orderExtension.getChannelErrorMsg(), outTradeNo, "");
  108 + }
  109 + // 成功状态
  110 + if (PayOrderStatusEnum.isSuccess(orderExtension.getStatus())) {
  111 + PayWalletTransactionDO walletTransaction = walletTransactionService.getWalletTransaction(
  112 + String.valueOf(orderExtension.getOrderId()), PayWalletBizTypeEnum.PAYMENT);
  113 + Assert.notNull(walletTransaction, "支付单 {} 钱包流水不能为空", outTradeNo);
  114 + return PayOrderRespDTO.successOf(walletTransaction.getNo(), walletTransaction.getCreator(),
  115 + walletTransaction.getCreateTime(), outTradeNo, walletTransaction);
  116 + }
  117 + // 其它状态为无效状态
  118 + log.error("[doGetOrder] 支付单 {} 的状态不正确", outTradeNo);
  119 + throw new IllegalStateException(String.format("支付单[%s] 状态不正确", outTradeNo));
70 } 120 }
71 121
72 @Override 122 @Override
73 protected PayRefundRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) { 123 protected PayRefundRespDTO doUnifiedRefund(PayRefundUnifiedReqDTO reqDTO) {
74 try { 124 try {
75 - PayWalletTransactionDO payWalletTransaction = wallService.refund(reqDTO.getOutRefundNo(), 125 + PayWalletTransactionDO payWalletTransaction = wallService.orderRefund(reqDTO.getOutRefundNo(),
76 reqDTO.getRefundPrice(), reqDTO.getReason()); 126 reqDTO.getRefundPrice(), reqDTO.getReason());
77 - return PayRefundRespDTO.successOf(payWalletTransaction.getNo(), payWalletTransaction.getTransactionTime(), 127 + return PayRefundRespDTO.successOf(payWalletTransaction.getNo(), payWalletTransaction.getCreateTime(),
78 reqDTO.getOutRefundNo(), payWalletTransaction); 128 reqDTO.getOutRefundNo(), payWalletTransaction);
79 } catch (Throwable ex) { 129 } catch (Throwable ex) {
80 log.error("[doUnifiedRefund] 失败", ex); 130 log.error("[doUnifiedRefund] 失败", ex);
@@ -97,7 +147,31 @@ public class WalletPayClient extends AbstractPayClient&lt;NonePayClientConfig&gt; { @@ -97,7 +147,31 @@ public class WalletPayClient extends AbstractPayClient&lt;NonePayClientConfig&gt; {
97 147
98 @Override 148 @Override
99 protected PayRefundRespDTO doGetRefund(String outTradeNo, String outRefundNo) { 149 protected PayRefundRespDTO doGetRefund(String outTradeNo, String outRefundNo) {
100 - throw new UnsupportedOperationException("待实现"); 150 + if (payRefundService == null) {
  151 + payRefundService = SpringUtil.getBean(PayRefundService.class);
  152 + }
  153 + PayRefundDO payRefund = payRefundService.getRefundByNo(outRefundNo);
  154 + // 支付退款单不存在, 返回退款失败状态
  155 + if (payRefund == null) {
  156 + return PayRefundRespDTO.failureOf(String.valueOf(REFUND_NOT_FOUND), REFUND_NOT_FOUND.getMsg(),
  157 + outRefundNo, "");
  158 + }
  159 + // 退款失败
  160 + if (PayRefundStatusRespEnum.isFailure(payRefund.getStatus())) {
  161 + return PayRefundRespDTO.failureOf(payRefund.getChannelErrorCode(), payRefund.getChannelErrorMsg(),
  162 + outRefundNo, "");
  163 + }
  164 + // 退款成功
  165 + if (PayRefundStatusRespEnum.isSuccess(payRefund.getStatus())) {
  166 + PayWalletTransactionDO walletTransaction = walletTransactionService.getWalletTransaction(
  167 + String.valueOf(payRefund.getId()), PayWalletBizTypeEnum.PAYMENT_REFUND);
  168 + Assert.notNull(walletTransaction, "支付退款单 {} 钱包流水不能为空", outRefundNo);
  169 + return PayRefundRespDTO.successOf(walletTransaction.getNo(), walletTransaction.getCreateTime(),
  170 + outRefundNo, walletTransaction);
  171 + }
  172 + // 其它状态为无效状态
  173 + log.error("[doGetRefund] 支付退款单 {} 的状态不正确", outRefundNo);
  174 + throw new IllegalStateException(String.format("支付退款单[%s] 状态不正确", outRefundNo));
101 } 175 }
102 176
103 } 177 }
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/order/PayOrderServiceImpl.java
@@ -345,7 +345,8 @@ public class PayOrderServiceImpl implements PayOrderService { @@ -345,7 +345,8 @@ public class PayOrderServiceImpl implements PayOrderService {
345 .channelId(channel.getId()).channelCode(channel.getCode()) 345 .channelId(channel.getId()).channelCode(channel.getCode())
346 .successTime(notify.getSuccessTime()).extensionId(orderExtension.getId()).no(orderExtension.getNo()) 346 .successTime(notify.getSuccessTime()).extensionId(orderExtension.getId()).no(orderExtension.getNo())
347 .channelOrderNo(notify.getChannelOrderNo()).channelUserId(notify.getChannelUserId()) 347 .channelOrderNo(notify.getChannelOrderNo()).channelUserId(notify.getChannelUserId())
348 - .channelFeeRate(channel.getFeeRate()).channelFeePrice(MoneyUtils.calculateRatePrice(order.getPrice(), channel.getFeeRate())) 348 + .channelFeeRate(channel.getFeeRate())
  349 + .channelFeePrice(MoneyUtils.calculateRatePrice(order.getPrice(), channel.getFeeRate()))
349 .build()); 350 .build());
350 if (updateCounts == 0) { // 校验状态,必须是待支付 351 if (updateCounts == 0) { // 校验状态,必须是待支付
351 throw exception(ORDER_STATUS_IS_NOT_WAITING); 352 throw exception(ORDER_STATUS_IS_NOT_WAITING);
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletService.java
@@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.pay.service.wallet; @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.pay.service.wallet;
2 2
3 import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO; 3 import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO;
4 import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO; 4 import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO;
  5 +import cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum;
5 6
6 /** 7 /**
7 * 钱包 Service 接口 8 * 钱包 Service 接口
@@ -10,30 +11,59 @@ import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO; @@ -10,30 +11,59 @@ import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO;
10 */ 11 */
11 public interface PayWalletService { 12 public interface PayWalletService {
12 13
13 - // TODO @jason:改成 getOrCreateWallet;因为目前解耦,用户注册时,不会创建钱包;需要这里兜底处理;  
14 /** 14 /**
15 - * 获取钱包信息 15 + * 获取钱包信息,如果不存在创建钱包。由于用户注册时候不会创建钱包
16 * 16 *
17 * @param userId 用户编号 17 * @param userId 用户编号
18 * @param userType 用户类型 18 * @param userType 用户类型
19 */ 19 */
20 - PayWalletDO getPayWallet(Long userId, Integer userType); 20 + PayWalletDO getOrCreatePayWallet(Long userId, Integer userType);
21 21
22 /** 22 /**
23 - * 钱包支付 23 + * 钱包订单支付
24 * 24 *
  25 + * @param userId 用户 id
  26 + * @param userType 用户类型
25 * @param outTradeNo 外部订单号 27 * @param outTradeNo 外部订单号
26 * @param price 金额 28 * @param price 金额
27 */ 29 */
28 - PayWalletTransactionDO pay(String outTradeNo, Integer price); 30 + PayWalletTransactionDO orderPay(Long userId, Integer userType, String outTradeNo, Integer price);
  31 +
  32 +
  33 + /**
  34 + * 扣减钱包余额
  35 + *
  36 + * @param userId 用户 id
  37 + * @param userType 用户类型
  38 + * @param bizId 业务关联 id
  39 + * @param bizType 业务关联分类
  40 + * @param price 扣减金额
  41 + * @return 钱包流水
  42 + */
  43 + PayWalletTransactionDO reduceWalletBalance(Long userId, Integer userType,
  44 + Long bizId, PayWalletBizTypeEnum bizType, Integer price);
  45 +
  46 +
  47 + /**
  48 + * 增加钱包余额
  49 + *
  50 + * @param userId 用户 id
  51 + * @param userType 用户类型
  52 + * @param bizId 业务关联 id
  53 + * @param bizType 业务关联分类
  54 + * @param price 增加金额
  55 + * @return 钱包流水
  56 + */
  57 + PayWalletTransactionDO addWalletBalance(Long userId, Integer userType,
  58 + Long bizId, PayWalletBizTypeEnum bizType, Integer price);
29 59
30 /** 60 /**
31 - * 钱包支付退款 61 + * 钱包订单支付退款
32 * 62 *
33 * @param outRefundNo 外部退款号 63 * @param outRefundNo 外部退款号
34 * @param refundPrice 退款金额 64 * @param refundPrice 退款金额
35 * @param reason 退款原因 65 * @param reason 退款原因
36 */ 66 */
37 - PayWalletTransactionDO refund(String outRefundNo, Integer refundPrice, String reason); 67 + PayWalletTransactionDO orderRefund(String outRefundNo, Integer refundPrice, String reason);
38 68
39 } 69 }
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletServiceImpl.java
1 package cn.iocoder.yudao.module.pay.service.wallet; 1 package cn.iocoder.yudao.module.pay.service.wallet;
2 2
  3 +import cn.hutool.core.lang.Assert;
3 import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderExtensionDO; 4 import cn.iocoder.yudao.module.pay.dal.dataobject.order.PayOrderExtensionDO;
4 import cn.iocoder.yudao.module.pay.dal.dataobject.refund.PayRefundDO; 5 import cn.iocoder.yudao.module.pay.dal.dataobject.refund.PayRefundDO;
5 import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO; 6 import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO;
6 import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO; 7 import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO;
7 import cn.iocoder.yudao.module.pay.dal.mysql.wallet.PayWalletMapper; 8 import cn.iocoder.yudao.module.pay.dal.mysql.wallet.PayWalletMapper;
8 import cn.iocoder.yudao.module.pay.dal.redis.no.PayNoRedisDAO; 9 import cn.iocoder.yudao.module.pay.dal.redis.no.PayNoRedisDAO;
  10 +import cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum;
9 import cn.iocoder.yudao.module.pay.service.order.PayOrderService; 11 import cn.iocoder.yudao.module.pay.service.order.PayOrderService;
10 import cn.iocoder.yudao.module.pay.service.refund.PayRefundService; 12 import cn.iocoder.yudao.module.pay.service.refund.PayRefundService;
11 import lombok.extern.slf4j.Slf4j; 13 import lombok.extern.slf4j.Slf4j;
@@ -16,9 +18,8 @@ import org.springframework.transaction.annotation.Transactional; @@ -16,9 +18,8 @@ import org.springframework.transaction.annotation.Transactional;
16 import javax.annotation.Resource; 18 import javax.annotation.Resource;
17 import java.time.LocalDateTime; 19 import java.time.LocalDateTime;
18 20
  21 +import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.TOO_MANY_REQUESTS;
19 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 22 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
20 -import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserId;  
21 -import static cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils.getLoginUserType;  
22 import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.*; 23 import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.*;
23 import static cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum.PAYMENT; 24 import static cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum.PAYMENT;
24 import static cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum.PAYMENT_REFUND; 25 import static cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum.PAYMENT_REFUND;
@@ -56,81 +57,111 @@ public class PayWalletServiceImpl implements PayWalletService { @@ -56,81 +57,111 @@ public class PayWalletServiceImpl implements PayWalletService {
56 private PayRefundService payRefundService; 57 private PayRefundService payRefundService;
57 58
58 @Override 59 @Override
59 - public PayWalletDO getPayWallet(Long userId, Integer userType) {  
60 - return payWalletMapper.selectByUserIdAndType(userId, userType); 60 + public PayWalletDO getOrCreatePayWallet(Long userId, Integer userType) {
  61 + PayWalletDO payWalletDO = payWalletMapper.selectByUserIdAndType(userId, userType);
  62 + if (payWalletDO == null) {
  63 + payWalletDO = new PayWalletDO();
  64 + payWalletDO.setUserId(userId);
  65 + payWalletDO.setUserType(userType);
  66 + payWalletDO.setBalance(0);
  67 + payWalletDO.setTotalExpense(0L);
  68 + payWalletDO.setTotalRecharge(0L);
  69 + payWalletDO.setCreateTime(LocalDateTime.now());
  70 + payWalletMapper.insert(payWalletDO);
  71 + }
  72 + return payWalletDO;
61 } 73 }
62 74
63 - // TODO @jason:可以做的更抽象一点;pay(bizType, bizId, price);reduceWalletBalance;  
64 - // TODO @jason:最好是,明确传入哪个 userId 或者 walletId; 75 +
65 @Override 76 @Override
66 @Transactional(rollbackFor = Exception.class) 77 @Transactional(rollbackFor = Exception.class)
67 - public PayWalletTransactionDO pay(String outTradeNo, Integer price) {  
68 - // 1.1 判断支付交易拓展单是否存 78 + public PayWalletTransactionDO orderPay(Long userId, Integer userType, String outTradeNo, Integer price) {
  79 + // 判断支付交易拓展单是否存
69 PayOrderExtensionDO orderExtension = payOrderService.getOrderExtensionByNo(outTradeNo); 80 PayOrderExtensionDO orderExtension = payOrderService.getOrderExtensionByNo(outTradeNo);
70 if (orderExtension == null) { 81 if (orderExtension == null) {
71 throw exception(ORDER_EXTENSION_NOT_FOUND); 82 throw exception(ORDER_EXTENSION_NOT_FOUND);
72 } 83 }
  84 + return reduceWalletBalance(userId, userType, orderExtension.getOrderId(), PAYMENT, price);
  85 + }
  86 +
  87 + @Override
  88 + public PayWalletTransactionDO reduceWalletBalance(Long userId, Integer userType,
  89 + Long bizId, PayWalletBizTypeEnum bizType, Integer price) {
  90 + // 1.1 获取钱包
  91 + PayWalletDO payWallet = getOrCreatePayWallet(userId, userType);
73 // 1.2 判断余额是否足够 92 // 1.2 判断余额是否足够
74 - PayWalletDO payWallet = validatePayWallet();  
75 int afterBalance = payWallet.getBalance() - price; 93 int afterBalance = payWallet.getBalance() - price;
76 if (afterBalance < 0) { 94 if (afterBalance < 0) {
77 throw exception(WALLET_BALANCE_NOT_ENOUGH); 95 throw exception(WALLET_BALANCE_NOT_ENOUGH);
78 } 96 }
79 97
80 // 2.1 扣除余额 98 // 2.1 扣除余额
81 - // TODO @jason:不要直接整个更新;而是 new 一个出来更新;然后要考虑并发,要 where 余额 > price,以及 - price  
82 - payWallet.setBalance(afterBalance);  
83 - payWallet.setTotalExpense(payWallet.getTotalExpense() + price);  
84 - payWalletMapper.updateById(payWallet);  
85 - 99 + int number = payWalletMapper.updateWhenDecBalance(bizType,payWallet.getBalance(), payWallet.getTotalRecharge(),
  100 + payWallet.getTotalExpense(), price, payWallet.getId());
  101 + if (number == 0) {
  102 + throw exception(TOO_MANY_REQUESTS);
  103 + }
86 // 2.2 生成钱包流水 104 // 2.2 生成钱包流水
87 - String walletNo = noRedisDAO.generate(WALLET_PAY_NO_PREFIX); 105 + String walletNo = generateWalletNo(bizType);
88 PayWalletTransactionDO walletTransaction = new PayWalletTransactionDO().setWalletId(payWallet.getId()) 106 PayWalletTransactionDO walletTransaction = new PayWalletTransactionDO().setWalletId(payWallet.getId())
89 - .setNo(walletNo).setAmount(price * -1).setBalance(afterBalance).setTransactionTime(LocalDateTime.now())  
90 - .setBizId(orderExtension.getOrderId()).setBizType(PAYMENT.getType()); 107 + .setNo(walletNo).setPrice(-price).setBalance(afterBalance)
  108 + .setBizId(String.valueOf(bizId)).setBizType(bizType.getType()).setTitle(bizType.getDescription());
91 payWalletTransactionService.createWalletTransaction(walletTransaction); 109 payWalletTransactionService.createWalletTransaction(walletTransaction);
92 return walletTransaction; 110 return walletTransaction;
93 } 111 }
94 112
95 - // TODO @jason:不要在 service 里去使用用户上下文,这样和 request 就耦合了。  
96 - private PayWalletDO validatePayWallet() {  
97 - Long userId = getLoginUserId();  
98 - Integer userType = getLoginUserType();  
99 - PayWalletDO payWallet = getPayWallet(userId, userType);  
100 - if (payWallet == null) {  
101 - log.error("[validatePayWallet] 用户 {} 钱包不存在", userId);  
102 - throw exception(WALLET_NOT_FOUND); 113 + @Override
  114 + public PayWalletTransactionDO addWalletBalance(Long userId, Integer userType, Long bizId,
  115 + PayWalletBizTypeEnum bizType, Integer price) {
  116 + // 1.1 获取钱包
  117 + PayWalletDO payWallet = getOrCreatePayWallet(userId, userType);
  118 +
  119 + // 2.1 增加余额
  120 + int number = payWalletMapper.updateWhenIncBalance(bizType, payWallet.getBalance(), payWallet.getTotalRecharge(),
  121 + payWallet.getTotalExpense(), price, payWallet.getId());
  122 + if (number == 0) {
  123 + throw exception(TOO_MANY_REQUESTS);
  124 + }
  125 +
  126 + // 2.2 生成钱包流水
  127 + String walletNo = generateWalletNo(bizType);
  128 + PayWalletTransactionDO newWalletTransaction = new PayWalletTransactionDO().setWalletId(payWallet.getId())
  129 + .setNo(walletNo).setPrice(price).setBalance(payWallet.getBalance()+price)
  130 + .setBizId(String.valueOf(bizId)).setBizType(bizType.getType())
  131 + .setTitle(bizType.getDescription());
  132 + payWalletTransactionService.createWalletTransaction(newWalletTransaction);
  133 + return newWalletTransaction;
  134 + }
  135 +
  136 + private String generateWalletNo(PayWalletBizTypeEnum bizType) {
  137 + String no = "";
  138 + switch(bizType){
  139 + case PAYMENT :
  140 + no = noRedisDAO.generate(WALLET_PAY_NO_PREFIX);
  141 + break;
  142 + case PAYMENT_REFUND :
  143 + no = noRedisDAO.generate(WALLET_REFUND_NO_PREFIX);
  144 + break;
  145 + default :
  146 + // TODO 待增加
103 } 147 }
104 - return payWallet; 148 + return no;
105 } 149 }
106 150
107 - // TODO @jason:可以做的更抽象一点;pay(bizType, bizId, price);addWalletBalance;这样,如果后续充值,应该也是能复用这个方法的;  
108 @Override 151 @Override
109 @Transactional(rollbackFor = Exception.class) 152 @Transactional(rollbackFor = Exception.class)
110 - public PayWalletTransactionDO refund(String outRefundNo, Integer refundPrice, String reason) { 153 + public PayWalletTransactionDO orderRefund(String outRefundNo, Integer refundPrice, String reason) {
111 // 1.1 判断退款单是否存在 154 // 1.1 判断退款单是否存在
112 PayRefundDO payRefund = payRefundService.getRefundByNo(outRefundNo); 155 PayRefundDO payRefund = payRefundService.getRefundByNo(outRefundNo);
113 if (payRefund == null) { 156 if (payRefund == null) {
114 throw exception(REFUND_NOT_FOUND); 157 throw exception(REFUND_NOT_FOUND);
115 } 158 }
116 // 1.2 校验是否可以退款 159 // 1.2 校验是否可以退款
117 - PayWalletDO payWallet = validatePayWallet();  
118 - validateWalletCanRefund(payRefund.getId(), payRefund.getChannelOrderNo(), payWallet.getId(), refundPrice);  
119 -  
120 - // TODO @jason:不要直接整个更新;而是 new 一个出来更新;然后要考虑并发,要 where 余额 + 金额  
121 - Integer afterBalance = payWallet.getBalance() + refundPrice;  
122 - payWallet.setBalance(afterBalance);  
123 - payWallet.setTotalExpense(payWallet.getTotalExpense() + refundPrice * -1L);  
124 - payWalletMapper.updateById(payWallet); 160 + Long walletId = validateWalletCanRefund(payRefund.getId(), payRefund.getChannelOrderNo(), refundPrice);
125 161
126 - // 2.2 生成钱包流水  
127 - String walletNo = noRedisDAO.generate(WALLET_REFUND_NO_PREFIX);  
128 - PayWalletTransactionDO newWalletTransaction = new PayWalletTransactionDO().setWalletId(payWallet.getId())  
129 - .setNo(walletNo).setAmount(refundPrice).setBalance(afterBalance).setTransactionTime(LocalDateTime.now())  
130 - .setBizId(payRefund.getId()).setBizType(PAYMENT_REFUND.getType())  
131 - .setDescription(reason);  
132 - payWalletTransactionService.createWalletTransaction(newWalletTransaction);  
133 - return newWalletTransaction; 162 + PayWalletDO payWallet = payWalletMapper.selectById(walletId);
  163 + Assert.notNull(payWallet, "钱包 {} 不存在", walletId);
  164 + return addWalletBalance(payWallet.getUserId(), payWallet.getUserType(),payRefund.getId(), PAYMENT_REFUND, refundPrice);
134 } 165 }
135 166
136 /** 167 /**
@@ -138,24 +169,23 @@ public class PayWalletServiceImpl implements PayWalletService { @@ -138,24 +169,23 @@ public class PayWalletServiceImpl implements PayWalletService {
138 * 169 *
139 * @param refundId 支付退款单 id 170 * @param refundId 支付退款单 id
140 * @param walletPayNo 钱包支付 no 171 * @param walletPayNo 钱包支付 no
141 - * @param walletId 钱包 id  
142 */ 172 */
143 - // TODO @jason:不要使用基本类型;  
144 - private void validateWalletCanRefund(long refundId, String walletPayNo, long walletId, int refundPrice) { 173 + private Long validateWalletCanRefund(Long refundId, String walletPayNo, Integer refundPrice) {
145 // 查询钱包支付交易 174 // 查询钱包支付交易
146 PayWalletTransactionDO payWalletTransaction = payWalletTransactionService.getWalletTransactionByNo(walletPayNo); 175 PayWalletTransactionDO payWalletTransaction = payWalletTransactionService.getWalletTransactionByNo(walletPayNo);
147 if (payWalletTransaction == null) { 176 if (payWalletTransaction == null) {
148 throw exception(WALLET_TRANSACTION_NOT_FOUND); 177 throw exception(WALLET_TRANSACTION_NOT_FOUND);
149 } 178 }
150 // 原来的支付金额 179 // 原来的支付金额
151 - int amount = payWalletTransaction.getAmount() * -1; // TODO @jason:直接 - payWalletTransaction.getAmount() 即可; 180 + int amount = - payWalletTransaction.getPrice();
152 if (refundPrice != amount) { 181 if (refundPrice != amount) {
153 throw exception(WALLET_REFUND_AMOUNT_ERROR); 182 throw exception(WALLET_REFUND_AMOUNT_ERROR);
154 } 183 }
155 - PayWalletTransactionDO refundTransaction = payWalletTransactionService.getWalletTransaction(walletId, refundId, PAYMENT_REFUND); 184 + PayWalletTransactionDO refundTransaction = payWalletTransactionService.getWalletTransaction(
  185 + String.valueOf(refundId), PAYMENT_REFUND);
156 if (refundTransaction != null) { 186 if (refundTransaction != null) {
157 throw exception(WALLET_REFUND_EXIST); 187 throw exception(WALLET_REFUND_EXIST);
158 } 188 }
  189 + return payWalletTransaction.getWalletId();
159 } 190 }
160 -  
161 } 191 }
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletTransactionService.java
@@ -40,11 +40,9 @@ public interface PayWalletTransactionService { @@ -40,11 +40,9 @@ public interface PayWalletTransactionService {
40 /** 40 /**
41 * 获取钱包流水 41 * 获取钱包流水
42 * 42 *
43 - * @param walletId 钱包编号  
44 * @param bizId 业务编号 43 * @param bizId 业务编号
45 * @param type 业务类型 44 * @param type 业务类型
46 * @return 钱包流水 45 * @return 钱包流水
47 */ 46 */
48 - PayWalletTransactionDO getWalletTransaction(Long walletId, Long bizId, PayWalletBizTypeEnum type);  
49 - 47 + PayWalletTransactionDO getWalletTransaction(String bizId, PayWalletBizTypeEnum type);
50 } 48 }
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletTransactionServiceImpl.java
@@ -11,9 +11,6 @@ import org.springframework.stereotype.Service; @@ -11,9 +11,6 @@ import org.springframework.stereotype.Service;
11 11
12 import javax.annotation.Resource; 12 import javax.annotation.Resource;
13 13
14 -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;  
15 -import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.WALLET_NOT_FOUND;  
16 -  
17 /** 14 /**
18 * 钱包流水 Service 实现类 15 * 钱包流水 Service 实现类
19 * 16 *
@@ -25,18 +22,13 @@ public class PayWalletTransactionServiceImpl implements PayWalletTransactionServ @@ -25,18 +22,13 @@ public class PayWalletTransactionServiceImpl implements PayWalletTransactionServ
25 22
26 @Resource 23 @Resource
27 private PayWalletService payWalletService; 24 private PayWalletService payWalletService;
28 -  
29 @Resource 25 @Resource
30 private PayWalletTransactionMapper payWalletTransactionMapper; 26 private PayWalletTransactionMapper payWalletTransactionMapper;
31 27
32 @Override 28 @Override
33 public PageResult<PayWalletTransactionDO> getWalletTransactionPage(Long userId, Integer userType, 29 public PageResult<PayWalletTransactionDO> getWalletTransactionPage(Long userId, Integer userType,
34 AppPayWalletTransactionPageReqVO pageVO) { 30 AppPayWalletTransactionPageReqVO pageVO) {
35 - PayWalletDO wallet = payWalletService.getPayWallet(userId, userType);  
36 - if (wallet == null) {  
37 - log.error("[getWalletTransactionPage][用户({}/{}) 钱包不存在", userId, userType);  
38 - throw exception(WALLET_NOT_FOUND);  
39 - } 31 + PayWalletDO wallet = payWalletService.getOrCreatePayWallet(userId, userType);
40 return payWalletTransactionMapper.selectPage(wallet.getId(), pageVO); 32 return payWalletTransactionMapper.selectPage(wallet.getId(), pageVO);
41 } 33 }
42 34
@@ -52,8 +44,7 @@ public class PayWalletTransactionServiceImpl implements PayWalletTransactionServ @@ -52,8 +44,7 @@ public class PayWalletTransactionServiceImpl implements PayWalletTransactionServ
52 } 44 }
53 45
54 @Override 46 @Override
55 - public PayWalletTransactionDO getWalletTransaction(Long walletId, Long bizId, PayWalletBizTypeEnum type) {  
56 - return payWalletTransactionMapper.selectByWalletIdAndBiz(walletId, bizId, type.getType()); 47 + public PayWalletTransactionDO getWalletTransaction(String bizId, PayWalletBizTypeEnum type) {
  48 + return payWalletTransactionMapper.selectByBiz(bizId, type.getType());
57 } 49 }
58 -  
59 } 50 }
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/util/MoneyUtils.java
1 package cn.iocoder.yudao.module.pay.util; 1 package cn.iocoder.yudao.module.pay.util;
2 2
  3 +import cn.hutool.core.util.NumberUtil;
  4 +
3 import java.math.BigDecimal; 5 import java.math.BigDecimal;
4 import java.math.RoundingMode; 6 import java.math.RoundingMode;
5 7
@@ -18,10 +20,20 @@ public class MoneyUtils { @@ -18,10 +20,20 @@ public class MoneyUtils {
18 * @return 百分比金额 20 * @return 百分比金额
19 */ 21 */
20 public static Integer calculateRatePrice(Integer price, Double rate) { 22 public static Integer calculateRatePrice(Integer price, Double rate) {
21 - return new BigDecimal(price)  
22 - .multiply(BigDecimal.valueOf(rate)) // 乘以  
23 - .setScale(0, RoundingMode.HALF_UP) // 四舍五入  
24 - .intValue(); 23 + return calculateRatePrice(price, rate, 0, RoundingMode.HALF_UP).intValue();
25 } 24 }
26 25
  26 + /**
  27 + * 计算百分比金额
  28 + *
  29 + * @param price 金额
  30 + * @param rate 百分比,例如说 56.77% 则传入 56.77
  31 + * @param scale 保留小数位数
  32 + * @param roundingMode 舍入模式
  33 + */
  34 + public static BigDecimal calculateRatePrice(Number price, Number rate, int scale, RoundingMode roundingMode) {
  35 + return NumberUtil.toBigDecimal(price).multiply(NumberUtil.toBigDecimal(rate)) // 乘以
  36 + .divide(BigDecimal.valueOf(100), scale, roundingMode); // 除以 100
  37 + }
  38 +
27 } 39 }
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notify/vo/message/NotifyMessageRespVO.java
1 package cn.iocoder.yudao.module.system.controller.admin.notify.vo.message; 1 package cn.iocoder.yudao.module.system.controller.admin.notify.vo.message;
2 2
3 import io.swagger.v3.oas.annotations.media.Schema; 3 import io.swagger.v3.oas.annotations.media.Schema;
4 -import lombok.*;  
5 -import java.util.*; 4 +import lombok.Data;
  5 +import lombok.EqualsAndHashCode;
  6 +import lombok.ToString;
  7 +
  8 +import java.time.LocalDateTime;
6 9
7 @Schema(description = "管理后台 - 站内信 Response VO") 10 @Schema(description = "管理后台 - 站内信 Response VO")
8 @Data 11 @Data
@@ -14,6 +17,6 @@ public class NotifyMessageRespVO extends NotifyMessageBaseVO { @@ -14,6 +17,6 @@ public class NotifyMessageRespVO extends NotifyMessageBaseVO {
14 private Long id; 17 private Long id;
15 18
16 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) 19 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
17 - private Date createTime; 20 + private LocalDateTime createTime;
18 21
19 } 22 }
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/notify/vo/template/NotifyTemplateRespVO.java
@@ -2,6 +2,8 @@ package cn.iocoder.yudao.module.system.controller.admin.notify.vo.template; @@ -2,6 +2,8 @@ package cn.iocoder.yudao.module.system.controller.admin.notify.vo.template;
2 2
3 import io.swagger.v3.oas.annotations.media.Schema; 3 import io.swagger.v3.oas.annotations.media.Schema;
4 import lombok.*; 4 import lombok.*;
  5 +
  6 +import java.time.LocalDateTime;
5 import java.util.*; 7 import java.util.*;
6 8
7 @Schema(description = "管理后台 - 站内信模版 Response VO") 9 @Schema(description = "管理后台 - 站内信模版 Response VO")
@@ -17,6 +19,6 @@ public class NotifyTemplateRespVO extends NotifyTemplateBaseVO { @@ -17,6 +19,6 @@ public class NotifyTemplateRespVO extends NotifyTemplateBaseVO {
17 private List<String> params; 19 private List<String> params;
18 20
19 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) 21 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
20 - private Date createTime; 22 + private LocalDateTime createTime;
21 23
22 } 24 }
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/notify/NotifyMessageConvert.java
@@ -24,5 +24,4 @@ public interface NotifyMessageConvert { @@ -24,5 +24,4 @@ public interface NotifyMessageConvert {
24 24
25 PageResult<NotifyMessageRespVO> convertPage(PageResult<NotifyMessageDO> page); 25 PageResult<NotifyMessageRespVO> convertPage(PageResult<NotifyMessageDO> page);
26 26
27 -  
28 } 27 }
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/notify/NotifyTemplateConvert.java
@@ -4,6 +4,7 @@ import java.util.*; @@ -4,6 +4,7 @@ import java.util.*;
4 4
5 import cn.iocoder.yudao.framework.common.pojo.PageResult; 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
6 6
  7 +import cn.iocoder.yudao.framework.common.util.date.DateUtils;
7 import cn.iocoder.yudao.module.system.controller.admin.notify.vo.template.NotifyTemplateCreateReqVO; 8 import cn.iocoder.yudao.module.system.controller.admin.notify.vo.template.NotifyTemplateCreateReqVO;
8 import cn.iocoder.yudao.module.system.controller.admin.notify.vo.template.NotifyTemplateRespVO; 9 import cn.iocoder.yudao.module.system.controller.admin.notify.vo.template.NotifyTemplateRespVO;
9 import cn.iocoder.yudao.module.system.controller.admin.notify.vo.template.NotifyTemplateUpdateReqVO; 10 import cn.iocoder.yudao.module.system.controller.admin.notify.vo.template.NotifyTemplateUpdateReqVO;
@@ -16,7 +17,7 @@ import cn.iocoder.yudao.module.system.dal.dataobject.notify.NotifyTemplateDO; @@ -16,7 +17,7 @@ import cn.iocoder.yudao.module.system.dal.dataobject.notify.NotifyTemplateDO;
16 * 17 *
17 * @author xrcoder 18 * @author xrcoder
18 */ 19 */
19 -@Mapper 20 +@Mapper(uses = DateUtils.class)
20 public interface NotifyTemplateConvert { 21 public interface NotifyTemplateConvert {
21 22
22 NotifyTemplateConvert INSTANCE = Mappers.getMapper(NotifyTemplateConvert.class); 23 NotifyTemplateConvert INSTANCE = Mappers.getMapper(NotifyTemplateConvert.class);
yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/tenant/TenantServiceImplTest.java
@@ -197,7 +197,7 @@ public class TenantServiceImplTest extends BaseDbUnitTest { @@ -197,7 +197,7 @@ public class TenantServiceImplTest extends BaseDbUnitTest {
197 role100.setTenantId(dbTenant.getId()); 197 role100.setTenantId(dbTenant.getId());
198 RoleDO role101 = randomPojo(RoleDO.class, o -> o.setId(101L)); 198 RoleDO role101 = randomPojo(RoleDO.class, o -> o.setId(101L));
199 role101.setTenantId(dbTenant.getId()); 199 role101.setTenantId(dbTenant.getId());
200 - when(roleService.getRoleListByStatus(isNull())).thenReturn(asList(role100, role101)); 200 + when(roleService.getRoleList()).thenReturn(asList(role100, role101));
201 // mock 每个角色的权限 201 // mock 每个角色的权限
202 when(permissionService.getRoleMenuListByRoleId(eq(101L))).thenReturn(asSet(201L, 202L)); 202 when(permissionService.getRoleMenuListByRoleId(eq(101L))).thenReturn(asSet(201L, 202L));
203 203
yudao-server/pom.xml
@@ -41,13 +41,13 @@ @@ -41,13 +41,13 @@
41 <artifactId>yudao-spring-boot-starter-biz-error-code</artifactId> 41 <artifactId>yudao-spring-boot-starter-biz-error-code</artifactId>
42 </dependency> 42 </dependency>
43 43
44 - <!-- 数据报表 --> 44 + <!-- 数据报表。默认注释,保证编译速度 -->
45 <!-- <dependency>--> 45 <!-- <dependency>-->
46 <!-- <groupId>cn.iocoder.boot</groupId>--> 46 <!-- <groupId>cn.iocoder.boot</groupId>-->
47 <!-- <artifactId>yudao-module-report-biz</artifactId>--> 47 <!-- <artifactId>yudao-module-report-biz</artifactId>-->
48 <!-- <version>${revision}</version>--> 48 <!-- <version>${revision}</version>-->
49 <!-- </dependency>--> 49 <!-- </dependency>-->
50 - <!-- 工作流 --> 50 + <!-- 工作流。默认注释,保证编译速度 -->
51 <!-- <dependency>--> 51 <!-- <dependency>-->
52 <!-- <groupId>cn.iocoder.boot</groupId>--> 52 <!-- <groupId>cn.iocoder.boot</groupId>-->
53 <!-- <artifactId>yudao-module-bpm-biz</artifactId>--> 53 <!-- <artifactId>yudao-module-bpm-biz</artifactId>-->
@@ -111,10 +111,7 @@ @@ -111,10 +111,7 @@
111 <plugin> 111 <plugin>
112 <groupId>org.springframework.boot</groupId> 112 <groupId>org.springframework.boot</groupId>
113 <artifactId>spring-boot-maven-plugin</artifactId> 113 <artifactId>spring-boot-maven-plugin</artifactId>
114 - <version>2.7.14</version> <!-- 如果 spring.boot.version 版本修改,则这里也要跟着修改 -->  
115 - <configuration>  
116 - <fork>true</fork>  
117 - </configuration> 114 + <version>${spring.boot.version}</version>
118 <executions> 115 <executions>
119 <execution> 116 <execution>
120 <goals> 117 <goals>
yudao-ui-admin/src/components/Crontab/day.vue
@@ -103,25 +103,25 @@ export default { @@ -103,25 +103,25 @@ export default {
103 }, 103 },
104 // 周期两个值变化时 104 // 周期两个值变化时
105 cycleChange() { 105 cycleChange() {
106 - if (this.radioValue === '3') { 106 + if (this.radioValue === 3) {
107 this.$emit('update', 'day', this.cycleTotal); 107 this.$emit('update', 'day', this.cycleTotal);
108 } 108 }
109 }, 109 },
110 // 平均两个值变化时 110 // 平均两个值变化时
111 averageChange() { 111 averageChange() {
112 - if (this.radioValue === '4') { 112 + if (this.radioValue === 4) {
113 this.$emit('update', 'day', this.averageTotal); 113 this.$emit('update', 'day', this.averageTotal);
114 } 114 }
115 }, 115 },
116 // 最近工作日值变化时 116 // 最近工作日值变化时
117 workdayChange() { 117 workdayChange() {
118 - if (this.radioValue === '5') { 118 + if (this.radioValue === 5) {
119 this.$emit('update', 'day', this.workdayCheck + 'W'); 119 this.$emit('update', 'day', this.workdayCheck + 'W');
120 } 120 }
121 }, 121 },
122 // checkbox值变化时 122 // checkbox值变化时
123 checkboxChange() { 123 checkboxChange() {
124 - if (this.radioValue === '7') { 124 + if (this.radioValue === 7) {
125 this.$emit('update', 'day', this.checkboxString); 125 this.$emit('update', 'day', this.checkboxString);
126 } 126 }
127 } 127 }
yudao-ui-admin/src/components/Crontab/hour.vue
@@ -68,19 +68,19 @@ export default { @@ -68,19 +68,19 @@ export default {
68 }, 68 },
69 // 周期两个值变化时 69 // 周期两个值变化时
70 cycleChange() { 70 cycleChange() {
71 - if (this.radioValue === '2') { 71 + if (this.radioValue === 2) {
72 this.$emit('update', 'hour', this.cycleTotal); 72 this.$emit('update', 'hour', this.cycleTotal);
73 } 73 }
74 }, 74 },
75 // 平均两个值变化时 75 // 平均两个值变化时
76 averageChange() { 76 averageChange() {
77 - if (this.radioValue === '3') { 77 + if (this.radioValue === 3) {
78 this.$emit('update', 'hour', this.averageTotal); 78 this.$emit('update', 'hour', this.averageTotal);
79 } 79 }
80 }, 80 },
81 // checkbox值变化时 81 // checkbox值变化时
82 checkboxChange() { 82 checkboxChange() {
83 - if (this.radioValue === '4') { 83 + if (this.radioValue === 4) {
84 this.$emit('update', 'hour', this.checkboxString); 84 this.$emit('update', 'hour', this.checkboxString);
85 } 85 }
86 } 86 }
yudao-ui-admin/src/components/Crontab/min.vue
@@ -69,19 +69,19 @@ export default { @@ -69,19 +69,19 @@ export default {
69 }, 69 },
70 // 周期两个值变化时 70 // 周期两个值变化时
71 cycleChange() { 71 cycleChange() {
72 - if (this.radioValue === '2') { 72 + if (this.radioValue === 2) {
73 this.$emit('update', 'min', this.cycleTotal, 'min'); 73 this.$emit('update', 'min', this.cycleTotal, 'min');
74 } 74 }
75 }, 75 },
76 // 平均两个值变化时 76 // 平均两个值变化时
77 averageChange() { 77 averageChange() {
78 - if (this.radioValue === '3') { 78 + if (this.radioValue === 3) {
79 this.$emit('update', 'min', this.averageTotal, 'min'); 79 this.$emit('update', 'min', this.averageTotal, 'min');
80 } 80 }
81 }, 81 },
82 // checkbox值变化时 82 // checkbox值变化时
83 checkboxChange() { 83 checkboxChange() {
84 - if (this.radioValue === '4') { 84 + if (this.radioValue === 4) {
85 this.$emit('update', 'min', this.checkboxString, 'min'); 85 this.$emit('update', 'min', this.checkboxString, 'min');
86 } 86 }
87 }, 87 },
yudao-ui-admin/src/components/Crontab/month.vue
@@ -68,19 +68,19 @@ export default { @@ -68,19 +68,19 @@ export default {
68 }, 68 },
69 // 周期两个值变化时 69 // 周期两个值变化时
70 cycleChange() { 70 cycleChange() {
71 - if (this.radioValue === '2') { 71 + if (this.radioValue === 2) {
72 this.$emit('update', 'month', this.cycleTotal); 72 this.$emit('update', 'month', this.cycleTotal);
73 } 73 }
74 }, 74 },
75 // 平均两个值变化时 75 // 平均两个值变化时
76 averageChange() { 76 averageChange() {
77 - if (this.radioValue === '3') { 77 + if (this.radioValue === 3) {
78 this.$emit('update', 'month', this.averageTotal); 78 this.$emit('update', 'month', this.averageTotal);
79 } 79 }
80 }, 80 },
81 // checkbox值变化时 81 // checkbox值变化时
82 checkboxChange() { 82 checkboxChange() {
83 - if (this.radioValue === '4') { 83 + if (this.radioValue === 4) {
84 this.$emit('update', 'month', this.checkboxString); 84 this.$emit('update', 'month', this.checkboxString);
85 } 85 }
86 } 86 }
yudao-ui-admin/src/components/Crontab/second.vue
@@ -68,19 +68,19 @@ export default { @@ -68,19 +68,19 @@ export default {
68 }, 68 },
69 // 周期两个值变化时 69 // 周期两个值变化时
70 cycleChange() { 70 cycleChange() {
71 - if (this.radioValue === '2') { 71 + if (this.radioValue === 2) {
72 this.$emit('update', 'second', this.cycleTotal); 72 this.$emit('update', 'second', this.cycleTotal);
73 } 73 }
74 }, 74 },
75 // 平均两个值变化时 75 // 平均两个值变化时
76 averageChange() { 76 averageChange() {
77 - if (this.radioValue === '3') { 77 + if (this.radioValue === 3) {
78 this.$emit('update', 'second', this.averageTotal); 78 this.$emit('update', 'second', this.averageTotal);
79 } 79 }
80 }, 80 },
81 // checkbox值变化时 81 // checkbox值变化时
82 checkboxChange() { 82 checkboxChange() {
83 - if (this.radioValue === '4') { 83 + if (this.radioValue === 4) {
84 this.$emit('update', 'second', this.checkboxString); 84 this.$emit('update', 'second', this.checkboxString);
85 } 85 }
86 } 86 }
yudao-ui-admin/src/components/Crontab/week.vue
@@ -144,25 +144,25 @@ export default { @@ -144,25 +144,25 @@ export default {
144 144
145 // 周期两个值变化时 145 // 周期两个值变化时
146 cycleChange() { 146 cycleChange() {
147 - if (this.radioValue === '3') { 147 + if (this.radioValue === 3) {
148 this.$emit('update', 'week', this.cycleTotal); 148 this.$emit('update', 'week', this.cycleTotal);
149 } 149 }
150 }, 150 },
151 // 平均两个值变化时 151 // 平均两个值变化时
152 averageChange() { 152 averageChange() {
153 - if (this.radioValue === '4') { 153 + if (this.radioValue === 4) {
154 this.$emit('update', 'week', this.averageTotal); 154 this.$emit('update', 'week', this.averageTotal);
155 } 155 }
156 }, 156 },
157 // 最近工作日值变化时 157 // 最近工作日值变化时
158 weekdayChange() { 158 weekdayChange() {
159 - if (this.radioValue === '5') { 159 + if (this.radioValue === 5) {
160 this.$emit('update', 'week', this.weekday + 'L'); 160 this.$emit('update', 'week', this.weekday + 'L');
161 } 161 }
162 }, 162 },
163 // checkbox值变化时 163 // checkbox值变化时
164 checkboxChange() { 164 checkboxChange() {
165 - if (this.radioValue === '6') { 165 + if (this.radioValue === 6) {
166 this.$emit('update', 'week', this.checkboxString); 166 this.$emit('update', 'week', this.checkboxString);
167 } 167 }
168 }, 168 },
yudao-ui-admin/src/components/Crontab/year.vue
@@ -79,19 +79,19 @@ export default { @@ -79,19 +79,19 @@ export default {
79 }, 79 },
80 // 周期两个值变化时 80 // 周期两个值变化时
81 cycleChange() { 81 cycleChange() {
82 - if (this.radioValue === '3') { 82 + if (this.radioValue === 3) {
83 this.$emit('update', 'year', this.cycleTotal); 83 this.$emit('update', 'year', this.cycleTotal);
84 } 84 }
85 }, 85 },
86 // 平均两个值变化时 86 // 平均两个值变化时
87 averageChange() { 87 averageChange() {
88 - if (this.radioValue === '4') { 88 + if (this.radioValue === 4) {
89 this.$emit('update', 'year', this.averageTotal); 89 this.$emit('update', 'year', this.averageTotal);
90 } 90 }
91 }, 91 },
92 // checkbox值变化时 92 // checkbox值变化时
93 checkboxChange() { 93 checkboxChange() {
94 - if (this.radioValue === '5') { 94 + if (this.radioValue === 5) {
95 this.$emit('update', 'year', this.checkboxString); 95 this.$emit('update', 'year', this.checkboxString);
96 } 96 }
97 } 97 }
yudao-ui-admin/src/utils/constants.js
@@ -163,6 +163,10 @@ export const PayChannelEnum = { @@ -163,6 +163,10 @@ export const PayChannelEnum = {
163 MOCK : { 163 MOCK : {
164 "code": "mock", 164 "code": "mock",
165 "name": "模拟支付" 165 "name": "模拟支付"
  166 + },
  167 + WALLET : {
  168 + "code": "wallet",
  169 + "name": "钱包支付"
166 } 170 }
167 } 171 }
168 172
yudao-ui-admin/src/views/pay/app/components/mockChannelForm.vue renamed to yudao-ui-admin/src/views/pay/app/components/noneConfigChannelForm.vue
@@ -5,7 +5,8 @@ @@ -5,7 +5,8 @@
5 <el-form-item label-width="180px" label="渠道状态" prop="status"> 5 <el-form-item label-width="180px" label="渠道状态" prop="status">
6 <el-radio-group v-model="formData.status" size="medium"> 6 <el-radio-group v-model="formData.status" size="medium">
7 <el-radio v-for="dict in this.getDictDatas(DICT_TYPE.COMMON_STATUS)" :key="parseInt(dict.value)" 7 <el-radio v-for="dict in this.getDictDatas(DICT_TYPE.COMMON_STATUS)" :key="parseInt(dict.value)"
8 - :label="parseInt(dict.value)"> 8 + :label="parseInt(dict.value)"
  9 + >
9 {{ dict.label }} 10 {{ dict.label }}
10 </el-radio> 11 </el-radio>
11 </el-radio-group> 12 </el-radio-group>
@@ -22,16 +23,16 @@ @@ -22,16 +23,16 @@
22 </div> 23 </div>
23 </template> 24 </template>
24 <script> 25 <script>
25 -import { createChannel, getChannel, updateChannel } from "@/api/pay/channel";  
26 -import { CommonStatusEnum } from "@/utils/constants"; 26 +import { createChannel, getChannel, updateChannel } from '@/api/pay/channel'
  27 +import { CommonStatusEnum } from '@/utils/constants'
27 28
28 export default { 29 export default {
29 - name: "mockChannelForm", 30 + name: 'noneConfigChannelForm',
30 data() { 31 data() {
31 return { 32 return {
32 dialogVisible: false, 33 dialogVisible: false,
33 formLoading: false, 34 formLoading: false,
34 - title:'', 35 + title: '',
35 formData: { 36 formData: {
36 appId: '', 37 appId: '',
37 code: '', 38 code: '',
@@ -39,54 +40,54 @@ export default { @@ -39,54 +40,54 @@ export default {
39 feeRate: 0, 40 feeRate: 0,
40 remark: '', 41 remark: '',
41 config: { 42 config: {
42 - name: 'mock-conf' 43 + name: 'none-config'
43 } 44 }
44 }, 45 },
45 rules: { 46 rules: {
46 - status: [{ required: true, message: '渠道状态不能为空', trigger: 'blur' }] 47 + status: [{ required: true, message: '渠道状态不能为空', trigger: 'blur' }]
47 } 48 }
48 } 49 }
49 }, 50 },
50 methods: { 51 methods: {
51 open(appId, code) { 52 open(appId, code) {
52 - this.dialogVisible = true;  
53 - this.formLoading = true;  
54 - this.reset(appId, code); 53 + this.dialogVisible = true
  54 + this.formLoading = true
  55 + this.reset(appId, code)
55 getChannel(appId, code).then(response => { 56 getChannel(appId, code).then(response => {
56 if (response.data && response.data.id) { 57 if (response.data && response.data.id) {
57 - this.formData = response.data;  
58 - this.formData.config = JSON.parse(response.data.config); 58 + this.formData = response.data
  59 + this.formData.config = JSON.parse(response.data.config)
59 } 60 }
60 this.title = !this.formData.id ? '创建支付渠道' : '编辑支付渠道' 61 this.title = !this.formData.id ? '创建支付渠道' : '编辑支付渠道'
61 }).finally(() => { 62 }).finally(() => {
62 - this.formLoading = false;  
63 - }); 63 + this.formLoading = false
  64 + })
64 }, 65 },
65 close() { 66 close() {
66 - this.dialogVisible = false;  
67 - this.reset(undefined, undefined); 67 + this.dialogVisible = false
  68 + this.reset(undefined, undefined)
68 }, 69 },
69 submitForm() { 70 submitForm() {
70 this.$refs['form'].validate(valid => { 71 this.$refs['form'].validate(valid => {
71 if (!valid) { 72 if (!valid) {
72 return 73 return
73 } 74 }
74 - const data = { ...this.formData };  
75 - data.config = JSON.stringify(this.formData.config); 75 + const data = { ...this.formData }
  76 + data.config = JSON.stringify(this.formData.config)
76 if (!data.id) { 77 if (!data.id) {
77 createChannel(data).then(response => { 78 createChannel(data).then(response => {
78 - this.$modal.msgSuccess("新增成功"); 79 + this.$modal.msgSuccess('新增成功')
79 this.$emit('success') 80 this.$emit('success')
80 - this.close();  
81 - }); 81 + this.close()
  82 + })
82 } else { 83 } else {
83 updateChannel(data).then(response => { 84 updateChannel(data).then(response => {
84 - this.$modal.msgSuccess("修改成功"); 85 + this.$modal.msgSuccess('修改成功')
85 this.$emit('success') 86 this.$emit('success')
86 - this.close(); 87 + this.close()
87 }) 88 })
88 } 89 }
89 - }); 90 + })
90 }, 91 },
91 /** 重置表单 */ 92 /** 重置表单 */
92 reset(appId, code) { 93 reset(appId, code) {
@@ -97,11 +98,11 @@ export default { @@ -97,11 +98,11 @@ export default {
97 remark: '', 98 remark: '',
98 feeRate: 0, 99 feeRate: 0,
99 config: { 100 config: {
100 - name: 'mock-conf' 101 + name: 'none-config'
101 } 102 }
102 } 103 }
103 this.resetForm('form') 104 this.resetForm('form')
104 - }, 105 + }
105 } 106 }
106 } 107 }
107 </script> 108 </script>
yudao-ui-admin/src/views/pay/app/index.vue
@@ -170,6 +170,19 @@ @@ -170,6 +170,19 @@
170 </template> 170 </template>
171 </el-table-column> 171 </el-table-column>
172 </el-table-column> 172 </el-table-column>
  173 + <el-table-column label="钱包支付配置" align="center">
  174 + <el-table-column :label="payChannelEnum.WALLET.name" align="center">
  175 + <template v-slot="scope">
  176 + <el-button type="success" icon="el-icon-check" circle
  177 + v-if="isChannelExists(scope.row.channelCodes, payChannelEnum.WALLET.code)"
  178 + @click="handleChannel(scope.row, payChannelEnum.WALLET.code)">
  179 + </el-button>
  180 + <el-button v-else type="danger" icon="el-icon-close" circle
  181 + @click="handleChannel(scope.row, payChannelEnum.WALLET.code)">
  182 + </el-button>
  183 + </template>
  184 + </el-table-column>
  185 + </el-table-column>
173 <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> 186 <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
174 <template v-slot="scope"> 187 <template v-slot="scope">
175 <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" 188 <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
@@ -219,7 +232,7 @@ @@ -219,7 +232,7 @@
219 <!-- 对话框(支付应用的配置) --> 232 <!-- 对话框(支付应用的配置) -->
220 <weixin-channel-form ref="weixinChannelFormRef" @success="getList" /> 233 <weixin-channel-form ref="weixinChannelFormRef" @success="getList" />
221 <alipay-channel-form ref="alipayChannelFormRef" @success="getList" /> 234 <alipay-channel-form ref="alipayChannelFormRef" @success="getList" />
222 - <mock-channel-form ref="mockChannelFormRef" @success="getList" /> 235 + <none-config-channel-form ref="noneConfigChannelFormRef" @success="getList" />
223 </div> 236 </div>
224 </template> 237 </template>
225 238
@@ -228,14 +241,14 @@ import { createApp, updateApp, changeAppStatus, deleteApp, getApp, getAppPage } @@ -228,14 +241,14 @@ import { createApp, updateApp, changeAppStatus, deleteApp, getApp, getAppPage }
228 import { PayChannelEnum, CommonStatusEnum } from "@/utils/constants"; 241 import { PayChannelEnum, CommonStatusEnum } from "@/utils/constants";
229 import weixinChannelForm from "@/views/pay/app/components/weixinChannelForm"; 242 import weixinChannelForm from "@/views/pay/app/components/weixinChannelForm";
230 import alipayChannelForm from "@/views/pay/app/components/alipayChannelForm"; 243 import alipayChannelForm from "@/views/pay/app/components/alipayChannelForm";
231 -import mockChannelForm from '@/views/pay/app/components/mockChannelForm'; 244 +import noneConfigChannelForm from '@/views/pay/app/components/noneConfigChannelForm';
232 245
233 export default { 246 export default {
234 name: "PayApp", 247 name: "PayApp",
235 components: { 248 components: {
236 weixinChannelForm, 249 weixinChannelForm,
237 alipayChannelForm, 250 alipayChannelForm,
238 - mockChannelForm 251 + noneConfigChannelForm
239 }, 252 },
240 data() { 253 data() {
241 return { 254 return {
@@ -391,7 +404,11 @@ export default { @@ -391,7 +404,11 @@ export default {
391 return 404 return
392 } 405 }
393 if (code === 'mock') { 406 if (code === 'mock') {
394 - this.$refs['mockChannelFormRef'].open(row.id, code); 407 + this.$refs['noneConfigChannelFormRef'].open(row.id, code);
  408 + return
  409 + }
  410 + if (code === 'wallet') {
  411 + this.$refs['noneConfigChannelFormRef'].open(row.id, code);
395 return 412 return
396 } 413 }
397 }, 414 },
yudao-ui-admin/src/views/pay/cashier/index.vue
@@ -136,6 +136,10 @@ export default { @@ -136,6 +136,10 @@ export default {
136 name: '模拟支付', 136 name: '模拟支付',
137 icon: require("@/assets/images/pay/icon/mock.svg"), 137 icon: require("@/assets/images/pay/icon/mock.svg"),
138 code: "mock" 138 code: "mock"
  139 + }, {
  140 + name: '钱包支付',
  141 + icon: require("@/assets/images/pay/icon/mock.svg"),
  142 + code: "wallet"
139 }], 143 }],
140 submitLoading: false, // 提交支付的 loading 144 submitLoading: false, // 提交支付的 loading
141 interval: undefined, // 定时任务,轮询是否完成支付 145 interval: undefined, // 定时任务,轮询是否完成支付