Commit 437131cc7a0fdc8b18bb37cc8305c93812ed1f72
Merge remote-tracking branch 'origin/master' into feature/auth
# Conflicts: # yudao-dependencies/pom.xml
Showing
616 changed files
with
4819 additions
and
46939 deletions
Too many changes.
To preserve performance only 100 of 616 files are displayed.
README.md
| @@ -62,7 +62,7 @@ | @@ -62,7 +62,7 @@ | ||
| 62 | | [yudao-ui-admin](https://gitee.com/zhijiantianya/ruoyi-vue-pro/tree/master/yudao-ui-admin) | [](https://gitee.com/zhijiantianya/ruoyi-vue-pro/tree/master/yudao-ui-admin) [](https://github.com/YunaiV/ruoyi-vue-pro/tree/master/yudao-ui-admin) | 基于 Vue2 + element-ui 实现的管理后台 | | 62 | | [yudao-ui-admin](https://gitee.com/zhijiantianya/ruoyi-vue-pro/tree/master/yudao-ui-admin) | [](https://gitee.com/zhijiantianya/ruoyi-vue-pro/tree/master/yudao-ui-admin) [](https://github.com/YunaiV/ruoyi-vue-pro/tree/master/yudao-ui-admin) | 基于 Vue2 + element-ui 实现的管理后台 | |
| 63 | | [yudao-ui-admin-uniapp](https://gitee.com/zhijiantianya/ruoyi-vue-pro/tree/master/yudao-ui-admin-uniapp) | [](https://gitee.com/zhijiantianya/ruoyi-vue-pro/tree/master/yudao-ui-admin-uniapp) [](https://github.com/YunaiV/ruoyi-vue-pro/tree/master/yudao-ui-admin-uniapp) | 基于 uni-app + uni-ui 实现的管理后台的小程序 | | 63 | | [yudao-ui-admin-uniapp](https://gitee.com/zhijiantianya/ruoyi-vue-pro/tree/master/yudao-ui-admin-uniapp) | [](https://gitee.com/zhijiantianya/ruoyi-vue-pro/tree/master/yudao-ui-admin-uniapp) [](https://github.com/YunaiV/ruoyi-vue-pro/tree/master/yudao-ui-admin-uniapp) | 基于 uni-app + uni-ui 实现的管理后台的小程序 | |
| 64 | | [yudao-ui-go-view](https://gitee.com/yudaocode/yudao-ui-go-view) | [](https://gitee.com/yudaocode/yudao-ui-go-view) [](https://github.com/yudaocode/yudao-ui-go-view) | 基于 Vue3 + naive-ui 实现的大屏报表 | | 64 | | [yudao-ui-go-view](https://gitee.com/yudaocode/yudao-ui-go-view) | [](https://gitee.com/yudaocode/yudao-ui-go-view) [](https://github.com/yudaocode/yudao-ui-go-view) | 基于 Vue3 + naive-ui 实现的大屏报表 | |
| 65 | -| [yudao-ui-app](https://gitee.com/zhijiantianya/ruoyi-vue-pro/tree/master/yudao-ui-app) | [](https://gitee.com/zhijiantianya/ruoyi-vue-pro/tree/master/yudao-ui-app) [](https://github.com/YunaiV/ruoyi-vue-pro/tree/master/yudao-ui-app) | 基于 uni-app + uview 实现的用户 App | | 65 | +| [yudao-mall-uniapp](https://gitee.com/yudaocode/yudao-mall-uniapp) | [](https://gitee.com/yudaocode/yudao-mall-uniapp) [](https://github.com/yudaocode/yudao-mall-uniapp) | 基于 uni-app 实现的商城小程序 | |
| 66 | 66 | ||
| 67 | ## 🐰 分支说明 | 67 | ## 🐰 分支说明 |
| 68 | 68 | ||
| @@ -218,7 +218,9 @@ | @@ -218,7 +218,9 @@ | ||
| 218 | 218 | ||
| 219 |  | 219 |  |
| 220 | 220 | ||
| 221 | -前端基于 crmeb uniapp 经过授权重构,优化代码实现,接入芋道快速开发平台 | 221 | +_前端基于 crmeb uniapp 经过授权重构,优化代码实现,接入芋道快速开发平台_ |
| 222 | + | ||
| 223 | +演示地址:<https://doc.iocoder.cn/mall-preview/> | ||
| 222 | 224 | ||
| 223 | ### 会员中心 | 225 | ### 会员中心 |
| 224 | 226 |
pom.xml
| @@ -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-pay</module>--> | ||
| 20 | -<!-- <module>yudao-module-bpm</module>--> | 19 | + <!-- <module>yudao-module-bpm</module>--> |
| 21 | <!-- <module>yudao-module-report</module>--> | 20 | <!-- <module>yudao-module-report</module>--> |
| 22 | <!-- <module>yudao-module-mp</module>--> | 21 | <!-- <module>yudao-module-mp</module>--> |
| 22 | +<!-- <module>yudao-module-pay</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> |
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 '分佣模式:1-人人分销 2-指定分销', | ||
| 7 | + brokerage_bind_mode tinyint default 0 not null comment '分销关系绑定模式: 1-没有推广人,2-新用户, 3-扫码覆盖', | ||
| 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 | + bind_user_id bigint null comment '推广员编号', | ||
| 28 | + bind_user_time datetime null comment '推广员绑定时间', | ||
| 29 | + brokerage_enabled bit default 1 not null comment '是否成为推广员', | ||
| 30 | + brokerage_time datetime null comment '成为分销员时间', | ||
| 31 | + price int default 0 not null comment '可用佣金', | ||
| 32 | + frozen_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 (bind_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', '人人分销', 1, 1, '所有用户都可以分销'), | ||
| 108 | + ('brokerage_enabled_condition', '指定分销', 2, 2, '仅可后台手动设置推广员'); | ||
| 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', '没有推广人', 1, 1, '只要用户没有推广人,随时都可以绑定推广关系'), | ||
| 114 | + ('brokerage_bind_mode', '新用户', 2, 2, '仅新用户注册时才能绑定推广关系'), | ||
| 115 | + ('brokerage_bind_mode', '扫码覆盖', 3, 3, '如果用户已经有推广人,推广人会被变更'); | ||
| 116 | + | ||
| 117 | +insert into system_dict_type(type, name) | ||
| 118 | +values ('brokerage_withdraw_type', '佣金提现类型'); | ||
| 119 | +insert into system_dict_data(dict_type, label, value, sort) | ||
| 120 | +values ('brokerage_withdraw_type', '钱包', 1, 1), | ||
| 121 | + ('brokerage_withdraw_type', '银行卡', 2, 2), | ||
| 122 | + ('brokerage_withdraw_type', '微信', 3, 3), | ||
| 123 | + ('brokerage_withdraw_type', '支付宝', 4, 4); | ||
| 124 | + | ||
| 125 | +insert into system_dict_type(type, name) | ||
| 126 | +values ('brokerage_record_biz_type', '佣金记录业务类型'); | ||
| 127 | +insert into system_dict_data(dict_type, label, value, sort) | ||
| 128 | +values ('brokerage_record_biz_type', '订单返佣', 1, 1), | ||
| 129 | + ('brokerage_record_biz_type', '申请提现', 2, 2); | ||
| 130 | + | ||
| 131 | +insert into system_dict_type(type, name) | ||
| 132 | +values ('brokerage_record_status', '佣金记录状态'); | ||
| 133 | +insert into system_dict_data(dict_type, label, value, sort) | ||
| 134 | +values ('brokerage_record_status', '待结算', 0, 0), | ||
| 135 | + ('brokerage_record_status', '已结算', 1, 1), | ||
| 136 | + ('brokerage_record_status', '已取消', 2, 2); | ||
| 137 | + | ||
| 138 | +insert into system_dict_type(type, name) | ||
| 139 | +values ('brokerage_withdraw_status', '佣金提现状态'); | ||
| 140 | +insert into system_dict_data(dict_type, label, value, sort) | ||
| 141 | +values ('brokerage_withdraw_status', '审核中', 0, 0), | ||
| 142 | + ('brokerage_withdraw_status', '审核通过', 10, 10), | ||
| 143 | + ('brokerage_withdraw_status', '提现成功', 11, 11), | ||
| 144 | + ('brokerage_withdraw_status', '审核不通过', 20, 20), | ||
| 145 | + ('brokerage_withdraw_status', '提现失败', 21, 21); | ||
| 146 | + | ||
| 147 | +insert into system_dict_type(type, name) | ||
| 148 | +values ('brokerage_bank_name', '佣金提现银行'); | ||
| 149 | +insert into system_dict_data(dict_type, label, value, sort) | ||
| 150 | +values ('brokerage_bank_name', '工商银行', 0, 0), | ||
| 151 | + ('brokerage_bank_name', '建设银行', 1, 1), | ||
| 152 | + ('brokerage_bank_name', '农业银行', 2, 2), | ||
| 153 | + ('brokerage_bank_name', '中国银行', 3, 3), | ||
| 154 | + ('brokerage_bank_name', '交通银行', 4, 4), | ||
| 155 | + ('brokerage_bank_name', '招商银行', 5, 5); | ||
| 156 | + | ||
| 157 | + | ||
| 158 | +-- 交易中心配置:菜单 SQL | ||
| 159 | +INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status, component_name) | ||
| 160 | +VALUES ('交易中心配置', '', 2, 0, 2072, 'config', 'ep:setting', 'trade/config/index', 0, 'TradeConfig'); | ||
| 161 | +-- 按钮父菜单ID | ||
| 162 | +-- 暂时只支持 MySQL。如果你是 Oracle、PostgreSQL、SQLServer 的话,需要手动修改 @parentId 的部分的代码 | ||
| 163 | +SELECT @parentId := LAST_INSERT_ID(); | ||
| 164 | +-- 按钮 SQL | ||
| 165 | +INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status) | ||
| 166 | +VALUES ('交易中心配置查询', 'trade:config:query', 3, 1, @parentId, '', '', '', 0); | ||
| 167 | +INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status) | ||
| 168 | +VALUES ('交易中心配置保存', 'trade:config:save', 3, 2, @parentId, '', '', '', 0); | ||
| 169 | + | ||
| 170 | + | ||
| 171 | +-- 增加菜单:分销 | ||
| 172 | +INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status, component_name) | ||
| 173 | +VALUES ('分销', '', 1, 5, 2072, 'brokerage', 'fa-solid:project-diagram', '', 0, ''); | ||
| 174 | +-- 按钮父菜单ID | ||
| 175 | +SELECT @brokerageMenuId := LAST_INSERT_ID(); | ||
| 176 | + | ||
| 177 | +-- 增加菜单:分销员 | ||
| 178 | +-- 菜单 SQL | ||
| 179 | +INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status, component_name) | ||
| 180 | +VALUES ('分销用户', '', 2, 0, @brokerageMenuId, 'brokerage-user', 'fa-solid:user-tie', 'trade/brokerage/user/index', 0, | ||
| 181 | + 'TradeBrokerageUser'); | ||
| 182 | +-- 按钮父菜单ID | ||
| 183 | +-- 暂时只支持 MySQL。如果你是 Oracle、PostgreSQL、SQLServer 的话,需要手动修改 @parentId 的部分的代码 | ||
| 184 | +SELECT @parentId := LAST_INSERT_ID(); | ||
| 185 | +-- 按钮 SQL | ||
| 186 | +INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status) | ||
| 187 | +VALUES ('分销用户查询', 'trade:brokerage-user:query', 3, 1, @parentId, '', '', '', 0); | ||
| 188 | +INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status) | ||
| 189 | +VALUES ('分销用户推广人查询', 'trade:brokerage-user:user-query', 3, 2, @parentId, '', '', '', 0); | ||
| 190 | +INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status) | ||
| 191 | +VALUES ('分销用户推广订单查询', 'trade:brokerage-user:order-query', 3, 3, @parentId, '', '', '', 0); | ||
| 192 | +INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status) | ||
| 193 | +VALUES ('分销用户修改推广资格', 'trade:brokerage-user:update-brokerage-enable', 3, 4, @parentId, '', '', '', 0); | ||
| 194 | +INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status) | ||
| 195 | +VALUES ('分销用户修改推广员', 'trade:brokerage-user:update-brokerage-user', 3, 5, @parentId, '', '', '', 0); | ||
| 196 | +INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status) | ||
| 197 | +VALUES ('分销用户清除推广员', 'trade:brokerage-user:clear-brokerage-user', 3, 6, @parentId, '', '', '', 0); | ||
| 198 | + | ||
| 199 | +-- 增加菜单:佣金记录 | ||
| 200 | +INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status, component_name) | ||
| 201 | +VALUES ('佣金记录', '', 2, 1, @brokerageMenuId, 'brokerage-record', 'fa:money', 'trade/brokerage/record/index', 0, | ||
| 202 | + 'TradeBrokerageRecord'); | ||
| 203 | +-- 按钮父菜单ID | ||
| 204 | +-- 暂时只支持 MySQL。如果你是 Oracle、PostgreSQL、SQLServer 的话,需要手动修改 @parentId 的部分的代码 | ||
| 205 | +SELECT @parentId := LAST_INSERT_ID(); | ||
| 206 | +-- 按钮 SQL | ||
| 207 | +INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status) | ||
| 208 | +VALUES ('佣金记录查询', 'trade:brokerage-record:query', 3, 1, @parentId, '', '', '', 0); | ||
| 209 | + | ||
| 210 | +-- 增加菜单:佣金提现 | ||
| 211 | +INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status, component_name) | ||
| 212 | +VALUES ('佣金提现', '', 2, 2, @brokerageMenuId, 'brokerage-withdraw', 'fa:credit-card', | ||
| 213 | + 'trade/brokerage/withdraw/index', 0, 'TradeBrokerageWithdraw'); | ||
| 214 | +-- 按钮父菜单ID | ||
| 215 | +-- 暂时只支持 MySQL。如果你是 Oracle、PostgreSQL、SQLServer 的话,需要手动修改 @parentId 的部分的代码 | ||
| 216 | +SELECT @parentId := LAST_INSERT_ID(); | ||
| 217 | +-- 按钮 SQL | ||
| 218 | +INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status) | ||
| 219 | +VALUES ('佣金提现查询', 'trade:brokerage-withdraw:query', 3, 1, @parentId, '', '', '', 0); | ||
| 220 | +INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status) | ||
| 221 | +VALUES ('佣金提现审核', 'trade:brokerage-withdraw:audit', 3, 2, @parentId, '', '', '', 0); | ||
| 0 | \ No newline at end of file | 222 | \ 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` |
| @@ -8,8 +8,8 @@ CREATE TABLE `pay_wallet` | @@ -8,8 +8,8 @@ CREATE TABLE `pay_wallet` | ||
| 8 | `user_id` bigint NOT NULL COMMENT '用户编号', | 8 | `user_id` bigint NOT NULL COMMENT '用户编号', |
| 9 | `user_type` tinyint NOT NULL DEFAULT 0 COMMENT '用户类型', | 9 | `user_type` tinyint NOT NULL DEFAULT 0 COMMENT '用户类型', |
| 10 | `balance` int NOT NULL DEFAULT 0 COMMENT '余额,单位分', | 10 | `balance` int NOT NULL DEFAULT 0 COMMENT '余额,单位分', |
| 11 | - `total_expense` bigint NOT NULL DEFAULT 0 COMMENT '累计支出,单位分', | ||
| 12 | - `total_recharge` bigint NOT NULL DEFAULT 0 COMMENT '累计充值,单位分', | 11 | + `total_expense` int NOT NULL DEFAULT 0 COMMENT '累计支出,单位分', |
| 12 | + `total_recharge` int NOT NULL DEFAULT 0 COMMENT '累计充值,单位分', | ||
| 13 | `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者', | 13 | `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者', |
| 14 | `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', | 14 | `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', |
| 15 | `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者', | 15 | `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者', |
| @@ -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='会员钱包流水表'; |
yudao-dependencies/pom.xml
| @@ -27,7 +27,7 @@ | @@ -27,7 +27,7 @@ | ||
| 27 | <mybatis-plus.version>3.5.3.2</mybatis-plus.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 | <mybatis-plus-generator.version>3.5.3.2</mybatis-plus-generator.version> |
| 29 | <dynamic-datasource.version>3.6.1</dynamic-datasource.version> | 29 | <dynamic-datasource.version>3.6.1</dynamic-datasource.version> |
| 30 | - <mybatis-plus-join-boot-starter.version>1.4.6</mybatis-plus-join-boot-starter.version> | 30 | + <mybatis-plus-join.version>1.4.6</mybatis-plus-join.version> |
| 31 | <redisson.version>3.18.0</redisson.version> | 31 | <redisson.version>3.18.0</redisson.version> |
| 32 | <dm8.jdbc.version>8.1.2.141</dm8.jdbc.version> | 32 | <dm8.jdbc.version>8.1.2.141</dm8.jdbc.version> |
| 33 | <!-- 服务保障相关 --> | 33 | <!-- 服务保障相关 --> |
| @@ -220,7 +220,7 @@ | @@ -220,7 +220,7 @@ | ||
| 220 | <dependency> | 220 | <dependency> |
| 221 | <groupId>com.github.yulichang</groupId> | 221 | <groupId>com.github.yulichang</groupId> |
| 222 | <artifactId>mybatis-plus-join-boot-starter</artifactId> <!-- MyBatis 联表查询 --> | 222 | <artifactId>mybatis-plus-join-boot-starter</artifactId> <!-- MyBatis 联表查询 --> |
| 223 | - <version>${mybatis-plus-join-boot-starter.version}</version> | 223 | + <version>${mybatis-plus-join.version}</version> |
| 224 | </dependency> | 224 | </dependency> |
| 225 | 225 | ||
| 226 | <dependency> | 226 | <dependency> |
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/pojo/CommonResult.java
| @@ -41,7 +41,7 @@ public class CommonResult<T> implements Serializable { | @@ -41,7 +41,7 @@ public class CommonResult<T> implements Serializable { | ||
| 41 | * 因为 A 方法返回的 CommonResult 对象,不满足调用其的 B 方法的返回,所以需要进行转换。 | 41 | * 因为 A 方法返回的 CommonResult 对象,不满足调用其的 B 方法的返回,所以需要进行转换。 |
| 42 | * | 42 | * |
| 43 | * @param result 传入的 result 对象 | 43 | * @param result 传入的 result 对象 |
| 44 | - * @param <T> 返回的泛型 | 44 | + * @param <T> 返回的泛型 |
| 45 | * @return 新的 CommonResult 对象 | 45 | * @return 新的 CommonResult 对象 |
| 46 | */ | 46 | */ |
| 47 | public static <T> CommonResult<T> error(CommonResult<?> result) { | 47 | public static <T> CommonResult<T> error(CommonResult<?> result) { |
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-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/util/MoneyUtils.java renamed to yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/number/MoneyUtils.java
| 1 | -package cn.iocoder.yudao.module.pay.util; | 1 | +package cn.iocoder.yudao.framework.common.util.number; |
| 2 | 2 | ||
| 3 | import cn.hutool.core.util.NumberUtil; | 3 | import cn.hutool.core.util.NumberUtil; |
| 4 | 4 | ||
| @@ -23,6 +23,17 @@ public class MoneyUtils { | @@ -23,6 +23,17 @@ public class MoneyUtils { | ||
| 23 | return calculateRatePrice(price, rate, 0, RoundingMode.HALF_UP).intValue(); | 23 | return calculateRatePrice(price, rate, 0, RoundingMode.HALF_UP).intValue(); |
| 24 | } | 24 | } |
| 25 | 25 | ||
| 26 | + /** | ||
| 27 | + * 计算百分比金额,向下传入 | ||
| 28 | + * | ||
| 29 | + * @param price 金额 | ||
| 30 | + * @param rate 百分比,例如说 56.77% 则传入 56.77 | ||
| 31 | + * @return 百分比金额 | ||
| 32 | + */ | ||
| 33 | + public static Integer calculateRatePriceFloor(Integer price, Double rate) { | ||
| 34 | + return calculateRatePrice(price, rate, 0, RoundingMode.FLOOR).intValue(); | ||
| 35 | + } | ||
| 36 | + | ||
| 26 | /** | 37 | /** |
| 27 | * 计算百分比金额 | 38 | * 计算百分比金额 |
| 28 | * | 39 | * |
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/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-biz-social/src/main/java/cn/iocoder/yudao/framework/social/core/YudaoAuthRequestFactory.java
| @@ -4,6 +4,7 @@ import cn.hutool.core.util.EnumUtil; | @@ -4,6 +4,7 @@ import cn.hutool.core.util.EnumUtil; | ||
| 4 | import cn.hutool.core.util.ReflectUtil; | 4 | import cn.hutool.core.util.ReflectUtil; |
| 5 | import cn.iocoder.yudao.framework.social.core.enums.AuthExtendSource; | 5 | import cn.iocoder.yudao.framework.social.core.enums.AuthExtendSource; |
| 6 | import cn.iocoder.yudao.framework.social.core.request.AuthWeChatMiniAppRequest; | 6 | import cn.iocoder.yudao.framework.social.core.request.AuthWeChatMiniAppRequest; |
| 7 | +import cn.iocoder.yudao.framework.social.core.request.AuthWeChatMpRequest; | ||
| 7 | import com.xingyuv.jushauth.cache.AuthStateCache; | 8 | import com.xingyuv.jushauth.cache.AuthStateCache; |
| 8 | import com.xingyuv.jushauth.config.AuthConfig; | 9 | import com.xingyuv.jushauth.config.AuthConfig; |
| 9 | import com.xingyuv.jushauth.config.AuthSource; | 10 | import com.xingyuv.jushauth.config.AuthSource; |
| @@ -13,6 +14,8 @@ import com.xingyuv.justauth.autoconfigure.JustAuthProperties; | @@ -13,6 +14,8 @@ import com.xingyuv.justauth.autoconfigure.JustAuthProperties; | ||
| 13 | 14 | ||
| 14 | import java.lang.reflect.Method; | 15 | import java.lang.reflect.Method; |
| 15 | 16 | ||
| 17 | +import static com.xingyuv.jushauth.config.AuthDefaultSource.WECHAT_MP; | ||
| 18 | + | ||
| 16 | /** | 19 | /** |
| 17 | * 第三方授权拓展 request 工厂类 | 20 | * 第三方授权拓展 request 工厂类 |
| 18 | * 为使得拓展配置 {@link AuthConfig} 和默认配置齐平,所以自定义本工厂类 | 21 | * 为使得拓展配置 {@link AuthConfig} 和默认配置齐平,所以自定义本工厂类 |
| @@ -55,6 +58,12 @@ public class YudaoAuthRequestFactory extends AuthRequestFactory { | @@ -55,6 +58,12 @@ public class YudaoAuthRequestFactory extends AuthRequestFactory { | ||
| 55 | } | 58 | } |
| 56 | 59 | ||
| 57 | protected AuthRequest getExtendRequest(String source) { | 60 | protected AuthRequest getExtendRequest(String source) { |
| 61 | + // TODO 芋艿:临时兼容 justauth 迁移的类型不对问题; | ||
| 62 | + if (WECHAT_MP.name().equalsIgnoreCase(source)) { | ||
| 63 | + AuthConfig config = properties.getType().get(WECHAT_MP.name()); | ||
| 64 | + return new AuthWeChatMpRequest(config, authStateCache); | ||
| 65 | + } | ||
| 66 | + | ||
| 58 | AuthExtendSource authExtendSource; | 67 | AuthExtendSource authExtendSource; |
| 59 | try { | 68 | try { |
| 60 | authExtendSource = EnumUtil.fromString(AuthExtendSource.class, source.toUpperCase()); | 69 | authExtendSource = EnumUtil.fromString(AuthExtendSource.class, source.toUpperCase()); |
yudao-framework/yudao-spring-boot-starter-biz-social/src/main/java/cn/iocoder/yudao/framework/social/core/request/AuthWeChatMpRequest.java
0 → 100644
| 1 | +package cn.iocoder.yudao.framework.social.core.request; | ||
| 2 | + | ||
| 3 | +import com.alibaba.fastjson.JSONObject; | ||
| 4 | +import com.xingyuv.jushauth.cache.AuthStateCache; | ||
| 5 | +import com.xingyuv.jushauth.config.AuthConfig; | ||
| 6 | +import com.xingyuv.jushauth.config.AuthDefaultSource; | ||
| 7 | +import com.xingyuv.jushauth.enums.AuthResponseStatus; | ||
| 8 | +import com.xingyuv.jushauth.enums.AuthUserGender; | ||
| 9 | +import com.xingyuv.jushauth.enums.scope.AuthWechatMpScope; | ||
| 10 | +import com.xingyuv.jushauth.exception.AuthException; | ||
| 11 | +import com.xingyuv.jushauth.model.AuthCallback; | ||
| 12 | +import com.xingyuv.jushauth.model.AuthResponse; | ||
| 13 | +import com.xingyuv.jushauth.model.AuthToken; | ||
| 14 | +import com.xingyuv.jushauth.model.AuthUser; | ||
| 15 | +import com.xingyuv.jushauth.request.AuthDefaultRequest; | ||
| 16 | +import com.xingyuv.jushauth.utils.AuthScopeUtils; | ||
| 17 | +import com.xingyuv.jushauth.utils.GlobalAuthUtils; | ||
| 18 | +import com.xingyuv.jushauth.utils.HttpUtils; | ||
| 19 | +import com.xingyuv.jushauth.utils.UrlBuilder; | ||
| 20 | + | ||
| 21 | +/** | ||
| 22 | + * 微信公众平台登录 | ||
| 23 | + * | ||
| 24 | + * @author yangkai.shen (https://xkcoding.com) | ||
| 25 | + * @since 1.1.0 | ||
| 26 | + */ | ||
| 27 | +public class AuthWeChatMpRequest extends AuthDefaultRequest { | ||
| 28 | + public AuthWeChatMpRequest(AuthConfig config) { | ||
| 29 | + super(config, AuthDefaultSource.WECHAT_MP); | ||
| 30 | + } | ||
| 31 | + | ||
| 32 | + public AuthWeChatMpRequest(AuthConfig config, AuthStateCache authStateCache) { | ||
| 33 | + super(config, AuthDefaultSource.WECHAT_MP, authStateCache); | ||
| 34 | + } | ||
| 35 | + | ||
| 36 | + /** | ||
| 37 | + * 微信的特殊性,此时返回的信息同时包含 openid 和 access_token | ||
| 38 | + * | ||
| 39 | + * @param authCallback 回调返回的参数 | ||
| 40 | + * @return 所有信息 | ||
| 41 | + */ | ||
| 42 | + @Override | ||
| 43 | + protected AuthToken getAccessToken(AuthCallback authCallback) { | ||
| 44 | + return this.getToken(accessTokenUrl(authCallback.getCode())); | ||
| 45 | + } | ||
| 46 | + | ||
| 47 | + @Override | ||
| 48 | + protected AuthUser getUserInfo(AuthToken authToken) { | ||
| 49 | + String openId = authToken.getOpenId(); | ||
| 50 | + | ||
| 51 | + String response = doGetUserInfo(authToken); | ||
| 52 | + JSONObject object = JSONObject.parseObject(response); | ||
| 53 | + | ||
| 54 | + this.checkResponse(object); | ||
| 55 | + | ||
| 56 | + String location = String.format("%s-%s-%s", object.getString("country"), object.getString("province"), object.getString("city")); | ||
| 57 | + | ||
| 58 | + if (object.containsKey("unionid")) { | ||
| 59 | + authToken.setUnionId(object.getString("unionid")); | ||
| 60 | + } | ||
| 61 | + | ||
| 62 | + return AuthUser.builder() | ||
| 63 | + .rawUserInfo(object) | ||
| 64 | + .username(object.getString("nickname")) | ||
| 65 | + .nickname(object.getString("nickname")) | ||
| 66 | + .avatar(object.getString("headimgurl")) | ||
| 67 | + .location(location) | ||
| 68 | + .uuid(openId) | ||
| 69 | + .gender(AuthUserGender.getWechatRealGender(object.getString("sex"))) | ||
| 70 | + .token(authToken) | ||
| 71 | + .source(source.toString()) | ||
| 72 | + .build(); | ||
| 73 | + } | ||
| 74 | + | ||
| 75 | + @Override | ||
| 76 | + public AuthResponse refresh(AuthToken oldToken) { | ||
| 77 | + return AuthResponse.builder() | ||
| 78 | + .code(AuthResponseStatus.SUCCESS.getCode()) | ||
| 79 | + .data(this.getToken(refreshTokenUrl(oldToken.getRefreshToken()))) | ||
| 80 | + .build(); | ||
| 81 | + } | ||
| 82 | + | ||
| 83 | + /** | ||
| 84 | + * 检查响应内容是否正确 | ||
| 85 | + * | ||
| 86 | + * @param object 请求响应内容 | ||
| 87 | + */ | ||
| 88 | + private void checkResponse(JSONObject object) { | ||
| 89 | + if (object.containsKey("errcode")) { | ||
| 90 | + throw new AuthException(object.getIntValue("errcode"), object.getString("errmsg")); | ||
| 91 | + } | ||
| 92 | + } | ||
| 93 | + | ||
| 94 | + /** | ||
| 95 | + * 获取token,适用于获取access_token和刷新token | ||
| 96 | + * | ||
| 97 | + * @param accessTokenUrl 实际请求token的地址 | ||
| 98 | + * @return token对象 | ||
| 99 | + */ | ||
| 100 | + private AuthToken getToken(String accessTokenUrl) { | ||
| 101 | + String response = new HttpUtils(config.getHttpConfig()).get(accessTokenUrl).getBody(); | ||
| 102 | + JSONObject accessTokenObject = JSONObject.parseObject(response); | ||
| 103 | + | ||
| 104 | + this.checkResponse(accessTokenObject); | ||
| 105 | + | ||
| 106 | + return AuthToken.builder() | ||
| 107 | + .accessToken(accessTokenObject.getString("access_token")) | ||
| 108 | + .refreshToken(accessTokenObject.getString("refresh_token")) | ||
| 109 | + .expireIn(accessTokenObject.getIntValue("expires_in")) | ||
| 110 | + .openId(accessTokenObject.getString("openid")) | ||
| 111 | + .scope(accessTokenObject.getString("scope")) | ||
| 112 | + .build(); | ||
| 113 | + } | ||
| 114 | + | ||
| 115 | + /** | ||
| 116 | + * 返回带{@code state}参数的授权url,授权回调时会带上这个{@code state} | ||
| 117 | + * | ||
| 118 | + * @param state state 验证授权流程的参数,可以防止csrf | ||
| 119 | + * @return 返回授权地址 | ||
| 120 | + * @since 1.9.3 | ||
| 121 | + */ | ||
| 122 | + @Override | ||
| 123 | + public String authorize(String state) { | ||
| 124 | + return UrlBuilder.fromBaseUrl(source.authorize()) | ||
| 125 | + .queryParam("appid", config.getClientId()) | ||
| 126 | + .queryParam("redirect_uri", GlobalAuthUtils.urlEncode(config.getRedirectUri())) | ||
| 127 | + .queryParam("response_type", "code") | ||
| 128 | + .queryParam("scope", this.getScopes(",", false, AuthScopeUtils.getDefaultScopes(AuthWechatMpScope.values()))) | ||
| 129 | + .queryParam("state", getRealState(state).concat("#wechat_redirect")) | ||
| 130 | + .build(); | ||
| 131 | + } | ||
| 132 | + | ||
| 133 | + /** | ||
| 134 | + * 返回获取accessToken的url | ||
| 135 | + * | ||
| 136 | + * @param code 授权码 | ||
| 137 | + * @return 返回获取accessToken的url | ||
| 138 | + */ | ||
| 139 | + @Override | ||
| 140 | + protected String accessTokenUrl(String code) { | ||
| 141 | + return UrlBuilder.fromBaseUrl(source.accessToken()) | ||
| 142 | + .queryParam("appid", config.getClientId()) | ||
| 143 | + .queryParam("secret", config.getClientSecret()) | ||
| 144 | + .queryParam("code", code) | ||
| 145 | + .queryParam("grant_type", "authorization_code") | ||
| 146 | + .build(); | ||
| 147 | + } | ||
| 148 | + | ||
| 149 | + /** | ||
| 150 | + * 返回获取userInfo的url | ||
| 151 | + * | ||
| 152 | + * @param authToken 用户授权后的token | ||
| 153 | + * @return 返回获取userInfo的url | ||
| 154 | + */ | ||
| 155 | + @Override | ||
| 156 | + protected String userInfoUrl(AuthToken authToken) { | ||
| 157 | + return UrlBuilder.fromBaseUrl(source.userInfo()) | ||
| 158 | + .queryParam("access_token", authToken.getAccessToken()) | ||
| 159 | + .queryParam("openid", authToken.getOpenId()) | ||
| 160 | + .queryParam("lang", "zh_CN") | ||
| 161 | + .build(); | ||
| 162 | + } | ||
| 163 | + | ||
| 164 | + /** | ||
| 165 | + * 返回获取userInfo的url | ||
| 166 | + * | ||
| 167 | + * @param refreshToken getAccessToken方法返回的refreshToken | ||
| 168 | + * @return 返回获取userInfo的url | ||
| 169 | + */ | ||
| 170 | + @Override | ||
| 171 | + protected String refreshTokenUrl(String refreshToken) { | ||
| 172 | + return UrlBuilder.fromBaseUrl(source.refresh()) | ||
| 173 | + .queryParam("appid", config.getClientId()) | ||
| 174 | + .queryParam("grant_type", "refresh_token") | ||
| 175 | + .queryParam("refresh_token", refreshToken) | ||
| 176 | + .build(); | ||
| 177 | + } | ||
| 178 | +} |
yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/mapper/BaseMapperX.java
| @@ -18,6 +18,9 @@ import java.util.List; | @@ -18,6 +18,9 @@ import java.util.List; | ||
| 18 | 18 | ||
| 19 | /** | 19 | /** |
| 20 | * 在 MyBatis Plus 的 BaseMapper 的基础上拓展,提供更多的能力 | 20 | * 在 MyBatis Plus 的 BaseMapper 的基础上拓展,提供更多的能力 |
| 21 | + * | ||
| 22 | + * 1. {@link BaseMapper} 为 MyBatis Plus 的基础接口,提供基础的 CRUD 能力 | ||
| 23 | + * 2. {@link MPJBaseMapper} 为 MyBatis Plus Join 的基础接口,提供连表 Join 能力 | ||
| 21 | */ | 24 | */ |
| 22 | public interface BaseMapperX<T> extends MPJBaseMapper<T> { | 25 | public interface BaseMapperX<T> extends MPJBaseMapper<T> { |
| 23 | 26 |
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/bargain/BargainActivityApi.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.promotion.api.bargain; | ||
| 2 | + | ||
| 3 | +/** | ||
| 4 | + * 砍价活动 Api 接口 | ||
| 5 | + * | ||
| 6 | + * @author HUIHUI | ||
| 7 | + */ | ||
| 8 | +public interface BargainActivityApi { | ||
| 9 | + | ||
| 10 | + /** | ||
| 11 | + * 更新砍价活动库存 | ||
| 12 | + * | ||
| 13 | + * @param activityId 砍价活动编号 | ||
| 14 | + * @param count 购买数量 | ||
| 15 | + */ | ||
| 16 | + void updateBargainActivityStock(Long activityId, Integer count); | ||
| 17 | + | ||
| 18 | +} |
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/bargain/dto/BargainRecordCreateReqDTO.java
| @@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.promotion.api.bargain.dto; | @@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.promotion.api.bargain.dto; | ||
| 2 | 2 | ||
| 3 | import lombok.Data; | 3 | import lombok.Data; |
| 4 | 4 | ||
| 5 | -import javax.validation.constraints.NotEmpty; | ||
| 6 | import javax.validation.constraints.NotNull; | 5 | import javax.validation.constraints.NotNull; |
| 7 | 6 | ||
| 8 | // TODO @芋艿:这块要在看看 | 7 | // TODO @芋艿:这块要在看看 |
| @@ -40,17 +39,7 @@ public class BargainRecordCreateReqDTO { | @@ -40,17 +39,7 @@ public class BargainRecordCreateReqDTO { | ||
| 40 | */ | 39 | */ |
| 41 | @NotNull(message = "订单编号不能为空") | 40 | @NotNull(message = "订单编号不能为空") |
| 42 | private Long orderId; | 41 | private Long orderId; |
| 43 | - // TODO @puhui999:spuName、picUrl、 之类字段不用传递; | ||
| 44 | - /** | ||
| 45 | - * 商品名字 | ||
| 46 | - */ | ||
| 47 | - @NotEmpty(message = "商品名字不能为空") | ||
| 48 | - private String spuName; | ||
| 49 | - /** | ||
| 50 | - * 商品图片 | ||
| 51 | - */ | ||
| 52 | - @NotEmpty(message = "商品图片不能为空") | ||
| 53 | - private String picUrl; | 42 | + |
| 54 | /** | 43 | /** |
| 55 | * 砍价商品单价 | 44 | * 砍价商品单价 |
| 56 | */ | 45 | */ |
| @@ -61,17 +50,7 @@ public class BargainRecordCreateReqDTO { | @@ -61,17 +50,7 @@ public class BargainRecordCreateReqDTO { | ||
| 61 | */ | 50 | */ |
| 62 | @NotNull(message = "商品原价不能为空") | 51 | @NotNull(message = "商品原价不能为空") |
| 63 | private Integer price; | 52 | private Integer price; |
| 64 | - // TODO @puhui999:nickname、avatar 不用传递,去查询; | ||
| 65 | - /** | ||
| 66 | - * 用户昵称 | ||
| 67 | - */ | ||
| 68 | - @NotEmpty(message = "用户昵称不能为空") | ||
| 69 | - private String nickname; | ||
| 70 | - /** | ||
| 71 | - * 用户头像 | ||
| 72 | - */ | ||
| 73 | - @NotEmpty(message = "用户头像不能为空") | ||
| 74 | - private String avatar; | 53 | + |
| 75 | /** | 54 | /** |
| 76 | * 开团状态:进行中 砍价成功 砍价失败 | 55 | * 开团状态:进行中 砍价成功 砍价失败 |
| 77 | */ | 56 | */ |
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationRecordApi.java
| @@ -2,9 +2,9 @@ package cn.iocoder.yudao.module.promotion.api.combination; | @@ -2,9 +2,9 @@ package cn.iocoder.yudao.module.promotion.api.combination; | ||
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO; | 3 | import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO; |
| 4 | import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordRespDTO; | 4 | import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordRespDTO; |
| 5 | -import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordUpdateStatusReqDTO; | ||
| 6 | 5 | ||
| 7 | import javax.validation.Valid; | 6 | import javax.validation.Valid; |
| 7 | +import java.time.LocalDateTime; | ||
| 8 | import java.util.List; | 8 | import java.util.List; |
| 9 | 9 | ||
| 10 | // TODO @芋艿:后面也再撸撸这几个接口 | 10 | // TODO @芋艿:后面也再撸撸这几个接口 |
| @@ -51,13 +51,29 @@ public interface CombinationRecordApi { | @@ -51,13 +51,29 @@ public interface CombinationRecordApi { | ||
| 51 | */ | 51 | */ |
| 52 | void validateCombinationLimitCount(Long activityId, Integer count, Integer sumCount); | 52 | void validateCombinationLimitCount(Long activityId, Integer count, Integer sumCount); |
| 53 | 53 | ||
| 54 | - // TODO @puhui999:是不是搞成具体的方法,拼团成功,拼团失败,这种方法; | 54 | + /** |
| 55 | + * 更新拼团状态为成功 | ||
| 56 | + * | ||
| 57 | + * @param userId 用户编号 | ||
| 58 | + * @param orderId 订单编号 | ||
| 59 | + */ | ||
| 60 | + void updateRecordStatusToSuccess(Long userId, Long orderId); | ||
| 55 | 61 | ||
| 56 | /** | 62 | /** |
| 57 | - * 更新开团记录状态 | 63 | + * 更新拼团状态为失败 |
| 58 | * | 64 | * |
| 59 | - * @param reqDTO 请求 DTO | 65 | + * @param userId 用户编号 |
| 66 | + * @param orderId 订单编号 | ||
| 67 | + */ | ||
| 68 | + void updateRecordStatusToFailed(Long userId, Long orderId); | ||
| 69 | + | ||
| 70 | + /** | ||
| 71 | + * 更新拼团状态为 进行中 | ||
| 72 | + * | ||
| 73 | + * @param userId 用户编号 | ||
| 74 | + * @param orderId 订单编号 | ||
| 75 | + * @param startTime 开始时间 | ||
| 60 | */ | 76 | */ |
| 61 | - void updateCombinationRecordStatus(CombinationRecordUpdateStatusReqDTO reqDTO); | 77 | + void updateRecordStatusToInProgress(Long userId, Long orderId, LocalDateTime startTime); |
| 62 | 78 | ||
| 63 | } | 79 | } |
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/dto/CombinationRecordUpdateStatusReqDTO.java deleted
| 1 | -package cn.iocoder.yudao.module.promotion.api.combination.dto; | ||
| 2 | - | ||
| 3 | -import lombok.Data; | ||
| 4 | - | ||
| 5 | -import javax.validation.constraints.NotNull; | ||
| 6 | -import java.time.LocalDateTime; | ||
| 7 | - | ||
| 8 | -/** | ||
| 9 | - * 拼团记录的更新状态 Request DTO | ||
| 10 | - * | ||
| 11 | - * @author HUIHUI | ||
| 12 | - */ | ||
| 13 | -@Data | ||
| 14 | -public class CombinationRecordUpdateStatusReqDTO { | ||
| 15 | - | ||
| 16 | - /** | ||
| 17 | - * 用户编号 | ||
| 18 | - */ | ||
| 19 | - @NotNull(message = "用户编号不能为空") | ||
| 20 | - private Long userId; | ||
| 21 | - | ||
| 22 | - /** | ||
| 23 | - * 订单编号 | ||
| 24 | - */ | ||
| 25 | - @NotNull(message = "订单编号不能为空") | ||
| 26 | - private Long orderId; | ||
| 27 | - | ||
| 28 | - /** | ||
| 29 | - * 开团状态:正在开团 拼团成功 拼团失败 | ||
| 30 | - */ | ||
| 31 | - @NotNull(message = "开团状态不能为空") | ||
| 32 | - private Integer status; | ||
| 33 | - | ||
| 34 | - /** | ||
| 35 | - * 团开始时间 | ||
| 36 | - */ | ||
| 37 | - private LocalDateTime startTime; | ||
| 38 | - | ||
| 39 | -} |
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/seckill/SeckillActivityApi.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.promotion.api.seckill; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.module.promotion.api.seckill.dto.SeckillActivityUpdateStockReqDTO; | ||
| 4 | + | ||
| 5 | +/** | ||
| 6 | + * 秒杀活动 API 接口 | ||
| 7 | + * | ||
| 8 | + * @author HUIHUI | ||
| 9 | + */ | ||
| 10 | +public interface SeckillActivityApi { | ||
| 11 | + | ||
| 12 | + /** | ||
| 13 | + * 更新秒杀库存 | ||
| 14 | + * | ||
| 15 | + * @param updateStockReqDTO 请求 | ||
| 16 | + */ | ||
| 17 | + void updateSeckillStock(SeckillActivityUpdateStockReqDTO updateStockReqDTO); | ||
| 18 | + | ||
| 19 | +} |
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/seckill/dto/SeckillActivityUpdateStockReqDTO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.promotion.api.seckill.dto; | ||
| 2 | + | ||
| 3 | +import lombok.Data; | ||
| 4 | + | ||
| 5 | +import java.util.List; | ||
| 6 | + | ||
| 7 | +/** | ||
| 8 | + * 更新秒杀库存 request DTO | ||
| 9 | + * | ||
| 10 | + * @author HUIHUI | ||
| 11 | + */ | ||
| 12 | +@Data | ||
| 13 | +public class SeckillActivityUpdateStockReqDTO { | ||
| 14 | + | ||
| 15 | + // TODO @puhui999:参数校验 | ||
| 16 | + | ||
| 17 | + // TODO @puhui999:秒杀的话,一次只能购买一种商品哈;不能多个哈; | ||
| 18 | + | ||
| 19 | + /** | ||
| 20 | + * 活动编号 | ||
| 21 | + */ | ||
| 22 | + private Long activityId; | ||
| 23 | + /** | ||
| 24 | + * 总购买数量 | ||
| 25 | + */ | ||
| 26 | + private Integer count; | ||
| 27 | + /** | ||
| 28 | + * 活动商品 | ||
| 29 | + */ | ||
| 30 | + private List<Item> items; | ||
| 31 | + | ||
| 32 | + @Data | ||
| 33 | + public static class Item { | ||
| 34 | + | ||
| 35 | + /** | ||
| 36 | + * SPU 编号 | ||
| 37 | + */ | ||
| 38 | + private Long spuId; | ||
| 39 | + /** | ||
| 40 | + * SKU 编号 | ||
| 41 | + */ | ||
| 42 | + private Long skuId; | ||
| 43 | + /** | ||
| 44 | + * 购买数量 | ||
| 45 | + */ | ||
| 46 | + private Integer count; | ||
| 47 | + | ||
| 48 | + } | ||
| 49 | + | ||
| 50 | +} |
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java
| @@ -55,6 +55,7 @@ public interface ErrorCodeConstants { | @@ -55,6 +55,7 @@ public interface ErrorCodeConstants { | ||
| 55 | ErrorCode SECKILL_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED = new ErrorCode(1_013_008_003, "秒杀活动已关闭,不能修改"); | 55 | ErrorCode SECKILL_ACTIVITY_UPDATE_FAIL_STATUS_CLOSED = new ErrorCode(1_013_008_003, "秒杀活动已关闭,不能修改"); |
| 56 | ErrorCode SECKILL_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED_OR_END = new ErrorCode(1_013_008_004, "秒杀活动未关闭或未结束,不能删除"); | 56 | ErrorCode SECKILL_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED_OR_END = new ErrorCode(1_013_008_004, "秒杀活动未关闭或未结束,不能删除"); |
| 57 | ErrorCode SECKILL_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED = new ErrorCode(1_013_008_005, "秒杀活动已关闭,不能重复关闭"); | 57 | ErrorCode SECKILL_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED = new ErrorCode(1_013_008_005, "秒杀活动已关闭,不能重复关闭"); |
| 58 | + ErrorCode SECKILL_ACTIVITY_UPDATE_STOCK_FAIL = new ErrorCode(1013008006, "更新秒杀活动库存失败,原因秒杀库存不足"); | ||
| 58 | 59 | ||
| 59 | // ========== 秒杀时段 1-013-009-000 ========== | 60 | // ========== 秒杀时段 1-013-009-000 ========== |
| 60 | ErrorCode SECKILL_CONFIG_NOT_EXISTS = new ErrorCode(1_013_009_000, "秒杀时段不存在"); | 61 | ErrorCode SECKILL_CONFIG_NOT_EXISTS = new ErrorCode(1_013_009_000, "秒杀时段不存在"); |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/bargain/BargainActivityApiImpl.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.promotion.api.bargain; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityUpdateReqVO; | ||
| 4 | +import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainActivityDO; | ||
| 5 | +import cn.iocoder.yudao.module.promotion.service.bargain.BargainActivityService; | ||
| 6 | +import org.springframework.stereotype.Service; | ||
| 7 | + | ||
| 8 | +import javax.annotation.Resource; | ||
| 9 | + | ||
| 10 | +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | ||
| 11 | +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.BARGAIN_ACTIVITY_NOT_EXISTS; | ||
| 12 | + | ||
| 13 | +/** | ||
| 14 | + * 砍价活动 Api 接口实现类 | ||
| 15 | + * | ||
| 16 | + * @author HUIHUI | ||
| 17 | + */ | ||
| 18 | +@Service | ||
| 19 | +public class BargainActivityApiImpl implements BargainActivityApi { | ||
| 20 | + | ||
| 21 | + @Resource | ||
| 22 | + private BargainActivityService bargainActivityService; | ||
| 23 | + | ||
| 24 | + @Override | ||
| 25 | + public void updateBargainActivityStock(Long activityId, Integer count) { | ||
| 26 | + // TODO @puhui999:可以整个实现到 bargainActivityService 中 | ||
| 27 | + // 查询砍价活动 | ||
| 28 | + BargainActivityDO activity = bargainActivityService.getBargainActivity(activityId); | ||
| 29 | + if (activity == null) { | ||
| 30 | + throw exception(BARGAIN_ACTIVITY_NOT_EXISTS); | ||
| 31 | + } | ||
| 32 | + | ||
| 33 | + // 更新砍价库存 | ||
| 34 | + // TODO @puhui999:考虑下并发更新问题 | ||
| 35 | + BargainActivityUpdateReqVO reqVO = new BargainActivityUpdateReqVO(); | ||
| 36 | + reqVO.setId(activityId); | ||
| 37 | + reqVO.setStock(activity.getStock() - count); | ||
| 38 | + bargainActivityService.updateBargainActivity(reqVO); | ||
| 39 | + } | ||
| 40 | + | ||
| 41 | +} |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationRecordApiImpl.java
| @@ -2,13 +2,13 @@ package cn.iocoder.yudao.module.promotion.api.combination; | @@ -2,13 +2,13 @@ package cn.iocoder.yudao.module.promotion.api.combination; | ||
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO; | 3 | import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO; |
| 4 | import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordRespDTO; | 4 | import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordRespDTO; |
| 5 | -import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordUpdateStatusReqDTO; | ||
| 6 | import cn.iocoder.yudao.module.promotion.convert.combination.CombinationActivityConvert; | 5 | import cn.iocoder.yudao.module.promotion.convert.combination.CombinationActivityConvert; |
| 7 | import cn.iocoder.yudao.module.promotion.enums.combination.CombinationRecordStatusEnum; | 6 | import cn.iocoder.yudao.module.promotion.enums.combination.CombinationRecordStatusEnum; |
| 8 | import cn.iocoder.yudao.module.promotion.service.combination.CombinationRecordService; | 7 | import cn.iocoder.yudao.module.promotion.service.combination.CombinationRecordService; |
| 9 | import org.springframework.stereotype.Service; | 8 | import org.springframework.stereotype.Service; |
| 10 | 9 | ||
| 11 | import javax.annotation.Resource; | 10 | import javax.annotation.Resource; |
| 11 | +import java.time.LocalDateTime; | ||
| 12 | import java.util.List; | 12 | import java.util.List; |
| 13 | 13 | ||
| 14 | /** | 14 | /** |
| @@ -43,12 +43,19 @@ public class CombinationRecordApiImpl implements CombinationRecordApi { | @@ -43,12 +43,19 @@ public class CombinationRecordApiImpl implements CombinationRecordApi { | ||
| 43 | } | 43 | } |
| 44 | 44 | ||
| 45 | @Override | 45 | @Override |
| 46 | - public void updateCombinationRecordStatus(CombinationRecordUpdateStatusReqDTO reqDTO) { | ||
| 47 | - if (null == reqDTO.getStartTime()) { | ||
| 48 | - recordService.updateCombinationRecordStatusByUserIdAndOrderId(reqDTO); | ||
| 49 | - } else { | ||
| 50 | - recordService.updateCombinationRecordStatusAndStartTimeByUserIdAndOrderId(reqDTO); | ||
| 51 | - } | 46 | + public void updateRecordStatusToSuccess(Long userId, Long orderId) { |
| 47 | + recordService.updateCombinationRecordStatusByUserIdAndOrderId(CombinationRecordStatusEnum.SUCCESS.getStatus(), userId, orderId); | ||
| 48 | + } | ||
| 49 | + | ||
| 50 | + @Override | ||
| 51 | + public void updateRecordStatusToFailed(Long userId, Long orderId) { | ||
| 52 | + recordService.updateCombinationRecordStatusByUserIdAndOrderId(CombinationRecordStatusEnum.FAILED.getStatus(), userId, orderId); | ||
| 53 | + } | ||
| 54 | + | ||
| 55 | + @Override | ||
| 56 | + public void updateRecordStatusToInProgress(Long userId, Long orderId, LocalDateTime startTime) { | ||
| 57 | + recordService.updateRecordStatusAndStartTimeByUserIdAndOrderId(CombinationRecordStatusEnum.IN_PROGRESS.getStatus(), | ||
| 58 | + userId, orderId, startTime); | ||
| 52 | } | 59 | } |
| 53 | 60 | ||
| 54 | } | 61 | } |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/seckill/SeckillActivityApiImpl.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.promotion.api.seckill; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | ||
| 4 | +import cn.iocoder.yudao.module.promotion.api.seckill.dto.SeckillActivityUpdateStockReqDTO; | ||
| 5 | +import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO; | ||
| 6 | +import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillProductDO; | ||
| 7 | +import cn.iocoder.yudao.module.promotion.service.seckill.SeckillActivityService; | ||
| 8 | +import org.springframework.stereotype.Service; | ||
| 9 | + | ||
| 10 | +import javax.annotation.Resource; | ||
| 11 | +import java.util.ArrayList; | ||
| 12 | +import java.util.HashMap; | ||
| 13 | +import java.util.List; | ||
| 14 | +import java.util.Map; | ||
| 15 | + | ||
| 16 | +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | ||
| 17 | +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.SECKILL_ACTIVITY_UPDATE_STOCK_FAIL; | ||
| 18 | + | ||
| 19 | +/** | ||
| 20 | + * 秒杀活动接口 Api 接口实现类 | ||
| 21 | + * | ||
| 22 | + * @author HUIHUI | ||
| 23 | + */ | ||
| 24 | +@Service | ||
| 25 | +public class SeckillActivityApiImpl implements SeckillActivityApi { | ||
| 26 | + | ||
| 27 | + @Resource | ||
| 28 | + private SeckillActivityService activityService; | ||
| 29 | + | ||
| 30 | + // TODO @puhui:建议这块弄到 activityService 实现哈; | ||
| 31 | + // TODO @puhui:这个方法,要考虑事务性 | ||
| 32 | + @Override | ||
| 33 | + public void updateSeckillStock(SeckillActivityUpdateStockReqDTO updateStockReqDTO) { | ||
| 34 | + // TODO @puhui999:长方法,最好有 1.1 1.2 2.1 这种步骤哈; | ||
| 35 | + SeckillActivityDO seckillActivity = activityService.getSeckillActivity(updateStockReqDTO.getActivityId()); | ||
| 36 | + if (seckillActivity.getStock() < updateStockReqDTO.getCount()) { | ||
| 37 | + throw exception(SECKILL_ACTIVITY_UPDATE_STOCK_FAIL); | ||
| 38 | + } | ||
| 39 | + // 获取活动商品 | ||
| 40 | + // TODO @puhui999:在一个方法里,dos 和 dolist 最好保持一致,要么用 s,要么用 list 哈; | ||
| 41 | + List<SeckillProductDO> productDOs = activityService.getSeckillProductListByActivityId(updateStockReqDTO.getActivityId()); | ||
| 42 | + // TODO @puhui999:这个是不是搞成 CollectionUtils.convertMultiMap() | ||
| 43 | + List<SeckillActivityUpdateStockReqDTO.Item> items = updateStockReqDTO.getItems(); | ||
| 44 | + Map<Long, List<Long>> map = new HashMap<>(); | ||
| 45 | + items.forEach(item -> { | ||
| 46 | + if (map.containsKey(item.getSpuId())) { | ||
| 47 | + List<Long> skuIds = map.get(item.getSpuId()); | ||
| 48 | + skuIds.add(item.getSkuId()); | ||
| 49 | + map.put(item.getSpuId(), skuIds); | ||
| 50 | + } else { | ||
| 51 | + List<Long> list = new ArrayList<>(); | ||
| 52 | + list.add(item.getSkuId()); | ||
| 53 | + map.put(item.getSpuId(), list); | ||
| 54 | + } | ||
| 55 | + }); | ||
| 56 | + // 过滤出购买的商品 | ||
| 57 | + // TODO @puhui999:productDOList 可以简化成 productList;一般来说,do 之类不用带着哈,在变量里; | ||
| 58 | + List<SeckillProductDO> productDOList = CollectionUtils.filterList(productDOs, item -> map.get(item.getSpuId()).contains(item.getSkuId())); | ||
| 59 | + Map<Long, SeckillActivityUpdateStockReqDTO.Item> productDOMap = CollectionUtils.convertMap(items, SeckillActivityUpdateStockReqDTO.Item::getSkuId, p -> p); | ||
| 60 | + // 检查活动商品库存是否充足 | ||
| 61 | + // TODO @puhui999:避免 b 这种无业务含义的变量; | ||
| 62 | + boolean b = CollectionUtils.anyMatch(productDOList, item -> { | ||
| 63 | + SeckillActivityUpdateStockReqDTO.Item item1 = productDOMap.get(item.getSkuId()); | ||
| 64 | + return (item.getStock() < item1.getCount()) || (item.getStock() - item1.getCount()) < 0; | ||
| 65 | + }); | ||
| 66 | + if (b) { | ||
| 67 | + throw exception(SECKILL_ACTIVITY_UPDATE_STOCK_FAIL); | ||
| 68 | + } | ||
| 69 | + // TODO @puhui999:类似 doList,应该和下面的 update 逻辑粘的更紧密一点;so 在空行的时候,应该挪到 74 之后里去;甚至更合理,应该是 79 之后;说白了,逻辑要分块,每个模块涉及的代码要紧密在一起; | ||
| 70 | + List<SeckillProductDO> doList = CollectionUtils.convertList(productDOList, item -> { | ||
| 71 | + item.setStock(item.getStock() - productDOMap.get(item.getSkuId()).getCount()); | ||
| 72 | + return item; | ||
| 73 | + }); | ||
| 74 | + | ||
| 75 | + // 更新活动库存 | ||
| 76 | + // TODO @puhui999:考虑下并发更新 | ||
| 77 | + seckillActivity.setStock(seckillActivity.getStock() + updateStockReqDTO.getCount()); | ||
| 78 | + seckillActivity.setTotalStock(seckillActivity.getTotalStock() - updateStockReqDTO.getCount()); | ||
| 79 | + activityService.updateSeckillActivity(seckillActivity); | ||
| 80 | + // 更新活动商品库存 | ||
| 81 | + activityService.updateSeckillActivityProductList(doList); | ||
| 82 | + } | ||
| 83 | + | ||
| 84 | +} |
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; |
| @@ -52,14 +52,13 @@ public class AppCombinationRecordController { | @@ -52,14 +52,13 @@ public class AppCombinationRecordController { | ||
| 52 | @RequestParam(value = "activityId", required = false) Long activityId, | 52 | @RequestParam(value = "activityId", required = false) Long activityId, |
| 53 | @RequestParam("status") Integer status, | 53 | @RequestParam("status") Integer status, |
| 54 | @RequestParam(value = "count", defaultValue = "20") @Max(20) Integer count) { | 54 | @RequestParam(value = "count", defaultValue = "20") @Max(20) Integer count) { |
| 55 | - ZoneId zoneId = ZoneId.systemDefault(); | ||
| 56 | List<AppCombinationRecordRespVO> list = new ArrayList<>(); | 55 | List<AppCombinationRecordRespVO> list = new ArrayList<>(); |
| 57 | for (int i = 1; i <= count; i++) { | 56 | for (int i = 1; i <= count; i++) { |
| 58 | AppCombinationRecordRespVO record = new AppCombinationRecordRespVO(); | 57 | AppCombinationRecordRespVO record = new AppCombinationRecordRespVO(); |
| 59 | record.setId((long) i); | 58 | record.setId((long) i); |
| 60 | record.setNickname("用户" + i); | 59 | record.setNickname("用户" + i); |
| 61 | record.setAvatar("头像" + i); | 60 | record.setAvatar("头像" + i); |
| 62 | - record.setExpireTime(LocalDateTime.ofInstant(new Date().toInstant(), zoneId)); | 61 | + record.setExpireTime(LocalDateTime.now()); |
| 63 | record.setUserSize(10); | 62 | record.setUserSize(10); |
| 64 | record.setUserCount(i); | 63 | record.setUserCount(i); |
| 65 | record.setPicUrl("https://static.iocoder.cn/mall/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg"); | 64 | record.setPicUrl("https://static.iocoder.cn/mall/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg"); |
| @@ -74,14 +73,13 @@ public class AppCombinationRecordController { | @@ -74,14 +73,13 @@ public class AppCombinationRecordController { | ||
| 74 | @Operation(summary = "获得拼团记录明细") | 73 | @Operation(summary = "获得拼团记录明细") |
| 75 | @Parameter(name = "id", description = "拼团记录编号", required = true, example = "1024") | 74 | @Parameter(name = "id", description = "拼团记录编号", required = true, example = "1024") |
| 76 | public CommonResult<AppCombinationRecordDetailRespVO> getCombinationRecordDetail(@RequestParam("id") Long id) { | 75 | public CommonResult<AppCombinationRecordDetailRespVO> getCombinationRecordDetail(@RequestParam("id") Long id) { |
| 77 | - ZoneId zoneId = ZoneId.systemDefault(); | ||
| 78 | AppCombinationRecordDetailRespVO detail = new AppCombinationRecordDetailRespVO(); | 76 | AppCombinationRecordDetailRespVO detail = new AppCombinationRecordDetailRespVO(); |
| 79 | // 团长 | 77 | // 团长 |
| 80 | AppCombinationRecordRespVO headRecord = new AppCombinationRecordRespVO(); | 78 | AppCombinationRecordRespVO headRecord = new AppCombinationRecordRespVO(); |
| 81 | headRecord.setId(1L); | 79 | headRecord.setId(1L); |
| 82 | headRecord.setNickname("用户" + 1); | 80 | headRecord.setNickname("用户" + 1); |
| 83 | headRecord.setAvatar("头像" + 1); | 81 | headRecord.setAvatar("头像" + 1); |
| 84 | - headRecord.setExpireTime((LocalDateTime.ofInstant(DateUtils.addTime(Duration.ofDays(1)).toInstant(), zoneId))); | 82 | + headRecord.setExpireTime(LocalDateTimeUtils.addTime(Duration.ofDays(1))); |
| 85 | headRecord.setUserSize(10); | 83 | headRecord.setUserSize(10); |
| 86 | headRecord.setUserCount(3); | 84 | headRecord.setUserCount(3); |
| 87 | headRecord.setStatus(1); | 85 | headRecord.setStatus(1); |
| @@ -96,7 +94,7 @@ public class AppCombinationRecordController { | @@ -96,7 +94,7 @@ public class AppCombinationRecordController { | ||
| 96 | record.setId((long) i); | 94 | record.setId((long) i); |
| 97 | record.setNickname("用户" + i); | 95 | record.setNickname("用户" + i); |
| 98 | record.setAvatar("头像" + i); | 96 | record.setAvatar("头像" + i); |
| 99 | - record.setExpireTime(LocalDateTime.ofInstant(new Date().toInstant(), zoneId)); | 97 | + record.setExpireTime(LocalDateTime.now()); |
| 100 | record.setUserSize(10); | 98 | record.setUserSize(10); |
| 101 | record.setUserCount(i); | 99 | record.setUserCount(i); |
| 102 | record.setStatus(1); | 100 | record.setStatus(1); |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/combination/CombinationRecordDO.java
| @@ -9,6 +9,7 @@ import lombok.*; | @@ -9,6 +9,7 @@ import lombok.*; | ||
| 9 | 9 | ||
| 10 | import java.time.LocalDateTime; | 10 | import java.time.LocalDateTime; |
| 11 | 11 | ||
| 12 | +// TODO 芋艿:把字段的顺序,和 do 顺序对齐下 | ||
| 12 | /** | 13 | /** |
| 13 | * 拼团记录 DO | 14 | * 拼团记录 DO |
| 14 | * | 15 | * |
| @@ -27,34 +28,28 @@ import java.time.LocalDateTime; | @@ -27,34 +28,28 @@ import java.time.LocalDateTime; | ||
| 27 | @AllArgsConstructor | 28 | @AllArgsConstructor |
| 28 | public class CombinationRecordDO extends BaseDO { | 29 | public class CombinationRecordDO extends BaseDO { |
| 29 | 30 | ||
| 31 | + /** | ||
| 32 | + * 编号,主键自增 | ||
| 33 | + */ | ||
| 30 | @TableId | 34 | @TableId |
| 31 | private Long id; | 35 | private Long id; |
| 36 | + | ||
| 32 | /** | 37 | /** |
| 33 | * 拼团活动编号 | 38 | * 拼团活动编号 |
| 39 | + * | ||
| 40 | + * 关联 {@link CombinationActivityDO#getId()} | ||
| 34 | */ | 41 | */ |
| 35 | private Long activityId; | 42 | private Long activityId; |
| 36 | /** | 43 | /** |
| 37 | - * SPU 编号 | ||
| 38 | - */ | ||
| 39 | - private Long spuId; | ||
| 40 | - /** | ||
| 41 | - * SKU 编号 | ||
| 42 | - */ | ||
| 43 | - private Long skuId; | ||
| 44 | - /** | ||
| 45 | - * 用户编号 | ||
| 46 | - */ | ||
| 47 | - private Long userId; | ||
| 48 | - /** | ||
| 49 | - * 订单编号 | 44 | + * 拼团商品单价 |
| 45 | + * | ||
| 46 | + * 冗余 {@link CombinationProductDO#getCombinationPrice()} | ||
| 50 | */ | 47 | */ |
| 51 | - private Long orderId; | 48 | + private Integer combinationPrice; |
| 52 | /** | 49 | /** |
| 53 | - * 团长编号 | ||
| 54 | - * | ||
| 55 | - * 关联 {@link CombinationRecordDO#getId()} | 50 | + * SPU 编号 |
| 56 | */ | 51 | */ |
| 57 | - private Long headId; | 52 | + private Long spuId; |
| 58 | /** | 53 | /** |
| 59 | * 商品名字 | 54 | * 商品名字 |
| 60 | */ | 55 | */ |
| @@ -64,9 +59,14 @@ public class CombinationRecordDO extends BaseDO { | @@ -64,9 +59,14 @@ public class CombinationRecordDO extends BaseDO { | ||
| 64 | */ | 59 | */ |
| 65 | private String picUrl; | 60 | private String picUrl; |
| 66 | /** | 61 | /** |
| 67 | - * 拼团商品单价 | 62 | + * SKU 编号 |
| 68 | */ | 63 | */ |
| 69 | - private Integer combinationPrice; | 64 | + private Long skuId; |
| 65 | + | ||
| 66 | + /** | ||
| 67 | + * 用户编号 | ||
| 68 | + */ | ||
| 69 | + private Long userId; | ||
| 70 | /** | 70 | /** |
| 71 | * 用户昵称 | 71 | * 用户昵称 |
| 72 | */ | 72 | */ |
| @@ -75,6 +75,13 @@ public class CombinationRecordDO extends BaseDO { | @@ -75,6 +75,13 @@ public class CombinationRecordDO extends BaseDO { | ||
| 75 | * 用户头像 | 75 | * 用户头像 |
| 76 | */ | 76 | */ |
| 77 | private String avatar; | 77 | private String avatar; |
| 78 | + | ||
| 79 | + /** | ||
| 80 | + * 团长编号 | ||
| 81 | + * | ||
| 82 | + * 关联 {@link CombinationRecordDO#getId()} | ||
| 83 | + */ | ||
| 84 | + private Long headId; | ||
| 78 | /** | 85 | /** |
| 79 | * 开团状态 | 86 | * 开团状态 |
| 80 | * | 87 | * |
| @@ -82,15 +89,30 @@ public class CombinationRecordDO extends BaseDO { | @@ -82,15 +89,30 @@ public class CombinationRecordDO extends BaseDO { | ||
| 82 | */ | 89 | */ |
| 83 | private Integer status; | 90 | private Integer status; |
| 84 | /** | 91 | /** |
| 92 | + * 订单编号 | ||
| 93 | + */ | ||
| 94 | + private Long orderId; | ||
| 95 | + /** | ||
| 96 | + * 开团需要人数 | ||
| 97 | + * | ||
| 98 | + * 关联 {@link CombinationActivityDO#getUserSize()} | ||
| 99 | + */ | ||
| 100 | + private Integer userSize; | ||
| 101 | + /** | ||
| 102 | + * 已加入拼团人数 | ||
| 103 | + */ | ||
| 104 | + private Integer userCount; | ||
| 105 | + /** | ||
| 85 | * 是否虚拟成团 | 106 | * 是否虚拟成团 |
| 86 | */ | 107 | */ |
| 87 | private Boolean virtualGroup; | 108 | private Boolean virtualGroup; |
| 109 | + | ||
| 88 | /** | 110 | /** |
| 89 | - * 过期时间,单位:小时 | 111 | + * 过期时间 |
| 90 | * | 112 | * |
| 91 | - * 关联 {@link CombinationActivityDO#getLimitDuration()} | 113 | + * 基于 {@link CombinationRecordDO#getStartTime()} + {@link CombinationActivityDO#getLimitDuration()} 计算 |
| 92 | */ | 114 | */ |
| 93 | - private Integer expireTime; | 115 | + private LocalDateTime expireTime; |
| 94 | /** | 116 | /** |
| 95 | * 开始时间 (订单付款后开始的时间) | 117 | * 开始时间 (订单付款后开始的时间) |
| 96 | */ | 118 | */ |
| @@ -99,15 +121,5 @@ public class CombinationRecordDO extends BaseDO { | @@ -99,15 +121,5 @@ public class CombinationRecordDO extends BaseDO { | ||
| 99 | * 结束时间(成团时间/失败时间) | 121 | * 结束时间(成团时间/失败时间) |
| 100 | */ | 122 | */ |
| 101 | private LocalDateTime endTime; | 123 | private LocalDateTime endTime; |
| 102 | - /** | ||
| 103 | - * 开团需要人数 | ||
| 104 | - * | ||
| 105 | - * 关联 {@link CombinationActivityDO#getUserSize()} | ||
| 106 | - */ | ||
| 107 | - private Integer userSize; | ||
| 108 | - /** | ||
| 109 | - * 已加入拼团人数 | ||
| 110 | - */ | ||
| 111 | - private Integer userCount; | ||
| 112 | 124 | ||
| 113 | } | 125 | } |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationRecordService.java
| 1 | package cn.iocoder.yudao.module.promotion.service.combination; | 1 | package cn.iocoder.yudao.module.promotion.service.combination; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO; | 3 | import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO; |
| 4 | -import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordUpdateStatusReqDTO; | ||
| 5 | import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationRecordDO; | 4 | import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationRecordDO; |
| 6 | 5 | ||
| 6 | +import java.time.LocalDateTime; | ||
| 7 | import java.util.List; | 7 | import java.util.List; |
| 8 | 8 | ||
| 9 | /** | 9 | /** |
| @@ -16,9 +16,11 @@ public interface CombinationRecordService { | @@ -16,9 +16,11 @@ public interface CombinationRecordService { | ||
| 16 | /** | 16 | /** |
| 17 | * 更新拼团状态 | 17 | * 更新拼团状态 |
| 18 | * | 18 | * |
| 19 | - * @param reqDTO 请求 DTO | 19 | + * @param status 状态 |
| 20 | + * @param userId 用户编号 | ||
| 21 | + * @param orderId 订单编号 | ||
| 20 | */ | 22 | */ |
| 21 | - void updateCombinationRecordStatusByUserIdAndOrderId(CombinationRecordUpdateStatusReqDTO reqDTO); | 23 | + void updateCombinationRecordStatusByUserIdAndOrderId(Integer status, Long userId, Long orderId); |
| 22 | 24 | ||
| 23 | /** | 25 | /** |
| 24 | * 创建拼团记录 | 26 | * 创建拼团记录 |
| @@ -30,9 +32,12 @@ public interface CombinationRecordService { | @@ -30,9 +32,12 @@ public interface CombinationRecordService { | ||
| 30 | /** | 32 | /** |
| 31 | * 更新拼团状态和开始时间 | 33 | * 更新拼团状态和开始时间 |
| 32 | * | 34 | * |
| 33 | - * @param reqDTO 请求 DTO | 35 | + * @param status 状态 |
| 36 | + * @param userId 用户编号 | ||
| 37 | + * @param orderId 订单编号 | ||
| 38 | + * @param startTime 开始时间 | ||
| 34 | */ | 39 | */ |
| 35 | - void updateCombinationRecordStatusAndStartTimeByUserIdAndOrderId(CombinationRecordUpdateStatusReqDTO reqDTO); | 40 | + void updateRecordStatusAndStartTimeByUserIdAndOrderId(Integer status, Long userId, Long orderId, LocalDateTime startTime); |
| 36 | 41 | ||
| 37 | /** | 42 | /** |
| 38 | * 获得拼团状态 | 43 | * 获得拼团状态 |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationRecordServiceImpl.java
| @@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.promotion.service.combination; | @@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.promotion.service.combination; | ||
| 3 | import cn.hutool.core.collection.CollUtil; | 3 | import cn.hutool.core.collection.CollUtil; |
| 4 | import cn.hutool.core.util.ObjectUtil; | 4 | import cn.hutool.core.util.ObjectUtil; |
| 5 | import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO; | 5 | import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO; |
| 6 | -import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordUpdateStatusReqDTO; | ||
| 7 | import cn.iocoder.yudao.module.promotion.convert.combination.CombinationActivityConvert; | 6 | import cn.iocoder.yudao.module.promotion.convert.combination.CombinationActivityConvert; |
| 8 | import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationActivityDO; | 7 | import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationActivityDO; |
| 9 | import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationRecordDO; | 8 | import cn.iocoder.yudao.module.promotion.dal.dataobject.combination.CombinationRecordDO; |
| @@ -21,6 +20,7 @@ import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionU | @@ -21,6 +20,7 @@ import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionU | ||
| 21 | import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*; | 20 | import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*; |
| 22 | 21 | ||
| 23 | // TODO 芋艿:等拼团记录做完,完整 review 下 | 22 | // TODO 芋艿:等拼团记录做完,完整 review 下 |
| 23 | + | ||
| 24 | /** | 24 | /** |
| 25 | * 拼团记录 Service 实现类 | 25 | * 拼团记录 Service 实现类 |
| 26 | * | 26 | * |
| @@ -38,27 +38,27 @@ public class CombinationRecordServiceImpl implements CombinationRecordService { | @@ -38,27 +38,27 @@ public class CombinationRecordServiceImpl implements CombinationRecordService { | ||
| 38 | 38 | ||
| 39 | @Override | 39 | @Override |
| 40 | @Transactional(rollbackFor = Exception.class) | 40 | @Transactional(rollbackFor = Exception.class) |
| 41 | - public void updateCombinationRecordStatusByUserIdAndOrderId(CombinationRecordUpdateStatusReqDTO reqDTO) { | 41 | + public void updateCombinationRecordStatusByUserIdAndOrderId(Integer status, Long userId, Long orderId) { |
| 42 | // 校验拼团是否存在 | 42 | // 校验拼团是否存在 |
| 43 | - CombinationRecordDO recordDO = validateCombinationRecord(reqDTO.getUserId(), reqDTO.getOrderId()); | 43 | + CombinationRecordDO recordDO = validateCombinationRecord(userId, orderId); |
| 44 | 44 | ||
| 45 | // 更新状态 | 45 | // 更新状态 |
| 46 | - recordDO.setStatus(reqDTO.getStatus()); | 46 | + recordDO.setStatus(status); |
| 47 | recordMapper.updateById(recordDO); | 47 | recordMapper.updateById(recordDO); |
| 48 | } | 48 | } |
| 49 | 49 | ||
| 50 | @Override | 50 | @Override |
| 51 | @Transactional(rollbackFor = Exception.class) | 51 | @Transactional(rollbackFor = Exception.class) |
| 52 | - public void updateCombinationRecordStatusAndStartTimeByUserIdAndOrderId(CombinationRecordUpdateStatusReqDTO reqDTO) { | ||
| 53 | - CombinationRecordDO recordDO = validateCombinationRecord(reqDTO.getUserId(), reqDTO.getOrderId()); | 52 | + public void updateRecordStatusAndStartTimeByUserIdAndOrderId(Integer status, Long userId, Long orderId, LocalDateTime startTime) { |
| 53 | + CombinationRecordDO recordDO = validateCombinationRecord(userId, orderId); | ||
| 54 | // 更新状态 | 54 | // 更新状态 |
| 55 | - recordDO.setStatus(reqDTO.getStatus()); | 55 | + recordDO.setStatus(status); |
| 56 | // 更新开始时间 | 56 | // 更新开始时间 |
| 57 | - recordDO.setStartTime(reqDTO.getStartTime()); | 57 | + recordDO.setStartTime(startTime); |
| 58 | recordMapper.updateById(recordDO); | 58 | recordMapper.updateById(recordDO); |
| 59 | 59 | ||
| 60 | // 更新拼团参入人数 | 60 | // 更新拼团参入人数 |
| 61 | - List<CombinationRecordDO> recordDOs = recordMapper.selectListByHeadIdAndStatus(recordDO.getHeadId(), reqDTO.getStatus()); | 61 | + List<CombinationRecordDO> recordDOs = recordMapper.selectListByHeadIdAndStatus(recordDO.getHeadId(), status); |
| 62 | if (CollUtil.isNotEmpty(recordDOs)) { | 62 | if (CollUtil.isNotEmpty(recordDOs)) { |
| 63 | recordDOs.forEach(item -> { | 63 | recordDOs.forEach(item -> { |
| 64 | item.setUserCount(recordDOs.size()); | 64 | item.setUserCount(recordDOs.size()); |
| @@ -115,8 +115,7 @@ public class CombinationRecordServiceImpl implements CombinationRecordService { | @@ -115,8 +115,7 @@ public class CombinationRecordServiceImpl implements CombinationRecordService { | ||
| 115 | // 2. 创建拼团记录 | 115 | // 2. 创建拼团记录 |
| 116 | CombinationRecordDO record = CombinationActivityConvert.INSTANCE.convert(reqDTO); | 116 | CombinationRecordDO record = CombinationActivityConvert.INSTANCE.convert(reqDTO); |
| 117 | record.setVirtualGroup(false); | 117 | record.setVirtualGroup(false); |
| 118 | - // TODO @puhui999:过期时间,应该是 Date 哈; | ||
| 119 | - record.setExpireTime(activity.getLimitDuration()); | 118 | + record.setExpireTime(record.getStartTime().plusHours(activity.getLimitDuration())); |
| 120 | record.setUserSize(activity.getUserSize()); | 119 | record.setUserSize(activity.getUserSize()); |
| 121 | recordMapper.insert(record); | 120 | recordMapper.insert(record); |
| 122 | } | 121 | } |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/SeckillActivityService.java
| @@ -34,6 +34,20 @@ public interface SeckillActivityService { | @@ -34,6 +34,20 @@ public interface SeckillActivityService { | ||
| 34 | void updateSeckillActivity(@Valid SeckillActivityUpdateReqVO updateReqVO); | 34 | void updateSeckillActivity(@Valid SeckillActivityUpdateReqVO updateReqVO); |
| 35 | 35 | ||
| 36 | /** | 36 | /** |
| 37 | + * 更新秒杀活动 | ||
| 38 | + * | ||
| 39 | + * @param activityDO 秒杀活动 | ||
| 40 | + */ | ||
| 41 | + void updateSeckillActivity(SeckillActivityDO activityDO); | ||
| 42 | + | ||
| 43 | + /** | ||
| 44 | + * 更新秒杀活动商品 | ||
| 45 | + * | ||
| 46 | + * @param productList 活动商品列表 | ||
| 47 | + */ | ||
| 48 | + void updateSeckillActivityProductList(List<SeckillProductDO> productList); | ||
| 49 | + | ||
| 50 | + /** | ||
| 37 | * 关闭秒杀活动 | 51 | * 关闭秒杀活动 |
| 38 | * | 52 | * |
| 39 | * @param id 编号 | 53 | * @param id 编号 |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/SeckillActivityServiceImpl.java
| @@ -79,8 +79,8 @@ public class SeckillActivityServiceImpl implements SeckillActivityService { | @@ -79,8 +79,8 @@ public class SeckillActivityServiceImpl implements SeckillActivityService { | ||
| 79 | * 1. 校验秒杀时段是否存在 | 79 | * 1. 校验秒杀时段是否存在 |
| 80 | * 2. 秒杀商品是否参加其它活动 | 80 | * 2. 秒杀商品是否参加其它活动 |
| 81 | * | 81 | * |
| 82 | - * @param configIds 秒杀时段数组 | ||
| 83 | - * @param spuId 商品 SPU 编号 | 82 | + * @param configIds 秒杀时段数组 |
| 83 | + * @param spuId 商品 SPU 编号 | ||
| 84 | * @param activityId 秒杀活动编号 | 84 | * @param activityId 秒杀活动编号 |
| 85 | */ | 85 | */ |
| 86 | private void validateProductConflict(List<Long> configIds, Long spuId, Long activityId) { | 86 | private void validateProductConflict(List<Long> configIds, Long spuId, Long activityId) { |
| @@ -92,15 +92,9 @@ public class SeckillActivityServiceImpl implements SeckillActivityService { | @@ -92,15 +92,9 @@ public class SeckillActivityServiceImpl implements SeckillActivityService { | ||
| 92 | if (activityId != null) { // 排除自己 | 92 | if (activityId != null) { // 排除自己 |
| 93 | activityList.removeIf(item -> ObjectUtil.equal(item.getId(), activityId)); | 93 | activityList.removeIf(item -> ObjectUtil.equal(item.getId(), activityId)); |
| 94 | } | 94 | } |
| 95 | - // TODO @puhui999:一个 spu,参与两个活动应该没关系,关键是活动时间不充能重叠; | ||
| 96 | - // 2.2 过滤出所有 spuId 有交集的活动,判断是否存在重叠 | ||
| 97 | - List<SeckillActivityDO> activityDOs1 = filterList(activityList, s -> ObjectUtil.equal(s.getSpuId(), spuId)); | ||
| 98 | - if (isNotEmpty(activityDOs1)) { | ||
| 99 | - throw exception(SECKILL_ACTIVITY_SPU_CONFLICTS); | ||
| 100 | - } | ||
| 101 | - // 2.3 过滤出所有 configIds 有交集的活动,判断是否存在重叠 | ||
| 102 | - List<SeckillActivityDO> activityDOs2 = filterList(activityList, s -> containsAny(s.getConfigIds(), configIds)); | ||
| 103 | - if (isNotEmpty(activityDOs2)) { | 95 | + // 2.2 过滤出所有 configIds 有交集的活动,判断是否存在重叠 |
| 96 | + List<SeckillActivityDO> conflictActivityList = filterList(activityList, s -> containsAny(s.getConfigIds(), configIds)); | ||
| 97 | + if (isNotEmpty(conflictActivityList)) { | ||
| 104 | throw exception(SECKILL_ACTIVITY_SPU_CONFLICTS); | 98 | throw exception(SECKILL_ACTIVITY_SPU_CONFLICTS); |
| 105 | } | 99 | } |
| 106 | } | 100 | } |
| @@ -108,7 +102,7 @@ public class SeckillActivityServiceImpl implements SeckillActivityService { | @@ -108,7 +102,7 @@ public class SeckillActivityServiceImpl implements SeckillActivityService { | ||
| 108 | /** | 102 | /** |
| 109 | * 校验秒杀商品是否都存在 | 103 | * 校验秒杀商品是否都存在 |
| 110 | * | 104 | * |
| 111 | - * @param spuId 商品 SPU 编号 | 105 | + * @param spuId 商品 SPU 编号 |
| 112 | * @param products 秒杀商品 | 106 | * @param products 秒杀商品 |
| 113 | */ | 107 | */ |
| 114 | private void validateProductExists(Long spuId, List<SeckillProductBaseVO> products) { | 108 | private void validateProductExists(Long spuId, List<SeckillProductBaseVO> products) { |
| @@ -150,11 +144,21 @@ public class SeckillActivityServiceImpl implements SeckillActivityService { | @@ -150,11 +144,21 @@ public class SeckillActivityServiceImpl implements SeckillActivityService { | ||
| 150 | updateSeckillProduct(updateObj, updateReqVO.getProducts()); | 144 | updateSeckillProduct(updateObj, updateReqVO.getProducts()); |
| 151 | } | 145 | } |
| 152 | 146 | ||
| 147 | + @Override | ||
| 148 | + public void updateSeckillActivity(SeckillActivityDO activityDO) { | ||
| 149 | + seckillActivityMapper.updateById(activityDO); | ||
| 150 | + } | ||
| 151 | + | ||
| 152 | + @Override | ||
| 153 | + public void updateSeckillActivityProductList(List<SeckillProductDO> productList) { | ||
| 154 | + seckillProductMapper.updateBatch(productList); | ||
| 155 | + } | ||
| 156 | + | ||
| 153 | /** | 157 | /** |
| 154 | * 更新秒杀商品 | 158 | * 更新秒杀商品 |
| 155 | * | 159 | * |
| 156 | * @param activity 秒杀活动 | 160 | * @param activity 秒杀活动 |
| 157 | - * @param products 该活动的最新商品配置 | 161 | + * @param products 该活动的最新商品配置 |
| 158 | */ | 162 | */ |
| 159 | private void updateSeckillProduct(SeckillActivityDO activity, List<SeckillProductBaseVO> products) { | 163 | private void updateSeckillProduct(SeckillActivityDO activity, List<SeckillProductBaseVO> products) { |
| 160 | // 第一步,对比新老数据,获得添加、修改、删除的列表 | 164 | // 第一步,对比新老数据,获得添加、修改、删除的列表 |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/util/PromotionUtils.java
| 1 | package cn.iocoder.yudao.module.promotion.util; | 1 | package cn.iocoder.yudao.module.promotion.util; |
| 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.util.collection.CollectionUtils; | ||
| 5 | import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils; | 4 | import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils; |
| 6 | -import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; | ||
| 7 | 5 | ||
| 8 | import java.time.LocalDateTime; | 6 | import java.time.LocalDateTime; |
| 9 | -import java.util.List; | ||
| 10 | -import java.util.Set; | ||
| 11 | -import java.util.function.Function; | ||
| 12 | - | ||
| 13 | -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | ||
| 14 | -import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.anyMatch; | ||
| 15 | -import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_NOT_EXISTS; | ||
| 16 | 7 | ||
| 17 | /** | 8 | /** |
| 18 | * 活动工具类 | 9 | * 活动工具类 |
| @@ -31,21 +22,4 @@ public class PromotionUtils { | @@ -31,21 +22,4 @@ public class PromotionUtils { | ||
| 31 | return LocalDateTimeUtils.beforeNow(endTime) ? CommonStatusEnum.DISABLE.getStatus() : CommonStatusEnum.ENABLE.getStatus(); | 22 | return LocalDateTimeUtils.beforeNow(endTime) ? CommonStatusEnum.DISABLE.getStatus() : CommonStatusEnum.ENABLE.getStatus(); |
| 32 | } | 23 | } |
| 33 | 24 | ||
| 34 | - /** | ||
| 35 | - * 校验商品 sku 是否都存在 | ||
| 36 | - * | ||
| 37 | - * @param skus 数据库中的商品 skus | ||
| 38 | - * @param products 需要校验的商品 | ||
| 39 | - * @param func 获取需要校验的商品的 skuId | ||
| 40 | - */ | ||
| 41 | - public static <T> void validateProductSkuAllExists(List<ProductSkuRespDTO> skus, List<T> products, Function<T, Long> func) { | ||
| 42 | - // 校验 sku 个数是否一致 | ||
| 43 | - Set<Long> skuIdsSet = CollectionUtils.convertSet(products, func); | ||
| 44 | - Set<Long> skuIdsSet1 = CollectionUtils.convertSet(skus, ProductSkuRespDTO::getId); | ||
| 45 | - // 校验 skuId 是否存在 | ||
| 46 | - if (anyMatch(skuIdsSet, s -> !skuIdsSet1.contains(s))) { | ||
| 47 | - throw exception(SKU_NOT_EXISTS); | ||
| 48 | - } | ||
| 49 | - } | ||
| 50 | - | ||
| 51 | } | 25 | } |
yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/api/brokerage/BrokerageApi.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.trade.api.brokerage; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.module.trade.api.brokerage.dto.BrokerageUserDTO; | ||
| 4 | + | ||
| 5 | +/** | ||
| 6 | + * 分销 API 接口 | ||
| 7 | + * | ||
| 8 | + * @author owen | ||
| 9 | + */ | ||
| 10 | +public interface BrokerageApi { | ||
| 11 | + | ||
| 12 | + /** | ||
| 13 | + * 获得分销用户 | ||
| 14 | + * | ||
| 15 | + * @param userId 用户编号 | ||
| 16 | + * @return 分销用户信息 | ||
| 17 | + */ | ||
| 18 | + BrokerageUserDTO getBrokerageUser(Long userId); | ||
| 19 | + | ||
| 20 | + /** | ||
| 21 | + * 绑定推广员 | ||
| 22 | + * | ||
| 23 | + * @param userId 用户编号 | ||
| 24 | + * @param bindUserId 推广员编号 | ||
| 25 | + * @param isNewUser 是否为新用户 | ||
| 26 | + * @return 是否绑定 | ||
| 27 | + */ | ||
| 28 | + boolean bindUser(Long userId, Long bindUserId, Boolean isNewUser); | ||
| 29 | +} |
yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/api/brokerage/dto/BrokerageUserDTO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.trade.api.brokerage.dto; | ||
| 2 | + | ||
| 3 | +import lombok.Data; | ||
| 4 | + | ||
| 5 | +import java.time.LocalDateTime; | ||
| 6 | + | ||
| 7 | +/** | ||
| 8 | + * 分销用户 DTO | ||
| 9 | + * | ||
| 10 | + * @author owen | ||
| 11 | + */ | ||
| 12 | +@Data | ||
| 13 | +public class BrokerageUserDTO { | ||
| 14 | + | ||
| 15 | + /** | ||
| 16 | + * 用户编号 | ||
| 17 | + * <p> | ||
| 18 | + * 对应 MemberUserDO 的 id 字段 | ||
| 19 | + */ | ||
| 20 | + private Long id; | ||
| 21 | + | ||
| 22 | + /** | ||
| 23 | + * 推广员编号 | ||
| 24 | + * <p> | ||
| 25 | + * 关联 MemberUserDO 的 id 字段 | ||
| 26 | + */ | ||
| 27 | + private Long bindUserId; | ||
| 28 | + /** | ||
| 29 | + * 推广员绑定时间 | ||
| 30 | + */ | ||
| 31 | + private LocalDateTime bindUserTime; | ||
| 32 | + | ||
| 33 | + /** | ||
| 34 | + * 推广资格 | ||
| 35 | + */ | ||
| 36 | + private Boolean brokerageEnabled; | ||
| 37 | + /** | ||
| 38 | + * 成为分销员时间 | ||
| 39 | + */ | ||
| 40 | + private LocalDateTime brokerageTime; | ||
| 41 | + | ||
| 42 | + /** | ||
| 43 | + * 可用佣金 | ||
| 44 | + */ | ||
| 45 | + private Integer price; | ||
| 46 | + /** | ||
| 47 | + * 冻结佣金 | ||
| 48 | + */ | ||
| 49 | + private Integer frozenPrice; | ||
| 50 | + | ||
| 51 | +} |
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 模块 1-011-000-000 ========== | 14 | + // ========== Order 模块 1-011-000-000 ========== |
| 15 | ErrorCode ORDER_CREATE_SKU_NOT_FOUND = new ErrorCode(1_011_000_001, "商品 SKU 不存在"); | 15 | ErrorCode ORDER_CREATE_SKU_NOT_FOUND = new ErrorCode(1_011_000_001, "商品 SKU 不存在"); |
| 16 | ErrorCode ORDER_CREATE_SPU_NOT_SALE = new ErrorCode(1_011_000_002, "商品 SPU 不可售卖"); | 16 | ErrorCode ORDER_CREATE_SPU_NOT_SALE = new ErrorCode(1_011_000_002, "商品 SPU 不可售卖"); |
| 17 | ErrorCode ORDER_CREATE_SKU_STOCK_NOT_ENOUGH = new ErrorCode(1_011_000_004, "商品 SKU 库存不足"); | 17 | ErrorCode ORDER_CREATE_SKU_STOCK_NOT_ENOUGH = new ErrorCode(1_011_000_004, "商品 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(1_011_000_024, "交易订单发货失败,发货类型不是快递"); | 35 | ErrorCode ORDER_DELIVERY_FAIL_DELIVERY_TYPE_NOT_EXPRESS = new ErrorCode(1_011_000_024, "交易订单发货失败,发货类型不是快递"); |
| 36 | ErrorCode ORDER_CANCEL_FAIL_STATUS_NOT_UNPAID = new ErrorCode(1_011_000_025, "交易订单取消失败,订单不是【待支付】状态"); | 36 | ErrorCode ORDER_CANCEL_FAIL_STATUS_NOT_UNPAID = new ErrorCode(1_011_000_025, "交易订单取消失败,订单不是【待支付】状态"); |
| 37 | 37 | ||
| 38 | - // ========== After Sale 模块 1-011-000-100 ========== | 38 | + // ========== After Sale 模块 1-011-000-100 ========== |
| 39 | ErrorCode AFTER_SALE_NOT_FOUND = new ErrorCode(1_011_000_100, "售后单不存在"); | 39 | ErrorCode AFTER_SALE_NOT_FOUND = new ErrorCode(1_011_000_100, "售后单不存在"); |
| 40 | ErrorCode AFTER_SALE_CREATE_FAIL_REFUND_PRICE_ERROR = new ErrorCode(1_011_000_101, "申请退款金额错误"); | 40 | ErrorCode AFTER_SALE_CREATE_FAIL_REFUND_PRICE_ERROR = new ErrorCode(1_011_000_101, "申请退款金额错误"); |
| 41 | ErrorCode AFTER_SALE_CREATE_FAIL_ORDER_STATUS_CANCELED = new ErrorCode(1_011_000_102, "订单已关闭,无法申请售后"); | 41 | ErrorCode AFTER_SALE_CREATE_FAIL_ORDER_STATUS_CANCELED = new ErrorCode(1_011_000_102, "订单已关闭,无法申请售后"); |
| @@ -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(1_011_000_111, "取消售后单失败,售后单状态不是【待审核】或【卖家同意】或【商家待收货】"); | 51 | new ErrorCode(1_011_000_111, "取消售后单失败,售后单状态不是【待审核】或【卖家同意】或【商家待收货】"); |
| 52 | 52 | ||
| 53 | - // ========== Cart 模块 1-011-002-000 ========== | 53 | + // ========== Cart 模块 1-011-002-000 ========== |
| 54 | ErrorCode CARD_ITEM_NOT_FOUND = new ErrorCode(1_011_002_000, "购物车项不存在"); | 54 | ErrorCode CARD_ITEM_NOT_FOUND = new ErrorCode(1_011_002_000, "购物车项不存在"); |
| 55 | 55 | ||
| 56 | // ========== Price 相关 1-011-003-000 ============ | 56 | // ========== Price 相关 1-011-003-000 ============ |
| @@ -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(1_011_003_001, "计算快递运费异常,收件人地址编号为空"); | 58 | ErrorCode PRICE_CALCULATE_DELIVERY_PRICE_USER_ADDR_IS_EMPTY = new ErrorCode(1_011_003_001, "计算快递运费异常,收件人地址编号为空"); |
| 59 | ErrorCode PRICE_CALCULATE_DELIVERY_PRICE_TEMPLATE_NOT_FOUND = new ErrorCode(1_011_003_002, "计算快递运费异常,找不到对应的运费模板"); | 59 | ErrorCode PRICE_CALCULATE_DELIVERY_PRICE_TEMPLATE_NOT_FOUND = new ErrorCode(1_011_003_002, "计算快递运费异常,找不到对应的运费模板"); |
| 60 | 60 | ||
| 61 | - // ========== 物流 Express 模块 1-011-004-000 ========== | 61 | + // ========== 物流 Express 模块 1-011-004-000 ========== |
| 62 | ErrorCode EXPRESS_NOT_EXISTS = new ErrorCode(1_011_004_000, "快递公司不存在"); | 62 | ErrorCode EXPRESS_NOT_EXISTS = new ErrorCode(1_011_004_000, "快递公司不存在"); |
| 63 | ErrorCode EXPRESS_CODE_DUPLICATE = new ErrorCode(1_011_004_001, "已经存在该编码的快递公司"); | 63 | ErrorCode EXPRESS_CODE_DUPLICATE = new ErrorCode(1_011_004_001, "已经存在该编码的快递公司"); |
| 64 | ErrorCode EXPRESS_CLIENT_NOT_PROVIDE = new ErrorCode(1_011_004_002, "需要接入快递服务商,比如【快递100】"); | 64 | ErrorCode EXPRESS_CLIENT_NOT_PROVIDE = new ErrorCode(1_011_004_002, "需要接入快递服务商,比如【快递100】"); |
| @@ -67,11 +67,21 @@ public interface ErrorCodeConstants { | @@ -67,11 +67,21 @@ public interface ErrorCodeConstants { | ||
| 67 | ErrorCode EXPRESS_API_QUERY_ERROR = new ErrorCode(1_011_004_101, "快递查询接口异常"); | 67 | ErrorCode EXPRESS_API_QUERY_ERROR = new ErrorCode(1_011_004_101, "快递查询接口异常"); |
| 68 | ErrorCode EXPRESS_API_QUERY_FAILED = new ErrorCode(1_011_004_102, "快递查询返回失败,原因:{}"); | 68 | ErrorCode EXPRESS_API_QUERY_FAILED = new ErrorCode(1_011_004_102, "快递查询返回失败,原因:{}"); |
| 69 | 69 | ||
| 70 | - // ========== 物流 Template 模块 1-011-005-000 ========== | 70 | + // ========== 物流 Template 模块 1-011-005-000 ========== |
| 71 | ErrorCode EXPRESS_TEMPLATE_NAME_DUPLICATE = new ErrorCode(1_011_005_000, "已经存在该运费模板名"); | 71 | ErrorCode EXPRESS_TEMPLATE_NAME_DUPLICATE = new ErrorCode(1_011_005_000, "已经存在该运费模板名"); |
| 72 | ErrorCode EXPRESS_TEMPLATE_NOT_EXISTS = new ErrorCode(1_011_005_001, "运费模板不存在"); | 72 | ErrorCode EXPRESS_TEMPLATE_NOT_EXISTS = new ErrorCode(1_011_005_001, "运费模板不存在"); |
| 73 | 73 | ||
| 74 | // ========== 物流 PICK_UP 模块 1-011-006-000 ========== | 74 | // ========== 物流 PICK_UP 模块 1-011-006-000 ========== |
| 75 | ErrorCode PICK_UP_STORE_NOT_EXISTS = new ErrorCode(1_011_006_000, "自提门店不存在"); | 75 | ErrorCode PICK_UP_STORE_NOT_EXISTS = new ErrorCode(1_011_006_000, "自提门店不存在"); |
| 76 | 76 | ||
| 77 | + // ========== 分销用户 模块 1011007000 ========== | ||
| 78 | + ErrorCode BROKERAGE_USER_NOT_EXISTS = new ErrorCode(1011007000, "分销用户不存在"); | ||
| 79 | + ErrorCode BROKERAGE_USER_FROZEN_PRICE_NOT_ENOUGH = new ErrorCode(1011007001, "用户冻结佣金({})数量不足"); | ||
| 80 | + ErrorCode BROKERAGE_BIND_SELF = new ErrorCode(1011007002, "不能绑定自己"); | ||
| 81 | + ErrorCode BROKERAGE_BIND_USER_NOT_ENABLED = new ErrorCode(1011007003, "绑定用户没有推广资格"); | ||
| 82 | + ErrorCode BROKERAGE_BIND_CONDITION_ADMIN = new ErrorCode(1011007004, "仅可在后台绑定推广员"); | ||
| 83 | + ErrorCode BROKERAGE_BIND_MODE_REGISTER = new ErrorCode(1011007005, "只有在注册时可以绑定"); | ||
| 84 | + ErrorCode BROKERAGE_BIND_OVERRIDE = new ErrorCode(1011007006, "已绑定了推广人"); | ||
| 85 | + ErrorCode BROKERAGE_BIND_LOOP = new ErrorCode(1011007007, "下级不能绑定自己的上级"); | ||
| 86 | + | ||
| 77 | } | 87 | } |
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 | + /** | ||
| 19 | + * 只要用户没有推广人,随时都可以绑定分销关系 | ||
| 20 | + */ | ||
| 21 | + ANYTIME(1, "没有推广人"), | ||
| 22 | + /** | ||
| 23 | + * 仅新用户注册时才能绑定推广关系 | ||
| 24 | + */ | ||
| 25 | + REGISTER(2, "新用户"), | ||
| 26 | + /** | ||
| 27 | + * 每次扫码都覆盖 | ||
| 28 | + */ | ||
| 29 | + OVERRIDE(3, "扫码覆盖"), | ||
| 30 | + ; | ||
| 31 | + | ||
| 32 | + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(BrokerageBindModeEnum::getMode).toArray(); | ||
| 33 | + | ||
| 34 | + /** | ||
| 35 | + * 模式 | ||
| 36 | + */ | ||
| 37 | + private final Integer mode; | ||
| 38 | + /** | ||
| 39 | + * 名字 | ||
| 40 | + */ | ||
| 41 | + private final String name; | ||
| 42 | + | ||
| 43 | + @Override | ||
| 44 | + public int[] array() { | ||
| 45 | + return ARRAYS; | ||
| 46 | + } | ||
| 47 | + | ||
| 48 | +} |
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 | + /** | ||
| 19 | + * 所有用户都可以分销 | ||
| 20 | + */ | ||
| 21 | + ALL(1, "人人分销"), | ||
| 22 | + /** | ||
| 23 | + * 仅可后台手动设置推广员 | ||
| 24 | + */ | ||
| 25 | + ADMIN(2, "指定分销"), | ||
| 26 | + ; | ||
| 27 | + | ||
| 28 | + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(BrokerageEnabledConditionEnum::getCondition).toArray(); | ||
| 29 | + | ||
| 30 | + /** | ||
| 31 | + * 模式 | ||
| 32 | + */ | ||
| 33 | + private final Integer condition; | ||
| 34 | + /** | ||
| 35 | + * 名字 | ||
| 36 | + */ | ||
| 37 | + private final String name; | ||
| 38 | + | ||
| 39 | + @Override | ||
| 40 | + public int[] array() { | ||
| 41 | + return ARRAYS; | ||
| 42 | + } | ||
| 43 | + | ||
| 44 | +} |
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 | + ORDER(1, "获得推广佣金", "获得推广佣金 {}", true), | ||
| 19 | + WITHDRAW(2, "提现申请", "提现申请扣除佣金 {}", false), | ||
| 20 | + ; | ||
| 21 | + | ||
| 22 | + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(BrokerageRecordBizTypeEnum::getType).toArray(); | ||
| 23 | + | ||
| 24 | + /** | ||
| 25 | + * 类型 | ||
| 26 | + */ | ||
| 27 | + private final Integer type; | ||
| 28 | + /** | ||
| 29 | + * 标题 | ||
| 30 | + */ | ||
| 31 | + private final String title; | ||
| 32 | + /** | ||
| 33 | + * 描述 | ||
| 34 | + */ | ||
| 35 | + private final String description; | ||
| 36 | + /** | ||
| 37 | + * 是否为增加佣金 | ||
| 38 | + */ | ||
| 39 | + private final boolean add; | ||
| 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/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 | ||
| @@ -82,6 +86,11 @@ | @@ -82,6 +86,11 @@ | ||
| 82 | <artifactId>yudao-spring-boot-starter-mybatis</artifactId> | 86 | <artifactId>yudao-spring-boot-starter-mybatis</artifactId> |
| 83 | </dependency> | 87 | </dependency> |
| 84 | 88 | ||
| 89 | + <dependency> | ||
| 90 | + <groupId>cn.iocoder.boot</groupId> | ||
| 91 | + <artifactId>yudao-spring-boot-starter-redis</artifactId> | ||
| 92 | + </dependency> | ||
| 93 | + | ||
| 85 | <!-- Test 测试相关 --> | 94 | <!-- Test 测试相关 --> |
| 86 | <dependency> | 95 | <dependency> |
| 87 | <groupId>cn.iocoder.boot</groupId> | 96 | <groupId>cn.iocoder.boot</groupId> |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/api/brokerage/BrokerageApiImpl.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.trade.api.brokerage; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.module.trade.api.brokerage.dto.BrokerageUserDTO; | ||
| 4 | +import cn.iocoder.yudao.module.trade.convert.brokerage.user.BrokerageUserConvert; | ||
| 5 | +import cn.iocoder.yudao.module.trade.service.brokerage.user.BrokerageUserService; | ||
| 6 | +import org.springframework.stereotype.Service; | ||
| 7 | +import org.springframework.validation.annotation.Validated; | ||
| 8 | + | ||
| 9 | +import javax.annotation.Resource; | ||
| 10 | + | ||
| 11 | +/** | ||
| 12 | + * 分销 API 接口实现类 | ||
| 13 | + * | ||
| 14 | + * @author owen | ||
| 15 | + */ | ||
| 16 | +@Service | ||
| 17 | +@Validated | ||
| 18 | +public class BrokerageApiImpl implements BrokerageApi { | ||
| 19 | + | ||
| 20 | + @Resource | ||
| 21 | + private BrokerageUserService brokerageUserService; | ||
| 22 | + | ||
| 23 | + @Override | ||
| 24 | + public BrokerageUserDTO getBrokerageUser(Long userId) { | ||
| 25 | + return BrokerageUserConvert.INSTANCE.convertDTO(brokerageUserService.getBrokerageUser(userId)); | ||
| 26 | + } | ||
| 27 | + | ||
| 28 | + @Override | ||
| 29 | + public boolean bindUser(Long userId, Long bindUserId, Boolean isNewUser) { | ||
| 30 | + return brokerageUserService.bindBrokerageUser(userId, bindUserId, isNewUser); | ||
| 31 | + } | ||
| 32 | + | ||
| 33 | +} |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/TradeAfterSaleController.java
| @@ -76,6 +76,11 @@ public class TradeAfterSaleController { | @@ -76,6 +76,11 @@ public class TradeAfterSaleController { | ||
| 76 | public CommonResult<TradeAfterSaleDetailRespVO> getOrderDetail(@RequestParam("id") Long id) { | 76 | public CommonResult<TradeAfterSaleDetailRespVO> getOrderDetail(@RequestParam("id") Long id) { |
| 77 | // 查询订单 | 77 | // 查询订单 |
| 78 | TradeAfterSaleDO afterSale = afterSaleService.getAfterSale(id); | 78 | TradeAfterSaleDO afterSale = afterSaleService.getAfterSale(id); |
| 79 | + // TODO @puhui999:这里建议改成,如果为 null,直接返回 success null;主要查询操作,尽量不要有非空的提示哈;交给前端处理; | ||
| 80 | +// if (afterSale == null) { | ||
| 81 | +// return success(null, AFTER_SALE_NOT_FOUND.getMsg()); | ||
| 82 | +// } | ||
| 83 | + | ||
| 79 | // 查询订单 | 84 | // 查询订单 |
| 80 | TradeOrderDO order = tradeOrderQueryService.getOrder(afterSale.getOrderId()); | 85 | TradeOrderDO order = tradeOrderQueryService.getOrder(afterSale.getOrderId()); |
| 81 | // 查询订单项 | 86 | // 查询订单项 |
| @@ -92,7 +97,11 @@ public class TradeAfterSaleController { | @@ -92,7 +97,11 @@ public class TradeAfterSaleController { | ||
| 92 | TradeAfterSaleLogRespDTO respVO = new TradeAfterSaleLogRespDTO(); | 97 | TradeAfterSaleLogRespDTO respVO = new TradeAfterSaleLogRespDTO(); |
| 93 | respVO.setId((long) i); | 98 | respVO.setId((long) i); |
| 94 | respVO.setUserId((long) i); | 99 | respVO.setUserId((long) i); |
| 95 | - respVO.setUserType(1); | 100 | + respVO.setUserType(i % 2 == 0 ? 2 : 1); |
| 101 | + // 模拟系统操作 | ||
| 102 | + if (i == 2) { | ||
| 103 | + respVO.setUserType(3); | ||
| 104 | + } | ||
| 96 | respVO.setAfterSaleId(id); | 105 | respVO.setAfterSaleId(id); |
| 97 | respVO.setOrderId((long) i); | 106 | respVO.setOrderId((long) i); |
| 98 | respVO.setOrderItemId((long) i); | 107 | respVO.setOrderItemId((long) i); |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/aftersale/vo/TradeAfterSaleDetailRespVO.java
| @@ -35,7 +35,7 @@ public class TradeAfterSaleDetailRespVO extends TradeAfterSaleBaseVO { | @@ -35,7 +35,7 @@ public class TradeAfterSaleDetailRespVO extends TradeAfterSaleBaseVO { | ||
| 35 | /** | 35 | /** |
| 36 | * 售后日志 | 36 | * 售后日志 |
| 37 | */ | 37 | */ |
| 38 | - private List<TradeAfterSaleLogRespVO> afterSaleLog; | 38 | + private List<TradeAfterSaleLogRespVO> logs; |
| 39 | 39 | ||
| 40 | @Schema(description = "管理后台 - 交易订单的详情的订单项目") | 40 | @Schema(description = "管理后台 - 交易订单的详情的订单项目") |
| 41 | @Data | 41 | @Data |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/record/BrokerageRecordController.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.BrokerageRecordPageReqVO; | ||
| 6 | +import cn.iocoder.yudao.module.trade.controller.admin.brokerage.record.vo.BrokerageRecordRespVO; | ||
| 7 | +import cn.iocoder.yudao.module.trade.convert.brokerage.record.BrokerageRecordConvert; | ||
| 8 | +import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.record.BrokerageRecordDO; | ||
| 9 | +import cn.iocoder.yudao.module.trade.service.brokerage.record.BrokerageRecordService; | ||
| 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 BrokerageRecordController { | ||
| 30 | + | ||
| 31 | + @Resource | ||
| 32 | + private BrokerageRecordService brokerageRecordService; | ||
| 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<BrokerageRecordRespVO> getBrokerageRecord(@RequestParam("id") Integer id) { | ||
| 39 | + BrokerageRecordDO brokerageRecord = brokerageRecordService.getBrokerageRecord(id); | ||
| 40 | + return success(BrokerageRecordConvert.INSTANCE.convert(brokerageRecord)); | ||
| 41 | + } | ||
| 42 | + | ||
| 43 | + @GetMapping("/page") | ||
| 44 | + @Operation(summary = "获得佣金记录分页") | ||
| 45 | + @PreAuthorize("@ss.hasPermission('trade:brokerage-record:query')") | ||
| 46 | + public CommonResult<PageResult<BrokerageRecordRespVO>> getBrokerageRecordPage(@Valid BrokerageRecordPageReqVO pageVO) { | ||
| 47 | + PageResult<BrokerageRecordDO> pageResult = brokerageRecordService.getBrokerageRecordPage(pageVO); | ||
| 48 | + return success(BrokerageRecordConvert.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/BrokerageRecordBaseVO.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 BrokerageRecordBaseVO { | ||
| 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/BrokerageRecordPageReqVO.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 BrokerageRecordPageReqVO 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/BrokerageRecordRespVO.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 BrokerageRecordRespVO extends BrokerageRecordBaseVO { | ||
| 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/BrokerageUserController.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.member.api.user.MemberUserApi; | ||
| 6 | +import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; | ||
| 7 | +import cn.iocoder.yudao.module.trade.controller.admin.brokerage.user.vo.*; | ||
| 8 | +import cn.iocoder.yudao.module.trade.convert.brokerage.user.BrokerageUserConvert; | ||
| 9 | +import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.user.BrokerageUserDO; | ||
| 10 | +import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordBizTypeEnum; | ||
| 11 | +import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordStatusEnum; | ||
| 12 | +import cn.iocoder.yudao.module.trade.service.brokerage.record.BrokerageRecordService; | ||
| 13 | +import cn.iocoder.yudao.module.trade.service.brokerage.bo.UserBrokerageSummaryBO; | ||
| 14 | +import cn.iocoder.yudao.module.trade.service.brokerage.user.BrokerageUserService; | ||
| 15 | +import io.swagger.v3.oas.annotations.Operation; | ||
| 16 | +import io.swagger.v3.oas.annotations.Parameter; | ||
| 17 | +import io.swagger.v3.oas.annotations.tags.Tag; | ||
| 18 | +import org.springframework.security.access.prepost.PreAuthorize; | ||
| 19 | +import org.springframework.validation.annotation.Validated; | ||
| 20 | +import org.springframework.web.bind.annotation.*; | ||
| 21 | + | ||
| 22 | +import javax.annotation.Resource; | ||
| 23 | +import javax.validation.Valid; | ||
| 24 | +import java.util.Map; | ||
| 25 | +import java.util.Set; | ||
| 26 | + | ||
| 27 | +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | ||
| 28 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; | ||
| 29 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; | ||
| 30 | + | ||
| 31 | +@Tag(name = "管理后台 - 分销用户") | ||
| 32 | +@RestController | ||
| 33 | +@RequestMapping("/trade/brokerage-user") | ||
| 34 | +@Validated | ||
| 35 | +public class BrokerageUserController { | ||
| 36 | + | ||
| 37 | + @Resource | ||
| 38 | + private BrokerageUserService brokerageUserService; | ||
| 39 | + @Resource | ||
| 40 | + private BrokerageRecordService brokerageRecordService; | ||
| 41 | + | ||
| 42 | + @Resource | ||
| 43 | + private MemberUserApi memberUserApi; | ||
| 44 | + | ||
| 45 | + @PutMapping("/update-brokerage-user") | ||
| 46 | + @Operation(summary = "修改推广员") | ||
| 47 | + @PreAuthorize("@ss.hasPermission('trade:brokerage-user:update-brokerage-user')") | ||
| 48 | + public CommonResult<Boolean> updateBrokerageUser(@Valid @RequestBody BrokerageUserUpdateBrokerageUserReqVO updateReqVO) { | ||
| 49 | + brokerageUserService.updateBrokerageUserId(updateReqVO.getId(), updateReqVO.getBindUserId()); | ||
| 50 | + return success(true); | ||
| 51 | + } | ||
| 52 | + | ||
| 53 | + @PutMapping("/clear-brokerage-user") | ||
| 54 | + @Operation(summary = "清除推广员") | ||
| 55 | + @PreAuthorize("@ss.hasPermission('trade:brokerage-user:clear-brokerage-user')") | ||
| 56 | + public CommonResult<Boolean> clearBrokerageUser(@Valid @RequestBody BrokerageUserClearBrokerageUserReqVO updateReqVO) { | ||
| 57 | + brokerageUserService.updateBrokerageUserId(updateReqVO.getId(), null); | ||
| 58 | + return success(true); | ||
| 59 | + } | ||
| 60 | + | ||
| 61 | + @PutMapping("/update-brokerage-enable") | ||
| 62 | + @Operation(summary = "修改推广资格") | ||
| 63 | + @PreAuthorize("@ss.hasPermission('trade:brokerage-user:update-brokerage-enable')") | ||
| 64 | + public CommonResult<Boolean> updateBrokerageEnabled(@Valid @RequestBody BrokerageUserUpdateBrokerageEnabledReqVO updateReqVO) { | ||
| 65 | + brokerageUserService.updateBrokerageUserEnabled(updateReqVO.getId(), updateReqVO.getEnabled()); | ||
| 66 | + return success(true); | ||
| 67 | + } | ||
| 68 | + | ||
| 69 | + @GetMapping("/get") | ||
| 70 | + @Operation(summary = "获得分销用户") | ||
| 71 | + @Parameter(name = "id", description = "编号", required = true, example = "1024") | ||
| 72 | + @PreAuthorize("@ss.hasPermission('trade:brokerage-user:query')") | ||
| 73 | + public CommonResult<BrokerageUserRespVO> getBrokerageUser(@RequestParam("id") Long id) { | ||
| 74 | + BrokerageUserDO brokerageUser = brokerageUserService.getBrokerageUser(id); | ||
| 75 | + return success(BrokerageUserConvert.INSTANCE.convert(brokerageUser)); | ||
| 76 | + } | ||
| 77 | + | ||
| 78 | + @GetMapping("/page") | ||
| 79 | + @Operation(summary = "获得分销用户分页") | ||
| 80 | + @PreAuthorize("@ss.hasPermission('trade:brokerage-user:query')") | ||
| 81 | + public CommonResult<PageResult<BrokerageUserRespVO>> getBrokerageUserPage(@Valid BrokerageUserPageReqVO pageVO) { | ||
| 82 | + // 分页查询 | ||
| 83 | + PageResult<BrokerageUserDO> pageResult = brokerageUserService.getBrokerageUserPage(pageVO); | ||
| 84 | + | ||
| 85 | + // 涉及到的用户 | ||
| 86 | + Set<Long> userIds = convertSet(pageResult.getList(), BrokerageUserDO::getId); | ||
| 87 | + // 查询用户信息 | ||
| 88 | + Map<Long, MemberUserRespDTO> userMap = memberUserApi.getUserMap(userIds); | ||
| 89 | + // 合计分佣订单 | ||
| 90 | + Map<Long, UserBrokerageSummaryBO> userOrderSummaryMap = convertMap(userIds, | ||
| 91 | + userId -> userId, | ||
| 92 | + userId -> brokerageRecordService.getUserBrokerageSummaryByUserId(userId, | ||
| 93 | + BrokerageRecordBizTypeEnum.ORDER.getType(), BrokerageRecordStatusEnum.SETTLEMENT.getStatus())); | ||
| 94 | + // 合计推广用户数量 | ||
| 95 | + Map<Long, Long> brokerageUserCountMap = convertMap(userIds, | ||
| 96 | + userId -> userId, | ||
| 97 | + userId -> brokerageUserService.getBrokerageUserCountByBindUserId(userId)); | ||
| 98 | + | ||
| 99 | + // todo 合计提现 | ||
| 100 | + | ||
| 101 | + return success(BrokerageUserConvert.INSTANCE.convertPage(pageResult, userMap, brokerageUserCountMap, userOrderSummaryMap)); | ||
| 102 | + } | ||
| 103 | + | ||
| 104 | +} |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/user/vo/BrokerageUserBaseVO.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 BrokerageUserBaseVO { | ||
| 18 | + | ||
| 19 | + @Schema(description = "推广员编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "4587") | ||
| 20 | + @NotNull(message = "推广员编号不能为空") | ||
| 21 | + private Long bindUserId; | ||
| 22 | + | ||
| 23 | + @Schema(description = "推广员绑定时间") | ||
| 24 | + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | ||
| 25 | + private LocalDateTime bindUserTime; | ||
| 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 price; | ||
| 38 | + | ||
| 39 | + @Schema(description = "冻结佣金", requiredMode = Schema.RequiredMode.REQUIRED, example = "30916") | ||
| 40 | + @NotNull(message = "冻结佣金不能为空") | ||
| 41 | + private Integer frozenPrice; | ||
| 42 | + | ||
| 43 | +} |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/user/vo/BrokerageUserClearBrokerageUserReqVO.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 BrokerageUserClearBrokerageUserReqVO { | ||
| 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/BrokerageUserPageReqVO.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 BrokerageUserPageReqVO extends PageParam { | ||
| 19 | + | ||
| 20 | + @Schema(description = "推广员编号", example = "4587") | ||
| 21 | + private Long bindUserId; | ||
| 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/BrokerageUserRespVO.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 BrokerageUserRespVO extends BrokerageUserBaseVO { | ||
| 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 | + // ========== 用户信息 ========== | ||
| 23 | + | ||
| 24 | + @Schema(description = "用户头像", example = "https://www.iocoder.cn/xxx.png") | ||
| 25 | + private String avatar; | ||
| 26 | + @Schema(description = "用户昵称", example = "李四") | ||
| 27 | + private String nickname; | ||
| 28 | + | ||
| 29 | + // ========== 推广信息 ========== | ||
| 30 | + | ||
| 31 | + @Schema(description = "推广用户数量(一级)", example = "20019") | ||
| 32 | + private Integer brokerageUserCount; | ||
| 33 | + @Schema(description = "推广订单数量", example = "20019") | ||
| 34 | + private Integer brokerageOrderCount; | ||
| 35 | + @Schema(description = "推广订单金额", example = "20019") | ||
| 36 | + private Integer brokerageOrderPrice; | ||
| 37 | + | ||
| 38 | + // ========== 提现信息 ========== | ||
| 39 | + | ||
| 40 | + @Schema(description = "已提现金额", example = "20019") | ||
| 41 | + private Integer withdrawPrice; | ||
| 42 | + @Schema(description = "已提现次数", example = "20019") | ||
| 43 | + private Integer withdrawCount; | ||
| 44 | + | ||
| 45 | +} |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/user/vo/BrokerageUserUpdateBrokerageEnabledReqVO.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 BrokerageUserUpdateBrokerageEnabledReqVO { | ||
| 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) | ||
| 19 | + @NotNull(message = "推广资格不能为空") | ||
| 20 | + private Boolean enabled; | ||
| 21 | + | ||
| 22 | +} |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/user/vo/BrokerageUserUpdateBrokerageUserReqVO.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 BrokerageUserUpdateBrokerageUserReqVO { | ||
| 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 bindUserId; | ||
| 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 | + @Schema(description = "提现银行", requiredMode = Schema.RequiredMode.REQUIRED, example = "[0, 1]") | ||
| 58 | + @NotEmpty(message = "提现银行不能为空") | ||
| 59 | + private List<Integer> brokerageBankNames; | ||
| 60 | + | ||
| 61 | + @Schema(description = "佣金冻结时间(天)", requiredMode = Schema.RequiredMode.REQUIRED, example = "7") | ||
| 62 | + @NotNull(message = "佣金冻结时间(天)不能为空") | ||
| 63 | + @PositiveOrZero(message = "佣金冻结时间不能是负数") | ||
| 64 | + private Integer brokerageFrozenDays; | ||
| 65 | + | ||
| 66 | + @Schema(description = "提现方式", requiredMode = Schema.RequiredMode.REQUIRED, example = "[0, 1]") | ||
| 67 | + @NotNull(message = "提现方式不能为空") | ||
| 68 | + @InEnum(value = BrokerageWithdrawTypeEnum.class, message = "提现方式必须是 {value}") | ||
| 69 | + private List<Integer> brokerageWithdrawType; | ||
| 70 | + | ||
| 71 | +} |
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/admin/order/TradeOrderController.java
| @@ -67,6 +67,11 @@ public class TradeOrderController { | @@ -67,6 +67,11 @@ public class TradeOrderController { | ||
| 67 | public CommonResult<TradeOrderDetailRespVO> getOrderDetail(@RequestParam("id") Long id) { | 67 | public CommonResult<TradeOrderDetailRespVO> getOrderDetail(@RequestParam("id") Long id) { |
| 68 | // 查询订单 | 68 | // 查询订单 |
| 69 | TradeOrderDO order = tradeOrderQueryService.getOrder(id); | 69 | TradeOrderDO order = tradeOrderQueryService.getOrder(id); |
| 70 | + // TODO @puhui999:这里建议改成,如果为 null,直接返回 success null;主要查询操作,尽量不要有非空的提示哈;交给前端处理; | ||
| 71 | +// if (order == null) { | ||
| 72 | +// return success(null, ORDER_NOT_FOUND.getMsg()); | ||
| 73 | +// } | ||
| 74 | + | ||
| 70 | // 查询订单项 | 75 | // 查询订单项 |
| 71 | List<TradeOrderItemDO> orderItems = tradeOrderQueryService.getOrderItemListByOrderId(id); | 76 | List<TradeOrderItemDO> orderItems = tradeOrderQueryService.getOrderItemListByOrderId(id); |
| 72 | // orderLog | 77 | // orderLog |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderDetailRespVO.java
| @@ -26,24 +26,23 @@ public class TradeOrderDetailRespVO extends TradeOrderBaseVO { | @@ -26,24 +26,23 @@ public class TradeOrderDetailRespVO extends TradeOrderBaseVO { | ||
| 26 | private MemberUserRespVO user; | 26 | private MemberUserRespVO user; |
| 27 | 27 | ||
| 28 | /** | 28 | /** |
| 29 | - * TODO 订单操作日志, 先模拟一波;返回 logs,简洁,然后复数哈 | 29 | + * TODO 订单操作日志, 先模拟一波 |
| 30 | */ | 30 | */ |
| 31 | - private List<OrderLog> orderLog; | 31 | + private List<OrderLog> logs; |
| 32 | 32 | ||
| 33 | - // TODO @puhui999:swagger 注解 | 33 | + @Schema(description = "管理后台 - 交易订单的操作日志") |
| 34 | @Data | 34 | @Data |
| 35 | public static class OrderLog { | 35 | public static class OrderLog { |
| 36 | 36 | ||
| 37 | - /** | ||
| 38 | - * 内容 | ||
| 39 | - */ | 37 | + @Schema(description = "操作详情", requiredMode = Schema.RequiredMode.REQUIRED, example = "订单发货") |
| 40 | private String content; | 38 | private String content; |
| 41 | 39 | ||
| 42 | - /** | ||
| 43 | - * 创建时间 | ||
| 44 | - */ | 40 | + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED, example = "2023-06-01 10:50:20") |
| 45 | private LocalDateTime createTime; | 41 | private LocalDateTime createTime; |
| 46 | 42 | ||
| 43 | + @Schema(description = "用户类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | ||
| 44 | + private Integer userType; | ||
| 45 | + | ||
| 47 | } | 46 | } |
| 48 | 47 | ||
| 49 | @Schema(description = "管理后台 - 交易订单的详情的订单项目") | 48 | @Schema(description = "管理后台 - 交易订单的详情的订单项目") |
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.AppBrokerageProductPriceRespVO; | ||
| 7 | +import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.record.AppBrokerageRecordPageReqVO; | ||
| 8 | +import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.record.AppBrokerageRecordRespVO; | ||
| 9 | +import io.swagger.v3.oas.annotations.Operation; | ||
| 10 | +import io.swagger.v3.oas.annotations.tags.Tag; | ||
| 11 | +import lombok.extern.slf4j.Slf4j; | ||
| 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 javax.validation.Valid; | ||
| 19 | +import java.time.LocalDateTime; | ||
| 20 | + | ||
| 21 | +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | ||
| 22 | +import static java.util.Arrays.asList; | ||
| 23 | + | ||
| 24 | +@Tag(name = "用户 APP - 分销用户") | ||
| 25 | +@RestController | ||
| 26 | +@RequestMapping("/trade/brokerage-record") | ||
| 27 | +@Validated | ||
| 28 | +@Slf4j | ||
| 29 | +public class AppBrokerageRecordController { | ||
| 30 | + | ||
| 31 | + // TODO 芋艿:临时 mock => | ||
| 32 | + @GetMapping("/page") | ||
| 33 | + @Operation(summary = "获得分销记录分页") | ||
| 34 | + @PreAuthenticated | ||
| 35 | + public CommonResult<PageResult<AppBrokerageRecordRespVO>> getBrokerageRecordPage(@Valid AppBrokerageRecordPageReqVO pageReqVO) { | ||
| 36 | + AppBrokerageRecordRespVO vo1 = new AppBrokerageRecordRespVO() | ||
| 37 | + .setId(1L).setPrice(10).setTitle("收到钱").setCreateTime(LocalDateTime.now()) | ||
| 38 | + .setFinishTime(LocalDateTime.now()); | ||
| 39 | + AppBrokerageRecordRespVO vo2 = new AppBrokerageRecordRespVO() | ||
| 40 | + .setId(2L).setPrice(-20).setTitle("提现钱").setCreateTime(LocalDateTime.now()) | ||
| 41 | + .setFinishTime(LocalDateTime.now()); | ||
| 42 | + return success(new PageResult<>(asList(vo1, vo2), 10L)); | ||
| 43 | + } | ||
| 44 | + | ||
| 45 | + @GetMapping("/get-product-brokerage-price") | ||
| 46 | + @Operation(summary = "获得商品的分销金额") | ||
| 47 | + public CommonResult<AppBrokerageProductPriceRespVO> getProductBrokeragePrice(@RequestParam("spuId") Long spuId) { | ||
| 48 | + AppBrokerageProductPriceRespVO respVO = new AppBrokerageProductPriceRespVO(); | ||
| 49 | + respVO.setEnabled(true); // TODO @疯狂:需要开启分销 + 人允许分销 | ||
| 50 | + respVO.setBrokerageMinPrice(1); | ||
| 51 | + respVO.setBrokerageMaxPrice(2); | ||
| 52 | + return success(respVO); | ||
| 53 | + } | ||
| 54 | + | ||
| 55 | +} |
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 cn.iocoder.yudao.module.trade.service.brokerage.user.BrokerageUserService; | ||
| 8 | +import io.swagger.v3.oas.annotations.Operation; | ||
| 9 | +import io.swagger.v3.oas.annotations.Parameter; | ||
| 10 | +import io.swagger.v3.oas.annotations.tags.Tag; | ||
| 11 | +import lombok.extern.slf4j.Slf4j; | ||
| 12 | +import org.springframework.format.annotation.DateTimeFormat; | ||
| 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 | +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 cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; | ||
| 23 | +import static java.util.Arrays.asList; | ||
| 24 | + | ||
| 25 | +@Tag(name = "用户 APP - 分销用户") | ||
| 26 | +@RestController | ||
| 27 | +@RequestMapping("/trade/brokerage-user") | ||
| 28 | +@Validated | ||
| 29 | +@Slf4j | ||
| 30 | +public class AppBrokerageUserController { | ||
| 31 | + @Resource | ||
| 32 | + private BrokerageUserService brokerageUserService; | ||
| 33 | + | ||
| 34 | + // TODO 芋艿:临时 mock => | ||
| 35 | + @GetMapping("/get") | ||
| 36 | + @Operation(summary = "获得个人分销信息") | ||
| 37 | + @PreAuthenticated | ||
| 38 | + public CommonResult<AppBrokerageUserRespVO> getBrokerageUser() { | ||
| 39 | + AppBrokerageUserRespVO respVO = new AppBrokerageUserRespVO() | ||
| 40 | + .setBrokerageEnabled(true) | ||
| 41 | + .setPrice(2000) | ||
| 42 | + .setFrozenPrice(3000); | ||
| 43 | + return success(respVO); | ||
| 44 | + } | ||
| 45 | + | ||
| 46 | + @PutMapping("/bind") | ||
| 47 | + @Operation(summary = "绑定推广员") | ||
| 48 | + @PreAuthenticated | ||
| 49 | + public CommonResult<Boolean> bindBrokerageUser(@Valid @RequestBody AppBrokerageUserBindReqVO reqVO) { | ||
| 50 | + return success(brokerageUserService.bindBrokerageUser(getLoginUserId(), reqVO.getBindUserId(), false)); | ||
| 51 | + } | ||
| 52 | + | ||
| 53 | + // TODO 芋艿:临时 mock => | ||
| 54 | + @GetMapping("/get-summary") | ||
| 55 | + @Operation(summary = "获得个人分销统计") | ||
| 56 | + @PreAuthenticated | ||
| 57 | + public CommonResult<AppBrokerageUserMySummaryRespVO> getBrokerageUserSummary() { | ||
| 58 | + AppBrokerageUserMySummaryRespVO respVO = new AppBrokerageUserMySummaryRespVO() | ||
| 59 | + .setYesterdayPrice(1) | ||
| 60 | + .setBrokeragePrice(2) | ||
| 61 | + .setFrozenPrice(3) | ||
| 62 | + .setWithdrawPrice(4) | ||
| 63 | + .setFirstBrokerageUserCount(166) | ||
| 64 | + .setSecondBrokerageUserCount(233); | ||
| 65 | + return success(respVO); | ||
| 66 | + } | ||
| 67 | + | ||
| 68 | + // TODO 芋艿:临时 mock => | ||
| 69 | + @GetMapping("/rank-page-by-user-count") | ||
| 70 | + @Operation(summary = "获得分销用户排行分页(基于用户量)") | ||
| 71 | + @PreAuthenticated | ||
| 72 | + public CommonResult<PageResult<AppBrokerageUserRankByUserCountRespVO>> getBrokerageUserRankPageByUserCount(AppBrokerageUserRankPageReqVO pageReqVO) { | ||
| 73 | + AppBrokerageUserRankByUserCountRespVO vo1 = new AppBrokerageUserRankByUserCountRespVO() | ||
| 74 | + .setId(1L).setNickname("芋1**艿").setAvatar("http://www.iocoder.cn/images/common/wechat_mp_2017_07_31_bak.jpg") | ||
| 75 | + .setBrokerageUserCount(10); | ||
| 76 | + AppBrokerageUserRankByUserCountRespVO vo2 = new AppBrokerageUserRankByUserCountRespVO() | ||
| 77 | + .setId(2L).setNickname("芋2**艿").setAvatar("http://www.iocoder.cn/images/common/wechat_mp_2017_07_31_bak.jpg") | ||
| 78 | + .setBrokerageUserCount(6); | ||
| 79 | + AppBrokerageUserRankByUserCountRespVO vo3 = new AppBrokerageUserRankByUserCountRespVO() | ||
| 80 | + .setId(3L).setNickname("芋3**艿").setAvatar("http://www.iocoder.cn/images/common/wechat_mp_2017_07_31_bak.jpg") | ||
| 81 | + .setBrokerageUserCount(4); | ||
| 82 | + AppBrokerageUserRankByUserCountRespVO vo4 = new AppBrokerageUserRankByUserCountRespVO() | ||
| 83 | + .setId(3L).setNickname("芋3**艿").setAvatar("http://www.iocoder.cn/images/common/wechat_mp_2017_07_31_bak.jpg") | ||
| 84 | + .setBrokerageUserCount(4); | ||
| 85 | + return success(new PageResult<>(asList(vo1, vo2, vo3, vo4), 10L)); | ||
| 86 | + } | ||
| 87 | + | ||
| 88 | + // TODO 芋艿:临时 mock => | ||
| 89 | + @GetMapping("/rank-page-by-price") | ||
| 90 | + @Operation(summary = "获得分销用户排行分页(基于佣金)") | ||
| 91 | + @PreAuthenticated | ||
| 92 | + public CommonResult<PageResult<AppBrokerageUserRankByPriceRespVO>> getBrokerageUserChildSummaryPageByPrice(AppBrokerageUserRankPageReqVO pageReqVO) { | ||
| 93 | + AppBrokerageUserRankByPriceRespVO vo1 = new AppBrokerageUserRankByPriceRespVO() | ||
| 94 | + .setId(1L).setNickname("芋1**艿").setAvatar("http://www.iocoder.cn/images/common/wechat_mp_2017_07_31_bak.jpg") | ||
| 95 | + .setBrokeragePrice(10); | ||
| 96 | + AppBrokerageUserRankByPriceRespVO vo2 = new AppBrokerageUserRankByPriceRespVO() | ||
| 97 | + .setId(2L).setNickname("芋2**艿").setAvatar("http://www.iocoder.cn/images/common/wechat_mp_2017_07_31_bak.jpg") | ||
| 98 | + .setBrokeragePrice(6); | ||
| 99 | + AppBrokerageUserRankByPriceRespVO vo3 = new AppBrokerageUserRankByPriceRespVO() | ||
| 100 | + .setId(3L).setNickname("芋3**艿").setAvatar("http://www.iocoder.cn/images/common/wechat_mp_2017_07_31_bak.jpg") | ||
| 101 | + .setBrokeragePrice(4); | ||
| 102 | + AppBrokerageUserRankByPriceRespVO vo4 = new AppBrokerageUserRankByPriceRespVO() | ||
| 103 | + .setId(3L).setNickname("芋3**艿").setAvatar("http://www.iocoder.cn/images/common/wechat_mp_2017_07_31_bak.jpg") | ||
| 104 | + .setBrokeragePrice(4); | ||
| 105 | + return success(new PageResult<>(asList(vo1, vo2, vo3, vo4), 10L)); | ||
| 106 | + } | ||
| 107 | + | ||
| 108 | + // TODO 芋艿:临时 mock => | ||
| 109 | + @GetMapping("/child-summary-page") | ||
| 110 | + @Operation(summary = "获得下级分销统计分页") | ||
| 111 | + @PreAuthenticated | ||
| 112 | + public CommonResult<PageResult<AppBrokerageUserChildSummaryRespVO>> getBrokerageUserChildSummaryPage( | ||
| 113 | + AppBrokerageUserChildSummaryPageReqVO pageReqVO) { | ||
| 114 | + AppBrokerageUserChildSummaryRespVO vo1 = new AppBrokerageUserChildSummaryRespVO() | ||
| 115 | + .setId(1L).setNickname("芋1**艿").setAvatar("http://www.iocoder.cn/images/common/wechat_mp_2017_07_31_bak.jpg") | ||
| 116 | + .setBrokeragePrice(10).setBrokeragePrice(20).setBrokerageOrderCount(30) | ||
| 117 | + .setBrokerageTime(LocalDateTime.now()); | ||
| 118 | + AppBrokerageUserChildSummaryRespVO vo2 = new AppBrokerageUserChildSummaryRespVO() | ||
| 119 | + .setId(1L).setNickname("芋2**艿").setAvatar("http://www.iocoder.cn/images/common/wechat_mp_2017_07_31_bak.jpg") | ||
| 120 | + .setBrokeragePrice(20).setBrokeragePrice(30).setBrokerageOrderCount(40) | ||
| 121 | + .setBrokerageTime(LocalDateTime.now()); | ||
| 122 | + return success(new PageResult<>(asList(vo1, vo2), 10L)); | ||
| 123 | + } | ||
| 124 | + | ||
| 125 | + // TODO 芋艿:临时 mock => | ||
| 126 | + @GetMapping("/get-rank-by-price") | ||
| 127 | + @Operation(summary = "获得分销用户排行(基于佣金)") | ||
| 128 | + @Parameter(name = "times", description = "时间段", required = true) | ||
| 129 | + public CommonResult<Integer> bindBrokerageUser( | ||
| 130 | + @RequestParam("times") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) LocalDateTime[] times) { | ||
| 131 | + return success(1); | ||
| 132 | + } | ||
| 133 | + | ||
| 134 | +} |
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/AppBrokerageProductPriceRespVO.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 | +@Schema(description = "用户 App - 商品的分销金额 Response VO") | ||
| 7 | +@Data | ||
| 8 | +public class AppBrokerageProductPriceRespVO { | ||
| 9 | + | ||
| 10 | + @Schema(description = "是否开启", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") | ||
| 11 | + private Boolean enabled; | ||
| 12 | + | ||
| 13 | + @Schema(description = "分销最小金额,单位:分", example = "100") | ||
| 14 | + private Integer brokerageMinPrice; | ||
| 15 | + | ||
| 16 | + @Schema(description = "分销最大金额,单位:分", example = "100") | ||
| 17 | + private Integer brokerageMaxPrice; | ||
| 18 | + | ||
| 19 | +} |
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 cn.iocoder.yudao.framework.common.validation.InEnum; | ||
| 5 | +import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordBizTypeEnum; | ||
| 6 | +import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordStatusEnum; | ||
| 7 | +import io.swagger.v3.oas.annotations.media.Schema; | ||
| 8 | +import lombok.Data; | ||
| 9 | + | ||
| 10 | +@Schema(description = "应用 App - 分销记录分页 Request VO") | ||
| 11 | +@Data | ||
| 12 | +public class AppBrokerageRecordPageReqVO extends PageParam { | ||
| 13 | + | ||
| 14 | + @Schema(description = "业务类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | ||
| 15 | + @InEnum(value = BrokerageRecordBizTypeEnum.class, message = "业务类型必须是 {value}") | ||
| 16 | + private Integer bizType; | ||
| 17 | + | ||
| 18 | + @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | ||
| 19 | + @InEnum(value = BrokerageRecordStatusEnum.class, message = "状态必须是 {value}") | ||
| 20 | + private Integer status; | ||
| 21 | + | ||
| 22 | +} |
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/AppBrokerageUserBindReqVO.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 | + | ||
| 7 | +import javax.validation.constraints.NotNull; | ||
| 8 | + | ||
| 9 | +@Schema(description = "应用 App - 绑定推广员 Request VO") | ||
| 10 | +@Data | ||
| 11 | +public class AppBrokerageUserBindReqVO extends PageParam { | ||
| 12 | + | ||
| 13 | + @Schema(description = "推广员编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") | ||
| 14 | + @NotNull(message = "推广员编号不能为空") | ||
| 15 | + private Long bindUserId; | ||
| 16 | + | ||
| 17 | +} |
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 yesterdayPrice; | ||
| 12 | + | ||
| 13 | + @Schema(description = "提现的佣金,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") | ||
| 14 | + private Integer withdrawPrice; | ||
| 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 frozenPrice; | ||
| 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 = "true") | ||
| 11 | + private Boolean brokerageEnabled; | ||
| 12 | + | ||
| 13 | + @Schema(description = "可用的佣金,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "2408") | ||
| 14 | + private Integer price; | ||
| 15 | + | ||
| 16 | + @Schema(description = "冻结的佣金,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "234") | ||
| 17 | + private Integer frozenPrice; | ||
| 18 | + | ||
| 19 | +} |
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 cn.iocoder.yudao.framework.common.util.validation.ValidationUtils; | ||
| 4 | +import cn.iocoder.yudao.framework.common.validation.InEnum; | ||
| 5 | +import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageWithdrawTypeEnum; | ||
| 6 | +import io.swagger.v3.oas.annotations.media.Schema; | ||
| 7 | +import lombok.Data; | ||
| 8 | +import org.hibernate.validator.constraints.URL; | ||
| 9 | + | ||
| 10 | +import javax.validation.Validator; | ||
| 11 | +import javax.validation.constraints.Min; | ||
| 12 | +import javax.validation.constraints.NotBlank; | ||
| 13 | + | ||
| 14 | +@Schema(description = "用户 App - 分销提现创建 Request VO") | ||
| 15 | +@Data | ||
| 16 | +public class AppBrokerageWithdrawCreateReqVO { | ||
| 17 | + | ||
| 18 | + @Schema(description = "提现方式", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | ||
| 19 | + @InEnum(value = BrokerageWithdrawTypeEnum.class, message = "提现方式必须是 {value}") | ||
| 20 | + private Integer type; | ||
| 21 | + | ||
| 22 | + @Schema(description = "提现金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "1000") | ||
| 23 | + @Min(value = 1, message = "提现金额不能小于 1") | ||
| 24 | + private Integer price; | ||
| 25 | + | ||
| 26 | + // ========== 银行卡、微信、支付宝 提现相关字段 ========== | ||
| 27 | + | ||
| 28 | + @Schema(description = "提现账号", requiredMode = Schema.RequiredMode.REQUIRED, example = "123456789") | ||
| 29 | + @NotBlank(message = "提现账号不能为空", groups = {Bank.class, Wechat.class, Alipay.class}) | ||
| 30 | + private String accountNo; | ||
| 31 | + | ||
| 32 | + // ========== 微信、支付宝 提现相关字段 ========== | ||
| 33 | + | ||
| 34 | + @Schema(description = "收款码的图片", example = "https://www.iocoder.cn/1.png") | ||
| 35 | + @URL(message = "收款码的图片,必须是一个 URL") | ||
| 36 | + private String accountQrCodeUrl; | ||
| 37 | + | ||
| 38 | + // ========== 银行卡 提现相关字段 ========== | ||
| 39 | + | ||
| 40 | + @Schema(description = "持卡人姓名", example = "张三") | ||
| 41 | + @NotBlank(message = "持卡人姓名不能为空", groups = {Bank.class}) | ||
| 42 | + private String name; | ||
| 43 | + @Schema(description = "提现银行", example = "1") | ||
| 44 | + @NotBlank(message = "提现银行不能为空", groups = {Bank.class}) | ||
| 45 | + private Integer bankName; | ||
| 46 | + @Schema(description = "开户地址", example = "海淀支行") | ||
| 47 | + private String bankAddress; | ||
| 48 | + | ||
| 49 | + public interface Wallet { | ||
| 50 | + } | ||
| 51 | + | ||
| 52 | + public interface Bank { | ||
| 53 | + } | ||
| 54 | + | ||
| 55 | + public interface Wechat { | ||
| 56 | + } | ||
| 57 | + | ||
| 58 | + public interface Alipay { | ||
| 59 | + } | ||
| 60 | + | ||
| 61 | + public void validate(Validator validator) { | ||
| 62 | + if (BrokerageWithdrawTypeEnum.WALLET.getType().equals(type)) { | ||
| 63 | + ValidationUtils.validate(validator, this, Wallet.class); | ||
| 64 | + } else if (BrokerageWithdrawTypeEnum.BANK.getType().equals(type)) { | ||
| 65 | + ValidationUtils.validate(validator, this, Bank.class); | ||
| 66 | + } else if (BrokerageWithdrawTypeEnum.WECHAT.getType().equals(type)) { | ||
| 67 | + ValidationUtils.validate(validator, this, Wechat.class); | ||
| 68 | + } else if (BrokerageWithdrawTypeEnum.ALIPAY.getType().equals(type)) { | ||
| 69 | + ValidationUtils.validate(validator, this, Alipay.class); | ||
| 70 | + } | ||
| 71 | + } | ||
| 72 | + | ||
| 73 | +} |
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/AppTradeOrderController.java
| @@ -4,7 +4,6 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult; | @@ -4,7 +4,6 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult; | ||
| 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 5 | import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated; | 5 | import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated; |
| 6 | import cn.iocoder.yudao.module.pay.api.notify.dto.PayOrderNotifyReqDTO; | 6 | import cn.iocoder.yudao.module.pay.api.notify.dto.PayOrderNotifyReqDTO; |
| 7 | -import cn.iocoder.yudao.module.product.api.property.ProductPropertyValueApi; | ||
| 8 | import cn.iocoder.yudao.module.trade.controller.app.order.vo.*; | 7 | import cn.iocoder.yudao.module.trade.controller.app.order.vo.*; |
| 9 | import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemCommentCreateReqVO; | 8 | import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemCommentCreateReqVO; |
| 10 | import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemRespVO; | 9 | import cn.iocoder.yudao.module.trade.controller.app.order.vo.item.AppTradeOrderItemRespVO; |
| @@ -82,9 +81,10 @@ public class AppTradeOrderController { | @@ -82,9 +81,10 @@ public class AppTradeOrderController { | ||
| 82 | public CommonResult<AppTradeOrderDetailRespVO> getOrder(@RequestParam("id") Long id) { | 81 | public CommonResult<AppTradeOrderDetailRespVO> getOrder(@RequestParam("id") Long id) { |
| 83 | // 查询订单 | 82 | // 查询订单 |
| 84 | TradeOrderDO order = tradeOrderQueryService.getOrder(getLoginUserId(), id); | 83 | TradeOrderDO order = tradeOrderQueryService.getOrder(getLoginUserId(), id); |
| 85 | - if (order == null) { | ||
| 86 | - return success(null); | ||
| 87 | - } | 84 | + // TODO @puhui999:这里建议改成,如果为 null,直接返回 success null;主要查询操作,尽量不要有非空的提示哈;交给前端处理; |
| 85 | +// if (order == null) { | ||
| 86 | +// return success(null, ORDER_NOT_FOUND.getMsg()); | ||
| 87 | +// } | ||
| 88 | 88 | ||
| 89 | // 查询订单项 | 89 | // 查询订单项 |
| 90 | List<TradeOrderItemDO> orderItems = tradeOrderQueryService.getOrderItemListByOrderId(order.getId()); | 90 | List<TradeOrderItemDO> orderItems = tradeOrderQueryService.getOrderItemListByOrderId(order.getId()); |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderSettlementReqVO.java
| @@ -50,12 +50,18 @@ public class AppTradeOrderSettlementReqVO { | @@ -50,12 +50,18 @@ public class AppTradeOrderSettlementReqVO { | ||
| 50 | private Long seckillActivityId; | 50 | private Long seckillActivityId; |
| 51 | 51 | ||
| 52 | // ========== 拼团活动相关字段 ========== | 52 | // ========== 拼团活动相关字段 ========== |
| 53 | + // TODO @puhui999:是不是拼团记录的编号哈? | ||
| 53 | @Schema(description = "拼团活动编号", example = "1024") | 54 | @Schema(description = "拼团活动编号", example = "1024") |
| 54 | private Long combinationActivityId; | 55 | private Long combinationActivityId; |
| 55 | 56 | ||
| 56 | @Schema(description = "拼团团长编号", example = "2048") | 57 | @Schema(description = "拼团团长编号", example = "2048") |
| 57 | private Long combinationHeadId; | 58 | private Long combinationHeadId; |
| 58 | 59 | ||
| 60 | + // ========== 砍价活动相关字段 ========== | ||
| 61 | + // TODO @puhui999:是不是砍价记录的编号哈? | ||
| 62 | + @Schema(description = "砍价活动编号", example = "123") | ||
| 63 | + private Long bargainActivityId; | ||
| 64 | + | ||
| 59 | @Data | 65 | @Data |
| 60 | @Schema(description = "用户 App - 商品项") | 66 | @Schema(description = "用户 App - 商品项") |
| 61 | @Valid | 67 | @Valid |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/aftersale/TradeAfterSaleConvert.java
| @@ -78,7 +78,7 @@ public interface TradeAfterSaleConvert { | @@ -78,7 +78,7 @@ public interface TradeAfterSaleConvert { | ||
| 78 | // 处理订单信息 | 78 | // 处理订单信息 |
| 79 | respVO.setOrder(convert(order)); | 79 | respVO.setOrder(convert(order)); |
| 80 | // 处理售后日志 | 80 | // 处理售后日志 |
| 81 | - respVO.setAfterSaleLog(convertList1(logs)); | 81 | + respVO.setLogs(convertList1(logs)); |
| 82 | return respVO; | 82 | return respVO; |
| 83 | } | 83 | } |
| 84 | List<TradeAfterSaleLogRespVO> convertList1(List<TradeAfterSaleLogRespDTO> list); | 84 | List<TradeAfterSaleLogRespVO> convertList1(List<TradeAfterSaleLogRespDTO> list); |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/brokerage/record/BrokerageRecordConvert.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.trade.convert.brokerage.record; | ||
| 2 | + | ||
| 3 | +import cn.hutool.core.util.ObjectUtil; | ||
| 4 | +import cn.hutool.core.util.StrUtil; | ||
| 5 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||
| 6 | +import cn.iocoder.yudao.module.trade.controller.admin.brokerage.record.vo.BrokerageRecordRespVO; | ||
| 7 | +import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.record.BrokerageRecordDO; | ||
| 8 | +import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.user.BrokerageUserDO; | ||
| 9 | +import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordBizTypeEnum; | ||
| 10 | +import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordStatusEnum; | ||
| 11 | +import org.mapstruct.Mapper; | ||
| 12 | +import org.mapstruct.factory.Mappers; | ||
| 13 | + | ||
| 14 | +import java.time.LocalDateTime; | ||
| 15 | +import java.util.List; | ||
| 16 | + | ||
| 17 | +/** | ||
| 18 | + * 佣金记录 Convert | ||
| 19 | + * | ||
| 20 | + * @author owen | ||
| 21 | + */ | ||
| 22 | +@Mapper | ||
| 23 | +public interface BrokerageRecordConvert { | ||
| 24 | + | ||
| 25 | + BrokerageRecordConvert INSTANCE = Mappers.getMapper(BrokerageRecordConvert.class); | ||
| 26 | + | ||
| 27 | + BrokerageRecordRespVO convert(BrokerageRecordDO bean); | ||
| 28 | + | ||
| 29 | + List<BrokerageRecordRespVO> convertList(List<BrokerageRecordDO> list); | ||
| 30 | + | ||
| 31 | + PageResult<BrokerageRecordRespVO> convertPage(PageResult<BrokerageRecordDO> page); | ||
| 32 | + | ||
| 33 | + // TODO @疯狂:可能 title 不是很固化,会存在类似:沐晴成功购买《XXX JVM 实战》 | ||
| 34 | + default BrokerageRecordDO convert(BrokerageUserDO user, BrokerageRecordBizTypeEnum bizType, String bizId, | ||
| 35 | + Integer brokerageFrozenDays, int brokeragePrice, LocalDateTime unfreezeTime, | ||
| 36 | + String title) { | ||
| 37 | + brokerageFrozenDays = ObjectUtil.defaultIfNull(brokerageFrozenDays, 0); | ||
| 38 | + // 不冻结时,佣金直接就是结算状态 | ||
| 39 | + Integer status = brokerageFrozenDays > 0 | ||
| 40 | + ? BrokerageRecordStatusEnum.WAIT_SETTLEMENT.getStatus() | ||
| 41 | + : BrokerageRecordStatusEnum.SETTLEMENT.getStatus(); | ||
| 42 | + return new BrokerageRecordDO().setUserId(user.getId()) | ||
| 43 | + .setBizType(bizType.getType()).setBizId(bizId) | ||
| 44 | + .setPrice(brokeragePrice).setTotalPrice(user.getBrokeragePrice()) | ||
| 45 | + .setTitle(title) | ||
| 46 | + .setDescription(StrUtil.format(bizType.getDescription(), String.valueOf(brokeragePrice / 100.0))) | ||
| 47 | + .setStatus(status).setFrozenDays(brokerageFrozenDays).setUnfreezeTime(unfreezeTime); | ||
| 48 | + } | ||
| 49 | + | ||
| 50 | +} |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/brokerage/user/BrokerageUserConvert.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.trade.convert.brokerage.user; | ||
| 2 | + | ||
| 3 | +import cn.hutool.core.map.MapUtil; | ||
| 4 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||
| 5 | +import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; | ||
| 6 | +import cn.iocoder.yudao.module.trade.api.brokerage.dto.BrokerageUserDTO; | ||
| 7 | +import cn.iocoder.yudao.module.trade.controller.admin.brokerage.user.vo.BrokerageUserRespVO; | ||
| 8 | +import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.user.BrokerageUserDO; | ||
| 9 | +import cn.iocoder.yudao.module.trade.service.brokerage.bo.UserBrokerageSummaryBO; | ||
| 10 | +import org.mapstruct.Mapper; | ||
| 11 | +import org.mapstruct.factory.Mappers; | ||
| 12 | + | ||
| 13 | +import java.util.List; | ||
| 14 | +import java.util.Map; | ||
| 15 | +import java.util.Optional; | ||
| 16 | + | ||
| 17 | +/** | ||
| 18 | + * 分销用户 Convert | ||
| 19 | + * | ||
| 20 | + * @author owen | ||
| 21 | + */ | ||
| 22 | +@Mapper | ||
| 23 | +public interface BrokerageUserConvert { | ||
| 24 | + | ||
| 25 | + BrokerageUserConvert INSTANCE = Mappers.getMapper(BrokerageUserConvert.class); | ||
| 26 | + | ||
| 27 | + BrokerageUserRespVO convert(BrokerageUserDO bean); | ||
| 28 | + | ||
| 29 | + List<BrokerageUserRespVO> convertList(List<BrokerageUserDO> list); | ||
| 30 | + | ||
| 31 | + PageResult<BrokerageUserRespVO> convertPage(PageResult<BrokerageUserDO> page); | ||
| 32 | + | ||
| 33 | + default PageResult<BrokerageUserRespVO> convertPage(PageResult<BrokerageUserDO> pageResult, | ||
| 34 | + Map<Long, MemberUserRespDTO> userMap, | ||
| 35 | + Map<Long, Long> brokerageUserCountMap, | ||
| 36 | + Map<Long, UserBrokerageSummaryBO> userOrderSummaryMap) { | ||
| 37 | + PageResult<BrokerageUserRespVO> result = convertPage(pageResult); | ||
| 38 | + for (BrokerageUserRespVO vo : result.getList()) { | ||
| 39 | + // 用户信息 | ||
| 40 | + Optional.ofNullable(userMap.get(vo.getId())).ifPresent( | ||
| 41 | + user -> vo.setNickname(user.getNickname()).setAvatar(user.getAvatar())); | ||
| 42 | + // 推广用户数量(一级) | ||
| 43 | + vo.setBrokerageUserCount(MapUtil.getInt(brokerageUserCountMap, vo.getId(), 0)); | ||
| 44 | + // 推广订单数量、推广订单金额 | ||
| 45 | + Optional<UserBrokerageSummaryBO> orderSummaryOptional = Optional.ofNullable(userOrderSummaryMap.get(vo.getId())); | ||
| 46 | + vo.setBrokerageOrderCount(orderSummaryOptional.map(UserBrokerageSummaryBO::getCount).orElse(0)) | ||
| 47 | + .setBrokerageOrderPrice(orderSummaryOptional.map(UserBrokerageSummaryBO::getPrice).orElse(0)); | ||
| 48 | + // todo 已提现次数、已提现金额 | ||
| 49 | + vo.setWithdrawCount(0); | ||
| 50 | + vo.setWithdrawPrice(0); | ||
| 51 | + } | ||
| 52 | + return result; | ||
| 53 | + } | ||
| 54 | + | ||
| 55 | + BrokerageUserDTO convertDTO(BrokerageUserDO brokerageUser); | ||
| 56 | +} |
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.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; |
| @@ -93,6 +95,7 @@ public interface TradeOrderConvert { | @@ -93,6 +95,7 @@ public interface TradeOrderConvert { | ||
| 93 | items.forEach(item -> item.setIncrCount(-item.getIncrCount())); | 95 | items.forEach(item -> item.setIncrCount(-item.getIncrCount())); |
| 94 | return new ProductSkuUpdateStockReqDTO(items); | 96 | return new ProductSkuUpdateStockReqDTO(items); |
| 95 | } | 97 | } |
| 98 | + | ||
| 96 | List<ProductSkuUpdateStockReqDTO.Item> convertList(List<TradeOrderItemDO> list); | 99 | List<ProductSkuUpdateStockReqDTO.Item> convertList(List<TradeOrderItemDO> list); |
| 97 | 100 | ||
| 98 | @Mappings({ | 101 | @Mappings({ |
| @@ -151,9 +154,10 @@ public interface TradeOrderConvert { | @@ -151,9 +154,10 @@ public interface TradeOrderConvert { | ||
| 151 | TradeOrderDetailRespVO.OrderLog orderLog = new TradeOrderDetailRespVO.OrderLog(); | 154 | TradeOrderDetailRespVO.OrderLog orderLog = new TradeOrderDetailRespVO.OrderLog(); |
| 152 | orderLog.setContent("订单操作" + i); | 155 | orderLog.setContent("订单操作" + i); |
| 153 | orderLog.setCreateTime(LocalDateTime.now()); | 156 | orderLog.setCreateTime(LocalDateTime.now()); |
| 157 | + orderLog.setUserType(i % 2 == 0 ? 2 : 1); | ||
| 154 | orderLogs.add(orderLog); | 158 | orderLogs.add(orderLog); |
| 155 | } | 159 | } |
| 156 | - orderVO.setOrderLog(orderLogs); | 160 | + orderVO.setLogs(orderLogs); |
| 157 | return orderVO; | 161 | return orderVO; |
| 158 | } | 162 | } |
| 159 | 163 | ||
| @@ -273,4 +277,10 @@ public interface TradeOrderConvert { | @@ -273,4 +277,10 @@ public interface TradeOrderConvert { | ||
| 273 | 277 | ||
| 274 | TradeOrderDO convert(TradeOrderRemarkReqVO reqVO); | 278 | TradeOrderDO convert(TradeOrderRemarkReqVO reqVO); |
| 275 | 279 | ||
| 280 | + default BrokerageAddReqBO convert(TradeOrderItemDO item, ProductSkuRespDTO sku) { | ||
| 281 | + return new BrokerageAddReqBO().setBizId(String.valueOf(item.getId())) | ||
| 282 | + .setBasePrice(item.getPayPrice() * item.getCount()) | ||
| 283 | + .setFirstFixedPrice(sku.getSubCommissionFirstPrice()) | ||
| 284 | + .setSecondFixedPrice(sku.getSubCommissionSecondPrice()); | ||
| 285 | + } | ||
| 276 | } | 286 | } |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/brokerage/record/BrokerageRecordDO.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 BrokerageRecordDO 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/BrokerageUserDO.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 | +/** | ||
| 12 | + * 分销用户 DO | ||
| 13 | + * | ||
| 14 | + * @author owen | ||
| 15 | + */ | ||
| 16 | +@TableName("trade_brokerage_user") | ||
| 17 | +@KeySequence("trade_brokerage_user_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 | ||
| 18 | +@Data | ||
| 19 | +@EqualsAndHashCode(callSuper = true) | ||
| 20 | +@ToString(callSuper = true) | ||
| 21 | +@Builder | ||
| 22 | +@NoArgsConstructor | ||
| 23 | +@AllArgsConstructor | ||
| 24 | +public class BrokerageUserDO extends BaseDO { | ||
| 25 | + | ||
| 26 | + /** | ||
| 27 | + * 用户编号 | ||
| 28 | + * <p> | ||
| 29 | + * 对应 MemberUserDO 的 id 字段 | ||
| 30 | + */ | ||
| 31 | + @TableId | ||
| 32 | + private Long id; | ||
| 33 | + | ||
| 34 | + /** | ||
| 35 | + * 推广员编号 | ||
| 36 | + * <p> | ||
| 37 | + * 关联 MemberUserDO 的 id 字段 | ||
| 38 | + */ | ||
| 39 | + private Long bindUserId; | ||
| 40 | + /** | ||
| 41 | + * 推广员绑定时间 | ||
| 42 | + */ | ||
| 43 | + private LocalDateTime bindUserTime; | ||
| 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 frozenPrice; | ||
| 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/BrokerageRecordMapper.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.BrokerageRecordPageReqVO; | ||
| 7 | +import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.record.BrokerageRecordDO; | ||
| 8 | +import cn.iocoder.yudao.module.trade.service.brokerage.bo.UserBrokerageSummaryBO; | ||
| 9 | +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | ||
| 10 | +import org.apache.ibatis.annotations.Mapper; | ||
| 11 | +import org.apache.ibatis.annotations.Param; | ||
| 12 | +import org.apache.ibatis.annotations.Select; | ||
| 13 | + | ||
| 14 | +import java.time.LocalDateTime; | ||
| 15 | +import java.util.List; | ||
| 16 | + | ||
| 17 | +/** | ||
| 18 | + * 佣金记录 Mapper | ||
| 19 | + * | ||
| 20 | + * @author owen | ||
| 21 | + */ | ||
| 22 | +@Mapper | ||
| 23 | +public interface BrokerageRecordMapper extends BaseMapperX<BrokerageRecordDO> { | ||
| 24 | + | ||
| 25 | + default PageResult<BrokerageRecordDO> selectPage(BrokerageRecordPageReqVO reqVO) { | ||
| 26 | + return selectPage(reqVO, new LambdaQueryWrapperX<BrokerageRecordDO>() | ||
| 27 | + .eqIfPresent(BrokerageRecordDO::getUserId, reqVO.getUserId()) | ||
| 28 | + .eqIfPresent(BrokerageRecordDO::getBizType, reqVO.getBizType()) | ||
| 29 | + .eqIfPresent(BrokerageRecordDO::getStatus, reqVO.getStatus()) | ||
| 30 | + .betweenIfPresent(BrokerageRecordDO::getCreateTime, reqVO.getCreateTime()) | ||
| 31 | + .orderByDesc(BrokerageRecordDO::getId)); | ||
| 32 | + } | ||
| 33 | + | ||
| 34 | + default List<BrokerageRecordDO> selectListByStatusAndUnfreezeTimeLt(Integer status, LocalDateTime unfreezeTime) { | ||
| 35 | + return selectList(new LambdaQueryWrapper<BrokerageRecordDO>() | ||
| 36 | + .eq(BrokerageRecordDO::getStatus, status) | ||
| 37 | + .lt(BrokerageRecordDO::getUnfreezeTime, unfreezeTime)); | ||
| 38 | + } | ||
| 39 | + | ||
| 40 | + default int updateByIdAndStatus(Integer id, Integer status, BrokerageRecordDO updateObj) { | ||
| 41 | + return update(updateObj, new LambdaQueryWrapper<BrokerageRecordDO>() | ||
| 42 | + .eq(BrokerageRecordDO::getId, id) | ||
| 43 | + .eq(BrokerageRecordDO::getStatus, status)); | ||
| 44 | + } | ||
| 45 | + | ||
| 46 | + default BrokerageRecordDO selectByBizTypeAndBizId(Integer bizType, String bizId) { | ||
| 47 | + return selectOne(BrokerageRecordDO::getBizType, bizType, | ||
| 48 | + BrokerageRecordDO::getBizId, bizId); | ||
| 49 | + } | ||
| 50 | + | ||
| 51 | + // TODO @疯狂:mysql 关键字,大写哈;这样看起来清晰点;例如说 SELECT COUNT(1) | ||
| 52 | + @Select("select count(1), sum(price) from trade_brokerage_record where user_id = #{userId} and biz_type = #{bizType} and status = #{status}") | ||
| 53 | + UserBrokerageSummaryBO selectCountAndSumPriceByUserIdAndBizTypeAndStatus(@Param("userId") Long userId, | ||
| 54 | + @Param("bizType") Integer bizType, | ||
| 55 | + @Param("status") Integer status); | ||
| 56 | +} |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/user/BrokerageUserMapper.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.BrokerageUserPageReqVO; | ||
| 8 | +import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.user.BrokerageUserDO; | ||
| 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 BrokerageUserMapper extends BaseMapperX<BrokerageUserDO> { | ||
| 19 | + | ||
| 20 | + default PageResult<BrokerageUserDO> selectPage(BrokerageUserPageReqVO reqVO) { | ||
| 21 | + return selectPage(reqVO, new LambdaQueryWrapperX<BrokerageUserDO>() | ||
| 22 | + .eqIfPresent(BrokerageUserDO::getBindUserId, reqVO.getBindUserId()) | ||
| 23 | + .eqIfPresent(BrokerageUserDO::getBrokerageEnabled, reqVO.getBrokerageEnabled()) | ||
| 24 | + .betweenIfPresent(BrokerageUserDO::getCreateTime, reqVO.getCreateTime()) | ||
| 25 | + .orderByDesc(BrokerageUserDO::getId)); | ||
| 26 | + } | ||
| 27 | + | ||
| 28 | + /** | ||
| 29 | + * 更新用户可用佣金(增加) | ||
| 30 | + * | ||
| 31 | + * @param id 用户编号 | ||
| 32 | + * @param incrCount 增加佣金(正数) | ||
| 33 | + */ | ||
| 34 | + default void updatePriceIncr(Long id, Integer incrCount) { | ||
| 35 | + Assert.isTrue(incrCount > 0); | ||
| 36 | + LambdaUpdateWrapper<BrokerageUserDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<BrokerageUserDO>() | ||
| 37 | + .setSql(" price = price + " + incrCount) | ||
| 38 | + .eq(BrokerageUserDO::getId, id); | ||
| 39 | + update(null, lambdaUpdateWrapper); | ||
| 40 | + } | ||
| 41 | + | ||
| 42 | + /** | ||
| 43 | + * 更新用户可用佣金(减少) | ||
| 44 | + * 注意:理论上佣金可能已经提现,这时会扣出负数,确保平台不会造成损失 | ||
| 45 | + * | ||
| 46 | + * @param id 用户编号 | ||
| 47 | + * @param incrCount 增加佣金(负数) | ||
| 48 | + */ | ||
| 49 | + default void updatePriceDecr(Long id, Integer incrCount) { | ||
| 50 | + Assert.isTrue(incrCount < 0); | ||
| 51 | + LambdaUpdateWrapper<BrokerageUserDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<BrokerageUserDO>() | ||
| 52 | + .setSql(" price = price + " + incrCount) // 负数,所以使用 + 号 | ||
| 53 | + .eq(BrokerageUserDO::getId, id); | ||
| 54 | + update(null, lambdaUpdateWrapper); | ||
| 55 | + } | ||
| 56 | + | ||
| 57 | + /** | ||
| 58 | + * 更新用户冻结佣金(增加) | ||
| 59 | + * | ||
| 60 | + * @param id 用户编号 | ||
| 61 | + * @param incrCount 增加冻结佣金(正数) | ||
| 62 | + */ | ||
| 63 | + default void updateFrozenPriceIncr(Long id, Integer incrCount) { | ||
| 64 | + Assert.isTrue(incrCount > 0); | ||
| 65 | + LambdaUpdateWrapper<BrokerageUserDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<BrokerageUserDO>() | ||
| 66 | + .setSql(" frozen_price = frozen_price + " + incrCount) | ||
| 67 | + .eq(BrokerageUserDO::getId, id); | ||
| 68 | + update(null, lambdaUpdateWrapper); | ||
| 69 | + } | ||
| 70 | + | ||
| 71 | + /** | ||
| 72 | + * 更新用户冻结佣金(减少) | ||
| 73 | + * 注意:理论上冻结佣金可能已经解冻,这时会扣出负数,确保平台不会造成损失 | ||
| 74 | + * | ||
| 75 | + * @param id 用户编号 | ||
| 76 | + * @param incrCount 减少冻结佣金(负数) | ||
| 77 | + */ | ||
| 78 | + default void updateFrozenPriceDecr(Long id, Integer incrCount) { | ||
| 79 | + Assert.isTrue(incrCount < 0); | ||
| 80 | + LambdaUpdateWrapper<BrokerageUserDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<BrokerageUserDO>() | ||
| 81 | + .setSql(" frozen_price = frozen_price + " + incrCount) // 负数,所以使用 + 号 | ||
| 82 | + .eq(BrokerageUserDO::getId, id); | ||
| 83 | + update(null, lambdaUpdateWrapper); | ||
| 84 | + } | ||
| 85 | + | ||
| 86 | + /** | ||
| 87 | + * 更新用户冻结佣金(减少), 更新用户佣金(增加) | ||
| 88 | + * | ||
| 89 | + * @param id 用户编号 | ||
| 90 | + * @param incrCount 减少冻结佣金(负数) | ||
| 91 | + * @return 更新条数 | ||
| 92 | + */ | ||
| 93 | + default int updateFrozenPriceDecrAndPriceIncr(Long id, Integer incrCount) { | ||
| 94 | + Assert.isTrue(incrCount < 0); | ||
| 95 | + LambdaUpdateWrapper<BrokerageUserDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<BrokerageUserDO>() | ||
| 96 | + .setSql(" frozen_price = frozen_price + " + incrCount + // 负数,所以使用 + 号 | ||
| 97 | + ", price = price + " + -incrCount) // 负数,所以使用 - 号 | ||
| 98 | + .eq(BrokerageUserDO::getId, id) | ||
| 99 | + .ge(BrokerageUserDO::getFrozenPrice, -incrCount); // cas 逻辑 | ||
| 100 | + return update(null, lambdaUpdateWrapper); | ||
| 101 | + } | ||
| 102 | + | ||
| 103 | + default void updateBindUserIdAndBindUserTimeToNull(Long id) { | ||
| 104 | + update(null, new LambdaUpdateWrapper<BrokerageUserDO>() | ||
| 105 | + .eq(BrokerageUserDO::getId, id) | ||
| 106 | + .set(BrokerageUserDO::getBindUserId, null).set(BrokerageUserDO::getBindUserTime, null)); | ||
| 107 | + } | ||
| 108 | + | ||
| 109 | + default void updateEnabledFalseAndBrokerageTimeToNull(Long id) { | ||
| 110 | + update(null, new LambdaUpdateWrapper<BrokerageUserDO>() | ||
| 111 | + .eq(BrokerageUserDO::getId, id) | ||
| 112 | + .set(BrokerageUserDO::getBrokerageEnabled, false).set(BrokerageUserDO::getBrokerageTime, null)); | ||
| 113 | + } | ||
| 114 | + | ||
| 115 | +} |
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/dal/redis/no/TradeOrderNoRedisDAO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.trade.dal.redis.no; | ||
| 2 | + | ||
| 3 | +import cn.hutool.core.date.DatePattern; | ||
| 4 | +import cn.hutool.core.date.DateUtil; | ||
| 5 | +import org.springframework.data.redis.core.StringRedisTemplate; | ||
| 6 | +import org.springframework.stereotype.Repository; | ||
| 7 | + | ||
| 8 | +import javax.annotation.Resource; | ||
| 9 | +import java.time.LocalDateTime; | ||
| 10 | + | ||
| 11 | +/** | ||
| 12 | + * 订单序号的 Redis DAO | ||
| 13 | + * | ||
| 14 | + * @author HUIHUI | ||
| 15 | + */ | ||
| 16 | +@Repository | ||
| 17 | +public class TradeOrderNoRedisDAO { | ||
| 18 | + | ||
| 19 | + public static final String TRADE_ORDER_NO_PREFIX = "O"; | ||
| 20 | + | ||
| 21 | + @Resource | ||
| 22 | + private StringRedisTemplate stringRedisTemplate; | ||
| 23 | + | ||
| 24 | + /** | ||
| 25 | + * 生成序号 | ||
| 26 | + * | ||
| 27 | + * @param prefix 前缀 | ||
| 28 | + * @return 序号 | ||
| 29 | + */ | ||
| 30 | + public String generate(String prefix) { | ||
| 31 | + String noPrefix = prefix + DateUtil.format(LocalDateTime.now(), DatePattern.PURE_DATETIME_PATTERN); | ||
| 32 | + Long no = stringRedisTemplate.opsForValue().increment(noPrefix); | ||
| 33 | + return noPrefix + no; | ||
| 34 | + } | ||
| 35 | + | ||
| 36 | +} |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/job/brokerage/BrokerageRecordUnfreezeJob.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.BrokerageRecordService; | ||
| 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 BrokerageRecordUnfreezeJob implements JobHandler { | ||
| 19 | + | ||
| 20 | + @Resource | ||
| 21 | + private BrokerageRecordService brokerageRecordService; | ||
| 22 | + | ||
| 23 | + @Override | ||
| 24 | + public String execute(String param) { | ||
| 25 | + int count = brokerageRecordService.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
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/aftersale/TradeAfterSaleServiceImpl.java
| @@ -90,12 +90,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa | @@ -90,12 +90,7 @@ public class TradeAfterSaleServiceImpl implements TradeAfterSaleService, AfterSa | ||
| 90 | 90 | ||
| 91 | @Override | 91 | @Override |
| 92 | public TradeAfterSaleDO getAfterSale(Long id) { | 92 | public TradeAfterSaleDO getAfterSale(Long id) { |
| 93 | - TradeAfterSaleDO afterSale = tradeAfterSaleMapper.selectById(id); | ||
| 94 | - // TODO @puhui999;读不到,不要这里报错哈;交给前端报错;一般是读取信息不到,message 提示,然后 close tab; | ||
| 95 | - if (afterSale == null) { | ||
| 96 | - throw exception(AFTER_SALE_NOT_FOUND); | ||
| 97 | - } | ||
| 98 | - return afterSale; | 93 | + return tradeAfterSaleMapper.selectById(id); |
| 99 | } | 94 | } |
| 100 | 95 | ||
| 101 | // TODO 芋艿:拼团失败,要不要发起售后的方式退款?还是走取消逻辑? | 96 | // TODO 芋艿:拼团失败,要不要发起售后的方式退款?还是走取消逻辑? |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/bo/BrokerageAddReqBO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.trade.service.brokerage.bo; | ||
| 2 | + | ||
| 3 | +import lombok.AllArgsConstructor; | ||
| 4 | +import lombok.Data; | ||
| 5 | +import lombok.NoArgsConstructor; | ||
| 6 | + | ||
| 7 | +import javax.validation.constraints.NotBlank; | ||
| 8 | +import javax.validation.constraints.NotNull; | ||
| 9 | + | ||
| 10 | +/** | ||
| 11 | + * 佣金 增加 Request BO | ||
| 12 | + * | ||
| 13 | + * @author owen | ||
| 14 | + */ | ||
| 15 | +@Data | ||
| 16 | +@NoArgsConstructor | ||
| 17 | +@AllArgsConstructor | ||
| 18 | +public class BrokerageAddReqBO { | ||
| 19 | + | ||
| 20 | + /** | ||
| 21 | + * 业务编号 | ||
| 22 | + */ | ||
| 23 | + @NotBlank(message = "业务编号不能为空") | ||
| 24 | + private String bizId; | ||
| 25 | + /** | ||
| 26 | + * 佣金基数 | ||
| 27 | + */ | ||
| 28 | + @NotNull(message = "佣金基数不能为空") | ||
| 29 | + private Integer basePrice; | ||
| 30 | + /** | ||
| 31 | + * 一级佣金(固定) | ||
| 32 | + */ | ||
| 33 | + private Integer firstFixedPrice; | ||
| 34 | + /** | ||
| 35 | + * 二级佣金(固定) | ||
| 36 | + */ | ||
| 37 | + private Integer secondFixedPrice; | ||
| 38 | + | ||
| 39 | +} |