Commit c880dbfa609c6244721db844168882322f5eba5b
Merge remote-tracking branch 'origin/feature/mall_product' into feature/mall_product
Showing
112 changed files
with
2008 additions
and
967 deletions
sql/mysql/brokerage.sql
| @@ -2,41 +2,50 @@ | @@ -2,41 +2,50 @@ | ||
| 2 | create table trade_config | 2 | create table trade_config |
| 3 | ( | 3 | ( |
| 4 | id bigint auto_increment comment '自增主键' primary key, | 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 '租户编å·' | 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) default '' null comment '创建者', | ||
| 16 | + create_time datetime default CURRENT_TIMESTAMP not null comment '创建时间', | ||
| 17 | + updater varchar(64) 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 '交易ä¸å¿ƒé…ç½®'; | 21 | ) comment '交易ä¸å¿ƒé…ç½®'; |
| 22 | 22 | ||
| 23 | +# alter table trade_brokerage_user | ||
| 24 | +# add level int not null default 1 comment 'ç‰çº§' after frozen_price; | ||
| 25 | +# alter table trade_brokerage_user | ||
| 26 | +# add path varchar(2000) null comment '路径' after level; | ||
| 27 | + | ||
| 28 | + | ||
| 23 | -- å¢žåŠ åˆ†é”€ç”¨æˆ·æ‰©å±•è¡¨ | 29 | -- å¢žåŠ åˆ†é”€ç”¨æˆ·æ‰©å±•è¡¨ |
| 24 | create table trade_brokerage_user | 30 | create table trade_brokerage_user |
| 25 | ( | 31 | ( |
| 26 | id bigint auto_increment comment '用户编å·' primary key, | 32 | 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 '分销用户'; | 33 | + bind_user_id bigint null comment '推广员编å·', |
| 34 | + bind_user_time datetime null comment '推广员绑定时间', | ||
| 35 | + brokerage_enabled bit default 1 not null comment 'æ˜¯å¦æˆä¸ºæŽ¨å¹¿å‘˜', | ||
| 36 | + brokerage_time datetime null comment 'æˆä¸ºåˆ†é”€å‘˜æ—¶é—´', | ||
| 37 | + price int default 0 not null comment 'å¯ç”¨ä½£é‡‘', | ||
| 38 | + frozen_price int default 0 not null comment '冻结佣金', | ||
| 39 | + level int default 1 not null comment 'ç‰çº§', | ||
| 40 | + path varchar(2000) null comment '路径', | ||
| 41 | + creator varchar(64) default '' null comment '创建者', | ||
| 42 | + create_time datetime default CURRENT_TIMESTAMP not null comment '创建时间', | ||
| 43 | + updater varchar(64) default '' null comment '更新者', | ||
| 44 | + update_time datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment 'æ›´æ–°æ—¶é—´', | ||
| 45 | + deleted bit default b'0' not null comment '是å¦åˆ 除', | ||
| 46 | + tenant_id bigint default 0 not null comment '租户编å·' | ||
| 47 | +) | ||
| 48 | + comment '分销用户'; | ||
| 40 | 49 | ||
| 41 | create index idx_invite_user_id on trade_brokerage_user (bind_user_id) comment '推广员编å·'; | 50 | 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 'æ˜¯å¦æˆä¸ºæŽ¨å¹¿å‘˜'; | 51 | create index idx_agent on trade_brokerage_user (brokerage_enabled) comment 'æ˜¯å¦æˆä¸ºæŽ¨å¹¿å‘˜'; |
| @@ -44,26 +53,26 @@ create index idx_agent on trade_brokerage_user (brokerage_enabled) comment '是å | @@ -44,26 +53,26 @@ create index idx_agent on trade_brokerage_user (brokerage_enabled) comment '是å | ||
| 44 | 53 | ||
| 45 | create table trade_brokerage_record | 54 | create table trade_brokerage_record |
| 46 | ( | 55 | ( |
| 47 | - id int auto_increment comment 'ç¼–å·' | 56 | + id int auto_increment comment 'ç¼–å·' |
| 48 | primary key, | 57 | 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 '业务类型:1-订å•,2-æçް', | ||
| 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 | - source_user_type tinyint not null comment 'æ¥æºç”¨æˆ·ç±»åž‹ï¼š1-一级推广用户,2-二级推广用户', | ||
| 60 | - source_user_id bigint not null comment 'æ¥æºç”¨æˆ·ç¼–å·', | ||
| 61 | - creator varchar(64) collate utf8mb4_general_ci default '' null comment '创建者', | ||
| 62 | - create_time datetime default CURRENT_TIMESTAMP not null comment '创建时间', | ||
| 63 | - updater varchar(64) collate utf8mb4_general_ci default '' null comment '更新者', | ||
| 64 | - update_time datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment 'æ›´æ–°æ—¶é—´', | ||
| 65 | - deleted bit default b'0' not null comment '是å¦åˆ 除', | ||
| 66 | - tenant_id bigint default 0 not null comment '租户编å·' | 58 | + user_id bigint not null comment '用户编å·', |
| 59 | + biz_id varchar(64) default '' not null comment '业务编å·', | ||
| 60 | + biz_type tinyint default 0 not null comment '业务类型:1-订å•,2-æçް', | ||
| 61 | + title varchar(64) default '' not null comment 'æ ‡é¢˜', | ||
| 62 | + price int default 0 not null comment '金é¢', | ||
| 63 | + total_price int default 0 not null comment '当剿€»ä½£é‡‘', | ||
| 64 | + description varchar(500) default '' not null comment '说明', | ||
| 65 | + status tinyint default 0 not null comment '状æ€ï¼š0-待结算,1-已结算,2-已喿¶ˆ', | ||
| 66 | + frozen_days int default 0 not null comment '冻结时间(天)', | ||
| 67 | + unfreeze_time datetime null comment '解冻时间', | ||
| 68 | + source_user_level int not null comment 'æ¥æºç”¨æˆ·ç‰çº§', | ||
| 69 | + source_user_id bigint not null comment 'æ¥æºç”¨æˆ·ç¼–å·', | ||
| 70 | + creator varchar(64) default '' null comment '创建者', | ||
| 71 | + create_time datetime default CURRENT_TIMESTAMP not null comment '创建时间', | ||
| 72 | + updater varchar(64) default '' null comment '更新者', | ||
| 73 | + update_time datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment 'æ›´æ–°æ—¶é—´', | ||
| 74 | + deleted bit default b'0' not null comment '是å¦åˆ 除', | ||
| 75 | + tenant_id bigint default 0 not null comment '租户编å·' | ||
| 67 | ) | 76 | ) |
| 68 | comment '佣金记录'; | 77 | comment '佣金记录'; |
| 69 | 78 | ||
| @@ -76,26 +85,26 @@ create table trade_brokerage_withdraw | @@ -76,26 +85,26 @@ create table trade_brokerage_withdraw | ||
| 76 | ( | 85 | ( |
| 77 | id int auto_increment comment 'ç¼–å·' | 86 | id int auto_increment comment 'ç¼–å·' |
| 78 | primary key, | 87 | primary key, |
| 79 | - user_id bigint not null comment '用户编å·', | ||
| 80 | - price int default 0 not null comment 'æçް金é¢', | ||
| 81 | - fee_price int default 0 not null comment 'æçŽ°æ‰‹ç»è´¹', | ||
| 82 | - total_price int default 0 not null comment '当剿€»ä½£é‡‘', | ||
| 83 | - type tinyint default 0 not null comment 'æçŽ°ç±»åž‹ï¼š1-钱包;2-银行å¡ï¼›3-微信;4-支付å®', | ||
| 84 | - name varchar(64) null comment '真实姓å', | ||
| 85 | - account_no varchar(64) null comment 'è´¦å·', | ||
| 86 | - bank_name varchar(100) null comment '银行åç§°', | ||
| 87 | - bank_address varchar(200) null comment '开户地å€', | ||
| 88 | - account_qr_code_url varchar(512) null comment '收款ç ', | ||
| 89 | - status tinyint(2) default 0 not null comment '状æ€ï¼š0-å®¡æ ¸ä¸ï¼Œ10-å®¡æ ¸é€šè¿‡ 20-å®¡æ ¸ä¸é€šè¿‡ï¼›é¢„留:11 - æçްæˆåŠŸï¼›21-æçŽ°å¤±è´¥', | ||
| 90 | - audit_reason varchar(128) null comment 'å®¡æ ¸é©³å›žåŽŸå› ', | ||
| 91 | - audit_time datetime null comment 'å®¡æ ¸æ—¶é—´', | ||
| 92 | - remark varchar(500) null comment '备注', | ||
| 93 | - creator varchar(64) collate utf8mb4_general_ci default '' null comment '创建者', | ||
| 94 | - create_time datetime default CURRENT_TIMESTAMP not null comment '创建时间', | ||
| 95 | - updater varchar(64) collate utf8mb4_general_ci default '' null comment '更新者', | ||
| 96 | - update_time datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment 'æ›´æ–°æ—¶é—´', | ||
| 97 | - deleted bit default b'0' not null comment '是å¦åˆ 除', | ||
| 98 | - tenant_id bigint default 0 not null comment '租户编å·' | 88 | + user_id bigint not null comment '用户编å·', |
| 89 | + price int default 0 not null comment 'æçް金é¢', | ||
| 90 | + fee_price int default 0 not null comment 'æçŽ°æ‰‹ç»è´¹', | ||
| 91 | + total_price int default 0 not null comment '当剿€»ä½£é‡‘', | ||
| 92 | + type tinyint default 0 not null comment 'æçŽ°ç±»åž‹ï¼š1-钱包;2-银行å¡ï¼›3-微信;4-支付å®', | ||
| 93 | + name varchar(64) null comment '真实姓å', | ||
| 94 | + account_no varchar(64) null comment 'è´¦å·', | ||
| 95 | + bank_name varchar(100) null comment '银行åç§°', | ||
| 96 | + bank_address varchar(200) null comment '开户地å€', | ||
| 97 | + account_qr_code_url varchar(512) null comment '收款ç ', | ||
| 98 | + status tinyint(2) default 0 not null comment '状æ€ï¼š0-å®¡æ ¸ä¸ï¼Œ10-å®¡æ ¸é€šè¿‡ 20-å®¡æ ¸ä¸é€šè¿‡ï¼›é¢„留:11 - æçްæˆåŠŸï¼›21-æçŽ°å¤±è´¥', | ||
| 99 | + audit_reason varchar(128) null comment 'å®¡æ ¸é©³å›žåŽŸå› ', | ||
| 100 | + audit_time datetime null comment 'å®¡æ ¸æ—¶é—´', | ||
| 101 | + remark varchar(500) null comment '备注', | ||
| 102 | + creator varchar(64) default '' null comment '创建者', | ||
| 103 | + create_time datetime default CURRENT_TIMESTAMP not null comment '创建时间', | ||
| 104 | + updater varchar(64) default '' null comment '更新者', | ||
| 105 | + update_time datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment 'æ›´æ–°æ—¶é—´', | ||
| 106 | + deleted bit default b'0' not null comment '是å¦åˆ 除', | ||
| 107 | + tenant_id bigint default 0 not null comment '租户编å·' | ||
| 99 | ) | 108 | ) |
| 100 | comment '佣金æçް'; | 109 | comment '佣金æçް'; |
| 101 | 110 | ||
| @@ -139,12 +148,12 @@ values ('brokerage_record_status', '待结算', 0, 0), | @@ -139,12 +148,12 @@ values ('brokerage_record_status', '待结算', 0, 0), | ||
| 139 | 148 | ||
| 140 | insert into system_dict_type(type, name) | 149 | insert into system_dict_type(type, name) |
| 141 | values ('brokerage_withdraw_status', '佣金æçŽ°çŠ¶æ€'); | 150 | values ('brokerage_withdraw_status', '佣金æçŽ°çŠ¶æ€'); |
| 142 | -insert into system_dict_data(dict_type, label, value, sort) | ||
| 143 | -values ('brokerage_withdraw_status', 'å®¡æ ¸ä¸', 0, 0), | ||
| 144 | - ('brokerage_withdraw_status', 'å®¡æ ¸é€šè¿‡', 10, 10), | ||
| 145 | - ('brokerage_withdraw_status', 'æçްæˆåŠŸ', 11, 11), | ||
| 146 | - ('brokerage_withdraw_status', 'å®¡æ ¸ä¸é€šè¿‡', 20, 20), | ||
| 147 | - ('brokerage_withdraw_status', 'æçŽ°å¤±è´¥', 21, 21); | 151 | +insert into system_dict_data(dict_type, label, value, sort, color_type) |
| 152 | +values ('brokerage_withdraw_status', 'å®¡æ ¸ä¸', 0, 0, ''), | ||
| 153 | + ('brokerage_withdraw_status', 'å®¡æ ¸é€šè¿‡', 10, 10, 'success'), | ||
| 154 | + ('brokerage_withdraw_status', 'æçްæˆåŠŸ', 11, 11, 'success'), | ||
| 155 | + ('brokerage_withdraw_status', 'å®¡æ ¸ä¸é€šè¿‡', 20, 20, 'danger'), | ||
| 156 | + ('brokerage_withdraw_status', 'æçŽ°å¤±è´¥', 21, 21, 'danger'); | ||
| 148 | 157 | ||
| 149 | insert into system_dict_type(type, name) | 158 | insert into system_dict_type(type, name) |
| 150 | values ('brokerage_bank_name', '佣金æçŽ°é“¶è¡Œ'); | 159 | values ('brokerage_bank_name', '佣金æçŽ°é“¶è¡Œ'); |
| @@ -220,4 +229,10 @@ SELECT @parentId := LAST_INSERT_ID(); | @@ -220,4 +229,10 @@ SELECT @parentId := LAST_INSERT_ID(); | ||
| 220 | INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status) | 229 | INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status) |
| 221 | VALUES ('佣金æçŽ°æŸ¥è¯¢', 'trade:brokerage-withdraw:query', 3, 1, @parentId, '', '', '', 0); | 230 | VALUES ('佣金æçŽ°æŸ¥è¯¢', 'trade:brokerage-withdraw:query', 3, 1, @parentId, '', '', '', 0); |
| 222 | INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status) | 231 | INSERT INTO system_menu(name, permission, type, sort, parent_id, path, icon, component, status) |
| 223 | -VALUES ('佣金æçŽ°å®¡æ ¸', 'trade:brokerage-withdraw:audit', 3, 2, @parentId, '', '', '', 0); | ||
| 224 | \ No newline at end of file | 232 | \ No newline at end of file |
| 233 | +VALUES ('佣金æçŽ°å®¡æ ¸', 'trade:brokerage-withdraw:audit', 3, 2, @parentId, '', '', '', 0); | ||
| 234 | + | ||
| 235 | +-- ç«™å†…ä¿¡æ¨¡æ¿ | ||
| 236 | +INSERT INTO `ruoyi-vue-pro`.system_notify_template (name, code, nickname, content, type, params, status) | ||
| 237 | +VALUES | ||
| 238 | + ('佣金æçŽ°ï¼ˆå®¡æ ¸é€šè¿‡ï¼‰', 'brokerage_withdraw_audit_approve', 'system', '您在{createTime}æçŽ°ï¿¥{price}å…ƒçš„ç”³è¯·å·²é€šè¿‡å®¡æ ¸', 2, '["createTime","price"]', 0), | ||
| 239 | + ('佣金æçŽ°ï¼ˆå®¡æ ¸ä¸é€šè¿‡ï¼‰', 'brokerage_withdraw_audit_reject', 'system', '您在{createTime}æçŽ°ï¿¥{price}å…ƒçš„ç”³è¯·æœªé€šè¿‡å®¡æ ¸ï¼ŒåŽŸå› ï¼š{reason}', 2, '["createTime","price","reason"]', 0); |
yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/LocalDateTimeUtils.java
| @@ -43,6 +43,17 @@ public class LocalDateTimeUtils { | @@ -43,6 +43,17 @@ public class LocalDateTimeUtils { | ||
| 43 | return LocalDateTime.of(year, mouth, day, 0, 0, 0); | 43 | return LocalDateTime.of(year, mouth, day, 0, 0, 0); |
| 44 | } | 44 | } |
| 45 | 45 | ||
| 46 | + /** | ||
| 47 | + * 创建指定时间 | ||
| 48 | + * | ||
| 49 | + * @param timeStr 时间字符串 | ||
| 50 | + * @return 指定时间 | ||
| 51 | + */ | ||
| 52 | + public static LocalDateTime buildTime(String timeStr) { | ||
| 53 | + // TODO @puhui999:这个方法的实现,和 LocalDateTimeUtil.parse() 的差异点是啥呀 | ||
| 54 | + return LocalDateTime.of(LocalDate.now(), LocalTime.parse(timeStr)); | ||
| 55 | + } | ||
| 56 | + | ||
| 46 | public static LocalDateTime[] buildBetweenTime(int year1, int mouth1, int day1, | 57 | public static LocalDateTime[] buildBetweenTime(int year1, int mouth1, int day1, |
| 47 | int year2, int mouth2, int day2) { | 58 | int year2, int mouth2, int day2) { |
| 48 | return new LocalDateTime[]{buildTime(year1, mouth1, day1), buildTime(year2, mouth2, day2)}; | 59 | return new LocalDateTime[]{buildTime(year1, mouth1, day1), buildTime(year2, mouth2, day2)}; |
| @@ -63,6 +74,22 @@ public class LocalDateTimeUtils { | @@ -63,6 +74,22 @@ public class LocalDateTimeUtils { | ||
| 63 | } | 74 | } |
| 64 | 75 | ||
| 65 | /** | 76 | /** |
| 77 | + * 判断当前时间是否在该时间范围内 | ||
| 78 | + * | ||
| 79 | + * @param startTime 开始时间 | ||
| 80 | + * @param endTime 结束时间 | ||
| 81 | + * @return 是否 | ||
| 82 | + */ | ||
| 83 | + public static boolean isBetween(String startTime, String endTime) { | ||
| 84 | + if (startTime == null || endTime == null) { | ||
| 85 | + return false; | ||
| 86 | + } | ||
| 87 | + LocalDate nowDate = LocalDate.now(); | ||
| 88 | + return LocalDateTimeUtil.isIn(LocalDateTime.now(), LocalDateTime.of(nowDate, LocalTime.parse(startTime)), | ||
| 89 | + LocalDateTime.of(nowDate, LocalTime.parse(endTime))); | ||
| 90 | + } | ||
| 91 | + | ||
| 92 | + /** | ||
| 66 | * 判断时间段是否重叠 | 93 | * 判断时间段是否重叠 |
| 67 | * | 94 | * |
| 68 | * @param startTime1 开始 time1 | 95 | * @param startTime1 开始 time1 |
yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/query/LambdaQueryWrapperX.java
| @@ -100,6 +100,14 @@ public class LambdaQueryWrapperX<T> extends LambdaQueryWrapper<T> { | @@ -100,6 +100,14 @@ public class LambdaQueryWrapperX<T> extends LambdaQueryWrapper<T> { | ||
| 100 | return betweenIfPresent(column, val1, val2); | 100 | return betweenIfPresent(column, val1, val2); |
| 101 | } | 101 | } |
| 102 | 102 | ||
| 103 | + // TODO @疯狂:这个是 mysql 独有的,不好做成通用的哈。如果多层级,有没可能先查询一个层级,再查询一个层级;形成 set 后,直接去 in? | ||
| 104 | + public LambdaQueryWrapperX<T> findInSetIfPresent(SFunction<T, ?> column, Object val) { | ||
| 105 | + if (val != null) { | ||
| 106 | + return (LambdaQueryWrapperX<T>) super.apply("FIND_IN_SET({0}, " + columnToString(column) + ")", val); | ||
| 107 | + } | ||
| 108 | + return this; | ||
| 109 | + } | ||
| 110 | + | ||
| 103 | // ========== 重写父类方法,方便链式调用 ========== | 111 | // ========== 重写父类方法,方便链式调用 ========== |
| 104 | 112 | ||
| 105 | @Override | 113 | @Override |
yudao-module-infra/yudao-module-infra-biz/src/main/resources/codegen/java/service/serviceImpl.vm
| @@ -64,14 +64,14 @@ public class ${table.className}ServiceImpl implements ${table.className}Service | @@ -64,14 +64,14 @@ public class ${table.className}ServiceImpl implements ${table.className}Service | ||
| 64 | 64 | ||
| 65 | @Override | 65 | @Override |
| 66 | public ${table.className}DO get${simpleClassName}(${primaryColumn.javaType} id) { | 66 | public ${table.className}DO get${simpleClassName}(${primaryColumn.javaType} id) { |
| 67 | - if (CollUtil.isEmpty(ids)) { | ||
| 68 | - return ListUtil.empty(); | ||
| 69 | - } | ||
| 70 | return ${classNameVar}Mapper.selectById(id); | 67 | return ${classNameVar}Mapper.selectById(id); |
| 71 | } | 68 | } |
| 72 | 69 | ||
| 73 | @Override | 70 | @Override |
| 74 | public List<${table.className}DO> get${simpleClassName}List(Collection<${primaryColumn.javaType}> ids) { | 71 | public List<${table.className}DO> get${simpleClassName}List(Collection<${primaryColumn.javaType}> ids) { |
| 72 | + if (CollUtil.isEmpty(ids)) { | ||
| 73 | + return ListUtil.empty(); | ||
| 74 | + } | ||
| 75 | return ${classNameVar}Mapper.selectBatchIds(ids); | 75 | return ${classNameVar}Mapper.selectBatchIds(ids); |
| 76 | } | 76 | } |
| 77 | 77 |
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/ProductSkuApi.java
| @@ -39,7 +39,7 @@ public interface ProductSkuApi { | @@ -39,7 +39,7 @@ public interface ProductSkuApi { | ||
| 39 | List<ProductSkuRespDTO> getSkuListBySpuId(Collection<Long> spuIds); | 39 | List<ProductSkuRespDTO> getSkuListBySpuId(Collection<Long> spuIds); |
| 40 | 40 | ||
| 41 | /** | 41 | /** |
| 42 | - * 更新 SKU 库存 | 42 | + * 更新 SKU 库存(增加 or 减少) |
| 43 | * | 43 | * |
| 44 | * @param updateStockReqDTO 更新请求 | 44 | * @param updateStockReqDTO 更新请求 |
| 45 | */ | 45 | */ |
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/sku/dto/ProductSkuRespDTO.java
| @@ -59,14 +59,13 @@ public class ProductSkuRespDTO { | @@ -59,14 +59,13 @@ public class ProductSkuRespDTO { | ||
| 59 | * 商品体积,单位:m^3 平米 | 59 | * 商品体积,单位:m^3 平米 |
| 60 | */ | 60 | */ |
| 61 | private Double volume; | 61 | private Double volume; |
| 62 | - // TODO @puhui999:firstBrokeragePrice ;尴尬,我当时打错了;secondBrokeragePrice | ||
| 63 | /** | 62 | /** |
| 64 | * 一级分销的佣金,单位:分 | 63 | * 一级分销的佣金,单位:分 |
| 65 | */ | 64 | */ |
| 66 | - private Integer firstBrokerageRecord; | 65 | + private Integer firstBrokeragePrice; |
| 67 | /** | 66 | /** |
| 68 | * 二级分销的佣金,单位:分 | 67 | * 二级分销的佣金,单位:分 |
| 69 | */ | 68 | */ |
| 70 | - private Integer secondBrokerageRecord; | 69 | + private Integer secondBrokeragePrice; |
| 71 | 70 | ||
| 72 | } | 71 | } |
yudao-module-mall/yudao-module-product-api/src/main/java/cn/iocoder/yudao/module/product/api/spu/dto/ProductSpuRespDTO.java
| 1 | package cn.iocoder.yudao.module.product.api.spu.dto; | 1 | package cn.iocoder.yudao.module.product.api.spu.dto; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; | ||
| 4 | import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; | 3 | import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; |
| 5 | import lombok.Data; | 4 | import lombok.Data; |
| 6 | 5 | ||
| @@ -32,6 +31,12 @@ public class ProductSpuRespDTO { | @@ -32,6 +31,12 @@ public class ProductSpuRespDTO { | ||
| 32 | */ | 31 | */ |
| 33 | private String keyword; | 32 | private String keyword; |
| 34 | /** | 33 | /** |
| 34 | + * 单位 | ||
| 35 | + * | ||
| 36 | + * 对应 product_unit 数据字典 | ||
| 37 | + */ | ||
| 38 | + private Integer unit; | ||
| 39 | + /** | ||
| 35 | * 商品简介 | 40 | * 商品简介 |
| 36 | */ | 41 | */ |
| 37 | private String introduction; | 42 | private String introduction; |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/controller/admin/sku/vo/ProductSkuBaseVO.java
| @@ -51,10 +51,10 @@ public class ProductSkuBaseVO { | @@ -51,10 +51,10 @@ public class ProductSkuBaseVO { | ||
| 51 | private Double volume; | 51 | private Double volume; |
| 52 | 52 | ||
| 53 | @Schema(description = "一级分销的佣金,单位:分", example = "199") | 53 | @Schema(description = "一级分销的佣金,单位:分", example = "199") |
| 54 | - private Integer firstBrokerageRecord; | 54 | + private Integer firstBrokeragePrice; |
| 55 | 55 | ||
| 56 | @Schema(description = "二级分销的佣金,单位:分", example = "19") | 56 | @Schema(description = "二级分销的佣金,单位:分", example = "19") |
| 57 | - private Integer secondBrokerageRecord; | 57 | + private Integer secondBrokeragePrice; |
| 58 | 58 | ||
| 59 | @Schema(description = "属性数组") | 59 | @Schema(description = "属性数组") |
| 60 | private List<Property> properties; | 60 | private List<Property> properties; |
yudao-module-mall/yudao-module-product-biz/src/main/java/cn/iocoder/yudao/module/product/dal/dataobject/sku/ProductSkuDO.java
| @@ -81,11 +81,11 @@ public class ProductSkuDO extends BaseDO { | @@ -81,11 +81,11 @@ public class ProductSkuDO extends BaseDO { | ||
| 81 | /** | 81 | /** |
| 82 | * 一级分销的佣金,单位:分 | 82 | * 一级分销的佣金,单位:分 |
| 83 | */ | 83 | */ |
| 84 | - private Integer firstBrokerageRecord; | 84 | + private Integer firstBrokeragePrice; |
| 85 | /** | 85 | /** |
| 86 | * 二级分销的佣金,单位:分 | 86 | * 二级分销的佣金,单位:分 |
| 87 | */ | 87 | */ |
| 88 | - private Integer secondBrokerageRecord; | 88 | + private Integer secondBrokeragePrice; |
| 89 | 89 | ||
| 90 | // ========== 营销相关字段 ========= | 90 | // ========== 营销相关字段 ========= |
| 91 | 91 |
yudao-module-mall/yudao-module-product-biz/src/test/java/cn/iocoder/yudao/module/product/service/spu/ProductSpuServiceImplTest.java
| @@ -92,8 +92,8 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest { | @@ -92,8 +92,8 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest { | ||
| 92 | o.setMarketPrice(generaInt()); | 92 | o.setMarketPrice(generaInt()); |
| 93 | o.setStock(generaInt()); | 93 | o.setStock(generaInt()); |
| 94 | o.setWarnStock(10); | 94 | o.setWarnStock(10); |
| 95 | - o.setFirstBrokerageRecord(generaInt()); | ||
| 96 | - o.setSecondBrokerageRecord(generaInt()); | 95 | + o.setFirstBrokeragePrice(generaInt()); |
| 96 | + o.setSecondBrokeragePrice(generaInt()); | ||
| 97 | // 限制分数为两位数 | 97 | // 限制分数为两位数 |
| 98 | o.setWeight(RandomUtil.randomDouble(10,2, RoundingMode.HALF_UP)); | 98 | o.setWeight(RandomUtil.randomDouble(10,2, RoundingMode.HALF_UP)); |
| 99 | o.setVolume(RandomUtil.randomDouble(10,2, RoundingMode.HALF_UP)); | 99 | o.setVolume(RandomUtil.randomDouble(10,2, RoundingMode.HALF_UP)); |
| @@ -143,8 +143,8 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest { | @@ -143,8 +143,8 @@ public class ProductSpuServiceImplTest extends BaseDbUnitTest { | ||
| 143 | o.setMarketPrice(generaInt()); | 143 | o.setMarketPrice(generaInt()); |
| 144 | o.setStock(generaInt()); | 144 | o.setStock(generaInt()); |
| 145 | o.setWarnStock(10); | 145 | o.setWarnStock(10); |
| 146 | - o.setFirstBrokerageRecord(generaInt()); | ||
| 147 | - o.setSecondBrokerageRecord(generaInt()); | 146 | + o.setFirstBrokeragePrice(generaInt()); |
| 147 | + o.setSecondBrokeragePrice(generaInt()); | ||
| 148 | // 限制分数为两位数 | 148 | // 限制分数为两位数 |
| 149 | o.setWeight(RandomUtil.randomDouble(10,2, RoundingMode.HALF_UP)); | 149 | o.setWeight(RandomUtil.randomDouble(10,2, RoundingMode.HALF_UP)); |
| 150 | o.setVolume(RandomUtil.randomDouble(10,2, RoundingMode.HALF_UP)); | 150 | o.setVolume(RandomUtil.randomDouble(10,2, RoundingMode.HALF_UP)); |
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationApi.java renamed to yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationActivityApi.java
| 1 | package cn.iocoder.yudao.module.promotion.api.combination; | 1 | package cn.iocoder.yudao.module.promotion.api.combination; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationActivityUpdateStockReqDTO; | ||
| 4 | - | ||
| 5 | -// TODO @puhui999:是不是改成 CombinationActivityApi | ||
| 6 | /** | 3 | /** |
| 7 | * 拼团活动 Api 接口 | 4 | * 拼团活动 Api 接口 |
| 8 | * | 5 | * |
| 9 | * @author HUIHUI | 6 | * @author HUIHUI |
| 10 | */ | 7 | */ |
| 11 | -public interface CombinationApi { | 8 | +public interface CombinationActivityApi { |
| 12 | 9 | ||
| 13 | /** | 10 | /** |
| 14 | - * 更新活动库存 | 11 | + * 校验是否满足拼团条件 |
| 15 | * | 12 | * |
| 16 | - * @param reqDTO 请求 | 13 | + * @param activityId 活动编号 |
| 14 | + * @param userId 用户编号 | ||
| 15 | + * @param skuId sku 编号 | ||
| 16 | + * @param count 数量 | ||
| 17 | */ | 17 | */ |
| 18 | - // TODO @puhui999:应该是更新哇?还是校验哈; | ||
| 19 | - void validateCombination(CombinationActivityUpdateStockReqDTO reqDTO); | 18 | + void validateCombination(Long activityId, Long userId, Long skuId, Integer count); |
| 20 | 19 | ||
| 21 | } | 20 | } |
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationRecordApi.java
| 1 | package cn.iocoder.yudao.module.promotion.api.combination; | 1 | 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; | ||
| 5 | 4 | ||
| 6 | import javax.validation.Valid; | 5 | import javax.validation.Valid; |
| 7 | import java.time.LocalDateTime; | 6 | import java.time.LocalDateTime; |
| 8 | -import java.util.List; | ||
| 9 | 7 | ||
| 10 | // TODO @芋艿:后面也再撸撸这几个接口 | 8 | // TODO @芋艿:后面也再撸撸这几个接口 |
| 11 | 9 | ||
| @@ -33,26 +31,7 @@ public interface CombinationRecordApi { | @@ -33,26 +31,7 @@ public interface CombinationRecordApi { | ||
| 33 | boolean isCombinationRecordSuccess(Long userId, Long orderId); | 31 | boolean isCombinationRecordSuccess(Long userId, Long orderId); |
| 34 | 32 | ||
| 35 | /** | 33 | /** |
| 36 | - * 获取拼团记录 | ||
| 37 | - * | ||
| 38 | - * @param userId 用户编号 | ||
| 39 | - * @param activityId 活动编号 | ||
| 40 | - * @return 拼团记录列表 | ||
| 41 | - */ | ||
| 42 | - List<CombinationRecordRespDTO> getRecordListByUserIdAndActivityId(Long userId, Long activityId); | ||
| 43 | - | ||
| 44 | - /** | ||
| 45 | - * 验证组合限制数 | ||
| 46 | - * 校验是否满足限购要求 | ||
| 47 | - * | ||
| 48 | - * @param count 本次购买数量 | ||
| 49 | - * @param sumCount 已购买数量合计 | ||
| 50 | - * @param activityId 活动编号 | ||
| 51 | - */ | ||
| 52 | - void validateCombinationLimitCount(Long activityId, Integer count, Integer sumCount); | ||
| 53 | - | ||
| 54 | - /** | ||
| 55 | - * 更新拼团状态为成功 | 34 | + * 更新拼团状态为【成功】 |
| 56 | * | 35 | * |
| 57 | * @param userId 用户编号 | 36 | * @param userId 用户编号 |
| 58 | * @param orderId 订单编号 | 37 | * @param orderId 订单编号 |
| @@ -60,7 +39,7 @@ public interface CombinationRecordApi { | @@ -60,7 +39,7 @@ public interface CombinationRecordApi { | ||
| 60 | void updateRecordStatusToSuccess(Long userId, Long orderId); | 39 | void updateRecordStatusToSuccess(Long userId, Long orderId); |
| 61 | 40 | ||
| 62 | /** | 41 | /** |
| 63 | - * 更新拼团状态为失败 | 42 | + * 更新拼团状态为【失败】 |
| 64 | * | 43 | * |
| 65 | * @param userId 用户编号 | 44 | * @param userId 用户编号 |
| 66 | * @param orderId 订单编号 | 45 | * @param orderId 订单编号 |
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/dto/CombinationActivityUpdateStockReqDTO.java deleted
| 1 | -package cn.iocoder.yudao.module.promotion.api.combination.dto; | ||
| 2 | - | ||
| 3 | -import lombok.Data; | ||
| 4 | - | ||
| 5 | -import javax.validation.Valid; | ||
| 6 | -import javax.validation.constraints.NotNull; | ||
| 7 | - | ||
| 8 | -/** | ||
| 9 | - * 拼团活动更新活动库存 Request DTO | ||
| 10 | - * | ||
| 11 | - * @author HUIHUI | ||
| 12 | - */ | ||
| 13 | -@Data | ||
| 14 | -public class CombinationActivityUpdateStockReqDTO { | ||
| 15 | - | ||
| 16 | - // TODO @puhui999:是不是一个 activityId、count、skuId 参数就完事啦。 | ||
| 17 | - | ||
| 18 | - @NotNull(message = "活动编号不能为空") | ||
| 19 | - private Long activityId; | ||
| 20 | - | ||
| 21 | - @NotNull(message = "购买数量不能为空") | ||
| 22 | - private Integer count; | ||
| 23 | - | ||
| 24 | - @NotNull(message = "活动商品不能为空") | ||
| 25 | - private Item item; | ||
| 26 | - | ||
| 27 | - @Data | ||
| 28 | - @Valid | ||
| 29 | - public static class Item { | ||
| 30 | - | ||
| 31 | - @NotNull(message = "SPU 编号不能为空") | ||
| 32 | - private Long spuId; | ||
| 33 | - | ||
| 34 | - @NotNull(message = "SKU 编号活动商品不能为空") | ||
| 35 | - private Long skuId; | ||
| 36 | - | ||
| 37 | - @NotNull(message = "购买数量不能为空") | ||
| 38 | - private Integer count; | ||
| 39 | - | ||
| 40 | - } | ||
| 41 | - | ||
| 42 | -} |
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/dto/CombinationRecordCreateReqDTO.java
| @@ -13,26 +13,39 @@ import javax.validation.constraints.NotNull; | @@ -13,26 +13,39 @@ import javax.validation.constraints.NotNull; | ||
| 13 | @Data | 13 | @Data |
| 14 | public class CombinationRecordCreateReqDTO { | 14 | public class CombinationRecordCreateReqDTO { |
| 15 | 15 | ||
| 16 | - // TODO @puhui999:注释还是要的哈 | ||
| 17 | - | 16 | + /** |
| 17 | + * 拼团活动编号 | ||
| 18 | + */ | ||
| 18 | @NotNull(message = "拼团活动编号不能为空") | 19 | @NotNull(message = "拼团活动编号不能为空") |
| 19 | private Long activityId; | 20 | private Long activityId; |
| 20 | - | 21 | + /** |
| 22 | + * spu 编号 | ||
| 23 | + */ | ||
| 21 | @NotNull(message = "spu 编号不能为空") | 24 | @NotNull(message = "spu 编号不能为空") |
| 22 | private Long spuId; | 25 | private Long spuId; |
| 23 | - | 26 | + /** |
| 27 | + * sku 编号 | ||
| 28 | + */ | ||
| 24 | @NotNull(message = "sku 编号不能为空") | 29 | @NotNull(message = "sku 编号不能为空") |
| 25 | private Long skuId; | 30 | private Long skuId; |
| 26 | - | 31 | + /** |
| 32 | + * 订单编号 | ||
| 33 | + */ | ||
| 27 | @NotNull(message = "订单编号不能为空") | 34 | @NotNull(message = "订单编号不能为空") |
| 28 | private Long orderId; | 35 | private Long orderId; |
| 29 | - | 36 | + /** |
| 37 | + * 用户编号 | ||
| 38 | + */ | ||
| 30 | @NotNull(message = "用户编号不能为空") | 39 | @NotNull(message = "用户编号不能为空") |
| 31 | private Long userId; | 40 | private Long userId; |
| 32 | - | 41 | + /** |
| 42 | + * 团长编号 | ||
| 43 | + */ | ||
| 33 | @NotNull(message = "团长编号不能为空") | 44 | @NotNull(message = "团长编号不能为空") |
| 34 | private Long headId; | 45 | private Long headId; |
| 35 | - | 46 | + /** |
| 47 | + * 拼团商品单价 | ||
| 48 | + */ | ||
| 36 | @NotNull(message = "拼团商品单价不能为空") | 49 | @NotNull(message = "拼团商品单价不能为空") |
| 37 | private Integer combinationPrice; | 50 | private Integer combinationPrice; |
| 38 | 51 |
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/seckill/SeckillActivityApi.java
| 1 | package cn.iocoder.yudao.module.promotion.api.seckill; | 1 | package cn.iocoder.yudao.module.promotion.api.seckill; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.yudao.module.promotion.api.seckill.dto.SeckillActivityUpdateStockReqDTO; | ||
| 4 | - | ||
| 5 | /** | 3 | /** |
| 6 | * 秒杀活动 API 接口 | 4 | * 秒杀活动 API 接口 |
| 7 | * | 5 | * |
| @@ -9,11 +7,14 @@ import cn.iocoder.yudao.module.promotion.api.seckill.dto.SeckillActivityUpdateSt | @@ -9,11 +7,14 @@ import cn.iocoder.yudao.module.promotion.api.seckill.dto.SeckillActivityUpdateSt | ||
| 9 | */ | 7 | */ |
| 10 | public interface SeckillActivityApi { | 8 | public interface SeckillActivityApi { |
| 11 | 9 | ||
| 10 | + // TODO @puhui999:activityId 改成 id 好点哈; | ||
| 12 | /** | 11 | /** |
| 13 | * 更新秒杀库存 | 12 | * 更新秒杀库存 |
| 14 | * | 13 | * |
| 15 | - * @param updateStockReqDTO 请求 | 14 | + * @param activityId 活动编号 |
| 15 | + * @param skuId sku 编号 | ||
| 16 | + * @param count 数量 | ||
| 16 | */ | 17 | */ |
| 17 | - void updateSeckillStock(SeckillActivityUpdateStockReqDTO updateStockReqDTO); | 18 | + void updateSeckillStock(Long activityId, Long skuId, Integer count); |
| 18 | 19 | ||
| 19 | } | 20 | } |
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/api/seckill/dto/SeckillActivityUpdateStockReqDTO.java deleted
| 1 | -package cn.iocoder.yudao.module.promotion.api.seckill.dto; | ||
| 2 | - | ||
| 3 | -import lombok.Data; | ||
| 4 | - | ||
| 5 | -import javax.validation.Valid; | ||
| 6 | -import javax.validation.constraints.NotNull; | ||
| 7 | - | ||
| 8 | -/** | ||
| 9 | - * 更新秒杀库存 request DTO | ||
| 10 | - * | ||
| 11 | - * @author HUIHUI | ||
| 12 | - */ | ||
| 13 | -@Data | ||
| 14 | -public class SeckillActivityUpdateStockReqDTO { | ||
| 15 | - | ||
| 16 | - // TODO @puhui999:可以不用 dto,直接 activityId、skuId、count 即可 | ||
| 17 | - | ||
| 18 | - @NotNull(message = "活动编号不能为空") | ||
| 19 | - private Long activityId; | ||
| 20 | - | ||
| 21 | - @NotNull(message = "购买数量不能为空") | ||
| 22 | - private Integer count; | ||
| 23 | - | ||
| 24 | - @NotNull(message = "活动商品不能为空") | ||
| 25 | - private Item item; | ||
| 26 | - | ||
| 27 | - @Data | ||
| 28 | - @Valid | ||
| 29 | - public static class Item { | ||
| 30 | - | ||
| 31 | - @NotNull(message = "SPU 编号不能为空") | ||
| 32 | - private Long spuId; | ||
| 33 | - | ||
| 34 | - @NotNull(message = "SKU 编号活动商品不能为空") | ||
| 35 | - private Long skuId; | ||
| 36 | - | ||
| 37 | - @NotNull(message = "购买数量不能为空") | ||
| 38 | - private Integer count; | ||
| 39 | - | ||
| 40 | - } | ||
| 41 | - | ||
| 42 | -} |
yudao-module-mall/yudao-module-promotion-api/src/main/java/cn/iocoder/yudao/module/promotion/enums/ErrorCodeConstants.java
| @@ -56,6 +56,7 @@ public interface ErrorCodeConstants { | @@ -56,6 +56,7 @@ public interface ErrorCodeConstants { | ||
| 56 | ErrorCode SECKILL_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED_OR_END = new ErrorCode(1013008004, "秒杀活动未关闭或未结束,不能删除"); | 56 | ErrorCode SECKILL_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED_OR_END = new ErrorCode(1013008004, "秒杀活动未关闭或未结束,不能删除"); |
| 57 | ErrorCode SECKILL_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED = new ErrorCode(1013008005, "秒杀活动已关闭,不能重复关闭"); | 57 | ErrorCode SECKILL_ACTIVITY_CLOSE_FAIL_STATUS_CLOSED = new ErrorCode(1013008005, "秒杀活动已关闭,不能重复关闭"); |
| 58 | ErrorCode SECKILL_ACTIVITY_UPDATE_STOCK_FAIL = new ErrorCode(1013008006, "秒杀失败,原因秒杀库存不足"); | 58 | ErrorCode SECKILL_ACTIVITY_UPDATE_STOCK_FAIL = new ErrorCode(1013008006, "秒杀失败,原因秒杀库存不足"); |
| 59 | + ErrorCode SECKILL_ACTIVITY_FAIL_STATUS_CLOSED = new ErrorCode(1013008007, "秒杀活动已关闭"); | ||
| 59 | 60 | ||
| 60 | // ========== 秒杀时段 1013009000 ========== | 61 | // ========== 秒杀时段 1013009000 ========== |
| 61 | ErrorCode SECKILL_CONFIG_NOT_EXISTS = new ErrorCode(1013009000, "秒杀时段不存在"); | 62 | ErrorCode SECKILL_CONFIG_NOT_EXISTS = new ErrorCode(1013009000, "秒杀时段不存在"); |
yudao-module-mall/yudao-module-promotion-biz/pom.xml
| @@ -77,6 +77,10 @@ | @@ -77,6 +77,10 @@ | ||
| 77 | <groupId>cn.iocoder.boot</groupId> | 77 | <groupId>cn.iocoder.boot</groupId> |
| 78 | <artifactId>yudao-spring-boot-starter-excel</artifactId> | 78 | <artifactId>yudao-spring-boot-starter-excel</artifactId> |
| 79 | </dependency> | 79 | </dependency> |
| 80 | + <dependency> | ||
| 81 | + <groupId>cn.iocoder.boot</groupId> | ||
| 82 | + <artifactId>yudao-spring-boot-starter-biz-dict</artifactId> | ||
| 83 | + </dependency> | ||
| 80 | </dependencies> | 84 | </dependencies> |
| 81 | 85 | ||
| 82 | </project> | 86 | </project> |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationApiImpl.java renamed to yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationActivityApiImpl.java
| 1 | package cn.iocoder.yudao.module.promotion.api.combination; | 1 | package cn.iocoder.yudao.module.promotion.api.combination; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationActivityUpdateStockReqDTO; | ||
| 4 | import cn.iocoder.yudao.module.promotion.service.combination.CombinationActivityService; | 3 | import cn.iocoder.yudao.module.promotion.service.combination.CombinationActivityService; |
| 5 | import org.springframework.stereotype.Service; | 4 | import org.springframework.stereotype.Service; |
| 6 | -import org.springframework.validation.annotation.Validated; | ||
| 7 | 5 | ||
| 8 | import javax.annotation.Resource; | 6 | import javax.annotation.Resource; |
| 9 | 7 | ||
| @@ -13,15 +11,14 @@ import javax.annotation.Resource; | @@ -13,15 +11,14 @@ import javax.annotation.Resource; | ||
| 13 | * @author HUIHUI | 11 | * @author HUIHUI |
| 14 | */ | 12 | */ |
| 15 | @Service | 13 | @Service |
| 16 | -@Validated | ||
| 17 | -public class CombinationApiImpl implements CombinationApi { | 14 | +public class CombinationActivityApiImpl implements CombinationActivityApi { |
| 18 | 15 | ||
| 19 | @Resource | 16 | @Resource |
| 20 | private CombinationActivityService activityService; | 17 | private CombinationActivityService activityService; |
| 21 | 18 | ||
| 22 | @Override | 19 | @Override |
| 23 | - public void validateCombination(CombinationActivityUpdateStockReqDTO reqDTO) { | ||
| 24 | - activityService.validateCombination(reqDTO); | 20 | + public void validateCombination(Long activityId, Long userId, Long skuId, Integer count) { |
| 21 | + activityService.validateCombination(activityId, userId, skuId, count); | ||
| 25 | } | 22 | } |
| 26 | 23 | ||
| 27 | } | 24 | } |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/combination/CombinationRecordApiImpl.java
| 1 | package cn.iocoder.yudao.module.promotion.api.combination; | 1 | 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; | ||
| 5 | -import cn.iocoder.yudao.module.promotion.convert.combination.CombinationActivityConvert; | ||
| 6 | import cn.iocoder.yudao.module.promotion.enums.combination.CombinationRecordStatusEnum; | 4 | import cn.iocoder.yudao.module.promotion.enums.combination.CombinationRecordStatusEnum; |
| 7 | import cn.iocoder.yudao.module.promotion.service.combination.CombinationRecordService; | 5 | import cn.iocoder.yudao.module.promotion.service.combination.CombinationRecordService; |
| 8 | import org.springframework.stereotype.Service; | 6 | import org.springframework.stereotype.Service; |
| 9 | 7 | ||
| 10 | import javax.annotation.Resource; | 8 | import javax.annotation.Resource; |
| 11 | import java.time.LocalDateTime; | 9 | import java.time.LocalDateTime; |
| 12 | -import java.util.List; | ||
| 13 | 10 | ||
| 14 | /** | 11 | /** |
| 15 | * 拼团活动 API 实现类 | 12 | * 拼团活动 API 实现类 |
| @@ -33,16 +30,6 @@ public class CombinationRecordApiImpl implements CombinationRecordApi { | @@ -33,16 +30,6 @@ public class CombinationRecordApiImpl implements CombinationRecordApi { | ||
| 33 | } | 30 | } |
| 34 | 31 | ||
| 35 | @Override | 32 | @Override |
| 36 | - public List<CombinationRecordRespDTO> getRecordListByUserIdAndActivityId(Long userId, Long activityId) { | ||
| 37 | - return CombinationActivityConvert.INSTANCE.convert(recordService.getRecordListByUserIdAndActivityId(userId, activityId)); | ||
| 38 | - } | ||
| 39 | - | ||
| 40 | - @Override | ||
| 41 | - public void validateCombinationLimitCount(Long activityId, Integer count, Integer sumCount) { | ||
| 42 | - recordService.validateCombinationLimitCount(activityId, count, sumCount); | ||
| 43 | - } | ||
| 44 | - | ||
| 45 | - @Override | ||
| 46 | public void updateRecordStatusToSuccess(Long userId, Long orderId) { | 33 | public void updateRecordStatusToSuccess(Long userId, Long orderId) { |
| 47 | recordService.updateCombinationRecordStatusByUserIdAndOrderId(CombinationRecordStatusEnum.SUCCESS.getStatus(), userId, orderId); | 34 | recordService.updateCombinationRecordStatusByUserIdAndOrderId(CombinationRecordStatusEnum.SUCCESS.getStatus(), userId, orderId); |
| 48 | } | 35 | } |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/api/seckill/SeckillActivityApiImpl.java
| 1 | package cn.iocoder.yudao.module.promotion.api.seckill; | 1 | package cn.iocoder.yudao.module.promotion.api.seckill; |
| 2 | 2 | ||
| 3 | -import cn.iocoder.yudao.module.promotion.api.seckill.dto.SeckillActivityUpdateStockReqDTO; | ||
| 4 | import cn.iocoder.yudao.module.promotion.service.seckill.SeckillActivityService; | 3 | import cn.iocoder.yudao.module.promotion.service.seckill.SeckillActivityService; |
| 5 | import org.springframework.stereotype.Service; | 4 | import org.springframework.stereotype.Service; |
| 6 | 5 | ||
| @@ -18,8 +17,8 @@ public class SeckillActivityApiImpl implements SeckillActivityApi { | @@ -18,8 +17,8 @@ public class SeckillActivityApiImpl implements SeckillActivityApi { | ||
| 18 | private SeckillActivityService activityService; | 17 | private SeckillActivityService activityService; |
| 19 | 18 | ||
| 20 | @Override | 19 | @Override |
| 21 | - public void updateSeckillStock(SeckillActivityUpdateStockReqDTO updateStockReqDTO) { | ||
| 22 | - activityService.updateSeckillStock(updateStockReqDTO); | 20 | + public void updateSeckillStock(Long activityId, Long skuId, Integer count) { |
| 21 | + activityService.updateSeckillStock(activityId, skuId, count); | ||
| 23 | } | 22 | } |
| 24 | 23 | ||
| 25 | } | 24 | } |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/admin/bargain/BargainActivityController.java
| @@ -3,6 +3,8 @@ package cn.iocoder.yudao.module.promotion.controller.admin.bargain; | @@ -3,6 +3,8 @@ package cn.iocoder.yudao.module.promotion.controller.admin.bargain; | ||
| 3 | import cn.hutool.core.collection.CollUtil; | 3 | import cn.hutool.core.collection.CollUtil; |
| 4 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; | 4 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 5 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 5 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 6 | +import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi; | ||
| 7 | +import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; | ||
| 6 | import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityCreateReqVO; | 8 | import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityCreateReqVO; |
| 7 | import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityPageReqVO; | 9 | import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityPageReqVO; |
| 8 | import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityRespVO; | 10 | import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityRespVO; |
| @@ -19,8 +21,10 @@ import org.springframework.web.bind.annotation.*; | @@ -19,8 +21,10 @@ import org.springframework.web.bind.annotation.*; | ||
| 19 | 21 | ||
| 20 | import javax.annotation.Resource; | 22 | import javax.annotation.Resource; |
| 21 | import javax.validation.Valid; | 23 | import javax.validation.Valid; |
| 24 | +import java.util.List; | ||
| 22 | 25 | ||
| 23 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | 26 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| 27 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; | ||
| 24 | 28 | ||
| 25 | @Tag(name = "管理后台 - 砍价活动") | 29 | @Tag(name = "管理后台 - 砍价活动") |
| 26 | @RestController | 30 | @RestController |
| @@ -30,6 +34,8 @@ public class BargainActivityController { | @@ -30,6 +34,8 @@ public class BargainActivityController { | ||
| 30 | 34 | ||
| 31 | @Resource | 35 | @Resource |
| 32 | private BargainActivityService activityService; | 36 | private BargainActivityService activityService; |
| 37 | + @Resource | ||
| 38 | + private ProductSpuApi spuApi; | ||
| 33 | 39 | ||
| 34 | @PostMapping("/create") | 40 | @PostMapping("/create") |
| 35 | @Operation(summary = "创建砍价活动") | 41 | @Operation(summary = "创建砍价活动") |
| @@ -73,7 +79,10 @@ public class BargainActivityController { | @@ -73,7 +79,10 @@ public class BargainActivityController { | ||
| 73 | if (CollUtil.isEmpty(pageResult.getList())) { | 79 | if (CollUtil.isEmpty(pageResult.getList())) { |
| 74 | return success(PageResult.empty(pageResult.getTotal())); | 80 | return success(PageResult.empty(pageResult.getTotal())); |
| 75 | } | 81 | } |
| 76 | - return success(BargainActivityConvert.INSTANCE.convertPage(activityService.getBargainActivityPage(pageVO))); | 82 | + |
| 83 | + // 拼接数据 | ||
| 84 | + List<ProductSpuRespDTO> spuList = spuApi.getSpuList(convertList(pageResult.getList(), BargainActivityDO::getSpuId)); | ||
| 85 | + return success(BargainActivityConvert.INSTANCE.convertPage(pageResult, spuList)); | ||
| 77 | } | 86 | } |
| 78 | 87 | ||
| 79 | } | 88 | } |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/bargain/AppBargainActivityController.java
| 1 | package cn.iocoder.yudao.module.promotion.controller.app.bargain; | 1 | package cn.iocoder.yudao.module.promotion.controller.app.bargain; |
| 2 | 2 | ||
| 3 | +import cn.hutool.core.collection.CollUtil; | ||
| 3 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; | 4 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 4 | import cn.iocoder.yudao.framework.common.pojo.PageParam; | 5 | import cn.iocoder.yudao.framework.common.pojo.PageParam; |
| 5 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 6 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 6 | -import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils; | 7 | +import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi; |
| 8 | +import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; | ||
| 7 | import cn.iocoder.yudao.module.promotion.controller.app.bargain.vo.activity.AppBargainActivityDetailRespVO; | 9 | import cn.iocoder.yudao.module.promotion.controller.app.bargain.vo.activity.AppBargainActivityDetailRespVO; |
| 8 | import cn.iocoder.yudao.module.promotion.controller.app.bargain.vo.activity.AppBargainActivityRespVO; | 10 | import cn.iocoder.yudao.module.promotion.controller.app.bargain.vo.activity.AppBargainActivityRespVO; |
| 11 | +import cn.iocoder.yudao.module.promotion.convert.bargain.BargainActivityConvert; | ||
| 12 | +import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainActivityDO; | ||
| 13 | +import cn.iocoder.yudao.module.promotion.service.bargain.BargainActivityService; | ||
| 9 | import io.swagger.v3.oas.annotations.Operation; | 14 | import io.swagger.v3.oas.annotations.Operation; |
| 15 | +import io.swagger.v3.oas.annotations.Parameter; | ||
| 10 | import io.swagger.v3.oas.annotations.tags.Tag; | 16 | import io.swagger.v3.oas.annotations.tags.Tag; |
| 11 | import org.springframework.validation.annotation.Validated; | 17 | import org.springframework.validation.annotation.Validated; |
| 12 | import org.springframework.web.bind.annotation.GetMapping; | 18 | import org.springframework.web.bind.annotation.GetMapping; |
| @@ -14,97 +20,60 @@ import org.springframework.web.bind.annotation.RequestMapping; | @@ -14,97 +20,60 @@ import org.springframework.web.bind.annotation.RequestMapping; | ||
| 14 | import org.springframework.web.bind.annotation.RequestParam; | 20 | import org.springframework.web.bind.annotation.RequestParam; |
| 15 | import org.springframework.web.bind.annotation.RestController; | 21 | import org.springframework.web.bind.annotation.RestController; |
| 16 | 22 | ||
| 17 | -import java.time.Duration; | ||
| 18 | -import java.util.ArrayList; | 23 | +import javax.annotation.Resource; |
| 19 | import java.util.List; | 24 | import java.util.List; |
| 20 | 25 | ||
| 21 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | 26 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| 27 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; | ||
| 22 | 28 | ||
| 23 | @Tag(name = "用户 App - 砍价活动") | 29 | @Tag(name = "用户 App - 砍价活动") |
| 24 | @RestController | 30 | @RestController |
| 25 | @RequestMapping("/promotion/bargain-activity") | 31 | @RequestMapping("/promotion/bargain-activity") |
| 26 | @Validated | 32 | @Validated |
| 27 | public class AppBargainActivityController { | 33 | public class AppBargainActivityController { |
| 34 | + @Resource | ||
| 35 | + private BargainActivityService bargainActivityService; | ||
| 36 | + @Resource | ||
| 37 | + private ProductSpuApi spuApi; | ||
| 28 | 38 | ||
| 29 | @GetMapping("/page") | 39 | @GetMapping("/page") |
| 30 | - @Operation(summary = "获得砍价活动活动") // TODO 芋艿:只查询进行中,且在时间范围内的 | ||
| 31 | - // TODO 芋艿:缺少 swagger 注解 | 40 | + @Operation(summary = "获得砍价活动分页") |
| 32 | public CommonResult<PageResult<AppBargainActivityRespVO>> getBargainActivityPage(PageParam pageReqVO) { | 41 | public CommonResult<PageResult<AppBargainActivityRespVO>> getBargainActivityPage(PageParam pageReqVO) { |
| 33 | - List<AppBargainActivityRespVO> activityList = new ArrayList<>(); | ||
| 34 | - AppBargainActivityRespVO activity1 = new AppBargainActivityRespVO(); | ||
| 35 | - activity1.setId(1L); | ||
| 36 | - activity1.setName("618 大砍价"); | ||
| 37 | - activity1.setSpuId(2048L); | ||
| 38 | - activity1.setPicUrl("https://static.iocoder.cn/mall/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg"); | ||
| 39 | - activity1.setMarketPrice(50); | ||
| 40 | - activity1.setBargainPrice(100); | ||
| 41 | - activity1.setStartTime(LocalDateTimeUtils.addTime(Duration.ofDays(-2))); | ||
| 42 | - activity1.setEndTime(LocalDateTimeUtils.addTime(Duration.ofDays(1))); | ||
| 43 | - activity1.setStock(10); | ||
| 44 | - activityList.add(activity1); | ||
| 45 | - | ||
| 46 | - AppBargainActivityRespVO activity2 = new AppBargainActivityRespVO(); | ||
| 47 | - activity2.setId(2L); | ||
| 48 | - activity2.setName("双十一砍价"); | ||
| 49 | - activity2.setSpuId(4096L); | ||
| 50 | - activity2.setPicUrl("https://static.iocoder.cn/mall/132.jpeg"); | ||
| 51 | - activity2.setMarketPrice(100); | ||
| 52 | - activity2.setBargainPrice(200); | ||
| 53 | - activity2.setStartTime(LocalDateTimeUtils.addTime(Duration.ofDays(-2))); | ||
| 54 | - activity2.setEndTime(LocalDateTimeUtils.addTime(Duration.ofDays(1))); | ||
| 55 | - activity2.setStock(0); | ||
| 56 | - activityList.add(activity2); | ||
| 57 | - | ||
| 58 | - return success(new PageResult<>(activityList, 10L)); | 42 | + PageResult<BargainActivityDO> result = bargainActivityService.getBargainActivityPageForApp(pageReqVO); |
| 43 | + if (CollUtil.isEmpty(result.getList())) { | ||
| 44 | + return success(PageResult.empty(result.getTotal())); | ||
| 45 | + } | ||
| 46 | + // 拼接数据 | ||
| 47 | + List<ProductSpuRespDTO> spuList = spuApi.getSpuList(convertList(result.getList(), BargainActivityDO::getSpuId)); | ||
| 48 | + return success(BargainActivityConvert.INSTANCE.convertAppPage(result, spuList)); | ||
| 59 | } | 49 | } |
| 60 | 50 | ||
| 51 | + // TODO 芋艿:增加 Spring Cache | ||
| 61 | @GetMapping("/list") | 52 | @GetMapping("/list") |
| 62 | @Operation(summary = "获得砍价活动列表", description = "用于小程序首页") | 53 | @Operation(summary = "获得砍价活动列表", description = "用于小程序首页") |
| 63 | - // TODO 芋艿:增加 Spring Cache | ||
| 64 | - // TODO 芋艿:缺少 swagger 注解 | 54 | + @Parameter(name = "count", description = "需要展示的数量", example = "6") |
| 65 | public CommonResult<List<AppBargainActivityRespVO>> getBargainActivityList( | 55 | public CommonResult<List<AppBargainActivityRespVO>> getBargainActivityList( |
| 66 | @RequestParam(name = "count", defaultValue = "6") Integer count) { | 56 | @RequestParam(name = "count", defaultValue = "6") Integer count) { |
| 67 | - List<AppBargainActivityRespVO> activityList = new ArrayList<>(); | ||
| 68 | - AppBargainActivityRespVO activity1 = new AppBargainActivityRespVO(); | ||
| 69 | - activity1.setId(1L); | ||
| 70 | - activity1.setName("618 大砍价"); | ||
| 71 | - activity1.setSpuId(2048L); | ||
| 72 | - activity1.setPicUrl("https://static.iocoder.cn/mall/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg"); | ||
| 73 | - activity1.setMarketPrice(50); | ||
| 74 | - activity1.setBargainPrice(100); | ||
| 75 | - activityList.add(activity1); | ||
| 76 | - | ||
| 77 | - AppBargainActivityRespVO activity2 = new AppBargainActivityRespVO(); | ||
| 78 | - activity2.setId(2L); | ||
| 79 | - activity2.setName("双十一砍价"); | ||
| 80 | - activity2.setSpuId(4096L); | ||
| 81 | - activity2.setPicUrl("https://static.iocoder.cn/mall/132.jpeg"); | ||
| 82 | - activity2.setMarketPrice(100); | ||
| 83 | - activity2.setBargainPrice(200); | ||
| 84 | - activityList.add(activity2); | ||
| 85 | - | ||
| 86 | - return success(activityList); | 57 | + List<BargainActivityDO> list = bargainActivityService.getBargainActivityListForApp(count); |
| 58 | + if (CollUtil.isEmpty(list)) { | ||
| 59 | + return success(BargainActivityConvert.INSTANCE.convertAppList(list)); | ||
| 60 | + } | ||
| 61 | + // 拼接数据 | ||
| 62 | + List<ProductSpuRespDTO> spuList = spuApi.getSpuList(convertList(list, BargainActivityDO::getSpuId)); | ||
| 63 | + return success(BargainActivityConvert.INSTANCE.convertAppList(list, spuList)); | ||
| 87 | } | 64 | } |
| 88 | 65 | ||
| 89 | @GetMapping("/get-detail") | 66 | @GetMapping("/get-detail") |
| 90 | @Operation(summary = "获得砍价活动详情") | 67 | @Operation(summary = "获得砍价活动详情") |
| 91 | - // TODO 芋艿:缺少 swagger 注解 | 68 | + @Parameter(name = "id", description = "活动编号", example = "1") |
| 92 | public CommonResult<AppBargainActivityDetailRespVO> getBargainActivityDetail(@RequestParam("id") Long id) { | 69 | public CommonResult<AppBargainActivityDetailRespVO> getBargainActivityDetail(@RequestParam("id") Long id) { |
| 93 | - AppBargainActivityDetailRespVO activity = new AppBargainActivityDetailRespVO(); | ||
| 94 | - activity.setId(2L); | ||
| 95 | - activity.setName("618 大砍价"); | ||
| 96 | - activity.setSpuId(2048L); | ||
| 97 | - activity.setPicUrl("https://static.iocoder.cn/mall/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg"); | ||
| 98 | - activity.setMarketPrice(50); | ||
| 99 | - activity.setBargainPrice(100); | ||
| 100 | - activity.setStock(10); | ||
| 101 | - activity.setUnitName("件"); | ||
| 102 | - activity.setPrice(40); | ||
| 103 | - activity.setStartTime(LocalDateTimeUtils.addTime(Duration.ofDays(-2))); | ||
| 104 | - activity.setEndTime(LocalDateTimeUtils.addTime(Duration.ofDays(-10))); | ||
| 105 | - activity.setDescription("我吃西红柿"); | ||
| 106 | - activity.setSuccessCount(10); | ||
| 107 | - return success(activity); | 70 | + BargainActivityDO activity = bargainActivityService.getBargainActivity(id); |
| 71 | + if (activity == null) { | ||
| 72 | + return success(null); | ||
| 73 | + } | ||
| 74 | + // 拼接数据 | ||
| 75 | + ProductSpuRespDTO spu = spuApi.getSpu(activity.getSpuId()); | ||
| 76 | + return success(BargainActivityConvert.INSTANCE.convert(activity, spu)); | ||
| 108 | } | 77 | } |
| 109 | 78 | ||
| 110 | } | 79 | } |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/bargain/vo/activity/AppBargainActivityDetailRespVO.java
| @@ -45,7 +45,7 @@ public class AppBargainActivityDetailRespVO { | @@ -45,7 +45,7 @@ public class AppBargainActivityDetailRespVO { | ||
| 45 | @Schema(description = "商品单位", required = true, example = "个") // 从 SPU 的 unit 读取,然后转换 | 45 | @Schema(description = "商品单位", required = true, example = "个") // 从 SPU 的 unit 读取,然后转换 |
| 46 | private String unitName; | 46 | private String unitName; |
| 47 | 47 | ||
| 48 | - @Schema(description = "砍价最低金额,单位:分", required = true, example = "100") // 从砍价商品里取最低价 | 48 | + @Schema(description = "砍价最低金额,单位:分", required = true, example = "100") |
| 49 | private Integer bargainPrice; | 49 | private Integer bargainPrice; |
| 50 | 50 | ||
| 51 | @Schema(description = "砍价成功数量", required = true, example = "100") | 51 | @Schema(description = "砍价成功数量", required = true, example = "100") |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/bargain/vo/activity/AppBargainActivityRespVO.java
| @@ -36,7 +36,7 @@ public class AppBargainActivityRespVO { | @@ -36,7 +36,7 @@ public class AppBargainActivityRespVO { | ||
| 36 | @Schema(description = "商品市场价,单位:分", required = true, example = "50") // 从 SPU 的 marketPrice 读取 | 36 | @Schema(description = "商品市场价,单位:分", required = true, example = "50") // 从 SPU 的 marketPrice 读取 |
| 37 | private Integer marketPrice; | 37 | private Integer marketPrice; |
| 38 | 38 | ||
| 39 | - @Schema(description = "砍价最低金额,单位:分", required = true, example = "100") // 从砍价商品里取最低价 | 39 | + @Schema(description = "砍价最低金额,单位:分", required = true, example = "100") |
| 40 | private Integer bargainPrice; | 40 | private Integer bargainPrice; |
| 41 | 41 | ||
| 42 | } | 42 | } |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/AppSeckillActivityController.java
| 1 | package cn.iocoder.yudao.module.promotion.controller.app.seckill; | 1 | package cn.iocoder.yudao.module.promotion.controller.app.seckill; |
| 2 | 2 | ||
| 3 | +import cn.hutool.core.util.ObjectUtil; | ||
| 4 | +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | ||
| 3 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; | 5 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 6 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 7 | +import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi; | ||
| 8 | +import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; | ||
| 5 | import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityDetailRespVO; | 9 | import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityDetailRespVO; |
| 6 | import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityNowRespVO; | 10 | import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityNowRespVO; |
| 7 | import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityPageReqVO; | 11 | import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityPageReqVO; |
| 8 | import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityRespVO; | 12 | import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityRespVO; |
| 9 | -import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.config.AppSeckillConfigRespVO; | 13 | +import cn.iocoder.yudao.module.promotion.convert.seckill.seckillactivity.SeckillActivityConvert; |
| 14 | +import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO; | ||
| 15 | +import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillProductDO; | ||
| 16 | +import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillconfig.SeckillConfigDO; | ||
| 17 | +import cn.iocoder.yudao.module.promotion.service.seckill.SeckillActivityService; | ||
| 18 | +import cn.iocoder.yudao.module.promotion.service.seckill.SeckillConfigService; | ||
| 10 | import io.swagger.v3.oas.annotations.Operation; | 19 | import io.swagger.v3.oas.annotations.Operation; |
| 11 | import io.swagger.v3.oas.annotations.Parameter; | 20 | import io.swagger.v3.oas.annotations.Parameter; |
| 12 | import io.swagger.v3.oas.annotations.tags.Tag; | 21 | import io.swagger.v3.oas.annotations.tags.Tag; |
| 22 | +import org.springframework.context.annotation.Lazy; | ||
| 13 | import org.springframework.validation.annotation.Validated; | 23 | import org.springframework.validation.annotation.Validated; |
| 14 | import org.springframework.web.bind.annotation.GetMapping; | 24 | import org.springframework.web.bind.annotation.GetMapping; |
| 15 | import org.springframework.web.bind.annotation.RequestMapping; | 25 | import org.springframework.web.bind.annotation.RequestMapping; |
| 16 | import org.springframework.web.bind.annotation.RequestParam; | 26 | import org.springframework.web.bind.annotation.RequestParam; |
| 17 | import org.springframework.web.bind.annotation.RestController; | 27 | import org.springframework.web.bind.annotation.RestController; |
| 18 | 28 | ||
| 19 | -import java.time.LocalDateTime; | ||
| 20 | -import java.util.ArrayList; | 29 | +import javax.annotation.Resource; |
| 30 | +import java.util.Arrays; | ||
| 21 | import java.util.List; | 31 | import java.util.List; |
| 22 | 32 | ||
| 33 | +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | ||
| 23 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | 34 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| 35 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; | ||
| 36 | +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.isBetween; | ||
| 37 | +import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.SECKILL_ACTIVITY_FAIL_STATUS_CLOSED; | ||
| 24 | 38 | ||
| 25 | @Tag(name = "用户 App - 秒杀活动") | 39 | @Tag(name = "用户 App - 秒杀活动") |
| 26 | @RestController | 40 | @RestController |
| 27 | @RequestMapping("/promotion/seckill-activity") | 41 | @RequestMapping("/promotion/seckill-activity") |
| 28 | @Validated | 42 | @Validated |
| 29 | public class AppSeckillActivityController { | 43 | public class AppSeckillActivityController { |
| 44 | + @Resource | ||
| 45 | + private SeckillActivityService activityService; | ||
| 46 | + @Resource | ||
| 47 | + @Lazy | ||
| 48 | + private SeckillConfigService configService; | ||
| 49 | + | ||
| 50 | + @Resource | ||
| 51 | + private ProductSpuApi spuApi; | ||
| 30 | 52 | ||
| 31 | @GetMapping("/get-now") | 53 | @GetMapping("/get-now") |
| 32 | @Operation(summary = "获得当前秒杀活动") // 提供给首页使用 | 54 | @Operation(summary = "获得当前秒杀活动") // 提供给首页使用 |
| 33 | // TODO 芋艿:需要增加 spring cache | 55 | // TODO 芋艿:需要增加 spring cache |
| 34 | public CommonResult<AppSeckillActivityNowRespVO> getNowSeckillActivity() { | 56 | public CommonResult<AppSeckillActivityNowRespVO> getNowSeckillActivity() { |
| 35 | - AppSeckillActivityNowRespVO respVO = new AppSeckillActivityNowRespVO(); | ||
| 36 | - respVO.setConfig(new AppSeckillConfigRespVO().setId(10L).setStartTime("01:00").setEndTime("09:59")); | ||
| 37 | - List<AppSeckillActivityRespVO> activityList = new ArrayList<>(); | ||
| 38 | - AppSeckillActivityRespVO activity1 = new AppSeckillActivityRespVO(); | ||
| 39 | - activity1.setId(1L); | ||
| 40 | - activity1.setName("618 大秒杀"); | ||
| 41 | - activity1.setSpuId(2048L); | ||
| 42 | - activity1.setPicUrl("https://static.iocoder.cn/mall/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg"); | ||
| 43 | - activity1.setMarketPrice(50); | ||
| 44 | - activity1.setSeckillPrice(100); | ||
| 45 | - activityList.add(activity1); | 57 | + // 1. 获取当前时间处在哪个秒杀阶段 |
| 58 | + // TODO @puhui999:可以考虑在 service 写个方法;这样 controller 不用关注过多逻辑 | ||
| 59 | + List<SeckillConfigDO> configList = configService.getSeckillConfigList(); | ||
| 60 | + SeckillConfigDO filteredConfig = findFirst(configList, config -> ObjectUtil.equal(config.getStatus(), | ||
| 61 | + CommonStatusEnum.ENABLE.getStatus()) && isBetween(config.getStartTime(), config.getEndTime())); | ||
| 62 | + if (filteredConfig == null) { // 时段不存在直接返回 null | ||
| 63 | + return success(null); | ||
| 64 | + } | ||
| 65 | + | ||
| 66 | + // 2. 查询满足当前阶段的活动 | ||
| 67 | + // TODO @puhui999:最好直接返回开启的;不多查询数据 | ||
| 68 | + List<SeckillActivityDO> activityList = activityService.getSeckillActivityListByConfigIds(Arrays.asList(filteredConfig.getId())); | ||
| 69 | + List<SeckillActivityDO> filteredList = filterList(activityList, item -> ObjectUtil.equal(item.getStatus(), CommonStatusEnum.ENABLE.getStatus())); | ||
| 46 | 70 | ||
| 47 | - AppSeckillActivityRespVO activity2 = new AppSeckillActivityRespVO(); | ||
| 48 | - activity2.setId(2L); | ||
| 49 | - activity2.setName("双十一大秒杀"); | ||
| 50 | - activity2.setSpuId(4096L); | ||
| 51 | - activity2.setPicUrl("https://static.iocoder.cn/mall/132.jpeg"); | ||
| 52 | - activity2.setMarketPrice(100); | ||
| 53 | - activity2.setSeckillPrice(200); | ||
| 54 | - activityList.add(activity2); | ||
| 55 | - respVO.setActivities(activityList); | ||
| 56 | - return success(respVO); | 71 | + // 3. 拼接数据 |
| 72 | + List<ProductSpuRespDTO> spuList = spuApi.getSpuList(convertList(filteredList, SeckillActivityDO::getSpuId)); | ||
| 73 | + return success(SeckillActivityConvert.INSTANCE.convert(filteredConfig, filteredList, spuList)); | ||
| 57 | } | 74 | } |
| 58 | 75 | ||
| 59 | @GetMapping("/page") | 76 | @GetMapping("/page") |
| 60 | @Operation(summary = "获得秒杀活动分页") | 77 | @Operation(summary = "获得秒杀活动分页") |
| 61 | - // TODO @芋艿:分页参数 | ||
| 62 | public CommonResult<PageResult<AppSeckillActivityRespVO>> getSeckillActivityPage(AppSeckillActivityPageReqVO pageReqVO) { | 78 | public CommonResult<PageResult<AppSeckillActivityRespVO>> getSeckillActivityPage(AppSeckillActivityPageReqVO pageReqVO) { |
| 63 | - List<AppSeckillActivityRespVO> activityList = new ArrayList<>(); | ||
| 64 | - AppSeckillActivityRespVO activity1 = new AppSeckillActivityRespVO(); | ||
| 65 | - activity1.setId(1L); | ||
| 66 | - activity1.setName("618 大秒杀"); | ||
| 67 | - activity1.setSpuId(2048L); | ||
| 68 | - activity1.setPicUrl("https://static.iocoder.cn/mall/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg"); | ||
| 69 | - activity1.setMarketPrice(50); | ||
| 70 | - activity1.setSeckillPrice(100); | ||
| 71 | - activity1.setUnitName("个"); | ||
| 72 | - activity1.setStock(1); | ||
| 73 | - activity1.setTotalStock(2); | ||
| 74 | - activityList.add(activity1); | 79 | + // 1. 查询满足当前阶段的活动 |
| 80 | + PageResult<SeckillActivityDO> pageResult = activityService.getSeckillActivityAppPageByConfigId(pageReqVO); | ||
| 75 | 81 | ||
| 76 | - AppSeckillActivityRespVO activity2 = new AppSeckillActivityRespVO(); | ||
| 77 | - activity2.setId(2L); | ||
| 78 | - activity2.setName("双十一大秒杀"); | ||
| 79 | - activity2.setSpuId(4096L); | ||
| 80 | - activity2.setPicUrl("https://static.iocoder.cn/mall/132.jpeg"); | ||
| 81 | - activity2.setMarketPrice(100); | ||
| 82 | - activity2.setSeckillPrice(200); | ||
| 83 | - activity2.setUnitName("套"); | ||
| 84 | - activity2.setStock(2); | ||
| 85 | - activity2.setTotalStock(3); | ||
| 86 | - activityList.add(activity2); | ||
| 87 | - return success(new PageResult<>(activityList, 100L)); | 82 | + // 2. 拼接数据 |
| 83 | + List<ProductSpuRespDTO> spuList = spuApi.getSpuList(convertList(pageResult.getList(), SeckillActivityDO::getSpuId)); | ||
| 84 | + return success(SeckillActivityConvert.INSTANCE.convertPage(pageResult, spuList)); | ||
| 88 | } | 85 | } |
| 89 | 86 | ||
| 90 | @GetMapping("/get-detail") | 87 | @GetMapping("/get-detail") |
| 91 | @Operation(summary = "获得秒杀活动明细") | 88 | @Operation(summary = "获得秒杀活动明细") |
| 92 | @Parameter(name = "id", description = "活动编号", required = true, example = "1024") | 89 | @Parameter(name = "id", description = "活动编号", required = true, example = "1024") |
| 93 | public CommonResult<AppSeckillActivityDetailRespVO> getSeckillActivity(@RequestParam("id") Long id) { | 90 | public CommonResult<AppSeckillActivityDetailRespVO> getSeckillActivity(@RequestParam("id") Long id) { |
| 91 | + // 1、获取当前时间处在哪个秒杀阶段 | ||
| 92 | + // TODO puhui999:这里,和 58 行是雷同的 | ||
| 93 | + List<SeckillConfigDO> configList = configService.getSeckillConfigList(); | ||
| 94 | + SeckillConfigDO filteredConfig = findFirst(configList, config -> ObjectUtil.equal(config.getStatus(), | ||
| 95 | + CommonStatusEnum.ENABLE.getStatus()) && isBetween(config.getStartTime(), config.getEndTime())); | ||
| 96 | + if (filteredConfig == null) { // 时段不存在直接返回 null | ||
| 97 | + return success(null); | ||
| 98 | + } | ||
| 99 | + | ||
| 100 | + // 2. 获取活动 | ||
| 101 | + SeckillActivityDO seckillActivity = activityService.getSeckillActivity(id); | ||
| 102 | + if (seckillActivity == null) { | ||
| 103 | + return success(null); | ||
| 104 | + } | ||
| 94 | // TODO 芋艿:如果禁用的时候,需要抛出异常; | 105 | // TODO 芋艿:如果禁用的时候,需要抛出异常; |
| 95 | - AppSeckillActivityDetailRespVO obj = new AppSeckillActivityDetailRespVO(); | ||
| 96 | - // 设置其属性的值 | ||
| 97 | - obj.setId(id); | ||
| 98 | - obj.setName("晚九点限时秒杀"); | ||
| 99 | - obj.setStatus(1); | ||
| 100 | - obj.setStartTime(LocalDateTime.of(2023, 6, 16, 0, 0, 0)); | ||
| 101 | - obj.setEndTime(LocalDateTime.of(2023, 6, 20, 23, 59, 0)); | ||
| 102 | - obj.setSpuId(633L); | ||
| 103 | - obj.setSingleLimitCount(2); | ||
| 104 | - obj.setTotalLimitCount(3); | ||
| 105 | - obj.setStock(100); | ||
| 106 | - obj.setTotalStock(200); | 106 | + if (ObjectUtil.equal(seckillActivity.getStatus(), CommonStatusEnum.DISABLE.getStatus())) { |
| 107 | + throw exception(SECKILL_ACTIVITY_FAIL_STATUS_CLOSED); | ||
| 108 | + } | ||
| 107 | 109 | ||
| 108 | - // 创建一个Product对象的列表 | ||
| 109 | - List<AppSeckillActivityDetailRespVO.Product> productList = new ArrayList<>(); | ||
| 110 | - // 创建三个新的Product对象并设置其属性的值 | ||
| 111 | - AppSeckillActivityDetailRespVO.Product product1 = new AppSeckillActivityDetailRespVO.Product(); | ||
| 112 | - product1.setSkuId(1L); | ||
| 113 | - product1.setSeckillPrice(100); | ||
| 114 | - product1.setStock(50); | ||
| 115 | - // 将第一个Product对象添加到列表中 | ||
| 116 | - productList.add(product1); | ||
| 117 | - // 创建第二个Product对象并设置其属性的值 | ||
| 118 | - AppSeckillActivityDetailRespVO.Product product2 = new AppSeckillActivityDetailRespVO.Product(); | ||
| 119 | - product2.setSkuId(2L); | ||
| 120 | - product2.setSeckillPrice(200); | ||
| 121 | - product2.setStock(100); | ||
| 122 | - // 将第二个Product对象添加到列表中 | ||
| 123 | - productList.add(product2); | ||
| 124 | - // 创建第三个Product对象并设置其属性的值 | ||
| 125 | - AppSeckillActivityDetailRespVO.Product product3 = new AppSeckillActivityDetailRespVO.Product(); | ||
| 126 | - product3.setSkuId(3L); | ||
| 127 | - product3.setSeckillPrice(300); | ||
| 128 | - product3.setStock(150); | ||
| 129 | - // 将第三个Product对象添加到列表中 | ||
| 130 | - productList.add(product3); | ||
| 131 | - // 将Product列表设置为对象的属性值 | ||
| 132 | - obj.setProducts(productList); | ||
| 133 | - return success(obj); | 110 | + // 3. 拼接数据 |
| 111 | + List<SeckillProductDO> products = activityService.getSeckillProductListByActivityId(seckillActivity.getId()); | ||
| 112 | + return success(SeckillActivityConvert.INSTANCE.convert3(seckillActivity, products, filteredConfig)); | ||
| 134 | } | 113 | } |
| 135 | 114 | ||
| 136 | } | 115 | } |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/AppSeckillConfigController.java
| 1 | package cn.iocoder.yudao.module.promotion.controller.app.seckill; | 1 | package cn.iocoder.yudao.module.promotion.controller.app.seckill; |
| 2 | 2 | ||
| 3 | +import cn.hutool.core.collection.CollectionUtil; | ||
| 4 | +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | ||
| 3 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; | 5 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 4 | import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.config.AppSeckillConfigRespVO; | 6 | import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.config.AppSeckillConfigRespVO; |
| 7 | +import cn.iocoder.yudao.module.promotion.convert.seckill.seckillconfig.SeckillConfigConvert; | ||
| 8 | +import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillconfig.SeckillConfigDO; | ||
| 9 | +import cn.iocoder.yudao.module.promotion.service.seckill.SeckillConfigService; | ||
| 5 | import io.swagger.v3.oas.annotations.Operation; | 10 | import io.swagger.v3.oas.annotations.Operation; |
| 6 | import io.swagger.v3.oas.annotations.tags.Tag; | 11 | import io.swagger.v3.oas.annotations.tags.Tag; |
| 7 | import org.springframework.validation.annotation.Validated; | 12 | import org.springframework.validation.annotation.Validated; |
| @@ -9,7 +14,8 @@ import org.springframework.web.bind.annotation.GetMapping; | @@ -9,7 +14,8 @@ import org.springframework.web.bind.annotation.GetMapping; | ||
| 9 | import org.springframework.web.bind.annotation.RequestMapping; | 14 | import org.springframework.web.bind.annotation.RequestMapping; |
| 10 | import org.springframework.web.bind.annotation.RestController; | 15 | import org.springframework.web.bind.annotation.RestController; |
| 11 | 16 | ||
| 12 | -import java.util.Arrays; | 17 | +import javax.annotation.Resource; |
| 18 | +import java.util.Collections; | ||
| 13 | import java.util.List; | 19 | import java.util.List; |
| 14 | 20 | ||
| 15 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | 21 | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; |
| @@ -19,18 +25,19 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | @@ -19,18 +25,19 @@ import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | ||
| 19 | @RequestMapping("/promotion/seckill-config") | 25 | @RequestMapping("/promotion/seckill-config") |
| 20 | @Validated | 26 | @Validated |
| 21 | public class AppSeckillConfigController { | 27 | public class AppSeckillConfigController { |
| 28 | + @Resource | ||
| 29 | + private SeckillConfigService configService; | ||
| 22 | 30 | ||
| 23 | @GetMapping("/list") | 31 | @GetMapping("/list") |
| 24 | @Operation(summary = "获得秒杀时间段列表") | 32 | @Operation(summary = "获得秒杀时间段列表") |
| 25 | public CommonResult<List<AppSeckillConfigRespVO>> getSeckillConfigList() { | 33 | public CommonResult<List<AppSeckillConfigRespVO>> getSeckillConfigList() { |
| 26 | - return success(Arrays.asList( | ||
| 27 | - new AppSeckillConfigRespVO().setId(1L).setStartTime("00:00").setEndTime("09:59") | ||
| 28 | - .setSliderPicUrls(Arrays.asList("https://static.iocoder.cn/mall/a79f5d2ea6bf0c3c11b2127332dfe2df.jpg", | ||
| 29 | - "https://static.iocoder.cn/mall/132.jpeg")), | ||
| 30 | - new AppSeckillConfigRespVO().setId(2L).setStartTime("10:00").setEndTime("12:59"), | ||
| 31 | - new AppSeckillConfigRespVO().setId(2L).setStartTime("13:00").setEndTime("22:59"), | ||
| 32 | - new AppSeckillConfigRespVO().setId(2L).setStartTime("23:00").setEndTime("23:59") | ||
| 33 | - )); | 34 | + List<SeckillConfigDO> list = configService.getSeckillConfigListByStatus(CommonStatusEnum.ENABLE.getStatus()); |
| 35 | + // TODO @puhui999:如果这种,不用判空也问题不大; | ||
| 36 | + if (CollectionUtil.isEmpty(list)) { | ||
| 37 | + return success(Collections.emptyList()); | ||
| 38 | + } | ||
| 39 | + | ||
| 40 | + return success(SeckillConfigConvert.INSTANCE.convertList2(list)); | ||
| 34 | } | 41 | } |
| 35 | 42 | ||
| 36 | } | 43 | } |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/vo/activity/AppSeckillActivityDetailRespVO.java
| @@ -19,7 +19,7 @@ public class AppSeckillActivityDetailRespVO { | @@ -19,7 +19,7 @@ public class AppSeckillActivityDetailRespVO { | ||
| 19 | @Schema(description = "活动状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | 19 | @Schema(description = "活动状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") |
| 20 | private Integer status; | 20 | private Integer status; |
| 21 | 21 | ||
| 22 | - // TODO @芋艿:开始时间、结束时间,要和场次结合起来;就是要算到当前场次,是几点哈; | 22 | + // TODO @芋艿:开始时间、结束时间,要和场次结合起来;就是要算到当前场次,是几点哈; |
| 23 | 23 | ||
| 24 | @Schema(description = "活动开始时间", requiredMode = Schema.RequiredMode.REQUIRED) | 24 | @Schema(description = "活动开始时间", requiredMode = Schema.RequiredMode.REQUIRED) |
| 25 | private LocalDateTime startTime; | 25 | private LocalDateTime startTime; |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/seckill/vo/activity/AppSeckillActivityRespVO.java
| @@ -31,7 +31,6 @@ public class AppSeckillActivityRespVO { | @@ -31,7 +31,6 @@ public class AppSeckillActivityRespVO { | ||
| 31 | private Integer totalStock; | 31 | private Integer totalStock; |
| 32 | 32 | ||
| 33 | @Schema(description = "秒杀金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "100") | 33 | @Schema(description = "秒杀金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "100") |
| 34 | - // 从秒杀商品里取最低价 | ||
| 35 | private Integer seckillPrice; | 34 | private Integer seckillPrice; |
| 36 | 35 | ||
| 37 | } | 36 | } |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/bargain/BargainActivityConvert.java
| 1 | package cn.iocoder.yudao.module.promotion.convert.bargain; | 1 | package cn.iocoder.yudao.module.promotion.convert.bargain; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | ||
| 5 | +import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils; | ||
| 6 | +import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; | ||
| 7 | +import cn.iocoder.yudao.module.product.enums.DictTypeConstants; | ||
| 4 | import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityBaseVO; | 8 | import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityBaseVO; |
| 5 | import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityRespVO; | 9 | import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityRespVO; |
| 6 | import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityUpdateReqVO; | 10 | import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityUpdateReqVO; |
| 11 | +import cn.iocoder.yudao.module.promotion.controller.app.bargain.vo.activity.AppBargainActivityDetailRespVO; | ||
| 12 | +import cn.iocoder.yudao.module.promotion.controller.app.bargain.vo.activity.AppBargainActivityRespVO; | ||
| 7 | import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainActivityDO; | 13 | import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainActivityDO; |
| 8 | import org.mapstruct.Mapper; | 14 | import org.mapstruct.Mapper; |
| 9 | import org.mapstruct.factory.Mappers; | 15 | import org.mapstruct.factory.Mappers; |
| 10 | 16 | ||
| 11 | import java.util.List; | 17 | import java.util.List; |
| 18 | +import java.util.Map; | ||
| 19 | + | ||
| 20 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; | ||
| 21 | +import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen; | ||
| 12 | 22 | ||
| 13 | /** | 23 | /** |
| 14 | * 拼团活动 Convert | 24 | * 拼团活动 Convert |
| @@ -30,4 +40,65 @@ public interface BargainActivityConvert { | @@ -30,4 +40,65 @@ public interface BargainActivityConvert { | ||
| 30 | 40 | ||
| 31 | PageResult<BargainActivityRespVO> convertPage(PageResult<BargainActivityDO> page); | 41 | PageResult<BargainActivityRespVO> convertPage(PageResult<BargainActivityDO> page); |
| 32 | 42 | ||
| 43 | + default PageResult<BargainActivityRespVO> convertPage(PageResult<BargainActivityDO> page, List<ProductSpuRespDTO> spuList) { | ||
| 44 | + PageResult<BargainActivityRespVO> result = convertPage(page); | ||
| 45 | + // 拼接关联属性 | ||
| 46 | + Map<Long, ProductSpuRespDTO> spuMap = convertMap(spuList, ProductSpuRespDTO::getId); | ||
| 47 | + List<BargainActivityRespVO> list = CollectionUtils.convertList(result.getList(), item -> { | ||
| 48 | + findAndThen(spuMap, item.getSpuId(), spu -> { | ||
| 49 | + // TODO @puhui999:这里可以使用链式哈 | ||
| 50 | + item.setPicUrl(spu.getPicUrl()); | ||
| 51 | + item.setSpuName(spu.getName()); | ||
| 52 | + }); | ||
| 53 | + return item; | ||
| 54 | + }); | ||
| 55 | + result.setList(list); | ||
| 56 | + return result; | ||
| 57 | + } | ||
| 58 | + | ||
| 59 | + AppBargainActivityDetailRespVO convert1(BargainActivityDO bean); | ||
| 60 | + | ||
| 61 | + default AppBargainActivityDetailRespVO convert(BargainActivityDO bean, ProductSpuRespDTO spu) { | ||
| 62 | + AppBargainActivityDetailRespVO detail = convert1(bean); | ||
| 63 | + if (spu != null) { | ||
| 64 | + detail.setPicUrl(spu.getPicUrl()); | ||
| 65 | + detail.setMarketPrice(spu.getMarketPrice()); | ||
| 66 | + detail.setUnitName(DictFrameworkUtils.getDictDataLabel(DictTypeConstants.PRODUCT_UNIT, spu.getUnit())); | ||
| 67 | + } | ||
| 68 | + return detail; | ||
| 69 | + } | ||
| 70 | + | ||
| 71 | + PageResult<AppBargainActivityRespVO> convertAppPage(PageResult<BargainActivityDO> page); | ||
| 72 | + | ||
| 73 | + default PageResult<AppBargainActivityRespVO> convertAppPage(PageResult<BargainActivityDO> page, List<ProductSpuRespDTO> spuList) { | ||
| 74 | + PageResult<AppBargainActivityRespVO> result = convertAppPage(page); | ||
| 75 | + // 拼接关联属性 | ||
| 76 | + Map<Long, ProductSpuRespDTO> spuMap = convertMap(spuList, ProductSpuRespDTO::getId); | ||
| 77 | + List<AppBargainActivityRespVO> list = CollectionUtils.convertList(result.getList(), item -> { | ||
| 78 | + findAndThen(spuMap, item.getSpuId(), spu -> { | ||
| 79 | + // TODO @puhui999:这里可以使用链式哈 | ||
| 80 | + item.setPicUrl(spu.getPicUrl()); | ||
| 81 | + item.setMarketPrice(spu.getMarketPrice()); | ||
| 82 | + }); | ||
| 83 | + return item; | ||
| 84 | + }); | ||
| 85 | + result.setList(list); | ||
| 86 | + return result; | ||
| 87 | + } | ||
| 88 | + | ||
| 89 | + List<AppBargainActivityRespVO> convertAppList(List<BargainActivityDO> list); | ||
| 90 | + | ||
| 91 | + default List<AppBargainActivityRespVO> convertAppList(List<BargainActivityDO> list, List<ProductSpuRespDTO> spuList) { | ||
| 92 | + List<AppBargainActivityRespVO> activityList = convertAppList(list); | ||
| 93 | + Map<Long, ProductSpuRespDTO> spuMap = convertMap(spuList, ProductSpuRespDTO::getId); | ||
| 94 | + return CollectionUtils.convertList(activityList, item -> { | ||
| 95 | + findAndThen(spuMap, item.getSpuId(), spu -> { | ||
| 96 | + // TODO @puhui999:这里可以使用链式哈 | ||
| 97 | + item.setPicUrl(spu.getPicUrl()); | ||
| 98 | + item.setMarketPrice(spu.getMarketPrice()); | ||
| 99 | + }); | ||
| 100 | + return item; | ||
| 101 | + }); | ||
| 102 | + } | ||
| 103 | + | ||
| 33 | } | 104 | } |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/combination/CombinationActivityConvert.java
| @@ -3,6 +3,8 @@ package cn.iocoder.yudao.module.promotion.convert.combination; | @@ -3,6 +3,8 @@ package cn.iocoder.yudao.module.promotion.convert.combination; | ||
| 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | 4 | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; |
| 5 | import cn.iocoder.yudao.framework.common.util.collection.MapUtils; | 5 | import cn.iocoder.yudao.framework.common.util.collection.MapUtils; |
| 6 | +import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; | ||
| 7 | +import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; | ||
| 6 | import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; | 8 | import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; |
| 7 | import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO; | 9 | import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO; |
| 8 | import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordRespDTO; | 10 | import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordRespDTO; |
| @@ -92,6 +94,21 @@ public interface CombinationActivityConvert { | @@ -92,6 +94,21 @@ public interface CombinationActivityConvert { | ||
| 92 | 94 | ||
| 93 | CombinationRecordDO convert(CombinationRecordCreateReqDTO reqDTO); | 95 | CombinationRecordDO convert(CombinationRecordCreateReqDTO reqDTO); |
| 94 | 96 | ||
| 97 | + default CombinationRecordDO convert(CombinationRecordCreateReqDTO reqDTO, | ||
| 98 | + CombinationActivityDO activity, MemberUserRespDTO user, | ||
| 99 | + ProductSpuRespDTO spu, ProductSkuRespDTO sku) { | ||
| 100 | + // TODO @puhui999:搞成链式的 set;这样会更规整一点; | ||
| 101 | + CombinationRecordDO record = convert(reqDTO); | ||
| 102 | + record.setVirtualGroup(false); | ||
| 103 | + record.setExpireTime(record.getStartTime().plusHours(activity.getLimitDuration())); | ||
| 104 | + record.setUserSize(activity.getUserSize()); | ||
| 105 | + record.setNickname(user.getNickname()); | ||
| 106 | + record.setAvatar(user.getAvatar()); | ||
| 107 | + record.setSpuName(spu.getName()); | ||
| 108 | + record.setPicUrl(sku.getPicUrl()); | ||
| 109 | + return record; | ||
| 110 | + } | ||
| 111 | + | ||
| 95 | List<CombinationRecordRespDTO> convert(List<CombinationRecordDO> bean); | 112 | List<CombinationRecordRespDTO> convert(List<CombinationRecordDO> bean); |
| 96 | 113 | ||
| 97 | } | 114 | } |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckill/seckillactivity/SeckillActivityConvert.java
| @@ -3,15 +3,22 @@ package cn.iocoder.yudao.module.promotion.convert.seckill.seckillactivity; | @@ -3,15 +3,22 @@ package cn.iocoder.yudao.module.promotion.convert.seckill.seckillactivity; | ||
| 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | 4 | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; |
| 5 | import cn.iocoder.yudao.framework.common.util.collection.MapUtils; | 5 | import cn.iocoder.yudao.framework.common.util.collection.MapUtils; |
| 6 | +import cn.iocoder.yudao.framework.dict.core.util.DictFrameworkUtils; | ||
| 6 | import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; | 7 | import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; |
| 8 | +import cn.iocoder.yudao.module.product.enums.DictTypeConstants; | ||
| 7 | import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityCreateReqVO; | 9 | import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityCreateReqVO; |
| 8 | import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityDetailRespVO; | 10 | import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityDetailRespVO; |
| 9 | import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityRespVO; | 11 | import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityRespVO; |
| 10 | import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityUpdateReqVO; | 12 | import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityUpdateReqVO; |
| 11 | import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product.SeckillProductBaseVO; | 13 | import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product.SeckillProductBaseVO; |
| 12 | import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product.SeckillProductRespVO; | 14 | import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product.SeckillProductRespVO; |
| 15 | +import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityDetailRespVO; | ||
| 16 | +import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityNowRespVO; | ||
| 17 | +import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityRespVO; | ||
| 18 | +import cn.iocoder.yudao.module.promotion.convert.seckill.seckillconfig.SeckillConfigConvert; | ||
| 13 | import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO; | 19 | import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO; |
| 14 | import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillProductDO; | 20 | import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillProductDO; |
| 21 | +import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillconfig.SeckillConfigDO; | ||
| 15 | import org.mapstruct.Mapper; | 22 | import org.mapstruct.Mapper; |
| 16 | import org.mapstruct.Mapping; | 23 | import org.mapstruct.Mapping; |
| 17 | import org.mapstruct.Mappings; | 24 | import org.mapstruct.Mappings; |
| @@ -20,6 +27,10 @@ import org.mapstruct.factory.Mappers; | @@ -20,6 +27,10 @@ import org.mapstruct.factory.Mappers; | ||
| 20 | import java.util.List; | 27 | import java.util.List; |
| 21 | import java.util.Map; | 28 | import java.util.Map; |
| 22 | 29 | ||
| 30 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap; | ||
| 31 | +import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen; | ||
| 32 | +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime; | ||
| 33 | + | ||
| 23 | /** | 34 | /** |
| 24 | * 秒杀活动 Convert | 35 | * 秒杀活动 Convert |
| 25 | * | 36 | * |
| @@ -79,4 +90,53 @@ public interface SeckillActivityConvert { | @@ -79,4 +90,53 @@ public interface SeckillActivityConvert { | ||
| 79 | 90 | ||
| 80 | List<SeckillProductRespVO> convertList2(List<SeckillProductDO> list); | 91 | List<SeckillProductRespVO> convertList2(List<SeckillProductDO> list); |
| 81 | 92 | ||
| 93 | + List<AppSeckillActivityRespVO> convertList3(List<SeckillActivityDO> activityList); | ||
| 94 | + | ||
| 95 | + default AppSeckillActivityNowRespVO convert(SeckillConfigDO filteredConfig, List<SeckillActivityDO> activityList, List<ProductSpuRespDTO> spuList) { | ||
| 96 | + AppSeckillActivityNowRespVO respVO = new AppSeckillActivityNowRespVO(); | ||
| 97 | + respVO.setConfig(SeckillConfigConvert.INSTANCE.convert1(filteredConfig)); | ||
| 98 | + Map<Long, ProductSpuRespDTO> spuMap = convertMap(spuList, ProductSpuRespDTO::getId); | ||
| 99 | + respVO.setActivities(CollectionUtils.convertList(convertList3(activityList), item -> { | ||
| 100 | + findAndThen(spuMap, item.getSpuId(), spu -> { | ||
| 101 | + // TODO @puhui999:可以尝试链式 set 哈; | ||
| 102 | + item.setPicUrl(spu.getPicUrl()); | ||
| 103 | + item.setMarketPrice(spu.getMarketPrice()); | ||
| 104 | + item.setUnitName(DictFrameworkUtils.getDictDataLabel(DictTypeConstants.PRODUCT_UNIT, spu.getUnit())); | ||
| 105 | + }); | ||
| 106 | + return item; | ||
| 107 | + })); | ||
| 108 | + return respVO; | ||
| 109 | + } | ||
| 110 | + | ||
| 111 | + PageResult<AppSeckillActivityRespVO> convertPage1(PageResult<SeckillActivityDO> pageResult); | ||
| 112 | + | ||
| 113 | + default PageResult<AppSeckillActivityRespVO> convertPage(PageResult<SeckillActivityDO> pageResult, List<ProductSpuRespDTO> spuList) { | ||
| 114 | + PageResult<AppSeckillActivityRespVO> result = convertPage1(pageResult); | ||
| 115 | + Map<Long, ProductSpuRespDTO> spuMap = convertMap(spuList, ProductSpuRespDTO::getId); | ||
| 116 | + List<AppSeckillActivityRespVO> list = CollectionUtils.convertList(result.getList(), item -> { | ||
| 117 | + findAndThen(spuMap, item.getSpuId(), spu -> { | ||
| 118 | + // TODO @puhui999:可以尝试链式 set 哈; | ||
| 119 | + item.setPicUrl(spu.getPicUrl()); | ||
| 120 | + item.setMarketPrice(spu.getMarketPrice()); | ||
| 121 | + item.setUnitName(DictFrameworkUtils.getDictDataLabel(DictTypeConstants.PRODUCT_UNIT, spu.getUnit())); | ||
| 122 | + }); | ||
| 123 | + return item; | ||
| 124 | + }); | ||
| 125 | + result.setList(list); | ||
| 126 | + return result; | ||
| 127 | + } | ||
| 128 | + | ||
| 129 | + AppSeckillActivityDetailRespVO convert2(SeckillActivityDO seckillActivity); | ||
| 130 | + | ||
| 131 | + List<AppSeckillActivityDetailRespVO.Product> convertList1(List<SeckillProductDO> products); | ||
| 132 | + | ||
| 133 | + default AppSeckillActivityDetailRespVO convert3(SeckillActivityDO seckillActivity, List<SeckillProductDO> products, SeckillConfigDO filteredConfig) { | ||
| 134 | + AppSeckillActivityDetailRespVO respVO = convert2(seckillActivity); | ||
| 135 | + respVO.setProducts(convertList1(products)); | ||
| 136 | + // TODO @puhui999:可以尝试链式 set 哈; | ||
| 137 | + respVO.setStartTime(buildTime(filteredConfig.getStartTime())); | ||
| 138 | + respVO.setEndTime(buildTime(filteredConfig.getEndTime())); | ||
| 139 | + return respVO; | ||
| 140 | + } | ||
| 141 | + | ||
| 82 | } | 142 | } |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/seckill/seckillconfig/SeckillConfigConvert.java
| @@ -5,6 +5,7 @@ import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.Seck | @@ -5,6 +5,7 @@ import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.Seck | ||
| 5 | import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigRespVO; | 5 | import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigRespVO; |
| 6 | import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigSimpleRespVO; | 6 | import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigSimpleRespVO; |
| 7 | import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigUpdateReqVO; | 7 | import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.config.SeckillConfigUpdateReqVO; |
| 8 | +import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.config.AppSeckillConfigRespVO; | ||
| 8 | import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillconfig.SeckillConfigDO; | 9 | import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillconfig.SeckillConfigDO; |
| 9 | import org.mapstruct.Mapper; | 10 | import org.mapstruct.Mapper; |
| 10 | import org.mapstruct.factory.Mappers; | 11 | import org.mapstruct.factory.Mappers; |
| @@ -33,4 +34,7 @@ public interface SeckillConfigConvert { | @@ -33,4 +34,7 @@ public interface SeckillConfigConvert { | ||
| 33 | 34 | ||
| 34 | PageResult<SeckillConfigRespVO> convertPage(PageResult<SeckillConfigDO> page); | 35 | PageResult<SeckillConfigRespVO> convertPage(PageResult<SeckillConfigDO> page); |
| 35 | 36 | ||
| 37 | + List<AppSeckillConfigRespVO> convertList2(List<SeckillConfigDO> list); | ||
| 38 | + | ||
| 39 | + AppSeckillConfigRespVO convert1(SeckillConfigDO filteredConfig); | ||
| 36 | } | 40 | } |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/dataobject/seckill/seckillactivity/SeckillActivityDO.java
| @@ -87,7 +87,7 @@ public class SeckillActivityDO extends BaseDO { | @@ -87,7 +87,7 @@ public class SeckillActivityDO extends BaseDO { | ||
| 87 | */ | 87 | */ |
| 88 | private Integer singleLimitCount; | 88 | private Integer singleLimitCount; |
| 89 | /** | 89 | /** |
| 90 | - * 秒杀库存 | 90 | + * 秒杀库存(剩余库存秒杀时扣减) |
| 91 | */ | 91 | */ |
| 92 | private Integer stock; | 92 | private Integer stock; |
| 93 | /** | 93 | /** |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/bargain/BargainActivityMapper.java
| 1 | package cn.iocoder.yudao.module.promotion.dal.mysql.bargain; | 1 | package cn.iocoder.yudao.module.promotion.dal.mysql.bargain; |
| 2 | 2 | ||
| 3 | +import cn.iocoder.yudao.framework.common.pojo.PageParam; | ||
| 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 4 | 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.mapper.BaseMapperX; |
| 5 | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; | 6 | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; |
| @@ -8,6 +9,7 @@ import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainActivityD | @@ -8,6 +9,7 @@ import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainActivityD | ||
| 8 | import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; | 9 | import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; |
| 9 | import org.apache.ibatis.annotations.Mapper; | 10 | import org.apache.ibatis.annotations.Mapper; |
| 10 | 11 | ||
| 12 | +import java.time.LocalDateTime; | ||
| 11 | import java.util.List; | 13 | import java.util.List; |
| 12 | 14 | ||
| 13 | /** | 15 | /** |
| @@ -39,8 +41,15 @@ public interface BargainActivityMapper extends BaseMapperX<BargainActivityDO> { | @@ -39,8 +41,15 @@ public interface BargainActivityMapper extends BaseMapperX<BargainActivityDO> { | ||
| 39 | default int updateActivityStock(Long id, int count) { | 41 | default int updateActivityStock(Long id, int count) { |
| 40 | return update(null, new LambdaUpdateWrapper<BargainActivityDO>() | 42 | return update(null, new LambdaUpdateWrapper<BargainActivityDO>() |
| 41 | .eq(BargainActivityDO::getId, id) | 43 | .eq(BargainActivityDO::getId, id) |
| 42 | - .gt(BargainActivityDO::getStock, 0) // TODO @puhui999:不是 > 0,是要大于 count 哈 | 44 | + .ge(BargainActivityDO::getStock, count) |
| 43 | .setSql("stock = stock - " + count)); | 45 | .setSql("stock = stock - " + count)); |
| 44 | } | 46 | } |
| 45 | 47 | ||
| 48 | + default PageResult<BargainActivityDO> selectAppPage(PageParam pageReqVO, Integer status, LocalDateTime now) { | ||
| 49 | + return selectPage(pageReqVO, new LambdaQueryWrapperX<BargainActivityDO>() | ||
| 50 | + .eq(BargainActivityDO::getStatus, status) | ||
| 51 | + .le(BargainActivityDO::getStartTime, now) | ||
| 52 | + .ge(BargainActivityDO::getEndTime, now)); | ||
| 53 | + } | ||
| 54 | + | ||
| 46 | } | 55 | } |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckillactivity/SeckillActivityMapper.java
| @@ -5,6 +5,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; | @@ -5,6 +5,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||
| 5 | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; | 5 | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; |
| 6 | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; | 6 | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; |
| 7 | import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityPageReqVO; | 7 | import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityPageReqVO; |
| 8 | +import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityPageReqVO; | ||
| 8 | import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO; | 9 | import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO; |
| 9 | import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; | 10 | import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; |
| 10 | import org.apache.ibatis.annotations.Mapper; | 11 | import org.apache.ibatis.annotations.Mapper; |
| @@ -24,7 +25,7 @@ public interface SeckillActivityMapper extends BaseMapperX<SeckillActivityDO> { | @@ -24,7 +25,7 @@ public interface SeckillActivityMapper extends BaseMapperX<SeckillActivityDO> { | ||
| 24 | .likeIfPresent(SeckillActivityDO::getName, reqVO.getName()) | 25 | .likeIfPresent(SeckillActivityDO::getName, reqVO.getName()) |
| 25 | .eqIfPresent(SeckillActivityDO::getStatus, reqVO.getStatus()) | 26 | .eqIfPresent(SeckillActivityDO::getStatus, reqVO.getStatus()) |
| 26 | .betweenIfPresent(SeckillActivityDO::getCreateTime, reqVO.getCreateTime()) | 27 | .betweenIfPresent(SeckillActivityDO::getCreateTime, reqVO.getCreateTime()) |
| 27 | - .apply(ObjectUtil.isNotNull(reqVO.getConfigId()), "FIND_IN_SET(" + reqVO.getConfigId() + ",time_ids) > 0") | 28 | + .apply(ObjectUtil.isNotNull(reqVO.getConfigId()), "FIND_IN_SET(" + reqVO.getConfigId() + ", config_ids) > 0") |
| 28 | .orderByDesc(SeckillActivityDO::getId)); | 29 | .orderByDesc(SeckillActivityDO::getId)); |
| 29 | } | 30 | } |
| 30 | 31 | ||
| @@ -48,4 +49,11 @@ public interface SeckillActivityMapper extends BaseMapperX<SeckillActivityDO> { | @@ -48,4 +49,11 @@ public interface SeckillActivityMapper extends BaseMapperX<SeckillActivityDO> { | ||
| 48 | .setSql("totalStock = totalStock - " + count)); | 49 | .setSql("totalStock = totalStock - " + count)); |
| 49 | } | 50 | } |
| 50 | 51 | ||
| 52 | + default PageResult<SeckillActivityDO> selectPage(AppSeckillActivityPageReqVO pageReqVO, Integer status) { | ||
| 53 | + return selectPage(pageReqVO, new LambdaQueryWrapperX<SeckillActivityDO>() | ||
| 54 | + .eqIfPresent(SeckillActivityDO::getStatus, status) | ||
| 55 | + // TODO 芋艿:对 find in set 的想法; | ||
| 56 | + .apply(ObjectUtil.isNotNull(pageReqVO.getConfigId()), "FIND_IN_SET(" + pageReqVO.getConfigId() + ",config_ids) > 0")); | ||
| 57 | + } | ||
| 58 | + | ||
| 51 | } | 59 | } |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/seckill/seckillactivity/SeckillProductMapper.java
| @@ -34,7 +34,7 @@ public interface SeckillProductMapper extends BaseMapperX<SeckillProductDO> { | @@ -34,7 +34,7 @@ public interface SeckillProductMapper extends BaseMapperX<SeckillProductDO> { | ||
| 34 | default int updateActivityStock(Long id, int count) { | 34 | default int updateActivityStock(Long id, int count) { |
| 35 | return update(null, new LambdaUpdateWrapper<SeckillProductDO>() | 35 | return update(null, new LambdaUpdateWrapper<SeckillProductDO>() |
| 36 | .eq(SeckillProductDO::getId, id) | 36 | .eq(SeckillProductDO::getId, id) |
| 37 | - .gt(SeckillProductDO::getStock, 0) // TODO @puhui999:不是 > 0,是要大于 count 哈 | 37 | + .gt(SeckillProductDO::getStock, count) |
| 38 | .setSql("stock = stock - " + count)); | 38 | .setSql("stock = stock - " + count)); |
| 39 | } | 39 | } |
| 40 | 40 |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainActivityService.java
| 1 | package cn.iocoder.yudao.module.promotion.service.bargain; | 1 | package cn.iocoder.yudao.module.promotion.service.bargain; |
| 2 | 2 | ||
| 3 | +import cn.iocoder.yudao.framework.common.pojo.PageParam; | ||
| 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityCreateReqVO; | 5 | import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityCreateReqVO; |
| 5 | import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityPageReqVO; | 6 | import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActivityPageReqVO; |
| @@ -7,6 +8,7 @@ import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActi | @@ -7,6 +8,7 @@ import cn.iocoder.yudao.module.promotion.controller.admin.bargain.vo.BargainActi | ||
| 7 | import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainActivityDO; | 8 | import cn.iocoder.yudao.module.promotion.dal.dataobject.bargain.BargainActivityDO; |
| 8 | 9 | ||
| 9 | import javax.validation.Valid; | 10 | import javax.validation.Valid; |
| 11 | +import java.util.List; | ||
| 10 | 12 | ||
| 11 | /** | 13 | /** |
| 12 | * 砍价活动 Service 接口 | 14 | * 砍价活动 Service 接口 |
| @@ -61,4 +63,22 @@ public interface BargainActivityService { | @@ -61,4 +63,22 @@ public interface BargainActivityService { | ||
| 61 | */ | 63 | */ |
| 62 | PageResult<BargainActivityDO> getBargainActivityPage(BargainActivityPageReqVO pageReqVO); | 64 | PageResult<BargainActivityDO> getBargainActivityPage(BargainActivityPageReqVO pageReqVO); |
| 63 | 65 | ||
| 66 | + // TODO @puhui999:这里可以改成进行中的活动;尽量避免专门为 app 定制,或者类似的名字哈;mapper 那也是 | ||
| 67 | + | ||
| 68 | + /** | ||
| 69 | + * 获取 APP 端活动分页数据 | ||
| 70 | + * | ||
| 71 | + * @param pageReqVO 分页请求 | ||
| 72 | + * @return 砍价活动分页 | ||
| 73 | + */ | ||
| 74 | + PageResult<BargainActivityDO> getBargainActivityPageForApp(PageParam pageReqVO); | ||
| 75 | + | ||
| 76 | + /** | ||
| 77 | + * 获取 APP 端活动展示数据 | ||
| 78 | + * | ||
| 79 | + * @param count 需要的数量 | ||
| 80 | + * @return 砍价活动分页 | ||
| 81 | + */ | ||
| 82 | + List<BargainActivityDO> getBargainActivityListForApp(Integer count); | ||
| 83 | + | ||
| 64 | } | 84 | } |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/bargain/BargainActivityServiceImpl.java
| @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.promotion.service.bargain; | @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.promotion.service.bargain; | ||
| 2 | 2 | ||
| 3 | import cn.hutool.core.util.ObjectUtil; | 3 | import cn.hutool.core.util.ObjectUtil; |
| 4 | import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | 4 | import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; |
| 5 | +import cn.iocoder.yudao.framework.common.pojo.PageParam; | ||
| 5 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 6 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 6 | import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; | 7 | import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; |
| 7 | import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; | 8 | import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; |
| @@ -16,6 +17,7 @@ import org.springframework.transaction.annotation.Transactional; | @@ -16,6 +17,7 @@ import org.springframework.transaction.annotation.Transactional; | ||
| 16 | import org.springframework.validation.annotation.Validated; | 17 | import org.springframework.validation.annotation.Validated; |
| 17 | 18 | ||
| 18 | import javax.annotation.Resource; | 19 | import javax.annotation.Resource; |
| 20 | +import java.time.LocalDateTime; | ||
| 19 | import java.util.List; | 21 | import java.util.List; |
| 20 | 22 | ||
| 21 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | 23 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| @@ -113,9 +115,9 @@ public class BargainActivityServiceImpl implements BargainActivityService { | @@ -113,9 +115,9 @@ public class BargainActivityServiceImpl implements BargainActivityService { | ||
| 113 | // 校验存在 | 115 | // 校验存在 |
| 114 | BargainActivityDO activityDO = validateBargainActivityExists(id); | 116 | BargainActivityDO activityDO = validateBargainActivityExists(id); |
| 115 | // 校验状态 | 117 | // 校验状态 |
| 116 | - if (ObjectUtil.equal(activityDO.getStatus(), CommonStatusEnum.ENABLE.getStatus())) { | ||
| 117 | - throw exception(BARGAIN_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED_OR_END); | ||
| 118 | - } | 118 | + //if (ObjectUtil.equal(activityDO.getStatus(), CommonStatusEnum.ENABLE.getStatus())) { |
| 119 | + // throw exception(BARGAIN_ACTIVITY_DELETE_FAIL_STATUS_NOT_CLOSED_OR_END); | ||
| 120 | + //} | ||
| 119 | 121 | ||
| 120 | // 删除 | 122 | // 删除 |
| 121 | bargainActivityMapper.deleteById(id); | 123 | bargainActivityMapper.deleteById(id); |
| @@ -139,4 +141,22 @@ public class BargainActivityServiceImpl implements BargainActivityService { | @@ -139,4 +141,22 @@ public class BargainActivityServiceImpl implements BargainActivityService { | ||
| 139 | return bargainActivityMapper.selectPage(pageReqVO); | 141 | return bargainActivityMapper.selectPage(pageReqVO); |
| 140 | } | 142 | } |
| 141 | 143 | ||
| 144 | + @Override | ||
| 145 | + public PageResult<BargainActivityDO> getBargainActivityPageForApp(PageParam pageReqVO) { | ||
| 146 | + // 只查询进行中,且在时间范围内的 | ||
| 147 | + return bargainActivityMapper.selectAppPage(pageReqVO, CommonStatusEnum.ENABLE.getStatus(), LocalDateTime.now()); | ||
| 148 | + } | ||
| 149 | + | ||
| 150 | + @Override | ||
| 151 | + public List<BargainActivityDO> getBargainActivityListForApp(Integer count) { | ||
| 152 | + // TODO @puhui999:这种 default count 的逻辑,可以放到 controller 哈;然后可以使用 ObjectUtils.default 方法 | ||
| 153 | + if (count == null) { | ||
| 154 | + count = 6; | ||
| 155 | + } | ||
| 156 | + // TODO @puhui999:这种不要用 page;会浪费一次 count; | ||
| 157 | + PageResult<BargainActivityDO> result = bargainActivityMapper.selectAppPage(new PageParam().setPageSize(count), | ||
| 158 | + CommonStatusEnum.ENABLE.getStatus(), LocalDateTime.now()); | ||
| 159 | + return result.getList(); | ||
| 160 | + } | ||
| 161 | + | ||
| 142 | } | 162 | } |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationActivityService.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.framework.common.pojo.PageResult; | 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | -import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationActivityUpdateStockReqDTO; | ||
| 5 | import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityCreateReqVO; | 4 | import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityCreateReqVO; |
| 6 | import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityPageReqVO; | 5 | import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityPageReqVO; |
| 7 | import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityUpdateReqVO; | 6 | import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityUpdateReqVO; |
| @@ -74,10 +73,14 @@ public interface CombinationActivityService { | @@ -74,10 +73,14 @@ public interface CombinationActivityService { | ||
| 74 | List<CombinationProductDO> getCombinationProductsByActivityIds(Collection<Long> activityIds); | 73 | List<CombinationProductDO> getCombinationProductsByActivityIds(Collection<Long> activityIds); |
| 75 | 74 | ||
| 76 | /** | 75 | /** |
| 77 | - * 更新拼图活动库存 | 76 | + * 校验是否满足拼团条件 |
| 77 | + * 如果不满足,会抛出异常 | ||
| 78 | * | 78 | * |
| 79 | - * @param reqDTO 请求 | 79 | + * @param activityId 活动编号 |
| 80 | + * @param userId 用户编号 | ||
| 81 | + * @param skuId sku 编号 | ||
| 82 | + * @param count 数量 | ||
| 80 | */ | 83 | */ |
| 81 | - void validateCombination(CombinationActivityUpdateStockReqDTO reqDTO); | 84 | + void validateCombination(Long activityId, Long userId, Long skuId, Integer count); |
| 82 | 85 | ||
| 83 | } | 86 | } |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationActivityServiceImpl.java
| @@ -9,7 +9,6 @@ import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; | @@ -9,7 +9,6 @@ import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; | ||
| 9 | import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; | 9 | import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; |
| 10 | import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi; | 10 | import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi; |
| 11 | import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; | 11 | import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; |
| 12 | -import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationActivityUpdateStockReqDTO; | ||
| 13 | import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityCreateReqVO; | 12 | import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityCreateReqVO; |
| 14 | import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityPageReqVO; | 13 | import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityPageReqVO; |
| 15 | import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityUpdateReqVO; | 14 | import cn.iocoder.yudao.module.promotion.controller.admin.combination.vo.activity.CombinationActivityUpdateReqVO; |
| @@ -34,7 +33,6 @@ import java.util.Map; | @@ -34,7 +33,6 @@ import java.util.Map; | ||
| 34 | 33 | ||
| 35 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | 34 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 36 | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; | 35 | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; |
| 37 | -import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; | ||
| 38 | import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_NOT_EXISTS; | 36 | import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SKU_NOT_EXISTS; |
| 39 | import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_EXISTS; | 37 | import static cn.iocoder.yudao.module.product.enums.ErrorCodeConstants.SPU_NOT_EXISTS; |
| 40 | import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*; | 38 | import static cn.iocoder.yudao.module.promotion.enums.ErrorCodeConstants.*; |
| @@ -88,7 +86,7 @@ public class CombinationActivityServiceImpl implements CombinationActivityServic | @@ -88,7 +86,7 @@ public class CombinationActivityServiceImpl implements CombinationActivityServic | ||
| 88 | /** | 86 | /** |
| 89 | * 校验拼团商品参与的活动是否存在冲突 | 87 | * 校验拼团商品参与的活动是否存在冲突 |
| 90 | * | 88 | * |
| 91 | - * @param spuId 商品 SPU 编号 | 89 | + * @param spuId 商品 SPU 编号 |
| 92 | * @param activityId 拼团活动编号 | 90 | * @param activityId 拼团活动编号 |
| 93 | */ | 91 | */ |
| 94 | private void validateProductConflict(Long spuId, Long activityId) { | 92 | private void validateProductConflict(Long spuId, Long activityId) { |
| @@ -107,7 +105,7 @@ public class CombinationActivityServiceImpl implements CombinationActivityServic | @@ -107,7 +105,7 @@ public class CombinationActivityServiceImpl implements CombinationActivityServic | ||
| 107 | /** | 105 | /** |
| 108 | * 校验拼团商品是否都存在 | 106 | * 校验拼团商品是否都存在 |
| 109 | * | 107 | * |
| 110 | - * @param spuId 商品 SPU 编号 | 108 | + * @param spuId 商品 SPU 编号 |
| 111 | * @param products 拼团商品 | 109 | * @param products 拼团商品 |
| 112 | */ | 110 | */ |
| 113 | private void validateProductExists(Long spuId, List<CombinationProductBaseVO> products) { | 111 | private void validateProductExists(Long spuId, List<CombinationProductBaseVO> products) { |
| @@ -152,7 +150,7 @@ public class CombinationActivityServiceImpl implements CombinationActivityServic | @@ -152,7 +150,7 @@ public class CombinationActivityServiceImpl implements CombinationActivityServic | ||
| 152 | * 更新拼团商品 | 150 | * 更新拼团商品 |
| 153 | * | 151 | * |
| 154 | * @param activity 拼团活动 | 152 | * @param activity 拼团活动 |
| 155 | - * @param products 该活动的最新商品配置 | 153 | + * @param products 该活动的最新商品配置 |
| 156 | */ | 154 | */ |
| 157 | private void updateCombinationProduct(CombinationActivityDO activity, List<CombinationProductBaseVO> products) { | 155 | private void updateCombinationProduct(CombinationActivityDO activity, List<CombinationProductBaseVO> products) { |
| 158 | // 第一步,对比新老数据,获得添加、修改、删除的列表 | 156 | // 第一步,对比新老数据,获得添加、修改、删除的列表 |
| @@ -217,34 +215,33 @@ public class CombinationActivityServiceImpl implements CombinationActivityServic | @@ -217,34 +215,33 @@ public class CombinationActivityServiceImpl implements CombinationActivityServic | ||
| 217 | } | 215 | } |
| 218 | 216 | ||
| 219 | @Override | 217 | @Override |
| 220 | - public void validateCombination(CombinationActivityUpdateStockReqDTO reqDTO) { | 218 | + public void validateCombination(Long activityId, Long userId, Long skuId, Integer count) { |
| 221 | // 1.1 校验拼团活动是否存在 | 219 | // 1.1 校验拼团活动是否存在 |
| 222 | - CombinationActivityDO activity = validateCombinationActivityExists(reqDTO.getActivityId()); | 220 | + CombinationActivityDO activity = validateCombinationActivityExists(activityId); |
| 223 | // 1.2 校验活动是否开启 | 221 | // 1.2 校验活动是否开启 |
| 224 | if (ObjectUtil.equal(activity.getStatus(), CommonStatusEnum.DISABLE.getStatus())) { | 222 | if (ObjectUtil.equal(activity.getStatus(), CommonStatusEnum.DISABLE.getStatus())) { |
| 225 | throw exception(COMBINATION_ACTIVITY_STATUS_DISABLE); | 223 | throw exception(COMBINATION_ACTIVITY_STATUS_DISABLE); |
| 226 | } | 224 | } |
| 227 | // 1.3 校验是否超出单次限购数量 | 225 | // 1.3 校验是否超出单次限购数量 |
| 228 | - if (activity.getSingleLimitCount() < reqDTO.getCount()) { | 226 | + // TODO puhui999:count > activity.getSingleLimitCount() 会更好理解点; |
| 227 | + if (activity.getSingleLimitCount() < count) { | ||
| 229 | throw exception(COMBINATION_RECORD_FAILED_SINGLE_LIMIT_COUNT_EXCEED); | 228 | throw exception(COMBINATION_RECORD_FAILED_SINGLE_LIMIT_COUNT_EXCEED); |
| 230 | } | 229 | } |
| 231 | 230 | ||
| 232 | // 2. 校验是否超出总限购数量 | 231 | // 2. 校验是否超出总限购数量 |
| 233 | - // TODO @puhui999:userId 应该接口传递哈;要保证 service 无状态 | ||
| 234 | - List<CombinationRecordDO> recordList = combinationRecordService.getRecordListByUserIdAndActivityId( | ||
| 235 | - getLoginUserId(), reqDTO.getActivityId()); | ||
| 236 | - // TODO @puhui999:最好 if true return;减少括号层数 | ||
| 237 | - if (CollUtil.isNotEmpty(recordList)) { | ||
| 238 | - // 过滤出拼团成功的 | ||
| 239 | - // TODO @puhui999:count 要不存一个在 record 里? | ||
| 240 | - List<Long> skuIds = convertList(recordList, CombinationRecordDO::getSkuId, | ||
| 241 | - item -> ObjectUtil.equals(item.getStatus(), CombinationRecordStatusEnum.SUCCESS.getStatus())); | ||
| 242 | - Integer countSum = tradeOrderApi.getOrderItemCountSumByOrderIdAndSkuId(convertList(recordList, | ||
| 243 | - CombinationRecordDO::getOrderId, | ||
| 244 | - item -> ObjectUtil.equals(item.getStatus(), CombinationRecordStatusEnum.SUCCESS.getStatus())), skuIds); | ||
| 245 | - if (activity.getTotalLimitCount() < countSum) { | ||
| 246 | - throw exception(COMBINATION_RECORD_FAILED_TOTAL_LIMIT_COUNT_EXCEED); | ||
| 247 | - } | 232 | + List<CombinationRecordDO> recordList = combinationRecordService.getRecordListByUserIdAndActivityId(userId, activityId); |
| 233 | + if (CollUtil.isEmpty(recordList)) { | ||
| 234 | + return; | ||
| 235 | + } | ||
| 236 | + // 过滤出拼团成功的 | ||
| 237 | + // TODO @puhui999:count 要不存一个在 record 里? | ||
| 238 | + List<Long> skuIds = convertList(recordList, CombinationRecordDO::getSkuId, | ||
| 239 | + item -> ObjectUtil.equals(item.getStatus(), CombinationRecordStatusEnum.SUCCESS.getStatus())); | ||
| 240 | + Integer countSum = tradeOrderApi.getOrderItemCountSumByOrderIdAndSkuId(convertList(recordList, | ||
| 241 | + CombinationRecordDO::getOrderId, | ||
| 242 | + item -> ObjectUtil.equals(item.getStatus(), CombinationRecordStatusEnum.SUCCESS.getStatus())), skuIds); | ||
| 243 | + if (activity.getTotalLimitCount() < countSum) { | ||
| 244 | + throw exception(COMBINATION_RECORD_FAILED_TOTAL_LIMIT_COUNT_EXCEED); | ||
| 248 | } | 245 | } |
| 249 | } | 246 | } |
| 250 | 247 |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationRecordService.java
| @@ -57,14 +57,4 @@ public interface CombinationRecordService { | @@ -57,14 +57,4 @@ public interface CombinationRecordService { | ||
| 57 | */ | 57 | */ |
| 58 | List<CombinationRecordDO> getRecordListByUserIdAndActivityId(Long userId, Long activityId); | 58 | List<CombinationRecordDO> getRecordListByUserIdAndActivityId(Long userId, Long activityId); |
| 59 | 59 | ||
| 60 | - /** | ||
| 61 | - * 验证组合限制数 | ||
| 62 | - * 校验是否满足限购要求 | ||
| 63 | - * | ||
| 64 | - * @param count 本次购买数量 | ||
| 65 | - * @param sumCount 已购买数量合计 | ||
| 66 | - * @param activityId 活动编号 | ||
| 67 | - */ | ||
| 68 | - void validateCombinationLimitCount(Long activityId, Integer count, Integer sumCount); | ||
| 69 | - | ||
| 70 | } | 60 | } |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationRecordServiceImpl.java
| @@ -129,19 +129,10 @@ public class CombinationRecordServiceImpl implements CombinationRecordService { | @@ -129,19 +129,10 @@ public class CombinationRecordServiceImpl implements CombinationRecordService { | ||
| 129 | } | 129 | } |
| 130 | 130 | ||
| 131 | // 2. 创建拼团记录 | 131 | // 2. 创建拼团记录 |
| 132 | - // TODO @puhui999:可以把 user、spu、sku 一起放 convert 里哈; | ||
| 133 | - CombinationRecordDO record = CombinationActivityConvert.INSTANCE.convert(reqDTO); | ||
| 134 | - record.setVirtualGroup(false); | ||
| 135 | - record.setExpireTime(record.getStartTime().plusHours(activity.getLimitDuration())); | ||
| 136 | - record.setUserSize(activity.getUserSize()); | ||
| 137 | MemberUserRespDTO user = memberUserApi.getUser(reqDTO.getUserId()); | 132 | MemberUserRespDTO user = memberUserApi.getUser(reqDTO.getUserId()); |
| 138 | - record.setNickname(user.getNickname()); | ||
| 139 | - record.setAvatar(user.getAvatar()); | ||
| 140 | - ProductSpuRespDTO spu = productSpuApi.getSpu(record.getSpuId()); | ||
| 141 | - record.setSpuName(spu.getName()); | ||
| 142 | - ProductSkuRespDTO sku = productSkuApi.getSku(record.getSkuId()); | ||
| 143 | - record.setPicUrl(sku.getPicUrl()); | ||
| 144 | - recordMapper.insert(record); | 133 | + ProductSpuRespDTO spu = productSpuApi.getSpu(reqDTO.getSpuId()); |
| 134 | + ProductSkuRespDTO sku = productSkuApi.getSku(reqDTO.getSkuId()); | ||
| 135 | + recordMapper.insert(CombinationActivityConvert.INSTANCE.convert(reqDTO, activity, user, spu, sku)); | ||
| 145 | } | 136 | } |
| 146 | 137 | ||
| 147 | @Override | 138 | @Override |
| @@ -154,20 +145,6 @@ public class CombinationRecordServiceImpl implements CombinationRecordService { | @@ -154,20 +145,6 @@ public class CombinationRecordServiceImpl implements CombinationRecordService { | ||
| 154 | return recordMapper.selectListByUserIdAndActivityId(userId, activityId); | 145 | return recordMapper.selectListByUserIdAndActivityId(userId, activityId); |
| 155 | } | 146 | } |
| 156 | 147 | ||
| 157 | - @Override | ||
| 158 | - public void validateCombinationLimitCount(Long activityId, Integer count, Integer sumCount) { | ||
| 159 | - // 1.1 校验拼团活动 | ||
| 160 | - CombinationActivityDO activity = combinationActivityService.validateCombinationActivityExists(activityId); | ||
| 161 | - // 校验是否达到限购总限购标准 | ||
| 162 | - if ((sumCount + count) > activity.getTotalLimitCount()) { | ||
| 163 | - throw exception(COMBINATION_RECORD_FAILED_TOTAL_LIMIT_COUNT_EXCEED); | ||
| 164 | - } | ||
| 165 | - // 单次购买是否达到限购标准 | ||
| 166 | - if (count > activity.getSingleLimitCount()) { | ||
| 167 | - throw exception(COMBINATION_RECORD_FAILED_SINGLE_LIMIT_COUNT_EXCEED); | ||
| 168 | - } | ||
| 169 | - } | ||
| 170 | - | ||
| 171 | /** | 148 | /** |
| 172 | * APP 端获取开团记录 | 149 | * APP 端获取开团记录 |
| 173 | * | 150 | * |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/SeckillActivityService.java
| 1 | package cn.iocoder.yudao.module.promotion.service.seckill; | 1 | package cn.iocoder.yudao.module.promotion.service.seckill; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | -import cn.iocoder.yudao.module.promotion.api.seckill.dto.SeckillActivityUpdateStockReqDTO; | ||
| 5 | import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityCreateReqVO; | 4 | import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityCreateReqVO; |
| 6 | import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityPageReqVO; | 5 | import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityPageReqVO; |
| 7 | import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityUpdateReqVO; | 6 | import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityUpdateReqVO; |
| 7 | +import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityPageReqVO; | ||
| 8 | import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO; | 8 | import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO; |
| 9 | import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillProductDO; | 9 | import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillProductDO; |
| 10 | 10 | ||
| @@ -37,9 +37,11 @@ public interface SeckillActivityService { | @@ -37,9 +37,11 @@ public interface SeckillActivityService { | ||
| 37 | /** | 37 | /** |
| 38 | * 更新秒杀库存 | 38 | * 更新秒杀库存 |
| 39 | * | 39 | * |
| 40 | - * @param updateStockReqDTO 更新信息 | 40 | + * @param activityId 活动编号 |
| 41 | + * @param skuId sku 编号 | ||
| 42 | + * @param count 数量 | ||
| 41 | */ | 43 | */ |
| 42 | - void updateSeckillStock(SeckillActivityUpdateStockReqDTO updateStockReqDTO); | 44 | + void updateSeckillStock(Long activityId, Long skuId, Integer count); |
| 43 | 45 | ||
| 44 | /** | 46 | /** |
| 45 | * 关闭秒杀活动 | 47 | * 关闭秒杀活动 |
| @@ -87,4 +89,20 @@ public interface SeckillActivityService { | @@ -87,4 +89,20 @@ public interface SeckillActivityService { | ||
| 87 | */ | 89 | */ |
| 88 | List<SeckillProductDO> getSeckillProductListByActivityId(Collection<Long> activityIds); | 90 | List<SeckillProductDO> getSeckillProductListByActivityId(Collection<Long> activityIds); |
| 89 | 91 | ||
| 92 | + /** | ||
| 93 | + * 通过活动时段获取秒杀活动 | ||
| 94 | + * | ||
| 95 | + * @param ids 时段配置编号 | ||
| 96 | + * @return 秒杀活动列表 | ||
| 97 | + */ | ||
| 98 | + List<SeckillActivityDO> getSeckillActivityListByConfigIds(Collection<Long> ids); | ||
| 99 | + | ||
| 100 | + /** | ||
| 101 | + * 通过活动时段获取秒杀活动 | ||
| 102 | + * | ||
| 103 | + * @param pageReqVO 请求 | ||
| 104 | + * @return 秒杀活动列表 | ||
| 105 | + */ | ||
| 106 | + PageResult<SeckillActivityDO> getSeckillActivityAppPageByConfigId(AppSeckillActivityPageReqVO pageReqVO); | ||
| 107 | + | ||
| 90 | } | 108 | } |
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/seckill/SeckillActivityServiceImpl.java
| @@ -3,15 +3,16 @@ package cn.iocoder.yudao.module.promotion.service.seckill; | @@ -3,15 +3,16 @@ package cn.iocoder.yudao.module.promotion.service.seckill; | ||
| 3 | import cn.hutool.core.util.ObjectUtil; | 3 | import cn.hutool.core.util.ObjectUtil; |
| 4 | import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | 4 | import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; |
| 5 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 5 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 6 | +import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | ||
| 6 | import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; | 7 | import cn.iocoder.yudao.module.product.api.sku.ProductSkuApi; |
| 7 | import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; | 8 | import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; |
| 8 | import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi; | 9 | import cn.iocoder.yudao.module.product.api.spu.ProductSpuApi; |
| 9 | import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; | 10 | import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; |
| 10 | -import cn.iocoder.yudao.module.promotion.api.seckill.dto.SeckillActivityUpdateStockReqDTO; | ||
| 11 | import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityCreateReqVO; | 11 | import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityCreateReqVO; |
| 12 | import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityPageReqVO; | 12 | import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityPageReqVO; |
| 13 | import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityUpdateReqVO; | 13 | import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.activity.SeckillActivityUpdateReqVO; |
| 14 | import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product.SeckillProductBaseVO; | 14 | import cn.iocoder.yudao.module.promotion.controller.admin.seckill.vo.product.SeckillProductBaseVO; |
| 15 | +import cn.iocoder.yudao.module.promotion.controller.app.seckill.vo.activity.AppSeckillActivityPageReqVO; | ||
| 15 | import cn.iocoder.yudao.module.promotion.convert.seckill.seckillactivity.SeckillActivityConvert; | 16 | import cn.iocoder.yudao.module.promotion.convert.seckill.seckillactivity.SeckillActivityConvert; |
| 16 | import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO; | 17 | import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillActivityDO; |
| 17 | import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillProductDO; | 18 | import cn.iocoder.yudao.module.promotion.dal.dataobject.seckill.seckillactivity.SeckillProductDO; |
| @@ -147,32 +148,32 @@ public class SeckillActivityServiceImpl implements SeckillActivityService { | @@ -147,32 +148,32 @@ public class SeckillActivityServiceImpl implements SeckillActivityService { | ||
| 147 | 148 | ||
| 148 | @Override | 149 | @Override |
| 149 | @Transactional(rollbackFor = Exception.class) | 150 | @Transactional(rollbackFor = Exception.class) |
| 150 | - public void updateSeckillStock(SeckillActivityUpdateStockReqDTO updateStockReqDTO) { | 151 | + public void updateSeckillStock(Long activityId, Long skuId, Integer count) { |
| 151 | // 1、校验秒杀活动是否存在 | 152 | // 1、校验秒杀活动是否存在 |
| 152 | - SeckillActivityDO seckillActivity = getSeckillActivity(updateStockReqDTO.getActivityId()); | 153 | + SeckillActivityDO seckillActivity = getSeckillActivity(activityId); |
| 153 | // 1.1、校验库存是否充足 | 154 | // 1.1、校验库存是否充足 |
| 154 | - if (seckillActivity.getTotalStock() < updateStockReqDTO.getCount()) { | 155 | + if (seckillActivity.getTotalStock() < count) { |
| 155 | throw exception(SECKILL_ACTIVITY_UPDATE_STOCK_FAIL); | 156 | throw exception(SECKILL_ACTIVITY_UPDATE_STOCK_FAIL); |
| 156 | } | 157 | } |
| 157 | 158 | ||
| 158 | // 2、获取活动商品 | 159 | // 2、获取活动商品 |
| 159 | - List<SeckillProductDO> products = getSeckillProductListByActivityId(updateStockReqDTO.getActivityId()); | 160 | + List<SeckillProductDO> products = getSeckillProductListByActivityId(activityId); |
| 160 | // 2.1、过滤出购买的商品 | 161 | // 2.1、过滤出购买的商品 |
| 161 | - SeckillProductDO product = findFirst(products, item -> ObjectUtil.equal(updateStockReqDTO.getItem().getSkuId(), item.getSkuId())); | 162 | + SeckillProductDO product = findFirst(products, item -> ObjectUtil.equal(skuId, item.getSkuId())); |
| 162 | // 2.2、检查活动商品库存是否充足 | 163 | // 2.2、检查活动商品库存是否充足 |
| 163 | - boolean isSufficient = product == null || (product.getStock() == 0 || (product.getStock() < updateStockReqDTO.getItem().getCount()) || (product.getStock() - updateStockReqDTO.getItem().getCount()) < 0); | 164 | + boolean isSufficient = product == null || (product.getStock() == 0 || (product.getStock() < count) || (product.getStock() - count) < 0); |
| 164 | if (isSufficient) { | 165 | if (isSufficient) { |
| 165 | throw exception(SECKILL_ACTIVITY_UPDATE_STOCK_FAIL); | 166 | throw exception(SECKILL_ACTIVITY_UPDATE_STOCK_FAIL); |
| 166 | } | 167 | } |
| 167 | 168 | ||
| 168 | // 3、更新活动商品库存 | 169 | // 3、更新活动商品库存 |
| 169 | - int updateCount = seckillProductMapper.updateActivityStock(product.getId(), updateStockReqDTO.getItem().getCount()); | 170 | + int updateCount = seckillProductMapper.updateActivityStock(product.getId(), count); |
| 170 | if (updateCount == 0) { | 171 | if (updateCount == 0) { |
| 171 | throw exception(SECKILL_ACTIVITY_UPDATE_STOCK_FAIL); | 172 | throw exception(SECKILL_ACTIVITY_UPDATE_STOCK_FAIL); |
| 172 | } | 173 | } |
| 173 | 174 | ||
| 174 | // 4、更新活动库存 | 175 | // 4、更新活动库存 |
| 175 | - updateCount = seckillActivityMapper.updateActivityStock(seckillActivity.getId(), updateStockReqDTO.getCount()); | 176 | + updateCount = seckillActivityMapper.updateActivityStock(seckillActivity.getId(), count); |
| 176 | if (updateCount == 0) { | 177 | if (updateCount == 0) { |
| 177 | throw exception(SECKILL_ACTIVITY_UPDATE_STOCK_FAIL); | 178 | throw exception(SECKILL_ACTIVITY_UPDATE_STOCK_FAIL); |
| 178 | } | 179 | } |
| @@ -265,4 +266,15 @@ public class SeckillActivityServiceImpl implements SeckillActivityService { | @@ -265,4 +266,15 @@ public class SeckillActivityServiceImpl implements SeckillActivityService { | ||
| 265 | return seckillProductMapper.selectListByActivityId(activityIds); | 266 | return seckillProductMapper.selectListByActivityId(activityIds); |
| 266 | } | 267 | } |
| 267 | 268 | ||
| 269 | + @Override | ||
| 270 | + public List<SeckillActivityDO> getSeckillActivityListByConfigIds(Collection<Long> ids) { | ||
| 271 | + return CollectionUtils.filterList(seckillActivityMapper.selectList(), | ||
| 272 | + item -> CollectionUtils.anyMatch(item.getConfigIds(), ids::contains)); | ||
| 273 | + } | ||
| 274 | + | ||
| 275 | + @Override | ||
| 276 | + public PageResult<SeckillActivityDO> getSeckillActivityAppPageByConfigId(AppSeckillActivityPageReqVO pageReqVO) { | ||
| 277 | + return seckillActivityMapper.selectPage(pageReqVO, CommonStatusEnum.ENABLE.getStatus()); | ||
| 278 | + } | ||
| 279 | + | ||
| 268 | } | 280 | } |
yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/api/brokerage/BrokerageApi.java deleted
| 1 | -package cn.iocoder.yudao.module.trade.api.brokerage; | ||
| 2 | - | ||
| 3 | -import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils; | ||
| 4 | -import cn.iocoder.yudao.module.trade.api.brokerage.dto.BrokerageUserDTO; | ||
| 5 | - | ||
| 6 | -import javax.validation.constraints.NotNull; | ||
| 7 | -import java.time.LocalDateTime; | ||
| 8 | - | ||
| 9 | -// TODO @疯狂:是不是不需要这个啦? | ||
| 10 | -/** | ||
| 11 | - * 分销 API 接口 | ||
| 12 | - * | ||
| 13 | - * @author owen | ||
| 14 | - */ | ||
| 15 | -public interface BrokerageApi { | ||
| 16 | - | ||
| 17 | - /** | ||
| 18 | - * 获得分销用户 | ||
| 19 | - * | ||
| 20 | - * @param userId 用户编号 | ||
| 21 | - * @return 分销用户信息 | ||
| 22 | - */ | ||
| 23 | - BrokerageUserDTO getBrokerageUser(Long userId); | ||
| 24 | - | ||
| 25 | - /** | ||
| 26 | - * 【会员】绑定推广员 | ||
| 27 | - * | ||
| 28 | - * @param userId 用户编号 | ||
| 29 | - * @param bindUserId 推广员编号 | ||
| 30 | - * @param registerTime 用户注册时间 | ||
| 31 | - * @return 是否绑定 | ||
| 32 | - */ | ||
| 33 | - default boolean bindUser(@NotNull Long userId, @NotNull Long bindUserId, @NotNull LocalDateTime registerTime) { | ||
| 34 | - // 注册时间在30秒内的,都算新用户 | ||
| 35 | - // TODO @疯狂:这个要不抽到 service 里哈? | ||
| 36 | - boolean isNewUser = LocalDateTimeUtils.afterNow(registerTime.minusSeconds(30)); | ||
| 37 | - return bindUser(userId, bindUserId, isNewUser); | ||
| 38 | - } | ||
| 39 | - | ||
| 40 | - /** | ||
| 41 | - * 绑定推广员 | ||
| 42 | - * | ||
| 43 | - * @param userId 用户编号 | ||
| 44 | - * @param bindUserId 推广员编号 | ||
| 45 | - * @param isNewUser 是否为新用户 | ||
| 46 | - * @return 是否绑定 | ||
| 47 | - */ | ||
| 48 | - boolean bindUser(@NotNull(message = "用户编号不能为空") Long userId, | ||
| 49 | - @NotNull(message = "推广员编号不能为空") Long bindUserId, | ||
| 50 | - @NotNull Boolean isNewUser); | ||
| 51 | - | ||
| 52 | -} |
yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/api/brokerage/dto/BrokerageUserDTO.java deleted
| 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
| @@ -58,8 +58,9 @@ public interface ErrorCodeConstants { | @@ -58,8 +58,9 @@ public interface ErrorCodeConstants { | ||
| 58 | 58 | ||
| 59 | // ========== Price 相关 1011003000 ============ | 59 | // ========== Price 相关 1011003000 ============ |
| 60 | ErrorCode PRICE_CALCULATE_PAY_PRICE_ILLEGAL = new ErrorCode(1011003000, "支付价格计算异常,原因:价格小于等于 0"); | 60 | ErrorCode PRICE_CALCULATE_PAY_PRICE_ILLEGAL = new ErrorCode(1011003000, "支付价格计算异常,原因:价格小于等于 0"); |
| 61 | - ErrorCode PRICE_CALCULATE_DELIVERY_PRICE_USER_ADDR_IS_EMPTY = new ErrorCode(1011003001, "计算快递运费异常,收件人地址编号为空"); | 61 | + ErrorCode PRICE_CALCULATE_DELIVERY_PRICE_USER_ADDRESS_IS_EMPTY = new ErrorCode(1011003001, "计算快递运费异常,收件人地址编号为空"); |
| 62 | ErrorCode PRICE_CALCULATE_DELIVERY_PRICE_TEMPLATE_NOT_FOUND = new ErrorCode(1011003002, "计算快递运费异常,找不到对应的运费模板"); | 62 | ErrorCode PRICE_CALCULATE_DELIVERY_PRICE_TEMPLATE_NOT_FOUND = new ErrorCode(1011003002, "计算快递运费异常,找不到对应的运费模板"); |
| 63 | + ErrorCode PRICE_CALCULATE_DELIVERY_PRICE_PICK_UP_STORE_IS_EMPTY = new ErrorCode(1011003003, "计算快递运费异常,自提点为空"); | ||
| 63 | 64 | ||
| 64 | // ========== 物流 Express 模块 1011004000 ========== | 65 | // ========== 物流 Express 模块 1011004000 ========== |
| 65 | ErrorCode EXPRESS_NOT_EXISTS = new ErrorCode(1011004000, "快递公司不存在"); | 66 | ErrorCode EXPRESS_NOT_EXISTS = new ErrorCode(1011004000, "快递公司不存在"); |
| @@ -88,4 +89,9 @@ public interface ErrorCodeConstants { | @@ -88,4 +89,9 @@ public interface ErrorCodeConstants { | ||
| 88 | ErrorCode BROKERAGE_BIND_OVERRIDE = new ErrorCode(1011007006, "已绑定了推广人"); | 89 | ErrorCode BROKERAGE_BIND_OVERRIDE = new ErrorCode(1011007006, "已绑定了推广人"); |
| 89 | ErrorCode BROKERAGE_BIND_LOOP = new ErrorCode(1011007007, "下级不能绑定自己的上级"); | 90 | ErrorCode BROKERAGE_BIND_LOOP = new ErrorCode(1011007007, "下级不能绑定自己的上级"); |
| 90 | 91 | ||
| 92 | + | ||
| 93 | + // ========== 分销提现 模块 1011008000 ========== | ||
| 94 | + ErrorCode BROKERAGE_WITHDRAW_NOT_EXISTS = new ErrorCode(1011008000, "佣金提现记录不存在"); | ||
| 95 | + ErrorCode BROKERAGE_WITHDRAW_STATUS_NOT_AUDITING = new ErrorCode(1011008001, "佣金提现记录状态不是审核中"); | ||
| 96 | + | ||
| 91 | } | 97 | } |
yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/MessageTemplateConstants.java
| @@ -10,4 +10,7 @@ public interface MessageTemplateConstants { | @@ -10,4 +10,7 @@ public interface MessageTemplateConstants { | ||
| 10 | 10 | ||
| 11 | String ORDER_DELIVERY = "order_delivery"; // 短信模版编号 | 11 | String ORDER_DELIVERY = "order_delivery"; // 短信模版编号 |
| 12 | 12 | ||
| 13 | + String BROKERAGE_WITHDRAW_AUDIT_APPROVE = "brokerage_withdraw_audit_approve"; // 佣金提现(审核通过) | ||
| 14 | + String BROKERAGE_WITHDRAW_AUDIT_REJECT = "brokerage_withdraw_audit_reject"; // 佣金提现(审核不通过) | ||
| 15 | + | ||
| 13 | } | 16 | } |
yudao-module-mall/yudao-module-trade-api/src/main/java/cn/iocoder/yudao/module/trade/enums/brokerage/BrokerageUserTypeEnum.java deleted
| 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 | -// TODO @疯狂:是不是搞成层级,类似 level 这样?因为本质上,它是 1 级、2 级、3 级这样的关系哈 | ||
| 10 | -/** | ||
| 11 | - * 分销用户类型枚举 | ||
| 12 | - * | ||
| 13 | - * @author owen | ||
| 14 | - */ | ||
| 15 | -@AllArgsConstructor | ||
| 16 | -@Getter | ||
| 17 | -public enum BrokerageUserTypeEnum implements IntArrayValuable { | ||
| 18 | - | ||
| 19 | - ALL(0, "全部"), | ||
| 20 | - FIRST(1, "一级推广人"), | ||
| 21 | - SECOND(2, "二级推广人"), | ||
| 22 | - ; | ||
| 23 | - | ||
| 24 | - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(BrokerageUserTypeEnum::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-api/src/main/java/cn/iocoder/yudao/module/trade/enums/delivery/DeliveryTypeEnum.java
| @@ -15,16 +15,15 @@ import java.util.Arrays; | @@ -15,16 +15,15 @@ import java.util.Arrays; | ||
| 15 | @AllArgsConstructor | 15 | @AllArgsConstructor |
| 16 | public enum DeliveryTypeEnum implements IntArrayValuable { | 16 | public enum DeliveryTypeEnum implements IntArrayValuable { |
| 17 | 17 | ||
| 18 | - NULL(0, "无需物流"), | ||
| 19 | EXPRESS(1, "快递发货"), | 18 | EXPRESS(1, "快递发货"), |
| 20 | PICK_UP(2, "用户自提"),; | 19 | PICK_UP(2, "用户自提"),; |
| 21 | 20 | ||
| 22 | - public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(DeliveryTypeEnum::getMode).toArray(); | 21 | + public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(DeliveryTypeEnum::getType).toArray(); |
| 23 | 22 | ||
| 24 | /** | 23 | /** |
| 25 | * 配送方式 | 24 | * 配送方式 |
| 26 | */ | 25 | */ |
| 27 | - private final Integer mode; | 26 | + private final Integer type; |
| 28 | /** | 27 | /** |
| 29 | * 状态名 | 28 | * 状态名 |
| 30 | */ | 29 | */ |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/api/brokerage/BrokerageApiImpl.java deleted
| 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/brokerage/record/vo/BrokerageRecordBaseVO.java
| @@ -57,8 +57,8 @@ public class BrokerageRecordBaseVO { | @@ -57,8 +57,8 @@ public class BrokerageRecordBaseVO { | ||
| 57 | @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | 57 | @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) |
| 58 | private LocalDateTime unfreezeTime; | 58 | private LocalDateTime unfreezeTime; |
| 59 | 59 | ||
| 60 | - @Schema(description = "来源用户类型") | ||
| 61 | - private Integer sourceUserType; | 60 | + @Schema(description = "来源用户等级") |
| 61 | + private Integer sourceUserLevel; | ||
| 62 | 62 | ||
| 63 | @Schema(description = "来源用户编号") | 63 | @Schema(description = "来源用户编号") |
| 64 | private Long sourceUserId; | 64 | private Long sourceUserId; |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/record/vo/BrokerageRecordPageReqVO.java
| 1 | package cn.iocoder.yudao.module.trade.controller.admin.brokerage.record.vo; | 1 | package cn.iocoder.yudao.module.trade.controller.admin.brokerage.record.vo; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.common.pojo.PageParam; | 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.BrokerageUserTypeEnum; | ||
| 6 | import io.swagger.v3.oas.annotations.media.Schema; | 4 | import io.swagger.v3.oas.annotations.media.Schema; |
| 7 | import lombok.Data; | 5 | import lombok.Data; |
| 8 | import lombok.EqualsAndHashCode; | 6 | import lombok.EqualsAndHashCode; |
| @@ -32,8 +30,7 @@ public class BrokerageRecordPageReqVO extends PageParam { | @@ -32,8 +30,7 @@ public class BrokerageRecordPageReqVO extends PageParam { | ||
| 32 | @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | 30 | @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) |
| 33 | private LocalDateTime[] createTime; | 31 | private LocalDateTime[] createTime; |
| 34 | 32 | ||
| 35 | - @Schema(description = "用户类型") | ||
| 36 | - @InEnum(value = BrokerageUserTypeEnum.class, message = "用户类型必须是 {value}") | ||
| 37 | - private Integer sourceUserType; | 33 | + @Schema(description = "用户类型", example = "1") |
| 34 | + private Integer sourceUserLevel; | ||
| 38 | 35 | ||
| 39 | } | 36 | } |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/user/BrokerageUserController.java
| @@ -9,7 +9,6 @@ import cn.iocoder.yudao.module.trade.convert.brokerage.user.BrokerageUserConvert | @@ -9,7 +9,6 @@ import cn.iocoder.yudao.module.trade.convert.brokerage.user.BrokerageUserConvert | ||
| 9 | import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.user.BrokerageUserDO; | 9 | import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.user.BrokerageUserDO; |
| 10 | import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordBizTypeEnum; | 10 | import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordBizTypeEnum; |
| 11 | import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordStatusEnum; | 11 | import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordStatusEnum; |
| 12 | -import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageUserTypeEnum; | ||
| 13 | import cn.iocoder.yudao.module.trade.service.brokerage.bo.UserBrokerageSummaryBO; | 12 | import cn.iocoder.yudao.module.trade.service.brokerage.bo.UserBrokerageSummaryBO; |
| 14 | import cn.iocoder.yudao.module.trade.service.brokerage.record.BrokerageRecordService; | 13 | import cn.iocoder.yudao.module.trade.service.brokerage.record.BrokerageRecordService; |
| 15 | import cn.iocoder.yudao.module.trade.service.brokerage.user.BrokerageUserService; | 14 | import cn.iocoder.yudao.module.trade.service.brokerage.user.BrokerageUserService; |
| @@ -96,7 +95,7 @@ public class BrokerageUserController { | @@ -96,7 +95,7 @@ public class BrokerageUserController { | ||
| 96 | // 合计推广用户数量 | 95 | // 合计推广用户数量 |
| 97 | Map<Long, Long> brokerageUserCountMap = convertMap(userIds, | 96 | Map<Long, Long> brokerageUserCountMap = convertMap(userIds, |
| 98 | userId -> userId, | 97 | userId -> userId, |
| 99 | - userId -> brokerageUserService.getBrokerageUserCountByBindUserId(userId, BrokerageUserTypeEnum.ALL)); | 98 | + userId -> brokerageUserService.getBrokerageUserCountByBindUserId(userId, null)); |
| 100 | 99 | ||
| 101 | // todo 合计提现 | 100 | // todo 合计提现 |
| 102 | 101 |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/user/vo/BrokerageUserPageReqVO.java
| 1 | package cn.iocoder.yudao.module.trade.controller.admin.brokerage.user.vo; | 1 | package cn.iocoder.yudao.module.trade.controller.admin.brokerage.user.vo; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.common.pojo.PageParam; | 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.BrokerageUserTypeEnum; | ||
| 6 | import io.swagger.v3.oas.annotations.media.Schema; | 4 | import io.swagger.v3.oas.annotations.media.Schema; |
| 7 | import lombok.Data; | 5 | import lombok.Data; |
| 8 | import lombok.EqualsAndHashCode; | 6 | import lombok.EqualsAndHashCode; |
| @@ -22,18 +20,18 @@ public class BrokerageUserPageReqVO extends PageParam { | @@ -22,18 +20,18 @@ public class BrokerageUserPageReqVO extends PageParam { | ||
| 22 | @Schema(description = "推广员编号", example = "4587") | 20 | @Schema(description = "推广员编号", example = "4587") |
| 23 | private Long bindUserId; | 21 | private Long bindUserId; |
| 24 | 22 | ||
| 25 | - @Schema(description = "推广资格") | 23 | + @Schema(description = "推广资格", example = "true") |
| 26 | private Boolean brokerageEnabled; | 24 | private Boolean brokerageEnabled; |
| 27 | 25 | ||
| 28 | @Schema(description = "创建时间") | 26 | @Schema(description = "创建时间") |
| 29 | @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | 27 | @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) |
| 30 | private LocalDateTime[] createTime; | 28 | private LocalDateTime[] createTime; |
| 31 | 29 | ||
| 32 | - @Schema(description = "用户类型") | ||
| 33 | - @InEnum(value = BrokerageUserTypeEnum.class, message = "用户类型必须是 {value}") | ||
| 34 | - private Integer userType; | 30 | + @Schema(description = "用户等级", example = "1") // 注意,这了不是用户的会员等级,而是过滤推广的层级 |
| 31 | + private Integer level; | ||
| 35 | 32 | ||
| 36 | @Schema(description = "绑定时间") | 33 | @Schema(description = "绑定时间") |
| 37 | @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | 34 | @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) |
| 38 | private LocalDateTime[] bindUserTime; | 35 | private LocalDateTime[] bindUserTime; |
| 36 | + | ||
| 39 | } | 37 | } |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/withdraw/BrokerageWithdrawController.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.trade.controller.admin.brokerage.withdraw; | ||
| 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.withdraw.vo.BrokerageWithdrawRejectReqVO; | ||
| 8 | +import cn.iocoder.yudao.module.trade.controller.admin.brokerage.withdraw.vo.BrokerageWithdrawPageReqVO; | ||
| 9 | +import cn.iocoder.yudao.module.trade.controller.admin.brokerage.withdraw.vo.BrokerageWithdrawRespVO; | ||
| 10 | +import cn.iocoder.yudao.module.trade.convert.brokerage.withdraw.BrokerageWithdrawConvert; | ||
| 11 | +import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.withdraw.BrokerageWithdrawDO; | ||
| 12 | +import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageWithdrawStatusEnum; | ||
| 13 | +import cn.iocoder.yudao.module.trade.service.brokerage.withdraw.BrokerageWithdrawService; | ||
| 14 | +import io.swagger.v3.oas.annotations.Operation; | ||
| 15 | +import io.swagger.v3.oas.annotations.Parameter; | ||
| 16 | +import io.swagger.v3.oas.annotations.tags.Tag; | ||
| 17 | +import org.springframework.security.access.prepost.PreAuthorize; | ||
| 18 | +import org.springframework.validation.annotation.Validated; | ||
| 19 | +import org.springframework.web.bind.annotation.*; | ||
| 20 | + | ||
| 21 | +import javax.annotation.Resource; | ||
| 22 | +import javax.validation.Valid; | ||
| 23 | +import java.util.Map; | ||
| 24 | + | ||
| 25 | +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | ||
| 26 | +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; | ||
| 27 | + | ||
| 28 | +@Tag(name = "管理后台 - 佣金提现") | ||
| 29 | +@RestController | ||
| 30 | +@RequestMapping("/trade/brokerage-withdraw") | ||
| 31 | +@Validated | ||
| 32 | +public class BrokerageWithdrawController { | ||
| 33 | + | ||
| 34 | + @Resource | ||
| 35 | + private BrokerageWithdrawService brokerageWithdrawService; | ||
| 36 | + | ||
| 37 | + @Resource | ||
| 38 | + private MemberUserApi memberUserApi; | ||
| 39 | + | ||
| 40 | + @PutMapping("/approve") | ||
| 41 | + @Operation(summary = "通过申请") | ||
| 42 | + @PreAuthorize("@ss.hasPermission('trade:brokerage-withdraw:audit')") | ||
| 43 | + public CommonResult<Boolean> approveBrokerageWithdraw(@RequestParam("id") Integer id) { | ||
| 44 | + brokerageWithdrawService.auditBrokerageWithdraw(id, BrokerageWithdrawStatusEnum.AUDIT_SUCCESS, ""); | ||
| 45 | + return success(true); | ||
| 46 | + } | ||
| 47 | + | ||
| 48 | + @PutMapping("/reject") | ||
| 49 | + @Operation(summary = "驳回申请") | ||
| 50 | + @PreAuthorize("@ss.hasPermission('trade:brokerage-withdraw:audit')") | ||
| 51 | + public CommonResult<Boolean> rejectBrokerageWithdraw(@Valid @RequestBody BrokerageWithdrawRejectReqVO reqVO) { | ||
| 52 | + brokerageWithdrawService.auditBrokerageWithdraw(reqVO.getId(), BrokerageWithdrawStatusEnum.AUDIT_FAIL, reqVO.getAuditReason()); | ||
| 53 | + return success(true); | ||
| 54 | + } | ||
| 55 | + | ||
| 56 | + @GetMapping("/get") | ||
| 57 | + @Operation(summary = "获得佣金提现") | ||
| 58 | + @Parameter(name = "id", description = "编号", required = true, example = "1024") | ||
| 59 | + @PreAuthorize("@ss.hasPermission('trade:brokerage-withdraw:query')") | ||
| 60 | + public CommonResult<BrokerageWithdrawRespVO> getBrokerageWithdraw(@RequestParam("id") Integer id) { | ||
| 61 | + BrokerageWithdrawDO brokerageWithdraw = brokerageWithdrawService.getBrokerageWithdraw(id); | ||
| 62 | + return success(BrokerageWithdrawConvert.INSTANCE.convert(brokerageWithdraw)); | ||
| 63 | + } | ||
| 64 | + | ||
| 65 | + @GetMapping("/page") | ||
| 66 | + @Operation(summary = "获得佣金提现分页") | ||
| 67 | + @PreAuthorize("@ss.hasPermission('trade:brokerage-withdraw:query')") | ||
| 68 | + public CommonResult<PageResult<BrokerageWithdrawRespVO>> getBrokerageWithdrawPage(@Valid BrokerageWithdrawPageReqVO pageVO) { | ||
| 69 | + // 分页查询 | ||
| 70 | + PageResult<BrokerageWithdrawDO> pageResult = brokerageWithdrawService.getBrokerageWithdrawPage(pageVO); | ||
| 71 | + | ||
| 72 | + // 拼接信息 | ||
| 73 | + Map<Long, MemberUserRespDTO> userMap = memberUserApi.getUserMap( | ||
| 74 | + convertSet(pageResult.getList(), BrokerageWithdrawDO::getUserId)); | ||
| 75 | + return success(BrokerageWithdrawConvert.INSTANCE.convertPage(pageResult, userMap)); | ||
| 76 | + } | ||
| 77 | + | ||
| 78 | +} |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/withdraw/vo/BrokerageWithdrawBaseVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.trade.controller.admin.brokerage.withdraw.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 BrokerageWithdrawBaseVO { | ||
| 18 | + | ||
| 19 | + @Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "11436") | ||
| 20 | + @NotNull(message = "用户编号不能为空") | ||
| 21 | + private Long userId; | ||
| 22 | + | ||
| 23 | + @Schema(description = "提现金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "18781") | ||
| 24 | + @NotNull(message = "提现金额不能为空") | ||
| 25 | + private Integer price; | ||
| 26 | + | ||
| 27 | + @Schema(description = "提现手续费", requiredMode = Schema.RequiredMode.REQUIRED, example = "11417") | ||
| 28 | + @NotNull(message = "提现手续费不能为空") | ||
| 29 | + private Integer feePrice; | ||
| 30 | + | ||
| 31 | + @Schema(description = "当前总佣金", requiredMode = Schema.RequiredMode.REQUIRED, example = "18576") | ||
| 32 | + @NotNull(message = "当前总佣金不能为空") | ||
| 33 | + private Integer totalPrice; | ||
| 34 | + | ||
| 35 | + @Schema(description = "提现类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | ||
| 36 | + @NotNull(message = "提现类型不能为空") | ||
| 37 | + private Integer type; | ||
| 38 | + | ||
| 39 | + @Schema(description = "真实姓名", example = "赵六") | ||
| 40 | + private String name; | ||
| 41 | + | ||
| 42 | + @Schema(description = "账号", example = "88677912132") | ||
| 43 | + private String accountNo; | ||
| 44 | + | ||
| 45 | + @Schema(description = "银行名称", example = "1") | ||
| 46 | + private String bankName; | ||
| 47 | + | ||
| 48 | + @Schema(description = "开户地址", example = "海淀支行") | ||
| 49 | + private String bankAddress; | ||
| 50 | + | ||
| 51 | + @Schema(description = "收款码", example = "https://www.iocoder.cn") | ||
| 52 | + private String accountQrCodeUrl; | ||
| 53 | + | ||
| 54 | + @Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | ||
| 55 | + @NotNull(message = "状态不能为空") | ||
| 56 | + private Integer status; | ||
| 57 | + | ||
| 58 | + @Schema(description = "审核驳回原因", example = "不对") | ||
| 59 | + private String auditReason; | ||
| 60 | + | ||
| 61 | + @Schema(description = "审核时间") | ||
| 62 | + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | ||
| 63 | + private LocalDateTime auditTime; | ||
| 64 | + | ||
| 65 | + @Schema(description = "备注", example = "随便") | ||
| 66 | + private String remark; | ||
| 67 | + | ||
| 68 | +} |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/withdraw/vo/BrokerageWithdrawPageReqVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.trade.controller.admin.brokerage.withdraw.vo; | ||
| 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.BrokerageWithdrawStatusEnum; | ||
| 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 lombok.EqualsAndHashCode; | ||
| 10 | +import lombok.ToString; | ||
| 11 | +import org.springframework.format.annotation.DateTimeFormat; | ||
| 12 | + | ||
| 13 | +import java.time.LocalDateTime; | ||
| 14 | + | ||
| 15 | +import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; | ||
| 16 | + | ||
| 17 | +@Schema(description = "管理后台 - 佣金提现分页 Request VO") | ||
| 18 | +@Data | ||
| 19 | +@EqualsAndHashCode(callSuper = true) | ||
| 20 | +@ToString(callSuper = true) | ||
| 21 | +public class BrokerageWithdrawPageReqVO extends PageParam { | ||
| 22 | + | ||
| 23 | + @Schema(description = "用户编号", example = "11436") | ||
| 24 | + private Long userId; | ||
| 25 | + | ||
| 26 | + @Schema(description = "提现类型", example = "1") | ||
| 27 | + @InEnum(value = BrokerageWithdrawTypeEnum.class, message = "提现类型必须是 {value}") | ||
| 28 | + private Integer type; | ||
| 29 | + | ||
| 30 | + @Schema(description = "真实姓名", example = "赵六") | ||
| 31 | + private String name; | ||
| 32 | + | ||
| 33 | + @Schema(description = "账号", example = "886779132") | ||
| 34 | + private String accountNo; | ||
| 35 | + | ||
| 36 | + @Schema(description = "银行名称", example = "1") | ||
| 37 | + private String bankName; | ||
| 38 | + | ||
| 39 | + @Schema(description = "状态", example = "1") | ||
| 40 | + @InEnum(value = BrokerageWithdrawStatusEnum.class, message = "状态必须是 {value}") | ||
| 41 | + private Integer status; | ||
| 42 | + | ||
| 43 | + @Schema(description = "创建时间") | ||
| 44 | + @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) | ||
| 45 | + private LocalDateTime[] createTime; | ||
| 46 | + | ||
| 47 | +} |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/withdraw/vo/BrokerageWithdrawRejectReqVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.trade.controller.admin.brokerage.withdraw.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.NotEmpty; | ||
| 8 | +import javax.validation.constraints.NotNull; | ||
| 9 | + | ||
| 10 | +@Schema(description = "管理后台 - 驳回申请 Request VO") | ||
| 11 | +@Data | ||
| 12 | +@ToString(callSuper = true) | ||
| 13 | +public class BrokerageWithdrawRejectReqVO { | ||
| 14 | + | ||
| 15 | + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "7161") | ||
| 16 | + @NotNull(message = "编号不能为空") | ||
| 17 | + private Integer id; | ||
| 18 | + | ||
| 19 | + @Schema(description = "审核驳回原因", example = "不对") | ||
| 20 | + @NotEmpty(message = "审核驳回原因不能为空") | ||
| 21 | + private String auditReason; | ||
| 22 | + | ||
| 23 | +} |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/withdraw/vo/BrokerageWithdrawRespVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.trade.controller.admin.brokerage.withdraw.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 BrokerageWithdrawRespVO extends BrokerageWithdrawBaseVO { | ||
| 15 | + | ||
| 16 | + @Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "7161") | ||
| 17 | + private Integer id; | ||
| 18 | + | ||
| 19 | + @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) | ||
| 20 | + private LocalDateTime createTime; | ||
| 21 | + | ||
| 22 | + @Schema(description = "用户昵称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿") | ||
| 23 | + private String userNickname; | ||
| 24 | + | ||
| 25 | +} |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.http
| @@ -8,14 +8,15 @@ GET {{appApi}}/trade/order/settlement?type=0&items[0].cartId=50&couponId=1 | @@ -8,14 +8,15 @@ GET {{appApi}}/trade/order/settlement?type=0&items[0].cartId=50&couponId=1 | ||
| 8 | Authorization: Bearer {{appToken}} | 8 | Authorization: Bearer {{appToken}} |
| 9 | tenant-id: {{appTenentId}} | 9 | tenant-id: {{appTenentId}} |
| 10 | 10 | ||
| 11 | -### /trade-order/create 创建订单(基于商品) | 11 | +### /trade-order/create 创建订单(基于商品)【快递】 |
| 12 | POST {{appApi}}/trade/order/create | 12 | POST {{appApi}}/trade/order/create |
| 13 | Content-Type: application/json | 13 | Content-Type: application/json |
| 14 | Authorization: Bearer {{appToken}} | 14 | Authorization: Bearer {{appToken}} |
| 15 | tenant-id: {{appTenentId}} | 15 | tenant-id: {{appTenentId}} |
| 16 | 16 | ||
| 17 | { | 17 | { |
| 18 | - "type": 0, | 18 | + "pointStatus": true, |
| 19 | + "deliveryType": 1, | ||
| 19 | "addressId": 21, | 20 | "addressId": 21, |
| 20 | "items": [ | 21 | "items": [ |
| 21 | { | 22 | { |
| @@ -26,6 +27,27 @@ tenant-id: {{appTenentId}} | @@ -26,6 +27,27 @@ tenant-id: {{appTenentId}} | ||
| 26 | "remark": "我是备注" | 27 | "remark": "我是备注" |
| 27 | } | 28 | } |
| 28 | 29 | ||
| 30 | +### /trade-order/create 创建订单(基于商品)【自提】 | ||
| 31 | +POST {{appApi}}/trade/order/create | ||
| 32 | +Content-Type: application/json | ||
| 33 | +Authorization: Bearer {{appToken}} | ||
| 34 | +tenant-id: {{appTenentId}} | ||
| 35 | + | ||
| 36 | +{ | ||
| 37 | + "pointStatus": true, | ||
| 38 | + "deliveryType": 2, | ||
| 39 | + "pickUpStoreId": 1, | ||
| 40 | + "items": [ | ||
| 41 | + { | ||
| 42 | + "skuId": 1, | ||
| 43 | + "count": 2 | ||
| 44 | + } | ||
| 45 | + ], | ||
| 46 | + "remark": "我是备注", | ||
| 47 | + "receiverName": "土豆", | ||
| 48 | + "receiverMobile": "15601691300" | ||
| 49 | +} | ||
| 50 | + | ||
| 29 | ### 获得订单交易的分页 | 51 | ### 获得订单交易的分页 |
| 30 | GET {{appApi}}/trade/order/page?pageNo=1&pageSize=10 | 52 | GET {{appApi}}/trade/order/page?pageNo=1&pageSize=10 |
| 31 | Authorization: Bearer {{appToken}} | 53 | Authorization: Bearer {{appToken}} |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/AppTradeOrderController.java
| 1 | package cn.iocoder.yudao.module.trade.controller.app.order; | 1 | package cn.iocoder.yudao.module.trade.controller.app.order; |
| 2 | 2 | ||
| 3 | -import cn.hutool.core.map.MapUtil; | ||
| 4 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; | 3 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 5 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 6 | import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated; | 5 | import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated; |
| @@ -12,11 +11,8 @@ import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert; | @@ -12,11 +11,8 @@ import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert; | ||
| 12 | import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressDO; | 11 | import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressDO; |
| 13 | import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; | 12 | import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; |
| 14 | import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; | 13 | import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; |
| 15 | -import cn.iocoder.yudao.module.trade.enums.order.TradeOrderOperateTypeEnum; | ||
| 16 | import cn.iocoder.yudao.module.trade.enums.order.TradeOrderStatusEnum; | 14 | import cn.iocoder.yudao.module.trade.enums.order.TradeOrderStatusEnum; |
| 17 | import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties; | 15 | import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties; |
| 18 | -import cn.iocoder.yudao.module.trade.framework.order.core.annotations.TradeOrderLog; | ||
| 19 | -import cn.iocoder.yudao.module.trade.framework.order.core.utils.TradeOrderLogUtils; | ||
| 20 | import cn.iocoder.yudao.module.trade.service.delivery.DeliveryExpressService; | 16 | import cn.iocoder.yudao.module.trade.service.delivery.DeliveryExpressService; |
| 21 | import cn.iocoder.yudao.module.trade.service.order.TradeOrderQueryService; | 17 | import cn.iocoder.yudao.module.trade.service.order.TradeOrderQueryService; |
| 22 | import cn.iocoder.yudao.module.trade.service.order.TradeOrderUpdateService; | 18 | import cn.iocoder.yudao.module.trade.service.order.TradeOrderUpdateService; |
| @@ -65,10 +61,7 @@ public class AppTradeOrderController { | @@ -65,10 +61,7 @@ public class AppTradeOrderController { | ||
| 65 | @PostMapping("/create") | 61 | @PostMapping("/create") |
| 66 | @Operation(summary = "创建订单") | 62 | @Operation(summary = "创建订单") |
| 67 | @PreAuthenticated | 63 | @PreAuthenticated |
| 68 | - @TradeOrderLog(operateType = TradeOrderOperateTypeEnum.TEST) | ||
| 69 | - public CommonResult<AppTradeOrderCreateRespVO> createOrder(@RequestBody AppTradeOrderCreateReqVO createReqVO) { | ||
| 70 | - TradeOrderLogUtils.setOrderInfo(10L, 1, 2, | ||
| 71 | - MapUtil.<String, Object>builder().put("nickname", "小明").put("thing", "种土豆").build()); | 64 | + public CommonResult<AppTradeOrderCreateRespVO> createOrder(@Valid @RequestBody AppTradeOrderCreateReqVO createReqVO) { |
| 72 | TradeOrderDO order = tradeOrderUpdateService.createOrder(getLoginUserId(), getClientIP(), createReqVO); | 65 | TradeOrderDO order = tradeOrderUpdateService.createOrder(getLoginUserId(), getClientIP(), createReqVO); |
| 73 | return success(new AppTradeOrderCreateRespVO().setId(order.getId()).setPayOrderId(order.getPayOrderId())); | 66 | return success(new AppTradeOrderCreateRespVO().setId(order.getId()).setPayOrderId(order.getPayOrderId())); |
| 74 | } | 67 | } |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderCreateReqVO.java
| 1 | package cn.iocoder.yudao.module.trade.controller.app.order.vo; | 1 | package cn.iocoder.yudao.module.trade.controller.app.order.vo; |
| 2 | 2 | ||
| 3 | +import com.fasterxml.jackson.annotation.JsonIgnore; | ||
| 3 | import io.swagger.v3.oas.annotations.media.Schema; | 4 | import io.swagger.v3.oas.annotations.media.Schema; |
| 4 | import lombok.Data; | 5 | import lombok.Data; |
| 5 | 6 | ||
| 7 | +import javax.validation.constraints.AssertTrue; | ||
| 8 | + | ||
| 6 | @Schema(description = "用户 App - 交易订单创建 Request VO") | 9 | @Schema(description = "用户 App - 交易订单创建 Request VO") |
| 7 | @Data | 10 | @Data |
| 8 | public class AppTradeOrderCreateReqVO extends AppTradeOrderSettlementReqVO { | 11 | public class AppTradeOrderCreateReqVO extends AppTradeOrderSettlementReqVO { |
| @@ -10,4 +13,10 @@ public class AppTradeOrderCreateReqVO extends AppTradeOrderSettlementReqVO { | @@ -10,4 +13,10 @@ public class AppTradeOrderCreateReqVO extends AppTradeOrderSettlementReqVO { | ||
| 10 | @Schema(description = "备注", example = "这个是我的订单哟") | 13 | @Schema(description = "备注", example = "这个是我的订单哟") |
| 11 | private String remark; | 14 | private String remark; |
| 12 | 15 | ||
| 16 | + @AssertTrue(message = "配送方式不能为空") | ||
| 17 | + @JsonIgnore | ||
| 18 | + public boolean isDeliveryTypeNotNull() { | ||
| 19 | + return getDeliveryType() != null; | ||
| 20 | + } | ||
| 21 | + | ||
| 13 | } | 22 | } |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/order/vo/AppTradeOrderSettlementReqVO.java
| @@ -30,7 +30,7 @@ public class AppTradeOrderSettlementReqVO { | @@ -30,7 +30,7 @@ public class AppTradeOrderSettlementReqVO { | ||
| 30 | private Boolean pointStatus; | 30 | private Boolean pointStatus; |
| 31 | 31 | ||
| 32 | // ========== 配送相关相关字段 ========== | 32 | // ========== 配送相关相关字段 ========== |
| 33 | - @Schema(description = "配送方式", required = true, example = "1") | 33 | + @Schema(description = "配送方式", example = "1") |
| 34 | @InEnum(value = DeliveryTypeEnum.class, message = "配送方式不正确") | 34 | @InEnum(value = DeliveryTypeEnum.class, message = "配送方式不正确") |
| 35 | private Integer deliveryType; | 35 | private Integer deliveryType; |
| 36 | 36 | ||
| @@ -62,6 +62,8 @@ public class AppTradeOrderSettlementReqVO { | @@ -62,6 +62,8 @@ public class AppTradeOrderSettlementReqVO { | ||
| 62 | @Schema(description = "砍价活动编号", example = "123") | 62 | @Schema(description = "砍价活动编号", example = "123") |
| 63 | private Long bargainActivityId; | 63 | private Long bargainActivityId; |
| 64 | 64 | ||
| 65 | + // TODO @puhui999:可以写个参数校验,如果 seckillActivityId 或 combinationActivityId 或 combinationHeadId 的情况,items 应该只有一个 | ||
| 66 | + | ||
| 65 | @Data | 67 | @Data |
| 66 | @Schema(description = "用户 App - 商品项") | 68 | @Schema(description = "用户 App - 商品项") |
| 67 | @Valid | 69 | @Valid |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/brokerage/record/BrokerageRecordConvert.java
| @@ -35,7 +35,7 @@ public interface BrokerageRecordConvert { | @@ -35,7 +35,7 @@ public interface BrokerageRecordConvert { | ||
| 35 | 35 | ||
| 36 | default BrokerageRecordDO convert(BrokerageUserDO user, BrokerageRecordBizTypeEnum bizType, String bizId, | 36 | default BrokerageRecordDO convert(BrokerageUserDO user, BrokerageRecordBizTypeEnum bizType, String bizId, |
| 37 | Integer brokerageFrozenDays, int brokeragePrice, LocalDateTime unfreezeTime, | 37 | Integer brokerageFrozenDays, int brokeragePrice, LocalDateTime unfreezeTime, |
| 38 | - String title, Long sourceUserId, Integer sourceUserType) { | 38 | + String title, Long sourceUserId, Integer sourceUserLevel) { |
| 39 | brokerageFrozenDays = ObjectUtil.defaultIfNull(brokerageFrozenDays, 0); | 39 | brokerageFrozenDays = ObjectUtil.defaultIfNull(brokerageFrozenDays, 0); |
| 40 | // 不冻结时,佣金直接就是结算状态 | 40 | // 不冻结时,佣金直接就是结算状态 |
| 41 | Integer status = brokerageFrozenDays > 0 | 41 | Integer status = brokerageFrozenDays > 0 |
| @@ -47,7 +47,7 @@ public interface BrokerageRecordConvert { | @@ -47,7 +47,7 @@ public interface BrokerageRecordConvert { | ||
| 47 | .setTitle(title) | 47 | .setTitle(title) |
| 48 | .setDescription(StrUtil.format(bizType.getDescription(), String.format("¥%.2f", brokeragePrice / 100d))) | 48 | .setDescription(StrUtil.format(bizType.getDescription(), String.format("¥%.2f", brokeragePrice / 100d))) |
| 49 | .setStatus(status).setFrozenDays(brokerageFrozenDays).setUnfreezeTime(unfreezeTime) | 49 | .setStatus(status).setFrozenDays(brokerageFrozenDays).setUnfreezeTime(unfreezeTime) |
| 50 | - .setSourceUserType(sourceUserType).setSourceUserId(sourceUserId); | 50 | + .setSourceUserLevel(sourceUserLevel).setSourceUserId(sourceUserId); |
| 51 | } | 51 | } |
| 52 | 52 | ||
| 53 | default PageResult<BrokerageRecordRespVO> convertPage(PageResult<BrokerageRecordDO> pageResult, Map<Long, MemberUserRespDTO> userMap) { | 53 | default PageResult<BrokerageRecordRespVO> convertPage(PageResult<BrokerageRecordDO> pageResult, Map<Long, MemberUserRespDTO> userMap) { |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/brokerage/user/BrokerageUserConvert.java
| @@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.trade.convert.brokerage.user; | @@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.trade.convert.brokerage.user; | ||
| 3 | import cn.hutool.core.map.MapUtil; | 3 | import cn.hutool.core.map.MapUtil; |
| 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 5 | import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; | 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; | 6 | import cn.iocoder.yudao.module.trade.controller.admin.brokerage.user.vo.BrokerageUserRespVO; |
| 8 | import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.user.BrokerageUserDO; | 7 | import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.user.BrokerageUserDO; |
| 9 | import cn.iocoder.yudao.module.trade.service.brokerage.bo.UserBrokerageSummaryBO; | 8 | import cn.iocoder.yudao.module.trade.service.brokerage.bo.UserBrokerageSummaryBO; |
| @@ -56,6 +55,4 @@ public interface BrokerageUserConvert { | @@ -56,6 +55,4 @@ public interface BrokerageUserConvert { | ||
| 56 | user -> target.setNickname(user.getNickname()).setAvatar(user.getAvatar())); | 55 | user -> target.setNickname(user.getNickname()).setAvatar(user.getAvatar())); |
| 57 | return target; | 56 | return target; |
| 58 | } | 57 | } |
| 59 | - | ||
| 60 | - BrokerageUserDTO convertDTO(BrokerageUserDO brokerageUser); | ||
| 61 | } | 58 | } |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/brokerage/withdraw/BrokerageWithdrawConvert.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.trade.convert.brokerage.withdraw; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||
| 4 | +import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; | ||
| 5 | +import cn.iocoder.yudao.module.trade.controller.admin.brokerage.withdraw.vo.BrokerageWithdrawRejectReqVO; | ||
| 6 | +import cn.iocoder.yudao.module.trade.controller.admin.brokerage.withdraw.vo.BrokerageWithdrawRespVO; | ||
| 7 | +import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.withdraw.BrokerageWithdrawDO; | ||
| 8 | +import org.mapstruct.Mapper; | ||
| 9 | +import org.mapstruct.factory.Mappers; | ||
| 10 | + | ||
| 11 | +import java.util.List; | ||
| 12 | +import java.util.Map; | ||
| 13 | +import java.util.Optional; | ||
| 14 | + | ||
| 15 | +/** | ||
| 16 | + * 佣金提现 Convert | ||
| 17 | + * | ||
| 18 | + * @author 芋道源码 | ||
| 19 | + */ | ||
| 20 | +@Mapper | ||
| 21 | +public interface BrokerageWithdrawConvert { | ||
| 22 | + | ||
| 23 | + BrokerageWithdrawConvert INSTANCE = Mappers.getMapper(BrokerageWithdrawConvert.class); | ||
| 24 | + | ||
| 25 | + BrokerageWithdrawDO convert(BrokerageWithdrawRejectReqVO bean); | ||
| 26 | + | ||
| 27 | + BrokerageWithdrawRespVO convert(BrokerageWithdrawDO bean); | ||
| 28 | + | ||
| 29 | + List<BrokerageWithdrawRespVO> convertList(List<BrokerageWithdrawDO> list); | ||
| 30 | + | ||
| 31 | + PageResult<BrokerageWithdrawRespVO> convertPage(PageResult<BrokerageWithdrawDO> page); | ||
| 32 | + | ||
| 33 | + default PageResult<BrokerageWithdrawRespVO> convertPage(PageResult<BrokerageWithdrawDO> pageResult, Map<Long, MemberUserRespDTO> userMap) { | ||
| 34 | + PageResult<BrokerageWithdrawRespVO> result = convertPage(pageResult); | ||
| 35 | + for (BrokerageWithdrawRespVO vo : result.getList()) { | ||
| 36 | + vo.setUserNickname(Optional.ofNullable(userMap.get(vo.getUserId())).map(MemberUserRespDTO::getNickname).orElse(null)); | ||
| 37 | + } | ||
| 38 | + return result; | ||
| 39 | + } | ||
| 40 | + | ||
| 41 | +} |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java
| @@ -14,9 +14,7 @@ import cn.iocoder.yudao.module.product.api.comment.dto.ProductCommentCreateReqDT | @@ -14,9 +14,7 @@ import cn.iocoder.yudao.module.product.api.comment.dto.ProductCommentCreateReqDT | ||
| 14 | import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO; | 14 | import cn.iocoder.yudao.module.product.api.property.dto.ProductPropertyValueDetailRespDTO; |
| 15 | import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; | 15 | import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; |
| 16 | import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO; | 16 | import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuUpdateStockReqDTO; |
| 17 | -import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationActivityUpdateStockReqDTO; | ||
| 18 | import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO; | 17 | import cn.iocoder.yudao.module.promotion.api.combination.dto.CombinationRecordCreateReqDTO; |
| 19 | -import cn.iocoder.yudao.module.promotion.api.seckill.dto.SeckillActivityUpdateStockReqDTO; | ||
| 20 | import cn.iocoder.yudao.module.trade.api.order.dto.TradeOrderRespDTO; | 18 | import cn.iocoder.yudao.module.trade.api.order.dto.TradeOrderRespDTO; |
| 21 | import cn.iocoder.yudao.module.trade.controller.admin.base.member.user.MemberUserRespVO; | 19 | import cn.iocoder.yudao.module.trade.controller.admin.base.member.user.MemberUserRespVO; |
| 22 | import cn.iocoder.yudao.module.trade.controller.admin.base.product.property.ProductPropertyValueDetailRespVO; | 20 | import cn.iocoder.yudao.module.trade.controller.admin.base.product.property.ProductPropertyValueDetailRespVO; |
| @@ -29,7 +27,6 @@ import cn.iocoder.yudao.module.trade.dal.dataobject.cart.CartDO; | @@ -29,7 +27,6 @@ import cn.iocoder.yudao.module.trade.dal.dataobject.cart.CartDO; | ||
| 29 | import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressDO; | 27 | import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressDO; |
| 30 | import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; | 28 | import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; |
| 31 | import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; | 29 | import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; |
| 32 | -import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordBizTypeEnum; | ||
| 33 | import cn.iocoder.yudao.module.trade.enums.order.TradeOrderItemAfterSaleStatusEnum; | 30 | import cn.iocoder.yudao.module.trade.enums.order.TradeOrderItemAfterSaleStatusEnum; |
| 34 | import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.ExpressTrackRespDTO; | 31 | import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.ExpressTrackRespDTO; |
| 35 | import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties; | 32 | import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties; |
| @@ -59,6 +56,7 @@ public interface TradeOrderConvert { | @@ -59,6 +56,7 @@ public interface TradeOrderConvert { | ||
| 59 | 56 | ||
| 60 | @Mappings({ | 57 | @Mappings({ |
| 61 | @Mapping(target = "id", ignore = true), | 58 | @Mapping(target = "id", ignore = true), |
| 59 | + @Mapping(source = "userId", target = "userId"), | ||
| 62 | @Mapping(source = "createReqVO.couponId", target = "couponId"), | 60 | @Mapping(source = "createReqVO.couponId", target = "couponId"), |
| 63 | @Mapping(target = "remark", ignore = true), | 61 | @Mapping(target = "remark", ignore = true), |
| 64 | @Mapping(source = "createReqVO.remark", target = "userRemark"), | 62 | @Mapping(source = "createReqVO.remark", target = "userRemark"), |
| @@ -67,14 +65,10 @@ public interface TradeOrderConvert { | @@ -67,14 +65,10 @@ public interface TradeOrderConvert { | ||
| 67 | @Mapping(source = "calculateRespBO.price.deliveryPrice", target = "deliveryPrice"), | 65 | @Mapping(source = "calculateRespBO.price.deliveryPrice", target = "deliveryPrice"), |
| 68 | @Mapping(source = "calculateRespBO.price.couponPrice", target = "couponPrice"), | 66 | @Mapping(source = "calculateRespBO.price.couponPrice", target = "couponPrice"), |
| 69 | @Mapping(source = "calculateRespBO.price.pointPrice", target = "pointPrice"), | 67 | @Mapping(source = "calculateRespBO.price.pointPrice", target = "pointPrice"), |
| 70 | - @Mapping(source = "calculateRespBO.price.payPrice", target = "payPrice"), | ||
| 71 | - @Mapping(source = "address.name", target = "receiverName"), | ||
| 72 | - @Mapping(source = "address.mobile", target = "receiverMobile"), | ||
| 73 | - @Mapping(source = "address.areaId", target = "receiverAreaId"), | ||
| 74 | - @Mapping(source = "address.detailAddress", target = "receiverDetailAddress"), | 68 | + @Mapping(source = "calculateRespBO.price.payPrice", target = "payPrice") |
| 75 | }) | 69 | }) |
| 76 | TradeOrderDO convert(Long userId, String userIp, AppTradeOrderCreateReqVO createReqVO, | 70 | TradeOrderDO convert(Long userId, String userIp, AppTradeOrderCreateReqVO createReqVO, |
| 77 | - TradePriceCalculateRespBO calculateRespBO, AddressRespDTO address); | 71 | + TradePriceCalculateRespBO calculateRespBO); |
| 78 | 72 | ||
| 79 | TradeOrderRespDTO convert(TradeOrderDO orderDO); | 73 | TradeOrderRespDTO convert(TradeOrderDO orderDO); |
| 80 | 74 | ||
| @@ -92,23 +86,16 @@ public interface TradeOrderConvert { | @@ -92,23 +86,16 @@ public interface TradeOrderConvert { | ||
| 92 | TradeOrderItemDO convert(TradePriceCalculateRespBO.OrderItem item); | 86 | TradeOrderItemDO convert(TradePriceCalculateRespBO.OrderItem item); |
| 93 | 87 | ||
| 94 | default ProductSkuUpdateStockReqDTO convert(List<TradeOrderItemDO> list) { | 88 | default ProductSkuUpdateStockReqDTO convert(List<TradeOrderItemDO> list) { |
| 95 | - return new ProductSkuUpdateStockReqDTO(TradeOrderConvert.INSTANCE.convertList(list)); | 89 | + List<ProductSkuUpdateStockReqDTO.Item> items = CollectionUtils.convertList(list, item -> |
| 90 | + new ProductSkuUpdateStockReqDTO.Item().setId(item.getSkuId()).setIncrCount(-item.getCount())); | ||
| 91 | + return new ProductSkuUpdateStockReqDTO(items); | ||
| 96 | } | 92 | } |
| 97 | - | ||
| 98 | - default ProductSkuUpdateStockReqDTO convertNegative(List<TradeOrderItemDO> list) { | ||
| 99 | - List<ProductSkuUpdateStockReqDTO.Item> items = TradeOrderConvert.INSTANCE.convertList(list); | ||
| 100 | - items.forEach(item -> item.setIncrCount(-item.getIncrCount())); | 93 | + default ProductSkuUpdateStockReqDTO convertNegative(List<AppTradeOrderSettlementReqVO.Item> list) { |
| 94 | + List<ProductSkuUpdateStockReqDTO.Item> items = CollectionUtils.convertList(list, item -> | ||
| 95 | + new ProductSkuUpdateStockReqDTO.Item().setId(item.getSkuId()).setIncrCount(-item.getCount())); | ||
| 101 | return new ProductSkuUpdateStockReqDTO(items); | 96 | return new ProductSkuUpdateStockReqDTO(items); |
| 102 | } | 97 | } |
| 103 | 98 | ||
| 104 | - List<ProductSkuUpdateStockReqDTO.Item> convertList(List<TradeOrderItemDO> list); | ||
| 105 | - | ||
| 106 | - @Mappings({ | ||
| 107 | - @Mapping(source = "skuId", target = "id"), | ||
| 108 | - @Mapping(source = "count", target = "incrCount"), | ||
| 109 | - }) | ||
| 110 | - ProductSkuUpdateStockReqDTO.Item convert(TradeOrderItemDO bean); | ||
| 111 | - | ||
| 112 | default PayOrderCreateReqDTO convert(TradeOrderDO order, List<TradeOrderItemDO> orderItems, | 99 | default PayOrderCreateReqDTO convert(TradeOrderDO order, List<TradeOrderItemDO> orderItems, |
| 113 | TradePriceCalculateRespBO calculateRespBO, TradeOrderProperties orderProperties) { | 100 | TradePriceCalculateRespBO calculateRespBO, TradeOrderProperties orderProperties) { |
| 114 | PayOrderCreateReqDTO createReqDTO = new PayOrderCreateReqDTO() | 101 | PayOrderCreateReqDTO createReqDTO = new PayOrderCreateReqDTO() |
| @@ -221,8 +208,10 @@ public interface TradeOrderConvert { | @@ -221,8 +208,10 @@ public interface TradeOrderConvert { | ||
| 221 | 208 | ||
| 222 | default TradePriceCalculateReqBO convert(Long userId, AppTradeOrderSettlementReqVO settlementReqVO, | 209 | default TradePriceCalculateReqBO convert(Long userId, AppTradeOrderSettlementReqVO settlementReqVO, |
| 223 | List<CartDO> cartList) { | 210 | List<CartDO> cartList) { |
| 224 | - TradePriceCalculateReqBO reqBO = new TradePriceCalculateReqBO(); | ||
| 225 | - reqBO.setUserId(userId).setCouponId(settlementReqVO.getCouponId()).setAddressId(settlementReqVO.getAddressId()) | 211 | + TradePriceCalculateReqBO reqBO = new TradePriceCalculateReqBO().setUserId(userId) |
| 212 | + .setCouponId(settlementReqVO.getCouponId()).setPointStatus(settlementReqVO.getPointStatus()) | ||
| 213 | + .setDeliveryType(settlementReqVO.getDeliveryType()).setAddressId(settlementReqVO.getAddressId()) | ||
| 214 | + .setPickUpStoreId(settlementReqVO.getPickUpStoreId()) | ||
| 226 | .setItems(new ArrayList<>(settlementReqVO.getItems().size())); | 215 | .setItems(new ArrayList<>(settlementReqVO.getItems().size())); |
| 227 | // 商品项的构建 | 216 | // 商品项的构建 |
| 228 | Map<Long, CartDO> cartMap = convertMap(cartList, CartDO::getId); | 217 | Map<Long, CartDO> cartMap = convertMap(cartList, CartDO::getId); |
| @@ -276,19 +265,13 @@ public interface TradeOrderConvert { | @@ -276,19 +265,13 @@ public interface TradeOrderConvert { | ||
| 276 | 265 | ||
| 277 | TradeOrderDO convert(TradeOrderRemarkReqVO reqVO); | 266 | TradeOrderDO convert(TradeOrderRemarkReqVO reqVO); |
| 278 | 267 | ||
| 279 | - default BrokerageAddReqBO convert(TradeOrderItemDO item, ProductSkuRespDTO sku) { | 268 | + default BrokerageAddReqBO convert(MemberUserRespDTO user, TradeOrderItemDO item, ProductSkuRespDTO sku) { |
| 280 | return new BrokerageAddReqBO().setBizId(String.valueOf(item.getId())).setSourceUserId(item.getUserId()) | 269 | return new BrokerageAddReqBO().setBizId(String.valueOf(item.getId())).setSourceUserId(item.getUserId()) |
| 281 | .setBasePrice(item.getPayPrice() * item.getCount()) | 270 | .setBasePrice(item.getPayPrice() * item.getCount()) |
| 282 | - .setTitle(BrokerageRecordBizTypeEnum.ORDER.getTitle()) // TODO @疯狂:标题类似:木晴冰雪成功购买云时代的JVM原理与实战;茫农成功购买深入拆解消息队列47讲 | ||
| 283 | - .setFirstFixedPrice(sku.getFirstBrokerageRecord()).setSecondFixedPrice(sku.getSecondBrokerageRecord()); | 271 | + .setTitle(StrUtil.format("{}成功购买{}", user.getNickname(), item.getSpuName())) |
| 272 | + .setFirstFixedPrice(sku.getFirstBrokeragePrice()).setSecondFixedPrice(sku.getSecondBrokeragePrice()); | ||
| 284 | } | 273 | } |
| 285 | 274 | ||
| 286 | - @Mapping(target = "activityId", source = "reqBO.seckillActivityId") | ||
| 287 | - SeckillActivityUpdateStockReqDTO convert(TradeBeforeOrderCreateReqBO reqBO); | ||
| 288 | - | ||
| 289 | - @Mapping(target = "activityId", source = "reqBO.combinationActivityId") | ||
| 290 | - CombinationActivityUpdateStockReqDTO convert1(TradeBeforeOrderCreateReqBO reqBO); | ||
| 291 | - | ||
| 292 | TradeBeforeOrderCreateReqBO convert(AppTradeOrderCreateReqVO createReqVO); | 275 | TradeBeforeOrderCreateReqBO convert(AppTradeOrderCreateReqVO createReqVO); |
| 293 | 276 | ||
| 294 | @Mappings({ | 277 | @Mappings({ |
| @@ -300,6 +283,7 @@ public interface TradeOrderConvert { | @@ -300,6 +283,7 @@ public interface TradeOrderConvert { | ||
| 300 | @Mapping(target = "userId", source = "userId"), | 283 | @Mapping(target = "userId", source = "userId"), |
| 301 | @Mapping(target = "payPrice", source = "tradeOrderDO.payPrice"), | 284 | @Mapping(target = "payPrice", source = "tradeOrderDO.payPrice"), |
| 302 | }) | 285 | }) |
| 303 | - TradeAfterOrderCreateReqBO convert(Long userId, AppTradeOrderCreateReqVO createReqVO, TradeOrderDO tradeOrderDO, TradeOrderItemDO orderItem); | 286 | + TradeAfterOrderCreateReqBO convert(Long userId, AppTradeOrderCreateReqVO createReqVO, |
| 287 | + TradeOrderDO tradeOrderDO, TradeOrderItemDO orderItem); | ||
| 304 | 288 | ||
| 305 | } | 289 | } |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/brokerage/record/BrokerageRecordDO.java
| @@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.record; | @@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.record; | ||
| 3 | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; | 3 | import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; |
| 4 | import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordBizTypeEnum; | 4 | import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordBizTypeEnum; |
| 5 | import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordStatusEnum; | 5 | import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordStatusEnum; |
| 6 | -import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageUserTypeEnum; | ||
| 7 | import com.baomidou.mybatisplus.annotation.KeySequence; | 6 | import com.baomidou.mybatisplus.annotation.KeySequence; |
| 8 | import com.baomidou.mybatisplus.annotation.TableId; | 7 | import com.baomidou.mybatisplus.annotation.TableId; |
| 9 | import com.baomidou.mybatisplus.annotation.TableName; | 8 | import com.baomidou.mybatisplus.annotation.TableName; |
| @@ -83,11 +82,11 @@ public class BrokerageRecordDO extends BaseDO { | @@ -83,11 +82,11 @@ public class BrokerageRecordDO extends BaseDO { | ||
| 83 | private LocalDateTime unfreezeTime; | 82 | private LocalDateTime unfreezeTime; |
| 84 | 83 | ||
| 85 | /** | 84 | /** |
| 86 | - * 来源用户类型 | 85 | + * 来源用户等级 |
| 87 | * <p> | 86 | * <p> |
| 88 | - * 枚举 {@link BrokerageUserTypeEnum},被推广用户和 {@link #userId} 的推广层级关系 | 87 | + * 被推广用户和 {@link #userId} 的推广层级关系 |
| 89 | */ | 88 | */ |
| 90 | - private Integer sourceUserType; | 89 | + private Integer sourceUserLevel; |
| 91 | /** | 90 | /** |
| 92 | * 来源用户编号 | 91 | * 来源用户编号 |
| 93 | * <p> | 92 | * <p> |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/brokerage/user/BrokerageUserDO.java
| @@ -60,4 +60,12 @@ public class BrokerageUserDO extends BaseDO { | @@ -60,4 +60,12 @@ public class BrokerageUserDO extends BaseDO { | ||
| 60 | */ | 60 | */ |
| 61 | private Integer frozenPrice; | 61 | private Integer frozenPrice; |
| 62 | 62 | ||
| 63 | + /** | ||
| 64 | + * 等级 | ||
| 65 | + */ | ||
| 66 | + private Integer level; | ||
| 67 | + /** | ||
| 68 | + * 路径 | ||
| 69 | + */ | ||
| 70 | + private String path; | ||
| 63 | } | 71 | } |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/brokerage/withdraw/BrokerageWithdrawDO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.withdraw; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; | ||
| 4 | +import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageWithdrawStatusEnum; | ||
| 5 | +import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageWithdrawTypeEnum; | ||
| 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 芋道源码 | ||
| 17 | + */ | ||
| 18 | +@TableName("trade_brokerage_withdraw") | ||
| 19 | +@KeySequence("trade_brokerage_withdraw_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 BrokerageWithdrawDO extends BaseDO { | ||
| 27 | + | ||
| 28 | + /** | ||
| 29 | + * 编号 | ||
| 30 | + */ | ||
| 31 | + @TableId | ||
| 32 | + private Integer id; | ||
| 33 | + /** | ||
| 34 | + * 用户编号 | ||
| 35 | + * | ||
| 36 | + * 关联 MemberUserDO 的 id 字段 | ||
| 37 | + */ | ||
| 38 | + private Long userId; | ||
| 39 | + | ||
| 40 | + /** | ||
| 41 | + * 提现金额,单位:分 | ||
| 42 | + */ | ||
| 43 | + private Integer price; | ||
| 44 | + /** | ||
| 45 | + * 提现手续费,单位:分 | ||
| 46 | + */ | ||
| 47 | + private Integer feePrice; | ||
| 48 | + /** | ||
| 49 | + * 当前总佣金,单位:分 | ||
| 50 | + */ | ||
| 51 | + private Integer totalPrice; | ||
| 52 | + /** | ||
| 53 | + * 提现类型 | ||
| 54 | + * <p> | ||
| 55 | + * 枚举 {@link BrokerageWithdrawTypeEnum} | ||
| 56 | + */ | ||
| 57 | + private Integer type; | ||
| 58 | + | ||
| 59 | + /** | ||
| 60 | + * 真实姓名 | ||
| 61 | + */ | ||
| 62 | + private String name; | ||
| 63 | + /** | ||
| 64 | + * 账号 | ||
| 65 | + */ | ||
| 66 | + private String accountNo; | ||
| 67 | + /** | ||
| 68 | + * 银行名称 | ||
| 69 | + */ | ||
| 70 | + private String bankName; | ||
| 71 | + /** | ||
| 72 | + * 开户地址 | ||
| 73 | + */ | ||
| 74 | + private String bankAddress; | ||
| 75 | + /** | ||
| 76 | + * 收款码 | ||
| 77 | + */ | ||
| 78 | + private String accountQrCodeUrl; | ||
| 79 | + /** | ||
| 80 | + * 状态 | ||
| 81 | + * <p> | ||
| 82 | + * 枚举 {@link BrokerageWithdrawStatusEnum} | ||
| 83 | + */ | ||
| 84 | + private Integer status; | ||
| 85 | + /** | ||
| 86 | + * 审核驳回原因 | ||
| 87 | + */ | ||
| 88 | + private String auditReason; | ||
| 89 | + /** | ||
| 90 | + * 审核时间 | ||
| 91 | + */ | ||
| 92 | + private LocalDateTime auditTime; | ||
| 93 | + /** | ||
| 94 | + * 备注 | ||
| 95 | + */ | ||
| 96 | + private String remark; | ||
| 97 | + | ||
| 98 | +} |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/order/TradeOrderDO.java
| @@ -224,6 +224,10 @@ public class TradeOrderDO extends BaseDO { | @@ -224,6 +224,10 @@ public class TradeOrderDO extends BaseDO { | ||
| 224 | * 关联 {@link DeliveryPickUpStoreDO#getId()} | 224 | * 关联 {@link DeliveryPickUpStoreDO#getId()} |
| 225 | */ | 225 | */ |
| 226 | private Long pickUpStoreId; | 226 | private Long pickUpStoreId; |
| 227 | + /** | ||
| 228 | + * 自提核销码 | ||
| 229 | + */ | ||
| 230 | + private String pickUpVerifyCode; | ||
| 227 | 231 | ||
| 228 | // ========== 售后基本信息 ========== | 232 | // ========== 售后基本信息 ========== |
| 229 | /** | 233 | /** |
| @@ -251,12 +255,19 @@ public class TradeOrderDO extends BaseDO { | @@ -251,12 +255,19 @@ public class TradeOrderDO extends BaseDO { | ||
| 251 | * 对应 taobao 的 trade.coupon_fee 字段 | 255 | * 对应 taobao 的 trade.coupon_fee 字段 |
| 252 | */ | 256 | */ |
| 253 | private Integer couponPrice; | 257 | private Integer couponPrice; |
| 254 | - // TODO 芋艿:需要记录使用的积分; | 258 | + /** |
| 259 | + * 使用的积分 | ||
| 260 | + */ | ||
| 261 | + private Integer usePoint; | ||
| 255 | /** | 262 | /** |
| 256 | * 积分抵扣的金额,单位:分 | 263 | * 积分抵扣的金额,单位:分 |
| 257 | * | 264 | * |
| 258 | * 对应 taobao 的 trade.point_fee 字段 | 265 | * 对应 taobao 的 trade.point_fee 字段 |
| 259 | */ | 266 | */ |
| 260 | private Integer pointPrice; | 267 | private Integer pointPrice; |
| 268 | +// /** | ||
| 269 | +// * 奖励的积分 TODO 疯狂:可以使用这个字段哈; | ||
| 270 | +// */ | ||
| 271 | +// private Integer rewardPoint; | ||
| 261 | 272 | ||
| 262 | } | 273 | } |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/record/BrokerageRecordMapper.java
| @@ -5,7 +5,6 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; | @@ -5,7 +5,6 @@ import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; | ||
| 5 | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; | 5 | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; |
| 6 | import cn.iocoder.yudao.module.trade.controller.admin.brokerage.record.vo.BrokerageRecordPageReqVO; | 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; | 7 | import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.record.BrokerageRecordDO; |
| 8 | -import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageUserTypeEnum; | ||
| 9 | import cn.iocoder.yudao.module.trade.service.brokerage.bo.UserBrokerageSummaryBO; | 8 | import cn.iocoder.yudao.module.trade.service.brokerage.bo.UserBrokerageSummaryBO; |
| 10 | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | 9 | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| 11 | import org.apache.ibatis.annotations.Mapper; | 10 | import org.apache.ibatis.annotations.Mapper; |
| @@ -24,14 +23,12 @@ import java.util.List; | @@ -24,14 +23,12 @@ import java.util.List; | ||
| 24 | public interface BrokerageRecordMapper extends BaseMapperX<BrokerageRecordDO> { | 23 | public interface BrokerageRecordMapper extends BaseMapperX<BrokerageRecordDO> { |
| 25 | 24 | ||
| 26 | default PageResult<BrokerageRecordDO> selectPage(BrokerageRecordPageReqVO reqVO) { | 25 | default PageResult<BrokerageRecordDO> selectPage(BrokerageRecordPageReqVO reqVO) { |
| 27 | - boolean sourceUserTypeCondition = reqVO.getSourceUserType() != null && | ||
| 28 | - !BrokerageUserTypeEnum.ALL.getType().equals(reqVO.getSourceUserType()); | ||
| 29 | // 分页查询 | 26 | // 分页查询 |
| 30 | return selectPage(reqVO, new LambdaQueryWrapperX<BrokerageRecordDO>() | 27 | return selectPage(reqVO, new LambdaQueryWrapperX<BrokerageRecordDO>() |
| 31 | .eqIfPresent(BrokerageRecordDO::getUserId, reqVO.getUserId()) | 28 | .eqIfPresent(BrokerageRecordDO::getUserId, reqVO.getUserId()) |
| 32 | .eqIfPresent(BrokerageRecordDO::getBizType, reqVO.getBizType()) | 29 | .eqIfPresent(BrokerageRecordDO::getBizType, reqVO.getBizType()) |
| 33 | .eqIfPresent(BrokerageRecordDO::getStatus, reqVO.getStatus()) | 30 | .eqIfPresent(BrokerageRecordDO::getStatus, reqVO.getStatus()) |
| 34 | - .eq(sourceUserTypeCondition, BrokerageRecordDO::getSourceUserType, reqVO.getSourceUserType()) | 31 | + .eqIfPresent(BrokerageRecordDO::getSourceUserLevel, reqVO.getSourceUserLevel()) |
| 35 | .betweenIfPresent(BrokerageRecordDO::getCreateTime, reqVO.getCreateTime()) | 32 | .betweenIfPresent(BrokerageRecordDO::getCreateTime, reqVO.getCreateTime()) |
| 36 | .orderByDesc(BrokerageRecordDO::getId)); | 33 | .orderByDesc(BrokerageRecordDO::getId)); |
| 37 | } | 34 | } |
| @@ -59,4 +56,5 @@ public interface BrokerageRecordMapper extends BaseMapperX<BrokerageRecordDO> { | @@ -59,4 +56,5 @@ public interface BrokerageRecordMapper extends BaseMapperX<BrokerageRecordDO> { | ||
| 59 | UserBrokerageSummaryBO selectCountAndSumPriceByUserIdAndBizTypeAndStatus(@Param("userId") Long userId, | 56 | UserBrokerageSummaryBO selectCountAndSumPriceByUserIdAndBizTypeAndStatus(@Param("userId") Long userId, |
| 60 | @Param("bizType") Integer bizType, | 57 | @Param("bizType") Integer bizType, |
| 61 | @Param("status") Integer status); | 58 | @Param("status") Integer status); |
| 59 | + | ||
| 62 | } | 60 | } |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/user/BrokerageUserMapper.java
| 1 | package cn.iocoder.yudao.module.trade.dal.mysql.brokerage.user; | 1 | package cn.iocoder.yudao.module.trade.dal.mysql.brokerage.user; |
| 2 | 2 | ||
| 3 | import cn.hutool.core.lang.Assert; | 3 | import cn.hutool.core.lang.Assert; |
| 4 | -import cn.hutool.core.util.StrUtil; | ||
| 5 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 6 | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; | 5 | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; |
| 7 | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; | 6 | import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; |
| 8 | import cn.iocoder.yudao.module.trade.controller.admin.brokerage.user.vo.BrokerageUserPageReqVO; | 7 | import cn.iocoder.yudao.module.trade.controller.admin.brokerage.user.vo.BrokerageUserPageReqVO; |
| 9 | import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.user.BrokerageUserDO; | 8 | import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.user.BrokerageUserDO; |
| 10 | -import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageUserTypeEnum; | ||
| 11 | -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | ||
| 12 | import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; | 9 | import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; |
| 13 | import org.apache.ibatis.annotations.Mapper; | 10 | import org.apache.ibatis.annotations.Mapper; |
| 14 | -import org.apache.ibatis.annotations.Select; | 11 | + |
| 12 | +import java.util.List; | ||
| 15 | 13 | ||
| 16 | /** | 14 | /** |
| 17 | * 分销用户 Mapper | 15 | * 分销用户 Mapper |
| @@ -21,35 +19,16 @@ import org.apache.ibatis.annotations.Select; | @@ -21,35 +19,16 @@ import org.apache.ibatis.annotations.Select; | ||
| 21 | @Mapper | 19 | @Mapper |
| 22 | public interface BrokerageUserMapper extends BaseMapperX<BrokerageUserDO> { | 20 | public interface BrokerageUserMapper extends BaseMapperX<BrokerageUserDO> { |
| 23 | 21 | ||
| 24 | - default PageResult<BrokerageUserDO> selectPage(BrokerageUserPageReqVO reqVO) { | 22 | + default PageResult<BrokerageUserDO> selectPage(BrokerageUserPageReqVO reqVO, List<Integer> levels) { |
| 25 | return selectPage(reqVO, new LambdaQueryWrapperX<BrokerageUserDO>() | 23 | return selectPage(reqVO, new LambdaQueryWrapperX<BrokerageUserDO>() |
| 26 | .eqIfPresent(BrokerageUserDO::getBrokerageEnabled, reqVO.getBrokerageEnabled()) | 24 | .eqIfPresent(BrokerageUserDO::getBrokerageEnabled, reqVO.getBrokerageEnabled()) |
| 27 | .betweenIfPresent(BrokerageUserDO::getCreateTime, reqVO.getCreateTime()) | 25 | .betweenIfPresent(BrokerageUserDO::getCreateTime, reqVO.getCreateTime()) |
| 28 | .betweenIfPresent(BrokerageUserDO::getBindUserTime, reqVO.getBindUserTime()) | 26 | .betweenIfPresent(BrokerageUserDO::getBindUserTime, reqVO.getBindUserTime()) |
| 29 | - .and(reqVO.getBindUserId() != null, w -> buildBindUserCondition(reqVO, w)) | 27 | + .findInSetIfPresent(BrokerageUserDO::getPath, reqVO.getBindUserId()) |
| 28 | + .inIfPresent(BrokerageUserDO::getLevel, levels) | ||
| 30 | .orderByDesc(BrokerageUserDO::getId)); | 29 | .orderByDesc(BrokerageUserDO::getId)); |
| 31 | } | 30 | } |
| 32 | 31 | ||
| 33 | - static void buildBindUserCondition(BrokerageUserPageReqVO reqVO, LambdaQueryWrapper<BrokerageUserDO> wrapper) { | ||
| 34 | - if (BrokerageUserTypeEnum.FIRST.getType().equals(reqVO.getUserType())) { | ||
| 35 | - buildFirstBindUserCondition(reqVO.getBindUserId(), wrapper); | ||
| 36 | - } else if (BrokerageUserTypeEnum.SECOND.getType().equals(reqVO.getUserType())) { | ||
| 37 | - buildSecondBindUserCondition(reqVO.getBindUserId(), wrapper); | ||
| 38 | - } else { | ||
| 39 | - // TODO @疯狂:要不要把这个逻辑,挪到 Service 里,算出子用户有哪些,然后 IN? | ||
| 40 | - buildFirstBindUserCondition(reqVO.getBindUserId(), wrapper); | ||
| 41 | - buildSecondBindUserCondition(reqVO.getBindUserId(), wrapper.or()); // 通过 or 实现多个条件 | ||
| 42 | - } | ||
| 43 | - } | ||
| 44 | - | ||
| 45 | - static void buildFirstBindUserCondition(Long bindUserId, LambdaQueryWrapper<BrokerageUserDO> wrapper) { | ||
| 46 | - wrapper.eq(BrokerageUserDO::getBindUserId, bindUserId); | ||
| 47 | - } | ||
| 48 | - | ||
| 49 | - static void buildSecondBindUserCondition(Long bindUserId, LambdaQueryWrapper<BrokerageUserDO> wrapper) { | ||
| 50 | - wrapper.inSql(BrokerageUserDO::getBindUserId, StrUtil.format("SELECT id FROM trade_brokerage_user WHERE bind_user_id = {}", bindUserId)); | ||
| 51 | - } | ||
| 52 | - | ||
| 53 | /** | 32 | /** |
| 54 | * 更新用户可用佣金(增加) | 33 | * 更新用户可用佣金(增加) |
| 55 | * | 34 | * |
| @@ -128,7 +107,8 @@ public interface BrokerageUserMapper extends BaseMapperX<BrokerageUserDO> { | @@ -128,7 +107,8 @@ public interface BrokerageUserMapper extends BaseMapperX<BrokerageUserDO> { | ||
| 128 | default void updateBindUserIdAndBindUserTimeToNull(Long id) { | 107 | default void updateBindUserIdAndBindUserTimeToNull(Long id) { |
| 129 | update(null, new LambdaUpdateWrapper<BrokerageUserDO>() | 108 | update(null, new LambdaUpdateWrapper<BrokerageUserDO>() |
| 130 | .eq(BrokerageUserDO::getId, id) | 109 | .eq(BrokerageUserDO::getId, id) |
| 131 | - .set(BrokerageUserDO::getBindUserId, null).set(BrokerageUserDO::getBindUserTime, null)); | 110 | + .set(BrokerageUserDO::getBindUserId, null).set(BrokerageUserDO::getBindUserTime, null) |
| 111 | + .set(BrokerageUserDO::getLevel, 1).set(BrokerageUserDO::getPath, "")); | ||
| 132 | } | 112 | } |
| 133 | 113 | ||
| 134 | default void updateEnabledFalseAndBrokerageTimeToNull(Long id) { | 114 | default void updateEnabledFalseAndBrokerageTimeToNull(Long id) { |
| @@ -137,11 +117,10 @@ public interface BrokerageUserMapper extends BaseMapperX<BrokerageUserDO> { | @@ -137,11 +117,10 @@ public interface BrokerageUserMapper extends BaseMapperX<BrokerageUserDO> { | ||
| 137 | .set(BrokerageUserDO::getBrokerageEnabled, false).set(BrokerageUserDO::getBrokerageTime, null)); | 117 | .set(BrokerageUserDO::getBrokerageEnabled, false).set(BrokerageUserDO::getBrokerageTime, null)); |
| 138 | } | 118 | } |
| 139 | 119 | ||
| 140 | - default Long selectCountByBindUserId(Long bindUserId) { | ||
| 141 | - return selectCount(BrokerageUserDO::getBindUserId, bindUserId); | 120 | + default Long selectCountByBindUserIdAndLevelIn(Long bindUserId, List<Integer> levels) { |
| 121 | + return selectCount(new LambdaQueryWrapperX<BrokerageUserDO>() | ||
| 122 | + .findInSetIfPresent(BrokerageUserDO::getPath, bindUserId) | ||
| 123 | + .inIfPresent(BrokerageUserDO::getLevel, levels)); | ||
| 142 | } | 124 | } |
| 143 | 125 | ||
| 144 | - @Select("SELECT COUNT(1) from trade_brokerage_user WHERE bind_user_id IN (SELECT id FROM trade_brokerage_user WHERE bind_user_id = #{bindUserId})") | ||
| 145 | - Long selectCountByBindUserIdInBindUserId(Long bindUserId); | ||
| 146 | - | ||
| 147 | } | 126 | } |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/brokerage/withdraw/BrokerageWithdrawMapper.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.trade.dal.mysql.brokerage.withdraw; | ||
| 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.withdraw.vo.BrokerageWithdrawPageReqVO; | ||
| 7 | +import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.withdraw.BrokerageWithdrawDO; | ||
| 8 | +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; | ||
| 9 | +import org.apache.ibatis.annotations.Mapper; | ||
| 10 | + | ||
| 11 | +/** | ||
| 12 | + * 佣金提现 Mapper | ||
| 13 | + * | ||
| 14 | + * @author 芋道源码 | ||
| 15 | + */ | ||
| 16 | +@Mapper | ||
| 17 | +public interface BrokerageWithdrawMapper extends BaseMapperX<BrokerageWithdrawDO> { | ||
| 18 | + | ||
| 19 | + default PageResult<BrokerageWithdrawDO> selectPage(BrokerageWithdrawPageReqVO reqVO) { | ||
| 20 | + return selectPage(reqVO, new LambdaQueryWrapperX<BrokerageWithdrawDO>() | ||
| 21 | + .eqIfPresent(BrokerageWithdrawDO::getUserId, reqVO.getUserId()) | ||
| 22 | + .eqIfPresent(BrokerageWithdrawDO::getType, reqVO.getType()) | ||
| 23 | + .likeIfPresent(BrokerageWithdrawDO::getName, reqVO.getName()) | ||
| 24 | + .eqIfPresent(BrokerageWithdrawDO::getAccountNo, reqVO.getAccountNo()) | ||
| 25 | + .likeIfPresent(BrokerageWithdrawDO::getBankName, reqVO.getBankName()) | ||
| 26 | + .eqIfPresent(BrokerageWithdrawDO::getStatus, reqVO.getStatus()) | ||
| 27 | + .betweenIfPresent(BrokerageWithdrawDO::getCreateTime, reqVO.getCreateTime()) | ||
| 28 | + .orderByAsc(BrokerageWithdrawDO::getStatus).orderByDesc(BrokerageWithdrawDO::getId)); | ||
| 29 | + } | ||
| 30 | + | ||
| 31 | + default int updateByIdAndStatus(Integer id, Integer status, BrokerageWithdrawDO updateObj) { | ||
| 32 | + return update(updateObj, new LambdaUpdateWrapper<BrokerageWithdrawDO>() | ||
| 33 | + .eq(BrokerageWithdrawDO::getId, id) | ||
| 34 | + .eq(BrokerageWithdrawDO::getStatus, status)); | ||
| 35 | + } | ||
| 36 | + | ||
| 37 | +} |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/record/BrokerageRecordServiceImpl.java
| @@ -15,7 +15,6 @@ import cn.iocoder.yudao.module.trade.dal.dataobject.config.TradeConfigDO; | @@ -15,7 +15,6 @@ import cn.iocoder.yudao.module.trade.dal.dataobject.config.TradeConfigDO; | ||
| 15 | import cn.iocoder.yudao.module.trade.dal.mysql.brokerage.record.BrokerageRecordMapper; | 15 | import cn.iocoder.yudao.module.trade.dal.mysql.brokerage.record.BrokerageRecordMapper; |
| 16 | import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordBizTypeEnum; | 16 | import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordBizTypeEnum; |
| 17 | import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordStatusEnum; | 17 | import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordStatusEnum; |
| 18 | -import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageUserTypeEnum; | ||
| 19 | import cn.iocoder.yudao.module.trade.service.brokerage.bo.BrokerageAddReqBO; | 18 | import cn.iocoder.yudao.module.trade.service.brokerage.bo.BrokerageAddReqBO; |
| 20 | import cn.iocoder.yudao.module.trade.service.brokerage.bo.UserBrokerageSummaryBO; | 19 | import cn.iocoder.yudao.module.trade.service.brokerage.bo.UserBrokerageSummaryBO; |
| 21 | import cn.iocoder.yudao.module.trade.service.brokerage.user.BrokerageUserService; | 20 | import cn.iocoder.yudao.module.trade.service.brokerage.user.BrokerageUserService; |
| @@ -29,6 +28,7 @@ import javax.annotation.Resource; | @@ -29,6 +28,7 @@ import javax.annotation.Resource; | ||
| 29 | import java.time.LocalDateTime; | 28 | import java.time.LocalDateTime; |
| 30 | import java.util.ArrayList; | 29 | import java.util.ArrayList; |
| 31 | import java.util.List; | 30 | import java.util.List; |
| 31 | +import java.util.Objects; | ||
| 32 | 32 | ||
| 33 | /** | 33 | /** |
| 34 | * 佣金记录 Service 实现类 | 34 | * 佣金记录 Service 实现类 |
| @@ -74,7 +74,7 @@ public class BrokerageRecordServiceImpl implements BrokerageRecordService { | @@ -74,7 +74,7 @@ public class BrokerageRecordServiceImpl implements BrokerageRecordService { | ||
| 74 | } | 74 | } |
| 75 | // 1.2 计算一级分佣 | 75 | // 1.2 计算一级分佣 |
| 76 | addBrokerage(firstUser, list, memberConfig.getBrokerageFrozenDays(), memberConfig.getBrokerageFirstPercent(), | 76 | addBrokerage(firstUser, list, memberConfig.getBrokerageFrozenDays(), memberConfig.getBrokerageFirstPercent(), |
| 77 | - bizType, BrokerageUserTypeEnum.FIRST); | 77 | + bizType, 1); |
| 78 | 78 | ||
| 79 | // 2.1 获得二级推广员 | 79 | // 2.1 获得二级推广员 |
| 80 | if (firstUser.getBindUserId() == null) { | 80 | if (firstUser.getBindUserId() == null) { |
| @@ -86,7 +86,7 @@ public class BrokerageRecordServiceImpl implements BrokerageRecordService { | @@ -86,7 +86,7 @@ public class BrokerageRecordServiceImpl implements BrokerageRecordService { | ||
| 86 | } | 86 | } |
| 87 | // 2.2 计算二级分佣 | 87 | // 2.2 计算二级分佣 |
| 88 | addBrokerage(secondUser, list, memberConfig.getBrokerageFrozenDays(), memberConfig.getBrokerageSecondPercent(), | 88 | addBrokerage(secondUser, list, memberConfig.getBrokerageFrozenDays(), memberConfig.getBrokerageSecondPercent(), |
| 89 | - bizType, BrokerageUserTypeEnum.SECOND); | 89 | + bizType, 2); |
| 90 | } | 90 | } |
| 91 | 91 | ||
| 92 | @Override | 92 | @Override |
| @@ -142,10 +142,10 @@ public class BrokerageRecordServiceImpl implements BrokerageRecordService { | @@ -142,10 +142,10 @@ public class BrokerageRecordServiceImpl implements BrokerageRecordService { | ||
| 142 | * @param brokerageFrozenDays 冻结天数 | 142 | * @param brokerageFrozenDays 冻结天数 |
| 143 | * @param brokeragePercent 佣金比例 | 143 | * @param brokeragePercent 佣金比例 |
| 144 | * @param bizType 业务类型 | 144 | * @param bizType 业务类型 |
| 145 | - * @param sourceUserType 来源用户类型 | 145 | + * @param sourceUserLevel 来源用户等级 |
| 146 | */ | 146 | */ |
| 147 | private void addBrokerage(BrokerageUserDO user, List<BrokerageAddReqBO> list, Integer brokerageFrozenDays, | 147 | private void addBrokerage(BrokerageUserDO user, List<BrokerageAddReqBO> list, Integer brokerageFrozenDays, |
| 148 | - Integer brokeragePercent, BrokerageRecordBizTypeEnum bizType, BrokerageUserTypeEnum sourceUserType) { | 148 | + Integer brokeragePercent, BrokerageRecordBizTypeEnum bizType, Integer sourceUserLevel) { |
| 149 | // 1.1 处理冻结时间 | 149 | // 1.1 处理冻结时间 |
| 150 | LocalDateTime unfreezeTime = null; | 150 | LocalDateTime unfreezeTime = null; |
| 151 | if (brokerageFrozenDays != null && brokerageFrozenDays > 0) { | 151 | if (brokerageFrozenDays != null && brokerageFrozenDays > 0) { |
| @@ -157,12 +157,12 @@ public class BrokerageRecordServiceImpl implements BrokerageRecordService { | @@ -157,12 +157,12 @@ public class BrokerageRecordServiceImpl implements BrokerageRecordService { | ||
| 157 | for (BrokerageAddReqBO item : list) { | 157 | for (BrokerageAddReqBO item : list) { |
| 158 | // 计算金额 | 158 | // 计算金额 |
| 159 | Integer fixedPrice; | 159 | Integer fixedPrice; |
| 160 | - if (BrokerageUserTypeEnum.FIRST.equals(sourceUserType)) { | 160 | + if (Objects.equals(sourceUserLevel, 1)) { |
| 161 | fixedPrice = item.getFirstFixedPrice(); | 161 | fixedPrice = item.getFirstFixedPrice(); |
| 162 | - } else if (BrokerageUserTypeEnum.SECOND.equals(sourceUserType)) { | 162 | + } else if (Objects.equals(sourceUserLevel, 2)) { |
| 163 | fixedPrice = item.getSecondFixedPrice(); | 163 | fixedPrice = item.getSecondFixedPrice(); |
| 164 | } else { | 164 | } else { |
| 165 | - throw new IllegalArgumentException(StrUtil.format("来源用户({}) 不合法", sourceUserType)); | 165 | + throw new IllegalArgumentException(StrUtil.format("用户等级({}) 不合法", sourceUserLevel)); |
| 166 | } | 166 | } |
| 167 | int brokeragePrice = calculatePrice(item.getBasePrice(), brokeragePercent, fixedPrice); | 167 | int brokeragePrice = calculatePrice(item.getBasePrice(), brokeragePercent, fixedPrice); |
| 168 | if (brokeragePrice <= 0) { | 168 | if (brokeragePrice <= 0) { |
| @@ -172,7 +172,7 @@ public class BrokerageRecordServiceImpl implements BrokerageRecordService { | @@ -172,7 +172,7 @@ public class BrokerageRecordServiceImpl implements BrokerageRecordService { | ||
| 172 | // 创建记录实体 | 172 | // 创建记录实体 |
| 173 | records.add(BrokerageRecordConvert.INSTANCE.convert(user, bizType, item.getBizId(), | 173 | records.add(BrokerageRecordConvert.INSTANCE.convert(user, bizType, item.getBizId(), |
| 174 | brokerageFrozenDays, brokeragePrice, unfreezeTime, item.getTitle(), | 174 | brokerageFrozenDays, brokeragePrice, unfreezeTime, item.getTitle(), |
| 175 | - item.getSourceUserId(), sourceUserType.getType())); | 175 | + item.getSourceUserId(), sourceUserLevel)); |
| 176 | } | 176 | } |
| 177 | if (CollUtil.isEmpty(records)) { | 177 | if (CollUtil.isEmpty(records)) { |
| 178 | return; | 178 | return; |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/user/BrokerageUserService.java
| 1 | package cn.iocoder.yudao.module.trade.service.brokerage.user; | 1 | package cn.iocoder.yudao.module.trade.service.brokerage.user; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | +import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils; | ||
| 4 | import cn.iocoder.yudao.module.trade.controller.admin.brokerage.user.vo.BrokerageUserPageReqVO; | 5 | import cn.iocoder.yudao.module.trade.controller.admin.brokerage.user.vo.BrokerageUserPageReqVO; |
| 5 | import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.user.BrokerageUserDO; | 6 | import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.user.BrokerageUserDO; |
| 6 | -import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageUserTypeEnum; | ||
| 7 | 7 | ||
| 8 | +import javax.validation.constraints.NotNull; | ||
| 9 | +import java.time.LocalDateTime; | ||
| 8 | import java.util.Collection; | 10 | import java.util.Collection; |
| 9 | import java.util.List; | 11 | import java.util.List; |
| 10 | 12 | ||
| @@ -91,10 +93,24 @@ public interface BrokerageUserService { | @@ -91,10 +93,24 @@ public interface BrokerageUserService { | ||
| 91 | * 获得推广用户数量 | 93 | * 获得推广用户数量 |
| 92 | * | 94 | * |
| 93 | * @param bindUserId 绑定的推广员编号 | 95 | * @param bindUserId 绑定的推广员编号 |
| 94 | - * @param userType 用户类型 | 96 | + * @param level 推广用户等级 |
| 95 | * @return 推广用户数量 | 97 | * @return 推广用户数量 |
| 96 | */ | 98 | */ |
| 97 | - Long getBrokerageUserCountByBindUserId(Long bindUserId, BrokerageUserTypeEnum userType); | 99 | + Long getBrokerageUserCountByBindUserId(Long bindUserId, Integer level); |
| 100 | + | ||
| 101 | + /** | ||
| 102 | + * 【会员】绑定推广员 | ||
| 103 | + * | ||
| 104 | + * @param userId 用户编号 | ||
| 105 | + * @param bindUserId 推广员编号 | ||
| 106 | + * @param registerTime 用户注册时间 | ||
| 107 | + * @return 是否绑定 | ||
| 108 | + */ | ||
| 109 | + default boolean bindBrokerageUser(@NotNull Long userId, @NotNull Long bindUserId, @NotNull LocalDateTime registerTime) { | ||
| 110 | + // 注册时间在30秒内的,都算新用户 | ||
| 111 | + boolean isNewUser = LocalDateTimeUtils.afterNow(registerTime.minusSeconds(30)); | ||
| 112 | + return bindBrokerageUser(userId, bindUserId, isNewUser); | ||
| 113 | + } | ||
| 98 | 114 | ||
| 99 | /** | 115 | /** |
| 100 | * 【会员】绑定推广员 | 116 | * 【会员】绑定推广员 |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/user/BrokerageUserServiceImpl.java
| 1 | package cn.iocoder.yudao.module.trade.service.brokerage.user; | 1 | package cn.iocoder.yudao.module.trade.service.brokerage.user; |
| 2 | 2 | ||
| 3 | +import cn.hutool.core.collection.CollUtil; | ||
| 3 | import cn.hutool.core.lang.Assert; | 4 | import cn.hutool.core.lang.Assert; |
| 4 | import cn.hutool.core.util.BooleanUtil; | 5 | import cn.hutool.core.util.BooleanUtil; |
| 6 | +import cn.hutool.core.util.ObjectUtil; | ||
| 7 | +import cn.hutool.core.util.StrUtil; | ||
| 5 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 8 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 6 | import cn.iocoder.yudao.module.trade.controller.admin.brokerage.user.vo.BrokerageUserPageReqVO; | 9 | import cn.iocoder.yudao.module.trade.controller.admin.brokerage.user.vo.BrokerageUserPageReqVO; |
| 7 | import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.user.BrokerageUserDO; | 10 | import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.user.BrokerageUserDO; |
| @@ -9,17 +12,13 @@ import cn.iocoder.yudao.module.trade.dal.dataobject.config.TradeConfigDO; | @@ -9,17 +12,13 @@ import cn.iocoder.yudao.module.trade.dal.dataobject.config.TradeConfigDO; | ||
| 9 | import cn.iocoder.yudao.module.trade.dal.mysql.brokerage.user.BrokerageUserMapper; | 12 | import cn.iocoder.yudao.module.trade.dal.mysql.brokerage.user.BrokerageUserMapper; |
| 10 | import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageBindModeEnum; | 13 | import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageBindModeEnum; |
| 11 | import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageEnabledConditionEnum; | 14 | import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageEnabledConditionEnum; |
| 12 | -import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageUserTypeEnum; | ||
| 13 | import cn.iocoder.yudao.module.trade.service.config.TradeConfigService; | 15 | import cn.iocoder.yudao.module.trade.service.config.TradeConfigService; |
| 14 | import org.springframework.stereotype.Service; | 16 | import org.springframework.stereotype.Service; |
| 15 | import org.springframework.validation.annotation.Validated; | 17 | import org.springframework.validation.annotation.Validated; |
| 16 | 18 | ||
| 17 | import javax.annotation.Resource; | 19 | import javax.annotation.Resource; |
| 18 | import java.time.LocalDateTime; | 20 | import java.time.LocalDateTime; |
| 19 | -import java.util.Collection; | ||
| 20 | -import java.util.List; | ||
| 21 | -import java.util.Objects; | ||
| 22 | -import java.util.Optional; | 21 | +import java.util.*; |
| 23 | 22 | ||
| 24 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | 23 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 25 | import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*; | 24 | import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*; |
| @@ -51,7 +50,8 @@ public class BrokerageUserServiceImpl implements BrokerageUserService { | @@ -51,7 +50,8 @@ public class BrokerageUserServiceImpl implements BrokerageUserService { | ||
| 51 | 50 | ||
| 52 | @Override | 51 | @Override |
| 53 | public PageResult<BrokerageUserDO> getBrokerageUserPage(BrokerageUserPageReqVO pageReqVO) { | 52 | public PageResult<BrokerageUserDO> getBrokerageUserPage(BrokerageUserPageReqVO pageReqVO) { |
| 54 | - return brokerageUserMapper.selectPage(pageReqVO); | 53 | + List<Integer> levels = buildUserQueryLevels(pageReqVO.getBindUserId(), pageReqVO.getLevel()); |
| 54 | + return brokerageUserMapper.selectPage(pageReqVO, levels); | ||
| 55 | } | 55 | } |
| 56 | 56 | ||
| 57 | @Override | 57 | @Override |
| @@ -66,10 +66,15 @@ public class BrokerageUserServiceImpl implements BrokerageUserService { | @@ -66,10 +66,15 @@ public class BrokerageUserServiceImpl implements BrokerageUserService { | ||
| 66 | return; | 66 | return; |
| 67 | } | 67 | } |
| 68 | 68 | ||
| 69 | + // 绑定关系未发生变化 | ||
| 70 | + // TODO @疯狂:这个放到“情况一”之前,貌似也没关系? | ||
| 71 | + if (Objects.equals(brokerageUser.getBindUserId(), bindUserId)) { | ||
| 72 | + return; | ||
| 73 | + } | ||
| 74 | + | ||
| 69 | // 情况二:修改推广员 | 75 | // 情况二:修改推广员 |
| 70 | validateCanBindUser(brokerageUser, bindUserId); | 76 | validateCanBindUser(brokerageUser, bindUserId); |
| 71 | - brokerageUserMapper.updateById(new BrokerageUserDO().setId(id) | ||
| 72 | - .setBindUserId(bindUserId).setBindUserTime(LocalDateTime.now())); | 77 | + brokerageUserMapper.updateById(fillBindUserData(bindUserId, new BrokerageUserDO().setId(id))); |
| 73 | } | 78 | } |
| 74 | 79 | ||
| 75 | @Override | 80 | @Override |
| @@ -132,19 +137,12 @@ public class BrokerageUserServiceImpl implements BrokerageUserService { | @@ -132,19 +137,12 @@ public class BrokerageUserServiceImpl implements BrokerageUserService { | ||
| 132 | } | 137 | } |
| 133 | 138 | ||
| 134 | @Override | 139 | @Override |
| 135 | - public Long getBrokerageUserCountByBindUserId(Long bindUserId, BrokerageUserTypeEnum userType) { | ||
| 136 | - switch (userType) { | ||
| 137 | - case ALL: // TODO @疯狂:ALL 是不是不用搞个枚举,默认为空就是不过滤哈~ | ||
| 138 | - Long firstCount = brokerageUserMapper.selectCountByBindUserId(bindUserId); | ||
| 139 | - Long secondCount = brokerageUserMapper.selectCountByBindUserIdInBindUserId(bindUserId); | ||
| 140 | - return firstCount + secondCount; | ||
| 141 | - case FIRST: | ||
| 142 | - return brokerageUserMapper.selectCountByBindUserId(bindUserId); | ||
| 143 | - case SECOND: | ||
| 144 | - return brokerageUserMapper.selectCountByBindUserIdInBindUserId(bindUserId); | ||
| 145 | - default: | ||
| 146 | - return 0L; | 140 | + public Long getBrokerageUserCountByBindUserId(Long bindUserId, Integer level) { |
| 141 | + List<Integer> levels = buildUserQueryLevels(bindUserId, level); | ||
| 142 | + if (CollUtil.isEmpty(levels)) { | ||
| 143 | + return 0L; | ||
| 147 | } | 144 | } |
| 145 | + return brokerageUserMapper.selectCountByBindUserIdAndLevelIn(bindUserId, levels); | ||
| 148 | } | 146 | } |
| 149 | 147 | ||
| 150 | @Override | 148 | @Override |
| @@ -171,14 +169,30 @@ public class BrokerageUserServiceImpl implements BrokerageUserService { | @@ -171,14 +169,30 @@ public class BrokerageUserServiceImpl implements BrokerageUserService { | ||
| 171 | brokerageUser.setBrokerageEnabled(true).setBrokerageTime(LocalDateTime.now()); | 169 | brokerageUser.setBrokerageEnabled(true).setBrokerageTime(LocalDateTime.now()); |
| 172 | } | 170 | } |
| 173 | brokerageUser.setBindUserId(bindUserId).setBindUserTime(LocalDateTime.now()); | 171 | brokerageUser.setBindUserId(bindUserId).setBindUserTime(LocalDateTime.now()); |
| 174 | - brokerageUserMapper.insert(brokerageUser); | 172 | + brokerageUserMapper.insert(fillBindUserData(bindUserId, brokerageUser)); |
| 175 | } else { | 173 | } else { |
| 176 | - brokerageUserMapper.updateById(new BrokerageUserDO().setId(userId) | ||
| 177 | - .setBindUserId(bindUserId).setBindUserTime(LocalDateTime.now())); | 174 | + brokerageUserMapper.updateById(fillBindUserData(bindUserId, new BrokerageUserDO().setId(userId))); |
| 178 | } | 175 | } |
| 179 | return true; | 176 | return true; |
| 180 | } | 177 | } |
| 181 | 178 | ||
| 179 | + private BrokerageUserDO fillBindUserData(Long bindUserId, BrokerageUserDO brokerageUser) { | ||
| 180 | + BrokerageUserDO bindUser = getBrokerageUser(bindUserId); | ||
| 181 | + | ||
| 182 | + Integer bindUserLevel = 0; | ||
| 183 | + String bindUserPath = ""; | ||
| 184 | + if (bindUser != null) { | ||
| 185 | + bindUserLevel = ObjectUtil.defaultIfNull(bindUser.getLevel(), 0); | ||
| 186 | + bindUserPath = bindUser.getPath(); | ||
| 187 | + } | ||
| 188 | + | ||
| 189 | + String path = StrUtil.isEmpty(bindUserPath) | ||
| 190 | + ? String.valueOf(bindUserId) | ||
| 191 | + : String.format("%s,%s", bindUserPath, bindUserId); | ||
| 192 | + return brokerageUser.setBindUserId(bindUserId).setBindUserTime(LocalDateTime.now()) | ||
| 193 | + .setLevel(bindUserLevel + 1).setPath(path); | ||
| 194 | + } | ||
| 195 | + | ||
| 182 | @Override | 196 | @Override |
| 183 | public Boolean getUserBrokerageEnabled(Long userId) { | 197 | public Boolean getUserBrokerageEnabled(Long userId) { |
| 184 | // 全局分销功能是否开启 | 198 | // 全局分销功能是否开启 |
| @@ -231,11 +245,30 @@ public class BrokerageUserServiceImpl implements BrokerageUserService { | @@ -231,11 +245,30 @@ public class BrokerageUserServiceImpl implements BrokerageUserService { | ||
| 231 | throw exception(BROKERAGE_BIND_SELF); | 245 | throw exception(BROKERAGE_BIND_SELF); |
| 232 | } | 246 | } |
| 233 | 247 | ||
| 234 | - // TODO @疯狂:这块是不是一直查询到根节点,中间不允许出现自己;就是不能形成环。虽然目前是 2 级,但是未来可能会改多级; = = 环的话,就会存在问题哈 | ||
| 235 | - // A->B->A:下级不能绑定自己的上级, A->B->C->A可以!! | ||
| 236 | - if (Objects.equals(user.getId(), bindUser.getBindUserId())) { | 248 | + // 下级不能绑定自己的上级 |
| 249 | + if (StrUtil.split(bindUser.getPath(), ",").contains(String.valueOf(user.getId()))) { | ||
| 237 | throw exception(BROKERAGE_BIND_LOOP); | 250 | throw exception(BROKERAGE_BIND_LOOP); |
| 238 | } | 251 | } |
| 239 | } | 252 | } |
| 240 | 253 | ||
| 254 | + // TODO @芋艿:这个层级,要微信讨论下; | ||
| 255 | + private List<Integer> buildUserQueryLevels(Long bindUserId, Integer level) { | ||
| 256 | + List<Integer> levels = new ArrayList<>(2); | ||
| 257 | + | ||
| 258 | + BrokerageUserDO bindUser = getBrokerageUser(bindUserId); | ||
| 259 | + if (bindUser == null) { | ||
| 260 | + return levels; | ||
| 261 | + } | ||
| 262 | + | ||
| 263 | + if (level == null) { | ||
| 264 | + // 默认查两层 | ||
| 265 | + levels.add(bindUser.getLevel() + 1); | ||
| 266 | + levels.add(bindUser.getLevel() + 2); | ||
| 267 | + } else { | ||
| 268 | + levels.add(bindUser.getLevel() + level); | ||
| 269 | + } | ||
| 270 | + return levels; | ||
| 271 | + | ||
| 272 | + } | ||
| 273 | + | ||
| 241 | } | 274 | } |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/withdraw/BrokerageWithdrawService.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.trade.service.brokerage.withdraw; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||
| 4 | +import cn.iocoder.yudao.module.trade.controller.admin.brokerage.withdraw.vo.BrokerageWithdrawPageReqVO; | ||
| 5 | +import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.withdraw.BrokerageWithdrawDO; | ||
| 6 | +import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageWithdrawStatusEnum; | ||
| 7 | + | ||
| 8 | +/** | ||
| 9 | + * 佣金提现 Service 接口 | ||
| 10 | + * | ||
| 11 | + * @author 芋道源码 | ||
| 12 | + */ | ||
| 13 | +public interface BrokerageWithdrawService { | ||
| 14 | + | ||
| 15 | + /** | ||
| 16 | + * 审核佣金提现 | ||
| 17 | + * | ||
| 18 | + * @param id 佣金编号 | ||
| 19 | + * @param status 审核状态 | ||
| 20 | + * @param auditReason 驳回原因 | ||
| 21 | + */ | ||
| 22 | + | ||
| 23 | + void auditBrokerageWithdraw(Integer id, BrokerageWithdrawStatusEnum status, String auditReason); | ||
| 24 | + | ||
| 25 | + /** | ||
| 26 | + * 获得佣金提现 | ||
| 27 | + * | ||
| 28 | + * @param id 编号 | ||
| 29 | + * @return 佣金提现 | ||
| 30 | + */ | ||
| 31 | + BrokerageWithdrawDO getBrokerageWithdraw(Integer id); | ||
| 32 | + | ||
| 33 | + /** | ||
| 34 | + * 获得佣金提现分页 | ||
| 35 | + * | ||
| 36 | + * @param pageReqVO 分页查询 | ||
| 37 | + * @return 佣金提现分页 | ||
| 38 | + */ | ||
| 39 | + PageResult<BrokerageWithdrawDO> getBrokerageWithdrawPage(BrokerageWithdrawPageReqVO pageReqVO); | ||
| 40 | +} |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/withdraw/BrokerageWithdrawServiceImpl.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.trade.service.brokerage.withdraw; | ||
| 2 | + | ||
| 3 | +import cn.hutool.core.date.LocalDateTimeUtil; | ||
| 4 | +import cn.hutool.core.map.MapUtil; | ||
| 5 | +import cn.hutool.core.util.ObjectUtil; | ||
| 6 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||
| 7 | +import cn.iocoder.yudao.module.system.api.notify.NotifyMessageSendApi; | ||
| 8 | +import cn.iocoder.yudao.module.system.api.notify.dto.NotifySendSingleToUserReqDTO; | ||
| 9 | +import cn.iocoder.yudao.module.trade.controller.admin.brokerage.withdraw.vo.BrokerageWithdrawPageReqVO; | ||
| 10 | +import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.withdraw.BrokerageWithdrawDO; | ||
| 11 | +import cn.iocoder.yudao.module.trade.dal.mysql.brokerage.withdraw.BrokerageWithdrawMapper; | ||
| 12 | +import cn.iocoder.yudao.module.trade.enums.MessageTemplateConstants; | ||
| 13 | +import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageWithdrawStatusEnum; | ||
| 14 | +import cn.iocoder.yudao.module.trade.service.brokerage.record.BrokerageRecordService; | ||
| 15 | +import org.springframework.stereotype.Service; | ||
| 16 | +import org.springframework.transaction.annotation.Transactional; | ||
| 17 | +import org.springframework.validation.annotation.Validated; | ||
| 18 | + | ||
| 19 | +import javax.annotation.Resource; | ||
| 20 | +import java.time.LocalDateTime; | ||
| 21 | +import java.util.Map; | ||
| 22 | + | ||
| 23 | +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | ||
| 24 | +import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.BROKERAGE_WITHDRAW_NOT_EXISTS; | ||
| 25 | +import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.BROKERAGE_WITHDRAW_STATUS_NOT_AUDITING; | ||
| 26 | + | ||
| 27 | +/** | ||
| 28 | + * 佣金提现 Service 实现类 | ||
| 29 | + * | ||
| 30 | + * @author 芋道源码 | ||
| 31 | + */ | ||
| 32 | +@Service | ||
| 33 | +@Validated | ||
| 34 | +public class BrokerageWithdrawServiceImpl implements BrokerageWithdrawService { | ||
| 35 | + | ||
| 36 | + @Resource | ||
| 37 | + private BrokerageWithdrawMapper brokerageWithdrawMapper; | ||
| 38 | + | ||
| 39 | + @Resource | ||
| 40 | + private BrokerageRecordService brokerageRecordService; | ||
| 41 | + | ||
| 42 | + @Resource | ||
| 43 | + private NotifyMessageSendApi notifyMessageSendApi; | ||
| 44 | + | ||
| 45 | + @Override | ||
| 46 | + @Transactional(rollbackFor = Exception.class) | ||
| 47 | + public void auditBrokerageWithdraw(Integer id, BrokerageWithdrawStatusEnum status, String auditReason) { | ||
| 48 | + // 1.1 校验存在 | ||
| 49 | + BrokerageWithdrawDO withdraw = validateBrokerageWithdrawExists(id); | ||
| 50 | + // 1.2 校验状态为审核中 | ||
| 51 | + if (ObjectUtil.notEqual(BrokerageWithdrawStatusEnum.AUDITING.getStatus(), withdraw.getStatus())) { | ||
| 52 | + throw exception(BROKERAGE_WITHDRAW_STATUS_NOT_AUDITING); | ||
| 53 | + } | ||
| 54 | + | ||
| 55 | + // 2. 更新 | ||
| 56 | + BrokerageWithdrawDO updateObj = new BrokerageWithdrawDO() | ||
| 57 | + .setStatus(status.getStatus()) | ||
| 58 | + .setAuditReason(auditReason) | ||
| 59 | + .setAuditTime(LocalDateTime.now()); | ||
| 60 | + int rows = brokerageWithdrawMapper.updateByIdAndStatus(id, BrokerageWithdrawStatusEnum.AUDITING.getStatus(), updateObj); | ||
| 61 | + if (rows == 0) { | ||
| 62 | + throw exception(BROKERAGE_WITHDRAW_STATUS_NOT_AUDITING); | ||
| 63 | + } | ||
| 64 | + | ||
| 65 | + // 3. 驳回时需要退还用户佣金 | ||
| 66 | + String templateCode = MessageTemplateConstants.BROKERAGE_WITHDRAW_AUDIT_APPROVE; | ||
| 67 | + if (BrokerageWithdrawStatusEnum.AUDIT_FAIL.equals(status)) { | ||
| 68 | + templateCode = MessageTemplateConstants.BROKERAGE_WITHDRAW_AUDIT_REJECT; | ||
| 69 | + | ||
| 70 | + // todo @owen | ||
| 71 | +// brokerageRecordService.addBrokerage(withdraw.getUserId(), BrokerageRecordBizTypeEnum.WITHDRAW, withdraw.getPrice(), ""); | ||
| 72 | + } | ||
| 73 | + | ||
| 74 | + // 4. 通知用户 | ||
| 75 | + Map<String, Object> templateParams = MapUtil.<String, Object>builder() | ||
| 76 | + .put("createTime", LocalDateTimeUtil.formatNormal(withdraw.getCreateTime())) | ||
| 77 | + .put("price", String.format("%.2f", withdraw.getPrice() / 100d)) | ||
| 78 | + .put("reason", withdraw.getAuditReason()) | ||
| 79 | + .build(); | ||
| 80 | + NotifySendSingleToUserReqDTO reqDTO = new NotifySendSingleToUserReqDTO() | ||
| 81 | + .setUserId(withdraw.getUserId()) | ||
| 82 | + .setTemplateCode(templateCode).setTemplateParams(templateParams); | ||
| 83 | + notifyMessageSendApi.sendSingleMessageToMember(reqDTO); | ||
| 84 | + } | ||
| 85 | + | ||
| 86 | + private BrokerageWithdrawDO validateBrokerageWithdrawExists(Integer id) { | ||
| 87 | + BrokerageWithdrawDO withdraw = brokerageWithdrawMapper.selectById(id); | ||
| 88 | + if (withdraw == null) { | ||
| 89 | + throw exception(BROKERAGE_WITHDRAW_NOT_EXISTS); | ||
| 90 | + } | ||
| 91 | + return withdraw; | ||
| 92 | + } | ||
| 93 | + | ||
| 94 | + @Override | ||
| 95 | + public BrokerageWithdrawDO getBrokerageWithdraw(Integer id) { | ||
| 96 | + return brokerageWithdrawMapper.selectById(id); | ||
| 97 | + } | ||
| 98 | + | ||
| 99 | + @Override | ||
| 100 | + public PageResult<BrokerageWithdrawDO> getBrokerageWithdrawPage(BrokerageWithdrawPageReqVO pageReqVO) { | ||
| 101 | + return brokerageWithdrawMapper.selectPage(pageReqVO); | ||
| 102 | + } | ||
| 103 | + | ||
| 104 | +} |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderUpdateServiceImpl.java
| @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.trade.service.order; | @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.trade.service.order; | ||
| 3 | import cn.hutool.core.collection.CollUtil; | 3 | import cn.hutool.core.collection.CollUtil; |
| 4 | import cn.hutool.core.lang.Assert; | 4 | import cn.hutool.core.lang.Assert; |
| 5 | import cn.hutool.core.util.ObjectUtil; | 5 | import cn.hutool.core.util.ObjectUtil; |
| 6 | +import cn.hutool.core.util.RandomUtil; | ||
| 6 | import cn.hutool.core.util.StrUtil; | 7 | import cn.hutool.core.util.StrUtil; |
| 7 | import cn.hutool.extra.spring.SpringUtil; | 8 | import cn.hutool.extra.spring.SpringUtil; |
| 8 | import cn.iocoder.yudao.framework.common.core.KeyValue; | 9 | import cn.iocoder.yudao.framework.common.core.KeyValue; |
| @@ -12,6 +13,8 @@ import cn.iocoder.yudao.module.member.api.address.AddressApi; | @@ -12,6 +13,8 @@ import cn.iocoder.yudao.module.member.api.address.AddressApi; | ||
| 12 | import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO; | 13 | import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO; |
| 13 | import cn.iocoder.yudao.module.member.api.level.MemberLevelApi; | 14 | import cn.iocoder.yudao.module.member.api.level.MemberLevelApi; |
| 14 | import cn.iocoder.yudao.module.member.api.point.MemberPointApi; | 15 | import cn.iocoder.yudao.module.member.api.point.MemberPointApi; |
| 16 | +import cn.iocoder.yudao.module.member.api.user.MemberUserApi; | ||
| 17 | +import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; | ||
| 15 | import cn.iocoder.yudao.module.member.enums.MemberExperienceBizTypeEnum; | 18 | import cn.iocoder.yudao.module.member.enums.MemberExperienceBizTypeEnum; |
| 16 | import cn.iocoder.yudao.module.member.enums.point.MemberPointBizTypeEnum; | 19 | import cn.iocoder.yudao.module.member.enums.point.MemberPointBizTypeEnum; |
| 17 | import cn.iocoder.yudao.module.pay.api.order.PayOrderApi; | 20 | import cn.iocoder.yudao.module.pay.api.order.PayOrderApi; |
| @@ -40,11 +43,11 @@ import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; | @@ -40,11 +43,11 @@ import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; | ||
| 40 | import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderItemMapper; | 43 | import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderItemMapper; |
| 41 | import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderMapper; | 44 | import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderMapper; |
| 42 | import cn.iocoder.yudao.module.trade.dal.redis.no.TradeOrderNoRedisDAO; | 45 | import cn.iocoder.yudao.module.trade.dal.redis.no.TradeOrderNoRedisDAO; |
| 43 | -import cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants; | ||
| 44 | import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordBizTypeEnum; | 46 | import cn.iocoder.yudao.module.trade.enums.brokerage.BrokerageRecordBizTypeEnum; |
| 45 | import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryTypeEnum; | 47 | import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryTypeEnum; |
| 46 | import cn.iocoder.yudao.module.trade.enums.order.*; | 48 | import cn.iocoder.yudao.module.trade.enums.order.*; |
| 47 | import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties; | 49 | import cn.iocoder.yudao.module.trade.framework.order.config.TradeOrderProperties; |
| 50 | +import cn.iocoder.yudao.module.trade.framework.order.core.annotations.TradeOrderLog; | ||
| 48 | import cn.iocoder.yudao.module.trade.service.brokerage.bo.BrokerageAddReqBO; | 51 | import cn.iocoder.yudao.module.trade.service.brokerage.bo.BrokerageAddReqBO; |
| 49 | import cn.iocoder.yudao.module.trade.service.brokerage.record.BrokerageRecordService; | 52 | import cn.iocoder.yudao.module.trade.service.brokerage.record.BrokerageRecordService; |
| 50 | import cn.iocoder.yudao.module.trade.service.cart.CartService; | 53 | import cn.iocoder.yudao.module.trade.service.cart.CartService; |
| @@ -115,6 +118,8 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { | @@ -115,6 +118,8 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { | ||
| 115 | @Resource | 118 | @Resource |
| 116 | private BargainRecordApi bargainRecordApi; | 119 | private BargainRecordApi bargainRecordApi; |
| 117 | @Resource | 120 | @Resource |
| 121 | + private MemberUserApi memberUserApi; | ||
| 122 | + @Resource | ||
| 118 | private MemberLevelApi memberLevelApi; | 123 | private MemberLevelApi memberLevelApi; |
| 119 | @Resource | 124 | @Resource |
| 120 | private MemberPointApi memberPointApi; | 125 | private MemberPointApi memberPointApi; |
| @@ -178,140 +183,127 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { | @@ -178,140 +183,127 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { | ||
| 178 | 183 | ||
| 179 | @Override | 184 | @Override |
| 180 | @Transactional(rollbackFor = Exception.class) | 185 | @Transactional(rollbackFor = Exception.class) |
| 186 | + @TradeOrderLog(operateType = TradeOrderOperateTypeEnum.MEMBER_CREATE) | ||
| 181 | public TradeOrderDO createOrder(Long userId, String userIp, AppTradeOrderCreateReqVO createReqVO) { | 187 | public TradeOrderDO createOrder(Long userId, String userIp, AppTradeOrderCreateReqVO createReqVO) { |
| 182 | - // 1、执行订单创建前置处理器 | ||
| 183 | - // TODO @puhui999:最好也抽个 beforeOrderCreate 方法; | ||
| 184 | - TradeBeforeOrderCreateReqBO beforeOrderCreateReqBO = TradeOrderConvert.INSTANCE.convert(createReqVO); | ||
| 185 | - beforeOrderCreateReqBO.setOrderType(validateActivity(createReqVO)); | ||
| 186 | - beforeOrderCreateReqBO.setCount(getSumValue(createReqVO.getItems(), AppTradeOrderSettlementReqVO.Item::getCount, Integer::sum)); | ||
| 187 | - // TODO @puhui999:这里有个纠结点;handler 的定义是只处理指定类型的订单的拓展逻辑;还是通用的 handler,类似可以处理优惠劵等等 | ||
| 188 | - tradeOrderHandlers.forEach(handler -> handler.beforeOrderCreate(beforeOrderCreateReqBO)); | ||
| 189 | - | ||
| 190 | - // 2. 价格计算 | 188 | + // 0. 价格计算 |
| 191 | TradePriceCalculateRespBO calculateRespBO = calculatePrice(userId, createReqVO); | 189 | TradePriceCalculateRespBO calculateRespBO = calculatePrice(userId, createReqVO); |
| 192 | 190 | ||
| 191 | + // 1. 订单创建前的逻辑 | ||
| 192 | + beforeCreateTradeOrder(userId, createReqVO, calculateRespBO); | ||
| 193 | + | ||
| 193 | // 2.1 插入 TradeOrderDO 订单 | 194 | // 2.1 插入 TradeOrderDO 订单 |
| 194 | TradeOrderDO order = createTradeOrder(userId, userIp, createReqVO, calculateRespBO); | 195 | TradeOrderDO order = createTradeOrder(userId, userIp, createReqVO, calculateRespBO); |
| 195 | // 2.2 插入 TradeOrderItemDO 订单项 | 196 | // 2.2 插入 TradeOrderItemDO 订单项 |
| 196 | List<TradeOrderItemDO> orderItems = createTradeOrderItems(order, calculateRespBO); | 197 | List<TradeOrderItemDO> orderItems = createTradeOrderItems(order, calculateRespBO); |
| 197 | 198 | ||
| 198 | - // 3. 订单创建完后的逻辑 | 199 | + // 3. 订单创建后的逻辑 |
| 199 | afterCreateTradeOrder(userId, createReqVO, order, orderItems, calculateRespBO); | 200 | afterCreateTradeOrder(userId, createReqVO, order, orderItems, calculateRespBO); |
| 200 | - | ||
| 201 | - // TODO @LeeYan9: 是可以思考下, 订单的营销优惠记录, 应该记录在哪里, 微信讨论起来! | ||
| 202 | return order; | 201 | return order; |
| 203 | } | 202 | } |
| 204 | 203 | ||
| 205 | - | ||
| 206 | // TODO @puhui999:订单超时,自动取消; | 204 | // TODO @puhui999:订单超时,自动取消; |
| 207 | 205 | ||
| 208 | - /** | ||
| 209 | - * 校验收件地址是否存在 | ||
| 210 | - * | ||
| 211 | - * @param userId 用户编号 | ||
| 212 | - * @param addressId 收件地址编号 | ||
| 213 | - * @return 收件地址 | ||
| 214 | - */ | ||
| 215 | - private AddressRespDTO validateAddress(Long userId, Long addressId) { | ||
| 216 | - AddressRespDTO address = addressApi.getAddress(addressId, userId); | ||
| 217 | - if (address == null) { | ||
| 218 | - throw exception(ErrorCodeConstants.ORDER_CREATE_ADDRESS_NOT_FOUND); | ||
| 219 | - } | ||
| 220 | - return address; | ||
| 221 | - } | ||
| 222 | - | ||
| 223 | private TradeOrderDO createTradeOrder(Long userId, String clientIp, AppTradeOrderCreateReqVO createReqVO, | 206 | private TradeOrderDO createTradeOrder(Long userId, String clientIp, AppTradeOrderCreateReqVO createReqVO, |
| 224 | TradePriceCalculateRespBO calculateRespBO) { | 207 | TradePriceCalculateRespBO calculateRespBO) { |
| 225 | - // 用户选择物流配送的时候才需要填写收货地址 | ||
| 226 | - AddressRespDTO address = new AddressRespDTO(); | ||
| 227 | - if (Objects.equals(createReqVO.getDeliveryType(), DeliveryTypeEnum.EXPRESS.getMode())) { | ||
| 228 | - // 用户收件地址的校验 | ||
| 229 | - address = validateAddress(userId, createReqVO.getAddressId()); | ||
| 230 | - } | ||
| 231 | - TradeOrderDO order = TradeOrderConvert.INSTANCE.convert(userId, clientIp, createReqVO, calculateRespBO, address); | ||
| 232 | - String no = orderNoRedisDAO.generate(TradeOrderNoRedisDAO.TRADE_ORDER_NO_PREFIX); | ||
| 233 | - order.setType(validateActivity(createReqVO)); | ||
| 234 | - order.setNo(no); | 208 | + TradeOrderDO order = TradeOrderConvert.INSTANCE.convert(userId, clientIp, createReqVO, calculateRespBO); |
| 209 | + order.setType(calculateRespBO.getType()); | ||
| 210 | + order.setNo(orderNoRedisDAO.generate(TradeOrderNoRedisDAO.TRADE_ORDER_NO_PREFIX)); | ||
| 235 | order.setStatus(TradeOrderStatusEnum.UNPAID.getStatus()); | 211 | order.setStatus(TradeOrderStatusEnum.UNPAID.getStatus()); |
| 236 | order.setRefundStatus(TradeOrderRefundStatusEnum.NONE.getStatus()); | 212 | order.setRefundStatus(TradeOrderRefundStatusEnum.NONE.getStatus()); |
| 237 | order.setProductCount(getSumValue(calculateRespBO.getItems(), TradePriceCalculateRespBO.OrderItem::getCount, Integer::sum)); | 213 | order.setProductCount(getSumValue(calculateRespBO.getItems(), TradePriceCalculateRespBO.OrderItem::getCount, Integer::sum)); |
| 238 | order.setTerminal(TerminalEnum.H5.getTerminal()); // todo 数据来源? | 214 | order.setTerminal(TerminalEnum.H5.getTerminal()); // todo 数据来源? |
| 239 | - // 支付信息 | 215 | + // 支付 + 退款信息 |
| 240 | order.setAdjustPrice(0).setPayStatus(false); | 216 | order.setAdjustPrice(0).setPayStatus(false); |
| 217 | + order.setRefundStatus(TradeOrderRefundStatusEnum.NONE.getStatus()).setRefundPrice(0); | ||
| 241 | // 物流信息 | 218 | // 物流信息 |
| 242 | order.setDeliveryType(createReqVO.getDeliveryType()); | 219 | order.setDeliveryType(createReqVO.getDeliveryType()); |
| 243 | - // 退款信息 | ||
| 244 | - order.setRefundStatus(TradeOrderRefundStatusEnum.NONE.getStatus()).setRefundPrice(0); | 220 | + if (Objects.equals(createReqVO.getDeliveryType(), DeliveryTypeEnum.EXPRESS.getType())) { |
| 221 | + AddressRespDTO address = addressApi.getAddress(createReqVO.getAddressId(), userId); | ||
| 222 | + Assert.notNull(address, "地址({}) 不能为空", createReqVO.getAddressId()); // 价格计算时,已经计算 | ||
| 223 | + order.setReceiverName(address.getName()).setReceiverMobile(address.getMobile()) | ||
| 224 | + .setReceiverAreaId(address.getAreaId()).setReceiverDetailAddress(address.getDetailAddress()); | ||
| 225 | + } else if (Objects.equals(createReqVO.getDeliveryType(), DeliveryTypeEnum.PICK_UP.getType())) { | ||
| 226 | + order.setReceiverName(createReqVO.getReceiverName()).setReceiverMobile(createReqVO.getReceiverMobile()); | ||
| 227 | + order.setPickUpVerifyCode(RandomUtil.randomNumbers(8)); // 随机一个核销码,长度为 8 位 | ||
| 228 | + } | ||
| 245 | tradeOrderMapper.insert(order); | 229 | tradeOrderMapper.insert(order); |
| 246 | - // TODO @puhui999:如果是门店订单,则需要生成核销码; | ||
| 247 | return order; | 230 | return order; |
| 248 | } | 231 | } |
| 249 | 232 | ||
| 233 | + private List<TradeOrderItemDO> createTradeOrderItems(TradeOrderDO tradeOrderDO, | ||
| 234 | + TradePriceCalculateRespBO calculateRespBO) { | ||
| 235 | + List<TradeOrderItemDO> orderItems = TradeOrderConvert.INSTANCE.convertList(tradeOrderDO, calculateRespBO); | ||
| 236 | + tradeOrderItemMapper.insertBatch(orderItems); | ||
| 237 | + return orderItems; | ||
| 238 | + } | ||
| 239 | + | ||
| 250 | /** | 240 | /** |
| 251 | - * 校验活动,并返回订单类型 | 241 | + * 订单创建前,执行前置逻辑 |
| 252 | * | 242 | * |
| 253 | - * @param createReqVO 请求参数 | ||
| 254 | - * @return 订单类型 | 243 | + * @param userId 用户编号 |
| 244 | + * @param createReqVO 创建订单请求 | ||
| 245 | + * @param calculateRespBO 订单价格计算结果 | ||
| 255 | */ | 246 | */ |
| 256 | - private Integer validateActivity(AppTradeOrderCreateReqVO createReqVO) { | ||
| 257 | - if (createReqVO.getSeckillActivityId() != null) { | ||
| 258 | - return TradeOrderTypeEnum.SECKILL.getType(); | ||
| 259 | - } | ||
| 260 | - if (createReqVO.getCombinationActivityId() != null) { | ||
| 261 | - return TradeOrderTypeEnum.COMBINATION.getType(); | ||
| 262 | - } | ||
| 263 | - // TODO 砍价敬请期待 | ||
| 264 | - return TradeOrderTypeEnum.NORMAL.getType(); | ||
| 265 | - } | 247 | + private void beforeCreateTradeOrder(Long userId, AppTradeOrderCreateReqVO createReqVO, |
| 248 | + TradePriceCalculateRespBO calculateRespBO) { | ||
| 249 | + // 1. 执行订单创建前置处理器 | ||
| 250 | + TradeBeforeOrderCreateReqBO beforeOrderCreateReqBO = TradeOrderConvert.INSTANCE.convert(createReqVO); | ||
| 251 | + beforeOrderCreateReqBO.setOrderType(calculateRespBO.getType()); | ||
| 252 | + beforeOrderCreateReqBO.setUserId(userId); | ||
| 253 | + beforeOrderCreateReqBO.setCount(getSumValue(createReqVO.getItems(), AppTradeOrderSettlementReqVO.Item::getCount, Integer::sum)); | ||
| 254 | + // TODO @puhui999:这里有个纠结点;handler 的定义是只处理指定类型的订单的拓展逻辑;还是通用的 handler,类似可以处理优惠劵等等 | ||
| 255 | + tradeOrderHandlers.forEach(handler -> handler.beforeOrderCreate(beforeOrderCreateReqBO)); | ||
| 266 | 256 | ||
| 267 | - private List<TradeOrderItemDO> createTradeOrderItems(TradeOrderDO tradeOrderDO, TradePriceCalculateRespBO calculateRespBO) { | ||
| 268 | - List<TradeOrderItemDO> orderItems = TradeOrderConvert.INSTANCE.convertList(tradeOrderDO, calculateRespBO); | ||
| 269 | - tradeOrderItemMapper.insertBatch(orderItems); | ||
| 270 | - return orderItems; | 257 | + // 2. 下单时扣减商品库存 |
| 258 | + productSkuApi.updateSkuStock(TradeOrderConvert.INSTANCE.convertNegative(createReqVO.getItems())); | ||
| 271 | } | 259 | } |
| 272 | 260 | ||
| 273 | /** | 261 | /** |
| 274 | - * 执行创建完创建完订单后的逻辑 | 262 | + * 订单创建后,执行后置逻辑 |
| 275 | * | 263 | * |
| 276 | * 例如说:优惠劵的扣减、积分的扣减、支付单的创建等等 | 264 | * 例如说:优惠劵的扣减、积分的扣减、支付单的创建等等 |
| 277 | * | 265 | * |
| 278 | * @param userId 用户编号 | 266 | * @param userId 用户编号 |
| 279 | * @param createReqVO 创建订单请求 | 267 | * @param createReqVO 创建订单请求 |
| 280 | - * @param tradeOrderDO 交易订单 | 268 | + * @param order 交易订单 |
| 281 | * @param calculateRespBO 订单价格计算结果 | 269 | * @param calculateRespBO 订单价格计算结果 |
| 282 | */ | 270 | */ |
| 283 | private void afterCreateTradeOrder(Long userId, AppTradeOrderCreateReqVO createReqVO, | 271 | private void afterCreateTradeOrder(Long userId, AppTradeOrderCreateReqVO createReqVO, |
| 284 | - TradeOrderDO tradeOrderDO, List<TradeOrderItemDO> orderItems, | 272 | + TradeOrderDO order, List<TradeOrderItemDO> orderItems, |
| 285 | TradePriceCalculateRespBO calculateRespBO) { | 273 | TradePriceCalculateRespBO calculateRespBO) { |
| 286 | - // 执行订单创建后置处理器 | ||
| 287 | - tradeOrderHandlers.forEach(handler -> handler.afterOrderCreate(TradeOrderConvert.INSTANCE.convert(userId, createReqVO, tradeOrderDO, orderItems.get(0)))); | ||
| 288 | - | ||
| 289 | - // 扣减积分 TODO 芋艿:待实现,需要前置; | ||
| 290 | - // 这个是不是应该放到支付成功之后?如果支付后的话,可能积分可以重复使用哈。资源类,都要预扣 | 274 | + // 1. 执行订单创建后置处理器 |
| 275 | + // TODO @puhui999:从通用性来说,应该不用 orderItems.get(0) | ||
| 276 | + tradeOrderHandlers.forEach(handler -> handler.afterOrderCreate( | ||
| 277 | + TradeOrderConvert.INSTANCE.convert(userId, createReqVO, order, orderItems.get(0)))); | ||
| 291 | 278 | ||
| 292 | - // 有使用优惠券时更新 TODO 芋艿:需要前置; | 279 | + // 2. 有使用优惠券时更新 |
| 280 | + // 不在前置扣减的原因,是因为优惠劵要记录使用的订单号 | ||
| 293 | if (createReqVO.getCouponId() != null) { | 281 | if (createReqVO.getCouponId() != null) { |
| 294 | couponApi.useCoupon(new CouponUseReqDTO().setId(createReqVO.getCouponId()).setUserId(userId) | 282 | couponApi.useCoupon(new CouponUseReqDTO().setId(createReqVO.getCouponId()).setUserId(userId) |
| 295 | - .setOrderId(tradeOrderDO.getId())); | 283 | + .setOrderId(order.getId())); |
| 296 | } | 284 | } |
| 297 | 285 | ||
| 298 | - // 下单时扣减商品库存 | ||
| 299 | - productSkuApi.updateSkuStock(TradeOrderConvert.INSTANCE.convertNegative(orderItems)); | 286 | + // 3. 扣减积分 |
| 287 | + // 不在前置扣减的原因,是因为积分扣减时,需要记录关联业务 | ||
| 288 | + if (order.getUsePoint() != null && order.getUsePoint() > 0) { | ||
| 289 | + memberPointApi.reducePoint(userId, calculateRespBO.getUsePoint(), | ||
| 290 | + MemberPointBizTypeEnum.ORDER_USE.getType(), String.valueOf(order.getId())); | ||
| 291 | + } | ||
| 300 | 292 | ||
| 301 | - // 删除购物车商品 | 293 | + // 4. 删除购物车商品 |
| 302 | Set<Long> cartIds = convertSet(createReqVO.getItems(), AppTradeOrderSettlementReqVO.Item::getCartId); | 294 | Set<Long> cartIds = convertSet(createReqVO.getItems(), AppTradeOrderSettlementReqVO.Item::getCartId); |
| 303 | if (CollUtil.isNotEmpty(cartIds)) { | 295 | if (CollUtil.isNotEmpty(cartIds)) { |
| 304 | cartService.deleteCart(userId, cartIds); | 296 | cartService.deleteCart(userId, cartIds); |
| 305 | } | 297 | } |
| 306 | 298 | ||
| 307 | - // 生成预支付 | ||
| 308 | - createPayOrder(tradeOrderDO, orderItems, calculateRespBO); | 299 | + // 5. 生成预支付 |
| 300 | + createPayOrder(order, orderItems, calculateRespBO); | ||
| 309 | 301 | ||
| 310 | - // 增加订单日志 TODO 芋艿:待实现 | 302 | + // TODO @LeeYan9: 是可以思考下, 订单的营销优惠记录, 应该记录在哪里, 微信讨论起来! |
| 311 | } | 303 | } |
| 312 | 304 | ||
| 313 | - | ||
| 314 | - private void createPayOrder(TradeOrderDO order, List<TradeOrderItemDO> orderItems, TradePriceCalculateRespBO calculateRespBO) { | 305 | + private void createPayOrder(TradeOrderDO order, List<TradeOrderItemDO> orderItems, |
| 306 | + TradePriceCalculateRespBO calculateRespBO) { | ||
| 315 | // 创建支付单,用于后续的支付 | 307 | // 创建支付单,用于后续的支付 |
| 316 | PayOrderCreateReqDTO payOrderCreateReqDTO = TradeOrderConvert.INSTANCE.convert( | 308 | PayOrderCreateReqDTO payOrderCreateReqDTO = TradeOrderConvert.INSTANCE.convert( |
| 317 | order, orderItems, calculateRespBO, tradeOrderProperties); | 309 | order, orderItems, calculateRespBO, tradeOrderProperties); |
| @@ -339,6 +331,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { | @@ -339,6 +331,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { | ||
| 339 | } | 331 | } |
| 340 | // 校验活动 | 332 | // 校验活动 |
| 341 | // 1、拼团活动 | 333 | // 1、拼团活动 |
| 334 | + // TODO @puhui999:这块也抽象到 handler 里 | ||
| 342 | if (Objects.equals(TradeOrderTypeEnum.COMBINATION.getType(), order.getType())) { | 335 | if (Objects.equals(TradeOrderTypeEnum.COMBINATION.getType(), order.getType())) { |
| 343 | // 更新拼团状态 TODO puhui999:订单支付失败或订单支付过期删除这条拼团记录 | 336 | // 更新拼团状态 TODO puhui999:订单支付失败或订单支付过期删除这条拼团记录 |
| 344 | combinationRecordApi.updateRecordStatusToInProgress(order.getUserId(), order.getId(), LocalDateTime.now()); | 337 | combinationRecordApi.updateRecordStatusToInProgress(order.getUserId(), order.getId(), LocalDateTime.now()); |
| @@ -416,7 +409,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { | @@ -416,7 +409,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { | ||
| 416 | // 1.1 校验并获得交易订单(可发货) | 409 | // 1.1 校验并获得交易订单(可发货) |
| 417 | TradeOrderDO order = validateOrderDeliverable(deliveryReqVO.getId()); | 410 | TradeOrderDO order = validateOrderDeliverable(deliveryReqVO.getId()); |
| 418 | // 1.2 校验 deliveryType 是否为快递,是快递才可以发货 | 411 | // 1.2 校验 deliveryType 是否为快递,是快递才可以发货 |
| 419 | - if (ObjectUtil.notEqual(order.getDeliveryType(), DeliveryTypeEnum.EXPRESS.getMode())) { | 412 | + if (ObjectUtil.notEqual(order.getDeliveryType(), DeliveryTypeEnum.EXPRESS.getType())) { |
| 420 | throw exception(ORDER_DELIVERY_FAIL_DELIVERY_TYPE_NOT_EXPRESS); | 413 | throw exception(ORDER_DELIVERY_FAIL_DELIVERY_TYPE_NOT_EXPRESS); |
| 421 | } | 414 | } |
| 422 | 415 | ||
| @@ -726,7 +719,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { | @@ -726,7 +719,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { | ||
| 726 | } | 719 | } |
| 727 | 720 | ||
| 728 | // TODO 活动相关库存回滚需要活动 id,活动 id 怎么获取?app 端能否传过来 | 721 | // TODO 活动相关库存回滚需要活动 id,活动 id 怎么获取?app 端能否传过来 |
| 729 | - tradeOrderHandlers.forEach(handler -> handler.rollbackStock()); | 722 | + tradeOrderHandlers.forEach(handler -> handler.rollback()); |
| 730 | 723 | ||
| 731 | // 2.回滚库存 | 724 | // 2.回滚库存 |
| 732 | List<TradeOrderItemDO> orderItems = tradeOrderItemMapper.selectListByOrderId(id); | 725 | List<TradeOrderItemDO> orderItems = tradeOrderItemMapper.selectListByOrderId(id); |
| @@ -736,6 +729,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { | @@ -736,6 +729,7 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { | ||
| 736 | couponApi.returnUsedCoupon(order.getCouponId()); | 729 | couponApi.returnUsedCoupon(order.getCouponId()); |
| 737 | 730 | ||
| 738 | // 4.回滚积分:积分是支付成功后才增加的吧? 回复:每个项目不同,目前看下来,确认收货貌似更合适,我再看看其它项目的业务选择; | 731 | // 4.回滚积分:积分是支付成功后才增加的吧? 回复:每个项目不同,目前看下来,确认收货貌似更合适,我再看看其它项目的业务选择; |
| 732 | + // TODO @疯狂:有赞是可配置(支付 or 确认收货),我们按照支付好列;然后这里的退积分,指的是下单时的积分抵扣。 | ||
| 739 | 733 | ||
| 740 | // TODO 芋艿:OrderLog | 734 | // TODO 芋艿:OrderLog |
| 741 | 735 | ||
| @@ -768,22 +762,26 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { | @@ -768,22 +762,26 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { | ||
| 768 | 762 | ||
| 769 | @Async | 763 | @Async |
| 770 | protected void addUserPointAsync(Long userId, Integer payPrice, Long orderId) { | 764 | protected void addUserPointAsync(Long userId, Integer payPrice, Long orderId) { |
| 771 | - int bizType = MemberPointBizTypeEnum.ORDER_BUY.getType(); | 765 | + // TODO @疯狂:具体多少积分,需要分成 2 不分:1. 支付金额;2. 商品金额 |
| 766 | + int bizType = MemberPointBizTypeEnum.ORDER_REWARD.getType(); | ||
| 772 | memberPointApi.addPoint(userId, payPrice, bizType, String.valueOf(orderId)); | 767 | memberPointApi.addPoint(userId, payPrice, bizType, String.valueOf(orderId)); |
| 773 | } | 768 | } |
| 774 | 769 | ||
| 775 | @Async | 770 | @Async |
| 776 | protected void reduceUserPointAsync(Long userId, Integer refundPrice, Long afterSaleId) { | 771 | protected void reduceUserPointAsync(Long userId, Integer refundPrice, Long afterSaleId) { |
| 772 | + // TODO @疯狂:退款时,按照金额比例,退还积分;https://help.youzan.com/displaylist/detail_4_4-1-49185 | ||
| 777 | int bizType = MemberPointBizTypeEnum.ORDER_CANCEL.getType(); | 773 | int bizType = MemberPointBizTypeEnum.ORDER_CANCEL.getType(); |
| 778 | memberPointApi.addPoint(userId, -refundPrice, bizType, String.valueOf(afterSaleId)); | 774 | memberPointApi.addPoint(userId, -refundPrice, bizType, String.valueOf(afterSaleId)); |
| 779 | } | 775 | } |
| 780 | 776 | ||
| 781 | - | ||
| 782 | @Async | 777 | @Async |
| 783 | protected void addBrokerageAsync(Long userId, Long orderId) { | 778 | protected void addBrokerageAsync(Long userId, Long orderId) { |
| 779 | + MemberUserRespDTO user = memberUserApi.getUser(userId); | ||
| 780 | + Assert.notNull(user); | ||
| 781 | + | ||
| 784 | List<TradeOrderItemDO> orderItems = tradeOrderItemMapper.selectListByOrderId(orderId); | 782 | List<TradeOrderItemDO> orderItems = tradeOrderItemMapper.selectListByOrderId(orderId); |
| 785 | List<BrokerageAddReqBO> list = convertList(orderItems, | 783 | List<BrokerageAddReqBO> list = convertList(orderItems, |
| 786 | - item -> TradeOrderConvert.INSTANCE.convert(item, productSkuApi.getSku(item.getSkuId()))); | 784 | + item -> TradeOrderConvert.INSTANCE.convert(user, item, productSkuApi.getSku(item.getSkuId()))); |
| 787 | brokerageRecordService.addBrokerage(userId, BrokerageRecordBizTypeEnum.ORDER, list); | 785 | brokerageRecordService.addBrokerage(userId, BrokerageRecordBizTypeEnum.ORDER, list); |
| 788 | } | 786 | } |
| 789 | 787 |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/bo/TradeBeforeOrderCreateReqBO.java
| @@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.trade.service.order.bo; | @@ -3,7 +3,6 @@ package cn.iocoder.yudao.module.trade.service.order.bo; | ||
| 3 | import io.swagger.v3.oas.annotations.media.Schema; | 3 | import io.swagger.v3.oas.annotations.media.Schema; |
| 4 | import lombok.Data; | 4 | import lombok.Data; |
| 5 | 5 | ||
| 6 | -import javax.validation.Valid; | ||
| 7 | import javax.validation.constraints.NotNull; | 6 | import javax.validation.constraints.NotNull; |
| 8 | 7 | ||
| 9 | // TODO 芋艿:在想想这些参数的定义 | 8 | // TODO 芋艿:在想想这些参数的定义 |
| @@ -15,6 +14,8 @@ import javax.validation.constraints.NotNull; | @@ -15,6 +14,8 @@ import javax.validation.constraints.NotNull; | ||
| 15 | @Data | 14 | @Data |
| 16 | public class TradeBeforeOrderCreateReqBO { | 15 | public class TradeBeforeOrderCreateReqBO { |
| 17 | 16 | ||
| 17 | + // TODO @puhui999:注释也写下哈;bo 还是写注释噢 | ||
| 18 | + | ||
| 18 | @NotNull(message = "订单类型不能为空") | 19 | @NotNull(message = "订单类型不能为空") |
| 19 | private Integer orderType; | 20 | private Integer orderType; |
| 20 | 21 | ||
| @@ -34,25 +35,16 @@ public class TradeBeforeOrderCreateReqBO { | @@ -34,25 +35,16 @@ public class TradeBeforeOrderCreateReqBO { | ||
| 34 | @Schema(description = "砍价活动编号", example = "123") | 35 | @Schema(description = "砍价活动编号", example = "123") |
| 35 | private Long bargainActivityId; | 36 | private Long bargainActivityId; |
| 36 | 37 | ||
| 37 | - @NotNull(message = "购买数量不能为空") | ||
| 38 | - private Integer count; | ||
| 39 | - | ||
| 40 | - @NotNull(message = "活动商品不能为空") | ||
| 41 | - private Item item; | 38 | + @NotNull(message = "SPU 编号不能为空") |
| 39 | + private Long spuId; | ||
| 42 | 40 | ||
| 43 | - @Data | ||
| 44 | - @Valid | ||
| 45 | - public static class Item { | 41 | + @NotNull(message = "SKU 编号活动商品不能为空") |
| 42 | + private Long skuId; | ||
| 46 | 43 | ||
| 47 | - @NotNull(message = "SPU 编号不能为空") | ||
| 48 | - private Long spuId; | 44 | + @NotNull(message = "用户编号不能为空") |
| 45 | + private Long userId; | ||
| 49 | 46 | ||
| 50 | - @NotNull(message = "SKU 编号活动商品不能为空") | ||
| 51 | - private Long skuId; | ||
| 52 | - | ||
| 53 | - @NotNull(message = "购买数量不能为空") | ||
| 54 | - private Integer count; | ||
| 55 | - | ||
| 56 | - } | 47 | + @NotNull(message = "购买数量不能为空") |
| 48 | + private Integer count; | ||
| 57 | 49 | ||
| 58 | } | 50 | } |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/handler/TradeBargainHandler.java
| @@ -22,7 +22,7 @@ public class TradeBargainHandler implements TradeOrderHandler { | @@ -22,7 +22,7 @@ public class TradeBargainHandler implements TradeOrderHandler { | ||
| 22 | 22 | ||
| 23 | @Override | 23 | @Override |
| 24 | public void beforeOrderCreate(TradeBeforeOrderCreateReqBO reqBO) { | 24 | public void beforeOrderCreate(TradeBeforeOrderCreateReqBO reqBO) { |
| 25 | - // 如果是秒杀订单 | 25 | + // 如果是砍价订单 |
| 26 | if (ObjectUtil.notEqual(TradeOrderTypeEnum.BARGAIN.getType(), reqBO.getOrderType())) { | 26 | if (ObjectUtil.notEqual(TradeOrderTypeEnum.BARGAIN.getType(), reqBO.getOrderType())) { |
| 27 | return; | 27 | return; |
| 28 | } | 28 | } |
| @@ -37,7 +37,7 @@ public class TradeBargainHandler implements TradeOrderHandler { | @@ -37,7 +37,7 @@ public class TradeBargainHandler implements TradeOrderHandler { | ||
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | @Override | 39 | @Override |
| 40 | - public void rollbackStock() { | 40 | + public void rollback() { |
| 41 | 41 | ||
| 42 | } | 42 | } |
| 43 | 43 |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/handler/TradeCombinationHandler.java
| 1 | package cn.iocoder.yudao.module.trade.service.order.handler; | 1 | package cn.iocoder.yudao.module.trade.service.order.handler; |
| 2 | 2 | ||
| 3 | import cn.hutool.core.util.ObjectUtil; | 3 | import cn.hutool.core.util.ObjectUtil; |
| 4 | -import cn.iocoder.yudao.module.promotion.api.combination.CombinationApi; | 4 | +import cn.iocoder.yudao.module.promotion.api.combination.CombinationActivityApi; |
| 5 | import cn.iocoder.yudao.module.promotion.api.combination.CombinationRecordApi; | 5 | import cn.iocoder.yudao.module.promotion.api.combination.CombinationRecordApi; |
| 6 | import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert; | 6 | import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert; |
| 7 | import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum; | 7 | import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum; |
| @@ -20,7 +20,7 @@ import javax.annotation.Resource; | @@ -20,7 +20,7 @@ import javax.annotation.Resource; | ||
| 20 | public class TradeCombinationHandler implements TradeOrderHandler { | 20 | public class TradeCombinationHandler implements TradeOrderHandler { |
| 21 | 21 | ||
| 22 | @Resource | 22 | @Resource |
| 23 | - private CombinationApi combinationApi; | 23 | + private CombinationActivityApi combinationActivityApi; |
| 24 | @Resource | 24 | @Resource |
| 25 | private CombinationRecordApi combinationRecordApi; | 25 | private CombinationRecordApi combinationRecordApi; |
| 26 | 26 | ||
| @@ -32,17 +32,22 @@ public class TradeCombinationHandler implements TradeOrderHandler { | @@ -32,17 +32,22 @@ public class TradeCombinationHandler implements TradeOrderHandler { | ||
| 32 | } | 32 | } |
| 33 | 33 | ||
| 34 | // 校验是否满足拼团活动相关限制 | 34 | // 校验是否满足拼团活动相关限制 |
| 35 | - combinationApi.validateCombination(TradeOrderConvert.INSTANCE.convert1(reqBO)); | 35 | + combinationActivityApi.validateCombination(reqBO.getCombinationActivityId(), reqBO.getUserId(), reqBO.getSkuId(), reqBO.getCount()); |
| 36 | } | 36 | } |
| 37 | 37 | ||
| 38 | @Override | 38 | @Override |
| 39 | public void afterOrderCreate(TradeAfterOrderCreateReqBO reqBO) { | 39 | public void afterOrderCreate(TradeAfterOrderCreateReqBO reqBO) { |
| 40 | + // TODO @puhui999:需要判断下; | ||
| 41 | + if (true) { | ||
| 42 | + return; | ||
| 43 | + } | ||
| 44 | + | ||
| 40 | // 创建砍价记录 | 45 | // 创建砍价记录 |
| 41 | combinationRecordApi.createCombinationRecord(TradeOrderConvert.INSTANCE.convert(reqBO)); | 46 | combinationRecordApi.createCombinationRecord(TradeOrderConvert.INSTANCE.convert(reqBO)); |
| 42 | } | 47 | } |
| 43 | 48 | ||
| 44 | @Override | 49 | @Override |
| 45 | - public void rollbackStock() { | 50 | + public void rollback() { |
| 46 | 51 | ||
| 47 | } | 52 | } |
| 48 | 53 |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/handler/TradeOrderHandler.java
| @@ -25,8 +25,8 @@ public interface TradeOrderHandler { | @@ -25,8 +25,8 @@ public interface TradeOrderHandler { | ||
| 25 | void afterOrderCreate(TradeAfterOrderCreateReqBO reqBO); | 25 | void afterOrderCreate(TradeAfterOrderCreateReqBO reqBO); |
| 26 | 26 | ||
| 27 | /** | 27 | /** |
| 28 | - * 回滚活动相关库存 | 28 | + * 回滚 |
| 29 | */ | 29 | */ |
| 30 | - void rollbackStock(); | 30 | + void rollback(); |
| 31 | 31 | ||
| 32 | } | 32 | } |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/handler/TradeSeckillHandler.java
| @@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.trade.service.order.handler; | @@ -2,7 +2,6 @@ package cn.iocoder.yudao.module.trade.service.order.handler; | ||
| 2 | 2 | ||
| 3 | import cn.hutool.core.util.ObjectUtil; | 3 | import cn.hutool.core.util.ObjectUtil; |
| 4 | import cn.iocoder.yudao.module.promotion.api.seckill.SeckillActivityApi; | 4 | import cn.iocoder.yudao.module.promotion.api.seckill.SeckillActivityApi; |
| 5 | -import cn.iocoder.yudao.module.trade.convert.order.TradeOrderConvert; | ||
| 6 | import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum; | 5 | import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum; |
| 7 | import cn.iocoder.yudao.module.trade.service.order.bo.TradeAfterOrderCreateReqBO; | 6 | import cn.iocoder.yudao.module.trade.service.order.bo.TradeAfterOrderCreateReqBO; |
| 8 | import cn.iocoder.yudao.module.trade.service.order.bo.TradeBeforeOrderCreateReqBO; | 7 | import cn.iocoder.yudao.module.trade.service.order.bo.TradeBeforeOrderCreateReqBO; |
| @@ -28,7 +27,7 @@ public class TradeSeckillHandler implements TradeOrderHandler { | @@ -28,7 +27,7 @@ public class TradeSeckillHandler implements TradeOrderHandler { | ||
| 28 | return; | 27 | return; |
| 29 | } | 28 | } |
| 30 | 29 | ||
| 31 | - seckillActivityApi.updateSeckillStock(TradeOrderConvert.INSTANCE.convert(reqBO)); | 30 | + seckillActivityApi.updateSeckillStock(reqBO.getSeckillActivityId(), reqBO.getSkuId(), reqBO.getCount()); |
| 32 | } | 31 | } |
| 33 | 32 | ||
| 34 | @Override | 33 | @Override |
| @@ -37,7 +36,7 @@ public class TradeSeckillHandler implements TradeOrderHandler { | @@ -37,7 +36,7 @@ public class TradeSeckillHandler implements TradeOrderHandler { | ||
| 37 | } | 36 | } |
| 38 | 37 | ||
| 39 | @Override | 38 | @Override |
| 40 | - public void rollbackStock() { | 39 | + public void rollback() { |
| 41 | 40 | ||
| 42 | } | 41 | } |
| 43 | 42 |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateReqBO.java
| 1 | package cn.iocoder.yudao.module.trade.service.price.bo; | 1 | package cn.iocoder.yudao.module.trade.service.price.bo; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryTypeEnum; | 3 | import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryTypeEnum; |
| 4 | -import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum; | ||
| 5 | import lombok.Data; | 4 | import lombok.Data; |
| 6 | 5 | ||
| 7 | import javax.validation.Valid; | 6 | import javax.validation.Valid; |
| @@ -18,13 +17,6 @@ import java.util.List; | @@ -18,13 +17,6 @@ import java.util.List; | ||
| 18 | public class TradePriceCalculateReqBO { | 17 | public class TradePriceCalculateReqBO { |
| 19 | 18 | ||
| 20 | /** | 19 | /** |
| 21 | - * 订单类型 | ||
| 22 | - * | ||
| 23 | - * 枚举 {@link TradeOrderTypeEnum} | ||
| 24 | - */ | ||
| 25 | - private Integer type; | ||
| 26 | - | ||
| 27 | - /** | ||
| 28 | * 用户编号 | 20 | * 用户编号 |
| 29 | * | 21 | * |
| 30 | * 对应 MemberUserDO 的 id 编号 | 22 | * 对应 MemberUserDO 的 id 编号 |
| @@ -37,20 +29,31 @@ public class TradePriceCalculateReqBO { | @@ -37,20 +29,31 @@ public class TradePriceCalculateReqBO { | ||
| 37 | * 对应 CouponDO 的 id 编号 | 29 | * 对应 CouponDO 的 id 编号 |
| 38 | */ | 30 | */ |
| 39 | private Long couponId; | 31 | private Long couponId; |
| 32 | + // TODO @疯狂:需要增加一个 PriceCalculator 实现积分扣减的计算;写回到 TradePriceCalculateRespBO 的 usePoint | ||
| 33 | + /** | ||
| 34 | + * 是否使用积分 | ||
| 35 | + */ | ||
| 36 | + @NotNull(message = "是否使用积分不能为空") | ||
| 37 | + private Boolean pointStatus; | ||
| 40 | 38 | ||
| 41 | /** | 39 | /** |
| 40 | + * 配送方式 | ||
| 41 | + * | ||
| 42 | + * 枚举 {@link DeliveryTypeEnum} | ||
| 43 | + */ | ||
| 44 | + private Integer deliveryType; | ||
| 45 | + /** | ||
| 42 | * 收货地址编号 | 46 | * 收货地址编号 |
| 43 | * | 47 | * |
| 44 | * 对应 MemberAddressDO 的 id 编号 | 48 | * 对应 MemberAddressDO 的 id 编号 |
| 45 | */ | 49 | */ |
| 46 | private Long addressId; | 50 | private Long addressId; |
| 47 | - | ||
| 48 | /** | 51 | /** |
| 49 | - * 配送方式 | 52 | + * 自提门店编号 |
| 50 | * | 53 | * |
| 51 | - * 枚举 {@link DeliveryTypeEnum} | 54 | + * 对应 PickUpStoreDO 的 id 编号 |
| 52 | */ | 55 | */ |
| 53 | - private Integer deliveryType; | 56 | + private Long pickUpStoreId; |
| 54 | 57 | ||
| 55 | /** | 58 | /** |
| 56 | * 商品 SKU 数组 | 59 | * 商品 SKU 数组 |
| @@ -58,6 +61,30 @@ public class TradePriceCalculateReqBO { | @@ -58,6 +61,30 @@ public class TradePriceCalculateReqBO { | ||
| 58 | @NotNull(message = "商品数组不能为空") | 61 | @NotNull(message = "商品数组不能为空") |
| 59 | private List<Item> items; | 62 | private List<Item> items; |
| 60 | 63 | ||
| 64 | + // ========== 秒杀活动相关字段 ========== | ||
| 65 | + /** | ||
| 66 | + * 秒杀活动编号 | ||
| 67 | + */ | ||
| 68 | + private Long seckillActivityId; | ||
| 69 | + | ||
| 70 | + // ========== 拼团活动相关字段 ========== | ||
| 71 | + // TODO @puhui999:是不是拼团记录的编号哈? | ||
| 72 | + /** | ||
| 73 | + * 拼团活动编号 | ||
| 74 | + */ | ||
| 75 | + private Long combinationActivityId; | ||
| 76 | + | ||
| 77 | + /** | ||
| 78 | + * 拼团团长编号 | ||
| 79 | + */ | ||
| 80 | + private Long combinationHeadId; | ||
| 81 | + | ||
| 82 | + // ========== 砍价活动相关字段 ========== | ||
| 83 | + /** | ||
| 84 | + * 砍价活动编号 | ||
| 85 | + */ | ||
| 86 | + private Long bargainActivityId; | ||
| 87 | + | ||
| 61 | /** | 88 | /** |
| 62 | * 商品 SKU | 89 | * 商品 SKU |
| 63 | */ | 90 | */ |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/bo/TradePriceCalculateRespBO.java
| @@ -49,6 +49,11 @@ public class TradePriceCalculateRespBO { | @@ -49,6 +49,11 @@ public class TradePriceCalculateRespBO { | ||
| 49 | private Long couponId; | 49 | private Long couponId; |
| 50 | 50 | ||
| 51 | /** | 51 | /** |
| 52 | + * 使用的积分 | ||
| 53 | + */ | ||
| 54 | + private Integer usePoint; | ||
| 55 | + | ||
| 56 | + /** | ||
| 52 | * 订单价格 | 57 | * 订单价格 |
| 53 | */ | 58 | */ |
| 54 | @Data | 59 | @Data |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculator.java
| @@ -2,11 +2,14 @@ package cn.iocoder.yudao.module.trade.service.price.calculator; | @@ -2,11 +2,14 @@ package cn.iocoder.yudao.module.trade.service.price.calculator; | ||
| 2 | 2 | ||
| 3 | import cn.hutool.core.collection.CollUtil; | 3 | import cn.hutool.core.collection.CollUtil; |
| 4 | import cn.hutool.core.lang.Assert; | 4 | import cn.hutool.core.lang.Assert; |
| 5 | +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | ||
| 5 | import cn.iocoder.yudao.module.member.api.address.AddressApi; | 6 | import cn.iocoder.yudao.module.member.api.address.AddressApi; |
| 6 | import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO; | 7 | import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO; |
| 8 | +import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryPickUpStoreDO; | ||
| 7 | import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryExpressChargeModeEnum; | 9 | import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryExpressChargeModeEnum; |
| 8 | import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryTypeEnum; | 10 | import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryTypeEnum; |
| 9 | import cn.iocoder.yudao.module.trade.service.delivery.DeliveryExpressTemplateService; | 11 | import cn.iocoder.yudao.module.trade.service.delivery.DeliveryExpressTemplateService; |
| 12 | +import cn.iocoder.yudao.module.trade.service.delivery.DeliveryPickUpStoreService; | ||
| 10 | import cn.iocoder.yudao.module.trade.service.delivery.bo.DeliveryExpressTemplateRespBO; | 13 | import cn.iocoder.yudao.module.trade.service.delivery.bo.DeliveryExpressTemplateRespBO; |
| 11 | import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; | 14 | import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; |
| 12 | import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; | 15 | import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; |
| @@ -22,8 +25,7 @@ import java.util.Set; | @@ -22,8 +25,7 @@ import java.util.Set; | ||
| 22 | 25 | ||
| 23 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | 26 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 24 | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; | 27 | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; |
| 25 | -import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.PRICE_CALCULATE_DELIVERY_PRICE_USER_ADDR_IS_EMPTY; | ||
| 26 | -import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.PRICE_CALCULATE_DELIVERY_PRICE_TEMPLATE_NOT_FOUND; | 28 | +import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.*; |
| 27 | 29 | ||
| 28 | /** | 30 | /** |
| 29 | * 运费的 {@link TradePriceCalculator} 实现类 | 31 | * 运费的 {@link TradePriceCalculator} 实现类 |
| @@ -37,20 +39,41 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator { | @@ -37,20 +39,41 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator { | ||
| 37 | 39 | ||
| 38 | @Resource | 40 | @Resource |
| 39 | private AddressApi addressApi; | 41 | private AddressApi addressApi; |
| 42 | + | ||
| 43 | + @Resource | ||
| 44 | + private DeliveryPickUpStoreService deliveryPickUpStoreService; | ||
| 40 | @Resource | 45 | @Resource |
| 41 | private DeliveryExpressTemplateService deliveryExpressTemplateService; | 46 | private DeliveryExpressTemplateService deliveryExpressTemplateService; |
| 42 | 47 | ||
| 43 | @Override | 48 | @Override |
| 44 | public void calculate(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result) { | 49 | public void calculate(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result) { |
| 45 | - // TODO @芋艿:如果门店自提,需要校验是否开启; | ||
| 46 | - // 1.1 判断配送方式 | ||
| 47 | - if (param.getDeliveryType() == null || DeliveryTypeEnum.PICK_UP.getMode().equals(param.getDeliveryType())) { | 50 | + if (param.getDeliveryType() == null) { |
| 48 | return; | 51 | return; |
| 49 | } | 52 | } |
| 53 | + if (DeliveryTypeEnum.PICK_UP.getType().equals(param.getDeliveryType())) { | ||
| 54 | + calculateByPickUp(param, result); | ||
| 55 | + } else if (DeliveryTypeEnum.EXPRESS.getType().equals(param.getDeliveryType())) { | ||
| 56 | + calculateExpress(param, result); | ||
| 57 | + } | ||
| 58 | + } | ||
| 59 | + | ||
| 60 | + private void calculateByPickUp(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result) { | ||
| 61 | + if (param.getPickUpStoreId() == null) { | ||
| 62 | + throw exception(PRICE_CALCULATE_DELIVERY_PRICE_PICK_UP_STORE_IS_EMPTY); | ||
| 63 | + } | ||
| 64 | + DeliveryPickUpStoreDO pickUpStore = deliveryPickUpStoreService.getDeliveryPickUpStore(param.getPickUpStoreId()); | ||
| 65 | + if (pickUpStore == null || CommonStatusEnum.DISABLE.getStatus().equals(pickUpStore.getStatus())) { | ||
| 66 | + throw exception(PICK_UP_STORE_NOT_EXISTS); | ||
| 67 | + } | ||
| 68 | + } | ||
| 69 | + | ||
| 70 | + // ========= 快递发货 ========== | ||
| 71 | + | ||
| 72 | + private void calculateExpress(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result) { | ||
| 73 | + // 1. 得到收件地址区域 | ||
| 50 | if (param.getAddressId() == null) { | 74 | if (param.getAddressId() == null) { |
| 51 | - throw exception(PRICE_CALCULATE_DELIVERY_PRICE_USER_ADDR_IS_EMPTY); | 75 | + throw exception(PRICE_CALCULATE_DELIVERY_PRICE_USER_ADDRESS_IS_EMPTY); |
| 52 | } | 76 | } |
| 53 | - // 1.2 得到收件地址区域 | ||
| 54 | AddressRespDTO address = addressApi.getAddress(param.getAddressId(), param.getUserId()); | 77 | AddressRespDTO address = addressApi.getAddress(param.getAddressId(), param.getUserId()); |
| 55 | Assert.notNull(address, "收件人({})的地址,不能为空", param.getUserId()); | 78 | Assert.notNull(address, "收件人({})的地址,不能为空", param.getUserId()); |
| 56 | 79 | ||
| @@ -89,8 +112,12 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator { | @@ -89,8 +112,12 @@ public class TradeDeliveryPriceCalculator implements TradePriceCalculator { | ||
| 89 | for (OrderItem orderItem : orderItems) { | 112 | for (OrderItem orderItem : orderItems) { |
| 90 | totalCount += orderItem.getCount(); | 113 | totalCount += orderItem.getCount(); |
| 91 | totalPrice += orderItem.getPayPrice(); | 114 | totalPrice += orderItem.getPayPrice(); |
| 92 | - totalWeight += totalWeight + orderItem.getWeight() * orderItem.getCount(); | ||
| 93 | - totalVolume += totalVolume + orderItem.getVolume() * orderItem.getCount(); | 115 | + if (orderItem.getWeight() != null) { |
| 116 | + totalWeight += totalWeight + orderItem.getWeight() * orderItem.getCount(); | ||
| 117 | + } | ||
| 118 | + if (orderItem.getVolume() != null) { | ||
| 119 | + totalVolume += totalVolume + orderItem.getVolume() * orderItem.getCount(); | ||
| 120 | + } | ||
| 94 | } | 121 | } |
| 95 | // 优先判断是否包邮. 如果包邮不计算快递运费 | 122 | // 优先判断是否包邮. 如果包邮不计算快递运费 |
| 96 | if (isExpressFree(templateBO.getChargeMode(), totalCount, totalWeight, | 123 | if (isExpressFree(templateBO.getChargeMode(), totalCount, totalWeight, |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePointUsePriceCalculator.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.trade.service.price.calculator; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; | ||
| 4 | +import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; | ||
| 5 | +import lombok.extern.slf4j.Slf4j; | ||
| 6 | +import org.springframework.core.annotation.Order; | ||
| 7 | +import org.springframework.stereotype.Component; | ||
| 8 | + | ||
| 9 | +/** | ||
| 10 | + * 使用积分的 {@link TradePriceCalculator} 实现类 | ||
| 11 | + * | ||
| 12 | + * @author owen | ||
| 13 | + */ | ||
| 14 | +@Component | ||
| 15 | +@Order(TradePriceCalculator.ORDER_POINT_USE) | ||
| 16 | +@Slf4j | ||
| 17 | +public class TradePointUsePriceCalculator implements TradePriceCalculator { | ||
| 18 | + | ||
| 19 | + @Override | ||
| 20 | + public void calculate(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result) { | ||
| 21 | + // TODO 疯狂:待实现,嘿嘿; | ||
| 22 | + if (param.getPointStatus()) { | ||
| 23 | + result.setUsePoint(10); | ||
| 24 | + } else { | ||
| 25 | + result.setUsePoint(0); | ||
| 26 | + } | ||
| 27 | + } | ||
| 28 | + | ||
| 29 | +} |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculator.java
| @@ -6,6 +6,9 @@ import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; | @@ -6,6 +6,9 @@ import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; | ||
| 6 | /** | 6 | /** |
| 7 | * 价格计算的计算器接口 | 7 | * 价格计算的计算器接口 |
| 8 | * | 8 | * |
| 9 | + * 优惠计算顺序: | ||
| 10 | + * 1. <a href="https://help.youzan.com/displaylist/detail_4_4-1-53316">积分抵现、会员价、优惠券、粉丝专享价、满减送哪个优先计算?</> | ||
| 11 | + * | ||
| 9 | * @author 芋道源码 | 12 | * @author 芋道源码 |
| 10 | */ | 13 | */ |
| 11 | public interface TradePriceCalculator { | 14 | public interface TradePriceCalculator { |
| @@ -13,12 +16,13 @@ public interface TradePriceCalculator { | @@ -13,12 +16,13 @@ public interface TradePriceCalculator { | ||
| 13 | int ORDER_DISCOUNT_ACTIVITY = 10; | 16 | int ORDER_DISCOUNT_ACTIVITY = 10; |
| 14 | int ORDER_REWARD_ACTIVITY = 20; | 17 | int ORDER_REWARD_ACTIVITY = 20; |
| 15 | int ORDER_COUPON = 30; | 18 | int ORDER_COUPON = 30; |
| 19 | + int ORDER_POINT_USE = 40; | ||
| 16 | /** | 20 | /** |
| 17 | * 快递运费的计算 | 21 | * 快递运费的计算 |
| 18 | * | 22 | * |
| 19 | * 放在各种营销活动、优惠劵后面 TODO | 23 | * 放在各种营销活动、优惠劵后面 TODO |
| 20 | */ | 24 | */ |
| 21 | - int ORDER_DELIVERY = 40; | 25 | + int ORDER_DELIVERY = 50; |
| 22 | 26 | ||
| 23 | void calculate(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result); | 27 | void calculate(TradePriceCalculateReqBO param, TradePriceCalculateRespBO result); |
| 24 | 28 |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradePriceCalculatorHelper.java
| @@ -4,6 +4,7 @@ import cn.hutool.core.lang.Assert; | @@ -4,6 +4,7 @@ import cn.hutool.core.lang.Assert; | ||
| 4 | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | 4 | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; |
| 5 | import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; | 5 | import cn.iocoder.yudao.module.product.api.sku.dto.ProductSkuRespDTO; |
| 6 | import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; | 6 | import cn.iocoder.yudao.module.product.api.spu.dto.ProductSpuRespDTO; |
| 7 | +import cn.iocoder.yudao.module.trade.enums.order.TradeOrderTypeEnum; | ||
| 7 | import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; | 8 | import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO; |
| 8 | import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; | 9 | import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO; |
| 9 | 10 | ||
| @@ -28,7 +29,7 @@ public class TradePriceCalculatorHelper { | @@ -28,7 +29,7 @@ public class TradePriceCalculatorHelper { | ||
| 28 | List<ProductSpuRespDTO> spuList, List<ProductSkuRespDTO> skuList) { | 29 | List<ProductSpuRespDTO> spuList, List<ProductSkuRespDTO> skuList) { |
| 29 | // 创建 PriceCalculateRespDTO 对象 | 30 | // 创建 PriceCalculateRespDTO 对象 |
| 30 | TradePriceCalculateRespBO result = new TradePriceCalculateRespBO(); | 31 | TradePriceCalculateRespBO result = new TradePriceCalculateRespBO(); |
| 31 | - result.setType(param.getType()); | 32 | + result.setType(getOrderType(param)); |
| 32 | result.setPromotions(new ArrayList<>()); | 33 | result.setPromotions(new ArrayList<>()); |
| 33 | 34 | ||
| 34 | // 创建它的 OrderItem 属性 | 35 | // 创建它的 OrderItem 属性 |
| @@ -70,6 +71,23 @@ public class TradePriceCalculatorHelper { | @@ -70,6 +71,23 @@ public class TradePriceCalculatorHelper { | ||
| 70 | } | 71 | } |
| 71 | 72 | ||
| 72 | /** | 73 | /** |
| 74 | + * 计算订单类型 | ||
| 75 | + * | ||
| 76 | + * @param param 计算参数 | ||
| 77 | + * @return 订单类型 | ||
| 78 | + */ | ||
| 79 | + private static Integer getOrderType(TradePriceCalculateReqBO param) { | ||
| 80 | + if (param.getSeckillActivityId() != null) { | ||
| 81 | + return TradeOrderTypeEnum.SECKILL.getType(); | ||
| 82 | + } | ||
| 83 | + if (param.getCombinationActivityId() != null) { | ||
| 84 | + return TradeOrderTypeEnum.COMBINATION.getType(); | ||
| 85 | + } | ||
| 86 | + // TODO 砍价敬请期待 | ||
| 87 | + return TradeOrderTypeEnum.NORMAL.getType(); | ||
| 88 | + } | ||
| 89 | + | ||
| 90 | + /** | ||
| 73 | * 基于订单项,重新计算 price 总价 | 91 | * 基于订单项,重新计算 price 总价 |
| 74 | * | 92 | * |
| 75 | * @param result 计算结果 | 93 | * @param result 计算结果 |
yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/TradePriceServiceImplTest.java
| @@ -45,7 +45,7 @@ public class TradePriceServiceImplTest extends BaseMockitoUnitTest { | @@ -45,7 +45,7 @@ public class TradePriceServiceImplTest extends BaseMockitoUnitTest { | ||
| 45 | public void testCalculatePrice() { | 45 | public void testCalculatePrice() { |
| 46 | // 准备参数 | 46 | // 准备参数 |
| 47 | TradePriceCalculateReqBO calculateReqBO = new TradePriceCalculateReqBO() | 47 | TradePriceCalculateReqBO calculateReqBO = new TradePriceCalculateReqBO() |
| 48 | - .setType(TradeOrderTypeEnum.NORMAL.getType()).setUserId(10L) | 48 | + .setUserId(10L) |
| 49 | .setCouponId(20L).setAddressId(30L) | 49 | .setCouponId(20L).setAddressId(30L) |
| 50 | .setItems(Arrays.asList( | 50 | .setItems(Arrays.asList( |
| 51 | new TradePriceCalculateReqBO.Item().setSkuId(100L).setCount(1).setSelected(true), | 51 | new TradePriceCalculateReqBO.Item().setSkuId(100L).setCount(1).setSelected(true), |
yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/price/calculator/TradeDeliveryPriceCalculatorTest.java
| @@ -50,7 +50,7 @@ public class TradeDeliveryPriceCalculatorTest extends BaseMockitoUnitTest { | @@ -50,7 +50,7 @@ public class TradeDeliveryPriceCalculatorTest extends BaseMockitoUnitTest { | ||
| 50 | public void init(){ | 50 | public void init(){ |
| 51 | // 准备参数 | 51 | // 准备参数 |
| 52 | reqBO = new TradePriceCalculateReqBO() | 52 | reqBO = new TradePriceCalculateReqBO() |
| 53 | - .setDeliveryType(DeliveryTypeEnum.EXPRESS.getMode()) | 53 | + .setDeliveryType(DeliveryTypeEnum.EXPRESS.getType()) |
| 54 | .setAddressId(10L) | 54 | .setAddressId(10L) |
| 55 | .setUserId(1L) | 55 | .setUserId(1L) |
| 56 | .setItems(asList( | 56 | .setItems(asList( |
yudao-module-mall/yudao-module-trade-biz/src/test/java/cn/iocoder/yudao/module/trade/service/withdraw/BrokerageWithdrawServiceImplTest.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.trade.service.withdraw; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||
| 4 | +import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; | ||
| 5 | +import cn.iocoder.yudao.module.trade.controller.admin.brokerage.withdraw.vo.BrokerageWithdrawPageReqVO; | ||
| 6 | +import cn.iocoder.yudao.module.trade.dal.dataobject.brokerage.withdraw.BrokerageWithdrawDO; | ||
| 7 | +import cn.iocoder.yudao.module.trade.dal.mysql.brokerage.withdraw.BrokerageWithdrawMapper; | ||
| 8 | +import cn.iocoder.yudao.module.trade.service.brokerage.withdraw.BrokerageWithdrawServiceImpl; | ||
| 9 | +import org.junit.jupiter.api.Disabled; | ||
| 10 | +import org.junit.jupiter.api.Test; | ||
| 11 | +import org.springframework.context.annotation.Import; | ||
| 12 | + | ||
| 13 | +import javax.annotation.Resource; | ||
| 14 | + | ||
| 15 | +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime; | ||
| 16 | +import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId; | ||
| 17 | +import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals; | ||
| 18 | +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo; | ||
| 19 | +import static org.junit.jupiter.api.Assertions.assertEquals; | ||
| 20 | + | ||
| 21 | +// TODO 芋艿:后续 review | ||
| 22 | +/** | ||
| 23 | + * {@link BrokerageWithdrawServiceImpl} 的单元测试类 | ||
| 24 | + * | ||
| 25 | + * @author 芋道源码 | ||
| 26 | + */ | ||
| 27 | +@Import(BrokerageWithdrawServiceImpl.class) | ||
| 28 | +public class BrokerageWithdrawServiceImplTest extends BaseDbUnitTest { | ||
| 29 | + | ||
| 30 | + @Resource | ||
| 31 | + private BrokerageWithdrawServiceImpl brokerageWithdrawService; | ||
| 32 | + | ||
| 33 | + @Resource | ||
| 34 | + private BrokerageWithdrawMapper brokerageWithdrawMapper; | ||
| 35 | + | ||
| 36 | + @Test | ||
| 37 | + @Disabled // TODO 请修改 null 为需要的值,然后删除 @Disabled 注解 | ||
| 38 | + public void testGetBrokerageWithdrawPage() { | ||
| 39 | + // mock 数据 | ||
| 40 | + BrokerageWithdrawDO dbBrokerageWithdraw = randomPojo(BrokerageWithdrawDO.class, o -> { // 等会查询到 | ||
| 41 | + o.setUserId(null); | ||
| 42 | + o.setType(null); | ||
| 43 | + o.setName(null); | ||
| 44 | + o.setAccountNo(null); | ||
| 45 | + o.setBankName(null); | ||
| 46 | + o.setStatus(null); | ||
| 47 | + o.setCreateTime(null); | ||
| 48 | + }); | ||
| 49 | + brokerageWithdrawMapper.insert(dbBrokerageWithdraw); | ||
| 50 | + // 测试 userId 不匹配 | ||
| 51 | + brokerageWithdrawMapper.insert(cloneIgnoreId(dbBrokerageWithdraw, o -> o.setUserId(null))); | ||
| 52 | + // 测试 type 不匹配 | ||
| 53 | + brokerageWithdrawMapper.insert(cloneIgnoreId(dbBrokerageWithdraw, o -> o.setType(null))); | ||
| 54 | + // 测试 name 不匹配 | ||
| 55 | + brokerageWithdrawMapper.insert(cloneIgnoreId(dbBrokerageWithdraw, o -> o.setName(null))); | ||
| 56 | + // 测试 accountNo 不匹配 | ||
| 57 | + brokerageWithdrawMapper.insert(cloneIgnoreId(dbBrokerageWithdraw, o -> o.setAccountNo(null))); | ||
| 58 | + // 测试 bankName 不匹配 | ||
| 59 | + brokerageWithdrawMapper.insert(cloneIgnoreId(dbBrokerageWithdraw, o -> o.setBankName(null))); | ||
| 60 | + // 测试 status 不匹配 | ||
| 61 | + brokerageWithdrawMapper.insert(cloneIgnoreId(dbBrokerageWithdraw, o -> o.setStatus(null))); | ||
| 62 | + // 测试 auditReason 不匹配 | ||
| 63 | + brokerageWithdrawMapper.insert(cloneIgnoreId(dbBrokerageWithdraw, o -> o.setAuditReason(null))); | ||
| 64 | + // 测试 auditTime 不匹配 | ||
| 65 | + brokerageWithdrawMapper.insert(cloneIgnoreId(dbBrokerageWithdraw, o -> o.setAuditTime(null))); | ||
| 66 | + // 测试 remark 不匹配 | ||
| 67 | + brokerageWithdrawMapper.insert(cloneIgnoreId(dbBrokerageWithdraw, o -> o.setRemark(null))); | ||
| 68 | + // 测试 createTime 不匹配 | ||
| 69 | + brokerageWithdrawMapper.insert(cloneIgnoreId(dbBrokerageWithdraw, o -> o.setCreateTime(null))); | ||
| 70 | + // 准备参数 | ||
| 71 | + BrokerageWithdrawPageReqVO reqVO = new BrokerageWithdrawPageReqVO(); | ||
| 72 | + reqVO.setUserId(null); | ||
| 73 | + reqVO.setType(null); | ||
| 74 | + reqVO.setName(null); | ||
| 75 | + reqVO.setAccountNo(null); | ||
| 76 | + reqVO.setBankName(null); | ||
| 77 | + reqVO.setStatus(null); | ||
| 78 | + reqVO.setCreateTime(buildBetweenTime(2023, 2, 1, 2023, 2, 28)); | ||
| 79 | + | ||
| 80 | + // 调用 | ||
| 81 | + PageResult<BrokerageWithdrawDO> pageResult = brokerageWithdrawService.getBrokerageWithdrawPage(reqVO); | ||
| 82 | + // 断言 | ||
| 83 | + assertEquals(1, pageResult.getTotal()); | ||
| 84 | + assertEquals(1, pageResult.getList().size()); | ||
| 85 | + assertPojoEquals(dbBrokerageWithdraw, pageResult.getList().get(0)); | ||
| 86 | + } | ||
| 87 | + | ||
| 88 | +} |
yudao-module-mall/yudao-module-trade-biz/src/test/resources/sql/clean.sql
| @@ -4,3 +4,4 @@ DELETE FROM trade_after_sale; | @@ -4,3 +4,4 @@ DELETE FROM trade_after_sale; | ||
| 4 | DELETE FROM trade_after_sale_log; | 4 | DELETE FROM trade_after_sale_log; |
| 5 | DELETE FROM trade_brokerage_user; | 5 | DELETE FROM trade_brokerage_user; |
| 6 | DELETE FROM trade_brokerage_record; | 6 | DELETE FROM trade_brokerage_record; |
| 7 | +DELETE FROM "trade_brokerage_withdraw"; |
yudao-module-mall/yudao-module-trade-biz/src/test/resources/sql/create_tables.sql
| @@ -163,4 +163,29 @@ CREATE TABLE IF NOT EXISTS "trade_brokerage_record" | @@ -163,4 +163,29 @@ CREATE TABLE IF NOT EXISTS "trade_brokerage_record" | ||
| 163 | "deleted" bit NOT NULL DEFAULT FALSE, | 163 | "deleted" bit NOT NULL DEFAULT FALSE, |
| 164 | "tenant_id" bigint not null default '0', | 164 | "tenant_id" bigint not null default '0', |
| 165 | PRIMARY KEY ("id") | 165 | PRIMARY KEY ("id") |
| 166 | -) COMMENT '佣金记录'; | ||
| 167 | \ No newline at end of file | 166 | \ No newline at end of file |
| 167 | +) COMMENT '佣金记录'; | ||
| 168 | +CREATE TABLE IF NOT EXISTS "trade_brokerage_withdraw" | ||
| 169 | +( | ||
| 170 | + "id" int NOT NULL GENERATED BY DEFAULT AS IDENTITY, | ||
| 171 | + "user_id" bigint NOT NULL, | ||
| 172 | + "price" int NOT NULL, | ||
| 173 | + "fee_price" int NOT NULL, | ||
| 174 | + "total_price" int NOT NULL, | ||
| 175 | + "type" varchar NOT NULL, | ||
| 176 | + "name" varchar, | ||
| 177 | + "account_no" varchar, | ||
| 178 | + "bank_name" varchar, | ||
| 179 | + "bank_address" varchar, | ||
| 180 | + "account_qr_code_url" varchar, | ||
| 181 | + "status" varchar NOT NULL, | ||
| 182 | + "audit_reason" varchar, | ||
| 183 | + "audit_time" varchar, | ||
| 184 | + "remark" varchar, | ||
| 185 | + "creator" varchar DEFAULT '', | ||
| 186 | + "create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, | ||
| 187 | + "updater" varchar DEFAULT '', | ||
| 188 | + "update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, | ||
| 189 | + "deleted" bit NOT NULL DEFAULT FALSE, | ||
| 190 | + "tenant_id" bigint not null default '0',目 | ||
| 191 | + PRIMARY KEY ("id") | ||
| 192 | +) COMMENT '佣金提现'; | ||
| 168 | \ No newline at end of file | 193 | \ No newline at end of file |
yudao-module-member/yudao-module-member-api/pom.xml
| @@ -21,6 +21,13 @@ | @@ -21,6 +21,13 @@ | ||
| 21 | <groupId>cn.iocoder.boot</groupId> | 21 | <groupId>cn.iocoder.boot</groupId> |
| 22 | <artifactId>yudao-common</artifactId> | 22 | <artifactId>yudao-common</artifactId> |
| 23 | </dependency> | 23 | </dependency> |
| 24 | + | ||
| 25 | + <!-- 参数校验 --> | ||
| 26 | + <dependency> | ||
| 27 | + <groupId>org.springframework.boot</groupId> | ||
| 28 | + <artifactId>spring-boot-starter-validation</artifactId> | ||
| 29 | + <optional>true</optional> | ||
| 30 | + </dependency> | ||
| 24 | </dependencies> | 31 | </dependencies> |
| 25 | 32 | ||
| 26 | </project> | 33 | </project> |
yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/api/point/MemberPointApi.java
| @@ -2,6 +2,8 @@ package cn.iocoder.yudao.module.member.api.point; | @@ -2,6 +2,8 @@ package cn.iocoder.yudao.module.member.api.point; | ||
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.module.member.enums.point.MemberPointBizTypeEnum; | 3 | import cn.iocoder.yudao.module.member.enums.point.MemberPointBizTypeEnum; |
| 4 | 4 | ||
| 5 | +import javax.validation.constraints.Min; | ||
| 6 | + | ||
| 5 | /** | 7 | /** |
| 6 | * 用户积分的 API 接口 | 8 | * 用户积分的 API 接口 |
| 7 | * | 9 | * |
| @@ -17,6 +19,18 @@ public interface MemberPointApi { | @@ -17,6 +19,18 @@ public interface MemberPointApi { | ||
| 17 | * @param bizType 业务类型 {@link MemberPointBizTypeEnum} | 19 | * @param bizType 业务类型 {@link MemberPointBizTypeEnum} |
| 18 | * @param bizId 业务编号 | 20 | * @param bizId 业务编号 |
| 19 | */ | 21 | */ |
| 20 | - void addPoint(Long userId, Integer point, Integer bizType, String bizId); | 22 | + void addPoint(Long userId, @Min(value = 1L, message = "积分必须是正数") Integer point, |
| 23 | + Integer bizType, String bizId); | ||
| 24 | + | ||
| 25 | + /** | ||
| 26 | + * 减少用户积分 | ||
| 27 | + * | ||
| 28 | + * @param userId 用户编号 | ||
| 29 | + * @param point 积分 | ||
| 30 | + * @param bizType 业务类型 {@link MemberPointBizTypeEnum} | ||
| 31 | + * @param bizId 业务编号 | ||
| 32 | + */ | ||
| 33 | + void reducePoint(Long userId, @Min(value = 1L, message = "积分必须是正数") Integer point, | ||
| 34 | + Integer bizType, String bizId); | ||
| 21 | 35 | ||
| 22 | } | 36 | } |
yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/ErrorCodeConstants.java
| @@ -39,7 +39,7 @@ public interface ErrorCodeConstants { | @@ -39,7 +39,7 @@ public interface ErrorCodeConstants { | ||
| 39 | ErrorCode SIGN_IN_CONFIG_EXISTS = new ErrorCode(1004009001, "签到天数规则已存在"); | 39 | ErrorCode SIGN_IN_CONFIG_EXISTS = new ErrorCode(1004009001, "签到天数规则已存在"); |
| 40 | 40 | ||
| 41 | //========== 签到配置 1004010000 ========== | 41 | //========== 签到配置 1004010000 ========== |
| 42 | - | 42 | + ErrorCode SIGN_IN_RECORD_TODAY_EXISTS = new ErrorCode(1004010000,"今日已签到,请勿重复签到"); |
| 43 | 43 | ||
| 44 | //========== 用户等级 1004011000 ========== | 44 | //========== 用户等级 1004011000 ========== |
| 45 | ErrorCode LEVEL_NOT_EXISTS = new ErrorCode(1004011000, "用户等级不存在"); | 45 | ErrorCode LEVEL_NOT_EXISTS = new ErrorCode(1004011000, "用户等级不存在"); |
yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/point/MemberPointBizTypeEnum.java
| @@ -17,8 +17,10 @@ import java.util.Objects; | @@ -17,8 +17,10 @@ import java.util.Objects; | ||
| 17 | public enum MemberPointBizTypeEnum implements IntArrayValuable { | 17 | public enum MemberPointBizTypeEnum implements IntArrayValuable { |
| 18 | 18 | ||
| 19 | SIGN(1, "签到", "签到获得 {} 积分", true), | 19 | SIGN(1, "签到", "签到获得 {} 积分", true), |
| 20 | - ORDER_BUY(10, "订单消费", "下单获得 {} 积分", true), | ||
| 21 | - ORDER_CANCEL(11, "订单取消", "退单获得 {} 积分", false); // 退回积分 | 20 | + ORDER_REWARD(10, "订单奖励", "下单获得 {} 积分", true), |
| 21 | + ORDER_CANCEL(11, "订单取消", "退单获得 {} 积分", false), // 退回积分 | ||
| 22 | + ORDER_USE(12, "订单使用", "下单使用 {} 积分", false), // 扣减积分 | ||
| 23 | + ; | ||
| 22 | 24 | ||
| 23 | /** | 25 | /** |
| 24 | * 类型 | 26 | * 类型 |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/api/point/MemberPointApiImpl.java
| @@ -31,4 +31,13 @@ public class MemberPointApiImpl implements MemberPointApi { | @@ -31,4 +31,13 @@ public class MemberPointApiImpl implements MemberPointApi { | ||
| 31 | memberPointRecordService.createPointRecord(userId, point, bizTypeEnum, bizId); | 31 | memberPointRecordService.createPointRecord(userId, point, bizTypeEnum, bizId); |
| 32 | } | 32 | } |
| 33 | 33 | ||
| 34 | + @Override | ||
| 35 | + public void reducePoint(Long userId, Integer point, Integer bizType, String bizId) { | ||
| 36 | + MemberPointBizTypeEnum bizTypeEnum = MemberPointBizTypeEnum.getByType(bizType); | ||
| 37 | + if (bizTypeEnum == null) { | ||
| 38 | + throw exception(POINT_RECORD_BIZ_NOT_SUPPORT); | ||
| 39 | + } | ||
| 40 | + memberPointRecordService.createPointRecord(userId, point, bizTypeEnum, bizId); | ||
| 41 | + } | ||
| 42 | + | ||
| 34 | } | 43 | } |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/signin/AppMemberSignInController.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.member.controller.app.signin; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.framework.common.pojo.CommonResult; | ||
| 4 | +import cn.iocoder.yudao.module.member.convert.signin.MemberSignInRecordConvert; | ||
| 5 | +import cn.iocoder.yudao.module.member.dal.dataobject.signin.MemberSignInRecordDO; | ||
| 6 | +import cn.iocoder.yudao.module.member.service.signin.MemberSignInRecordService; | ||
| 7 | +import io.swagger.v3.oas.annotations.Operation; | ||
| 8 | +import io.swagger.v3.oas.annotations.tags.Tag; | ||
| 9 | +import org.springframework.web.bind.annotation.GetMapping; | ||
| 10 | +import org.springframework.web.bind.annotation.PostMapping; | ||
| 11 | +import org.springframework.web.bind.annotation.RequestMapping; | ||
| 12 | +import org.springframework.web.bind.annotation.RestController; | ||
| 13 | + | ||
| 14 | +import javax.annotation.Resource; | ||
| 15 | + | ||
| 16 | +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | ||
| 17 | +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; | ||
| 18 | + | ||
| 19 | +// TODO @xiaqing:sign-in | ||
| 20 | +@Tag(name = "签到APP - 签到") | ||
| 21 | +@RestController | ||
| 22 | +@RequestMapping("/member/signin") | ||
| 23 | +public class AppMemberSignInController { | ||
| 24 | + | ||
| 25 | + @Resource | ||
| 26 | + private MemberSignInRecordService signInRecordService; | ||
| 27 | + | ||
| 28 | + // TODO @xiaqing:泛型: | ||
| 29 | + // TODO @xiaqing:合并到 AppMemberSignInRecordController 的 getSignInRecordSummary 里哈。 | ||
| 30 | + @Operation(summary = "个人签到信息") | ||
| 31 | + @GetMapping("/get-summary") | ||
| 32 | + public CommonResult getUserSummary(){ | ||
| 33 | + return success(signInRecordService.getSignInRecordSummary(getLoginUserId())); | ||
| 34 | + } | ||
| 35 | + | ||
| 36 | + // TODO @xiaqing:泛型: | ||
| 37 | + // TODO @xiaqing:合并到 AppMemberSignInRecordController 的 createSignInRecord 里哈。 | ||
| 38 | + @Operation(summary = "会员签到") | ||
| 39 | + @PostMapping("/create") | ||
| 40 | + public CommonResult create(){ | ||
| 41 | + MemberSignInRecordDO recordDO = signInRecordService.createSignRecord(getLoginUserId()); | ||
| 42 | + return success(MemberSignInRecordConvert.INSTANCE.coverRecordToAppRecordVo(recordDO)); | ||
| 43 | + } | ||
| 44 | + | ||
| 45 | +} |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/signin/vo/AppMemberSignInRecordRespVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.member.controller.app.signin.vo; | ||
| 2 | + | ||
| 3 | +import io.swagger.v3.oas.annotations.media.Schema; | ||
| 4 | +import lombok.Data; | ||
| 5 | + | ||
| 6 | +import java.time.LocalDateTime; | ||
| 7 | + | ||
| 8 | +@Schema(description = "用户签到积分 Response VO") | ||
| 9 | +@Data | ||
| 10 | +public class AppMemberSignInRecordRespVO { | ||
| 11 | + | ||
| 12 | + @Schema(description = "第几天签到", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") | ||
| 13 | + private Integer day; | ||
| 14 | + | ||
| 15 | + @Schema(description = "签到的分数", requiredMode = Schema.RequiredMode.REQUIRED, example = "10") | ||
| 16 | + private Integer point; | ||
| 17 | + | ||
| 18 | + @Schema(description = "签到时间", requiredMode = Schema.RequiredMode.REQUIRED) | ||
| 19 | + private LocalDateTime createTime; | ||
| 20 | + | ||
| 21 | +} |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/signin/vo/AppMemberSignInSummaryRespVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.member.controller.app.signin.vo; | ||
| 2 | + | ||
| 3 | +import io.swagger.v3.oas.annotations.media.Schema; | ||
| 4 | +import lombok.Data; | ||
| 5 | + | ||
| 6 | +import java.time.LocalDateTime; | ||
| 7 | + | ||
| 8 | +@Schema(description = "用户签到统计信息 Response VO") | ||
| 9 | +@Data | ||
| 10 | +public class AppMemberSignInSummaryRespVO { | ||
| 11 | + | ||
| 12 | + @Schema(description = "持续签到天数", requiredMode = Schema.RequiredMode.REQUIRED, example = "5") | ||
| 13 | + private Integer continuousDay; | ||
| 14 | + | ||
| 15 | + @Schema(description = "总签到天数", requiredMode = Schema.RequiredMode.REQUIRED, example = "10") | ||
| 16 | + private Integer totalDay; | ||
| 17 | + | ||
| 18 | + @Schema(description = "当天是否签到", requiredMode = Schema.RequiredMode.REQUIRED,example = "true") | ||
| 19 | + private Boolean todaySignIn ; | ||
| 20 | + | ||
| 21 | +} |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/signin/MemberSignInRecordConvert.java
| @@ -36,4 +36,6 @@ public interface MemberSignInRecordConvert { | @@ -36,4 +36,6 @@ public interface MemberSignInRecordConvert { | ||
| 36 | 36 | ||
| 37 | PageResult<AppMemberSignInRecordRespVO> convertPage02(PageResult<MemberSignInRecordDO> pageResult); | 37 | PageResult<AppMemberSignInRecordRespVO> convertPage02(PageResult<MemberSignInRecordDO> pageResult); |
| 38 | 38 | ||
| 39 | + AppMemberSignInRecordRespVO coverRecordToAppRecordVo(MemberSignInRecordDO memberSignInRecordDO); | ||
| 40 | + | ||
| 39 | } | 41 | } |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/signin/MemberSignInConfigMapper.java
| @@ -18,7 +18,7 @@ public interface MemberSignInConfigMapper extends BaseMapperX<MemberSignInConfig | @@ -18,7 +18,7 @@ public interface MemberSignInConfigMapper extends BaseMapperX<MemberSignInConfig | ||
| 18 | return selectOne(MemberSignInConfigDO::getDay, day); | 18 | return selectOne(MemberSignInConfigDO::getDay, day); |
| 19 | } | 19 | } |
| 20 | 20 | ||
| 21 | - default List<MemberSignInConfigDO> selectListByStatus(Integer status) { | 21 | + default List <MemberSignInConfigDO> selectListByStatus(Integer status) { |
| 22 | return selectList(MemberSignInConfigDO::getStatus, status); | 22 | return selectList(MemberSignInConfigDO::getStatus, status); |
| 23 | } | 23 | } |
| 24 | } | 24 | } |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/dal/mysql/signin/MemberSignInRecordMapper.java
| @@ -8,6 +8,7 @@ import cn.iocoder.yudao.module.member.controller.admin.signin.vo.record.MemberSi | @@ -8,6 +8,7 @@ import cn.iocoder.yudao.module.member.controller.admin.signin.vo.record.MemberSi | ||
| 8 | import cn.iocoder.yudao.module.member.dal.dataobject.signin.MemberSignInRecordDO; | 8 | import cn.iocoder.yudao.module.member.dal.dataobject.signin.MemberSignInRecordDO; |
| 9 | import org.apache.ibatis.annotations.Mapper; | 9 | import org.apache.ibatis.annotations.Mapper; |
| 10 | 10 | ||
| 11 | +import java.util.List; | ||
| 11 | import java.util.Set; | 12 | import java.util.Set; |
| 12 | 13 | ||
| 13 | /** | 14 | /** |
| @@ -33,4 +34,12 @@ public interface MemberSignInRecordMapper extends BaseMapperX<MemberSignInRecord | @@ -33,4 +34,12 @@ public interface MemberSignInRecordMapper extends BaseMapperX<MemberSignInRecord | ||
| 33 | .orderByDesc(MemberSignInRecordDO::getId)); | 34 | .orderByDesc(MemberSignInRecordDO::getId)); |
| 34 | } | 35 | } |
| 35 | 36 | ||
| 37 | + | ||
| 38 | + //获取用户的签到记录列表信息,根据签到时间倒序 | ||
| 39 | + default List<MemberSignInRecordDO> selectListByUserId(Long userId){ | ||
| 40 | + return selectList(new LambdaQueryWrapperX <MemberSignInRecordDO>() | ||
| 41 | + .eq(MemberSignInRecordDO::getUserId, userId) | ||
| 42 | + .orderByDesc(MemberSignInRecordDO::getCreateTime)); | ||
| 43 | + } | ||
| 44 | + | ||
| 36 | } | 45 | } |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/signin/MemberSignInRecordService.java
| @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.member.service.signin; | @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.member.service.signin; | ||
| 3 | import cn.iocoder.yudao.framework.common.pojo.PageParam; | 3 | import cn.iocoder.yudao.framework.common.pojo.PageParam; |
| 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 5 | import cn.iocoder.yudao.module.member.controller.admin.signin.vo.record.MemberSignInRecordPageReqVO; | 5 | import cn.iocoder.yudao.module.member.controller.admin.signin.vo.record.MemberSignInRecordPageReqVO; |
| 6 | +import cn.iocoder.yudao.module.member.controller.app.signin.vo.AppMemberSignInSummaryRespVO; | ||
| 6 | import cn.iocoder.yudao.module.member.dal.dataobject.signin.MemberSignInRecordDO; | 7 | import cn.iocoder.yudao.module.member.dal.dataobject.signin.MemberSignInRecordDO; |
| 7 | 8 | ||
| 8 | /** | 9 | /** |
| @@ -29,4 +30,21 @@ public interface MemberSignInRecordService { | @@ -29,4 +30,21 @@ public interface MemberSignInRecordService { | ||
| 29 | */ | 30 | */ |
| 30 | PageResult<MemberSignInRecordDO> getSignRecordPage(Long userId, PageParam pageParam); | 31 | PageResult<MemberSignInRecordDO> getSignRecordPage(Long userId, PageParam pageParam); |
| 31 | 32 | ||
| 33 | + /** | ||
| 34 | + * 创建签到记录 | ||
| 35 | + * | ||
| 36 | + * @param userId 用户编号 | ||
| 37 | + * @return 签到记录 | ||
| 38 | + */ | ||
| 39 | + MemberSignInRecordDO createSignRecord(Long userId); | ||
| 40 | + | ||
| 41 | + /** | ||
| 42 | + * 根据用户编号,获得个人签到统计信息 | ||
| 43 | + * | ||
| 44 | + * @param userId 用户编号 | ||
| 45 | + * @return 个人签到统计信息 | ||
| 46 | + */ | ||
| 47 | + AppMemberSignInSummaryRespVO getSignInRecordSummary(Long userId); | ||
| 48 | + | ||
| 49 | + | ||
| 32 | } | 50 | } |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/signin/MemberSignInRecordServiceImpl.java
| 1 | package cn.iocoder.yudao.module.member.service.signin; | 1 | package cn.iocoder.yudao.module.member.service.signin; |
| 2 | 2 | ||
| 3 | +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | ||
| 3 | import cn.iocoder.yudao.framework.common.pojo.PageParam; | 4 | import cn.iocoder.yudao.framework.common.pojo.PageParam; |
| 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 5 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 6 | +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; | ||
| 5 | import cn.iocoder.yudao.module.member.api.user.MemberUserApi; | 7 | import cn.iocoder.yudao.module.member.api.user.MemberUserApi; |
| 6 | import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; | 8 | import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; |
| 7 | import cn.iocoder.yudao.module.member.controller.admin.signin.vo.record.MemberSignInRecordPageReqVO; | 9 | import cn.iocoder.yudao.module.member.controller.admin.signin.vo.record.MemberSignInRecordPageReqVO; |
| 10 | +import cn.iocoder.yudao.module.member.controller.app.signin.vo.AppMemberSignInSummaryRespVO; | ||
| 11 | +import cn.iocoder.yudao.module.member.dal.dataobject.signin.MemberSignInConfigDO; | ||
| 8 | import cn.iocoder.yudao.module.member.dal.dataobject.signin.MemberSignInRecordDO; | 12 | import cn.iocoder.yudao.module.member.dal.dataobject.signin.MemberSignInRecordDO; |
| 13 | +import cn.iocoder.yudao.module.member.dal.mysql.signin.MemberSignInConfigMapper; | ||
| 9 | import cn.iocoder.yudao.module.member.dal.mysql.signin.MemberSignInRecordMapper; | 14 | import cn.iocoder.yudao.module.member.dal.mysql.signin.MemberSignInRecordMapper; |
| 15 | +import cn.iocoder.yudao.module.member.enums.ErrorCodeConstants; | ||
| 10 | import org.apache.commons.lang3.StringUtils; | 16 | import org.apache.commons.lang3.StringUtils; |
| 11 | import org.springframework.stereotype.Service; | 17 | import org.springframework.stereotype.Service; |
| 12 | import org.springframework.util.CollectionUtils; | 18 | import org.springframework.util.CollectionUtils; |
| 13 | import org.springframework.validation.annotation.Validated; | 19 | import org.springframework.validation.annotation.Validated; |
| 14 | 20 | ||
| 15 | import javax.annotation.Resource; | 21 | import javax.annotation.Resource; |
| 22 | +import java.time.LocalDate; | ||
| 23 | +import java.time.temporal.ChronoUnit; | ||
| 16 | import java.util.List; | 24 | import java.util.List; |
| 17 | import java.util.Set; | 25 | import java.util.Set; |
| 18 | 26 | ||
| 27 | +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | ||
| 19 | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; | 28 | import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; |
| 20 | 29 | ||
| 21 | /** | 30 | /** |
| @@ -28,17 +37,66 @@ import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils. | @@ -28,17 +37,66 @@ import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils. | ||
| 28 | public class MemberSignInRecordServiceImpl implements MemberSignInRecordService { | 37 | public class MemberSignInRecordServiceImpl implements MemberSignInRecordService { |
| 29 | 38 | ||
| 30 | @Resource | 39 | @Resource |
| 31 | - private MemberSignInRecordMapper memberSignInRecordMapper; | 40 | + private MemberSignInRecordMapper signInRecordMapper; |
| 41 | + @Resource | ||
| 42 | + private MemberSignInConfigMapper signInConfigMapper; | ||
| 32 | 43 | ||
| 33 | @Resource | 44 | @Resource |
| 34 | private MemberUserApi memberUserApi; | 45 | private MemberUserApi memberUserApi; |
| 35 | 46 | ||
| 36 | @Override | 47 | @Override |
| 37 | - public PageResult<MemberSignInRecordDO> getSignInRecordPage(MemberSignInRecordPageReqVO pageReqVO) { | ||
| 38 | - // 根据用户昵称查询出用户 ids | ||
| 39 | - Set<Long> userIds = null; | 48 | + public AppMemberSignInSummaryRespVO getSignInRecordSummary(Long userId) { |
| 49 | + AppMemberSignInSummaryRespVO vo = new AppMemberSignInSummaryRespVO(); | ||
| 50 | + vo.setTotalDay(0); | ||
| 51 | + vo.setContinuousDay(0); | ||
| 52 | + vo.setTodaySignIn(false); | ||
| 53 | + //获取用户签到的记录,按照天数倒序获取 | ||
| 54 | + List <MemberSignInRecordDO> signInRecordDOList = signInRecordMapper.selectListByUserId(userId); | ||
| 55 | + // TODO @xiaqing:if 空的时候,直接 return;这样括号少,逻辑更简洁; | ||
| 56 | + if(!CollectionUtils.isEmpty(signInRecordDOList)){ | ||
| 57 | + //设置总签到天数 | ||
| 58 | + vo.setTotalDay(signInRecordDOList.size()); // TODO @xiaqing:是不是不用读取 signInRecordDOList 所有的,而是 count下,然后另外再读取一条最后一条; | ||
| 59 | + //判断当天是否有签到复用校验方法 | ||
| 60 | + // TODO @xiaqing:不要用异常实现逻辑;还是判断哈; | ||
| 61 | + try { | ||
| 62 | + validSignDay(signInRecordDOList.get(0)); | ||
| 63 | + vo.setTodaySignIn(false); | ||
| 64 | + }catch (Exception e){ | ||
| 65 | + vo.setTodaySignIn(true); | ||
| 66 | + } | ||
| 67 | + //如果当天签到了则说明连续签到天数有意义,否则直接用默认值0 | ||
| 68 | + if(vo.getTodaySignIn()){ | ||
| 69 | + //下方计算连续签到从2天开始,此处直接设置一天连续签到 | ||
| 70 | + vo.setContinuousDay(1); | ||
| 71 | + //判断连续签到天数 | ||
| 72 | + // TODO @xiaqing:这里逻辑,想想怎么在简化下,可读性可以在提升下哈; | ||
| 73 | + for (int i = 1; i < signInRecordDOList.size(); i++) { | ||
| 74 | + //前一天减1等于当前天数则说明连续,继续循环 | ||
| 75 | + LocalDate cur = signInRecordDOList.get(i).getCreateTime().toLocalDate(); | ||
| 76 | + LocalDate pre = signInRecordDOList.get(i-1).getCreateTime().toLocalDate(); | ||
| 77 | + if(1==daysBetween(cur,pre)){ | ||
| 78 | + vo.setContinuousDay(i+1); | ||
| 79 | + }else{ | ||
| 80 | + break; | ||
| 81 | + } | ||
| 82 | + } | ||
| 83 | + } | ||
| 84 | + | ||
| 85 | + | ||
| 86 | + } | ||
| 87 | + return vo; | ||
| 88 | + } | ||
| 89 | + | ||
| 90 | + private long daysBetween(LocalDate date1,LocalDate date2){ | ||
| 91 | + return ChronoUnit.DAYS.between(date1, date2); | ||
| 92 | + } | ||
| 93 | + | ||
| 94 | + @Override | ||
| 95 | + public PageResult <MemberSignInRecordDO> getSignInRecordPage(MemberSignInRecordPageReqVO pageReqVO) { | ||
| 96 | + // 根据用户昵称查询出用户ids | ||
| 97 | + Set <Long> userIds = null; | ||
| 40 | if (StringUtils.isNotBlank(pageReqVO.getNickname())) { | 98 | if (StringUtils.isNotBlank(pageReqVO.getNickname())) { |
| 41 | - List<MemberUserRespDTO> users = memberUserApi.getUserListByNickname(pageReqVO.getNickname()); | 99 | + List <MemberUserRespDTO> users = memberUserApi.getUserListByNickname(pageReqVO.getNickname()); |
| 42 | // 如果查询用户结果为空直接返回无需继续查询 | 100 | // 如果查询用户结果为空直接返回无需继续查询 |
| 43 | if (CollectionUtils.isEmpty(users)) { | 101 | if (CollectionUtils.isEmpty(users)) { |
| 44 | return PageResult.empty(); | 102 | return PageResult.empty(); |
| @@ -46,12 +104,72 @@ public class MemberSignInRecordServiceImpl implements MemberSignInRecordService | @@ -46,12 +104,72 @@ public class MemberSignInRecordServiceImpl implements MemberSignInRecordService | ||
| 46 | userIds = convertSet(users, MemberUserRespDTO::getId); | 104 | userIds = convertSet(users, MemberUserRespDTO::getId); |
| 47 | } | 105 | } |
| 48 | // 分页查询 | 106 | // 分页查询 |
| 49 | - return memberSignInRecordMapper.selectPage(pageReqVO, userIds); | 107 | + return signInRecordMapper.selectPage(pageReqVO, userIds); |
| 50 | } | 108 | } |
| 51 | 109 | ||
| 52 | @Override | 110 | @Override |
| 53 | public PageResult<MemberSignInRecordDO> getSignRecordPage(Long userId, PageParam pageParam) { | 111 | public PageResult<MemberSignInRecordDO> getSignRecordPage(Long userId, PageParam pageParam) { |
| 54 | - return memberSignInRecordMapper.selectPage(userId, pageParam); | 112 | + return signInRecordMapper.selectPage(userId, pageParam); |
| 113 | + } | ||
| 114 | + | ||
| 115 | + @Override | ||
| 116 | + public MemberSignInRecordDO createSignRecord(Long userId) { | ||
| 117 | + // 获取当前用户签到的最大天数 | ||
| 118 | + // TODO @xiaqing:db 操作,dou封装到 mapper 中; | ||
| 119 | + // TODO @xiaqing:maxSignDay,是不是变量叫 lastRecord 会更容易理解哈; | ||
| 120 | + MemberSignInRecordDO maxSignDay = signInRecordMapper.selectOne(new LambdaQueryWrapperX <MemberSignInRecordDO>() | ||
| 121 | + .eq(MemberSignInRecordDO::getUserId, userId) | ||
| 122 | + .orderByDesc(MemberSignInRecordDO::getDay) | ||
| 123 | + .last("limit 1")); | ||
| 124 | + // 判断是否重复签到 | ||
| 125 | + validSignDay(maxSignDay); | ||
| 126 | + | ||
| 127 | + // TODO @xiaqing:可以使用 // 进行注释 | ||
| 128 | + /**1.查询出当前签到的天数**/ | ||
| 129 | + MemberSignInRecordDO sign = new MemberSignInRecordDO().setUserId(userId); // TODO @xiaqing:应该使用 record 变量,会更合适 | ||
| 130 | + sign.setDay(1); // 设置签到初始化天数 | ||
| 131 | + sign.setPoint(0); // 设置签到分数默认为 0 | ||
| 132 | + // 如果不为空则修改当前签到对应的天数 | ||
| 133 | + // TODO @xiaqing:应该是要判断连续哈,就是昨天; | ||
| 134 | + if (maxSignDay != null) { | ||
| 135 | + sign.setDay(maxSignDay.getDay() + 1); | ||
| 136 | + } | ||
| 137 | + /**2.获取签到对应的分数**/ | ||
| 138 | + // 获取所有的签到规则,按照天数排序,只获取启用的 TODO @xiaqing:不要使用 signInConfigMapper 直接查询,而是要通过 SigninConfigService; | ||
| 139 | + List <MemberSignInConfigDO> configDOList = signInConfigMapper.selectList(new LambdaQueryWrapperX <MemberSignInConfigDO>() | ||
| 140 | + .eq(MemberSignInConfigDO::getStatus, CommonStatusEnum.ENABLE.getStatus()) | ||
| 141 | + .orderByAsc(MemberSignInConfigDO::getDay)); | ||
| 142 | + // 如果签到的天数大于最大启用的规则天数,直接给最大签到的分数 | ||
| 143 | + // TODO @xiaqing:超过最大配置的天数,应该直接重置到第一天哈; | ||
| 144 | + MemberSignInConfigDO lastConfig = configDOList.get(configDOList.size() - 1); | ||
| 145 | + if (sign.getDay() > lastConfig.getDay()) { | ||
| 146 | + sign.setPoint(lastConfig.getPoint()); | ||
| 147 | + } else { | ||
| 148 | + configDOList.forEach(el -> { | ||
| 149 | + // 循环匹配对应天数,设置对应分数 | ||
| 150 | + // TODO @xiaqing:使用 equals;另外,这种不应该去遍历比较,从可读性来说,应该 CollUtil.findOne() | ||
| 151 | + if (el.getDay() == sign.getDay()) { | ||
| 152 | + sign.setPoint(el.getPoint()); | ||
| 153 | + } | ||
| 154 | + | ||
| 155 | + }); | ||
| 156 | + } | ||
| 157 | + | ||
| 158 | + // 3. 插入当前签到获取的分数 | ||
| 159 | + signInRecordMapper.insert(sign); | ||
| 160 | + return sign; | ||
| 161 | + } | ||
| 162 | + | ||
| 163 | + // TODO @xiaqing:校验使用 validate 动词哈;可以改成 validateSigned | ||
| 164 | + private void validSignDay(MemberSignInRecordDO signInRecordDO) { | ||
| 165 | + // TODO @xiaqing:代码格式:if () {} 要有括号哈 | ||
| 166 | + if (signInRecordDO == null) | ||
| 167 | + return; | ||
| 168 | + // TODO @xiaqing:可以直接使用 DateUtils.isToday() | ||
| 169 | + LocalDate today = LocalDate.now(); | ||
| 170 | + if (today.equals(signInRecordDO.getCreateTime().toLocalDate())) { | ||
| 171 | + throw exception(ErrorCodeConstants.SIGN_IN_RECORD_TODAY_EXISTS); | ||
| 172 | + } | ||
| 55 | } | 173 | } |
| 56 | 174 | ||
| 57 | } | 175 | } |
yudao-server/src/main/resources/application-local.yaml
| @@ -56,7 +56,7 @@ spring: | @@ -56,7 +56,7 @@ spring: | ||
| 56 | # password: JSm:g(*%lU4ZAkz06cd52KqT3)i1?H7W | 56 | # password: JSm:g(*%lU4ZAkz06cd52KqT3)i1?H7W |
| 57 | slave: # 模拟从库,可根据自己需要修改 | 57 | slave: # 模拟从库,可根据自己需要修改 |
| 58 | name: ruoyi-vue-pro | 58 | name: ruoyi-vue-pro |
| 59 | - url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.master.name}?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例 | 59 | + url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.slave.name}?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true # MySQL Connector/J 8.X 连接的示例 |
| 60 | # url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.slave.name}?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT # MySQL Connector/J 5.X 连接的示例 | 60 | # url: jdbc:mysql://127.0.0.1:3306/${spring.datasource.dynamic.datasource.slave.name}?useSSL=false&allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=CTT # MySQL Connector/J 5.X 连接的示例 |
| 61 | # url: jdbc:postgresql://127.0.0.1:5432/${spring.datasource.dynamic.datasource.slave.name} # PostgreSQL 连接的示例 | 61 | # url: jdbc:postgresql://127.0.0.1:5432/${spring.datasource.dynamic.datasource.slave.name} # PostgreSQL 连接的示例 |
| 62 | # url: jdbc:oracle:thin:@127.0.0.1:1521:xe # Oracle 连接的示例 | 62 | # url: jdbc:oracle:thin:@127.0.0.1:1521:xe # Oracle 连接的示例 |