Commit f462ac7f9688b7f9195d552f16c2937a92ea9afe

Authored by puhui999
2 parents 283ca908 6c8e82ca

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

Showing 96 changed files with 1384 additions and 359 deletions
sql/mysql/mall.sql 0 → 100644
  1 +INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, component_name)
  2 +VALUES ('核销订单', '', 2, 2, 2166, 'pick-up-order', 'ep:list', 'mall/trade/delivery/pickUpOrder/index', 'PickUpOrder');
0 \ No newline at end of file 3 \ No newline at end of file
sql/mysql/pay_wallet.sql
@@ -77,7 +77,7 @@ ALTER TABLE `pay_channel` @@ -77,7 +77,7 @@ ALTER TABLE `pay_channel`
77 MODIFY COLUMN `config` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '支付渠道配置' AFTER `app_id`; 77 MODIFY COLUMN `config` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '支付渠道配置' AFTER `app_id`;
78 78
79 -- ---------------------------- 79 -- ----------------------------
80 --- 套餐充值表 80 +-- 充值套餐表
81 -- ---------------------------- 81 -- ----------------------------
82 DROP TABLE IF EXISTS `pay_wallet_recharge_package`; 82 DROP TABLE IF EXISTS `pay_wallet_recharge_package`;
83 CREATE TABLE `pay_wallet_recharge_package` 83 CREATE TABLE `pay_wallet_recharge_package`
@@ -94,7 +94,7 @@ CREATE TABLE `pay_wallet_recharge_package` @@ -94,7 +94,7 @@ CREATE TABLE `pay_wallet_recharge_package`
94 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', 94 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
95 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', 95 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
96 PRIMARY KEY (`id`) USING BTREE 96 PRIMARY KEY (`id`) USING BTREE
97 -) ENGINE=InnoDB COMMENT='套餐充值表'; 97 +) ENGINE=InnoDB COMMENT='充值套餐表';
98 98
99 -- ---------------------------- 99 -- ----------------------------
100 -- Table structure for pay_wallet_recharge 100 -- Table structure for pay_wallet_recharge
sql/mysql/ruoyi-vue-pro.sql
@@ -11,7 +11,7 @@ @@ -11,7 +11,7 @@
11 Target Server Version : 80034 11 Target Server Version : 80034
12 File Encoding : 65001 12 File Encoding : 65001
13 13
14 - Date: 17/10/2023 23:22:59 14 + Date: 18/10/2023 23:33:15
15 */ 15 */
16 16
17 SET NAMES utf8mb4; 17 SET NAMES utf8mb4;
@@ -384,7 +384,7 @@ CREATE TABLE `infra_api_error_log` ( @@ -384,7 +384,7 @@ CREATE TABLE `infra_api_error_log` (
384 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', 384 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
385 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', 385 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
386 PRIMARY KEY (`id`) USING BTREE 386 PRIMARY KEY (`id`) USING BTREE
387 -) ENGINE = InnoDB AUTO_INCREMENT = 1735 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '系统异常日志'; 387 +) ENGINE = InnoDB AUTO_INCREMENT = 1739 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '系统异常日志';
388 388
389 -- ---------------------------- 389 -- ----------------------------
390 -- Records of infra_api_error_log 390 -- Records of infra_api_error_log
@@ -422,7 +422,7 @@ CREATE TABLE `infra_codegen_column` ( @@ -422,7 +422,7 @@ CREATE TABLE `infra_codegen_column` (
422 `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', 422 `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
423 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', 423 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
424 PRIMARY KEY (`id`) USING BTREE 424 PRIMARY KEY (`id`) USING BTREE
425 -) ENGINE = InnoDB AUTO_INCREMENT = 1804 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '代码生成表字段定义'; 425 +) ENGINE = InnoDB AUTO_INCREMENT = 1805 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '代码生成表字段定义';
426 426
427 -- ---------------------------- 427 -- ----------------------------
428 -- Records of infra_codegen_column 428 -- Records of infra_codegen_column
@@ -455,7 +455,7 @@ CREATE TABLE `infra_codegen_table` ( @@ -455,7 +455,7 @@ CREATE TABLE `infra_codegen_table` (
455 `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', 455 `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
456 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', 456 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
457 PRIMARY KEY (`id`) USING BTREE 457 PRIMARY KEY (`id`) USING BTREE
458 -) ENGINE = InnoDB AUTO_INCREMENT = 136 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '代码生成表定义'; 458 +) ENGINE = InnoDB AUTO_INCREMENT = 137 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '代码生成表定义';
459 459
460 -- ---------------------------- 460 -- ----------------------------
461 -- Records of infra_codegen_table 461 -- Records of infra_codegen_table
@@ -615,7 +615,7 @@ CREATE TABLE `infra_job` ( @@ -615,7 +615,7 @@ CREATE TABLE `infra_job` (
615 `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', 615 `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
616 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', 616 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
617 PRIMARY KEY (`id`) USING BTREE 617 PRIMARY KEY (`id`) USING BTREE
618 -) ENGINE = InnoDB AUTO_INCREMENT = 27 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '定时任务表'; 618 +) ENGINE = InnoDB AUTO_INCREMENT = 28 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '定时任务表';
619 619
620 -- ---------------------------- 620 -- ----------------------------
621 -- Records of infra_job 621 -- Records of infra_job
@@ -656,7 +656,7 @@ CREATE TABLE `infra_job_log` ( @@ -656,7 +656,7 @@ CREATE TABLE `infra_job_log` (
656 `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', 656 `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
657 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', 657 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
658 PRIMARY KEY (`id`) USING BTREE 658 PRIMARY KEY (`id`) USING BTREE
659 -) ENGINE = InnoDB AUTO_INCREMENT = 232 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '定时任务日志表'; 659 +) ENGINE = InnoDB AUTO_INCREMENT = 233 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '定时任务日志表';
660 660
661 -- ---------------------------- 661 -- ----------------------------
662 -- Records of infra_job_log 662 -- Records of infra_job_log
@@ -709,7 +709,7 @@ CREATE TABLE `member_address` ( @@ -709,7 +709,7 @@ CREATE TABLE `member_address` (
709 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', 709 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
710 PRIMARY KEY (`id`) USING BTREE, 710 PRIMARY KEY (`id`) USING BTREE,
711 INDEX `idx_userId`(`user_id` ASC) USING BTREE 711 INDEX `idx_userId`(`user_id` ASC) USING BTREE
712 -) ENGINE = InnoDB AUTO_INCREMENT = 24 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin COMMENT = '用户收件地址'; 712 +) ENGINE = InnoDB AUTO_INCREMENT = 25 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin COMMENT = '用户收件地址';
713 713
714 -- ---------------------------- 714 -- ----------------------------
715 -- Records of member_address 715 -- Records of member_address
@@ -768,7 +768,7 @@ CREATE TABLE `member_experience_record` ( @@ -768,7 +768,7 @@ CREATE TABLE `member_experience_record` (
768 PRIMARY KEY (`id`) USING BTREE, 768 PRIMARY KEY (`id`) USING BTREE,
769 INDEX `idx_user_id`(`user_id` ASC) USING BTREE COMMENT '会员经验记录-用户编号', 769 INDEX `idx_user_id`(`user_id` ASC) USING BTREE COMMENT '会员经验记录-用户编号',
770 INDEX `idx_user_biz_type`(`user_id` ASC, `biz_type` ASC) USING BTREE COMMENT '会员经验记录-用户业务类型' 770 INDEX `idx_user_biz_type`(`user_id` ASC, `biz_type` ASC) USING BTREE COMMENT '会员经验记录-用户业务类型'
771 -) ENGINE = InnoDB AUTO_INCREMENT = 40 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '会员经验记录'; 771 +) ENGINE = InnoDB AUTO_INCREMENT = 41 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '会员经验记录';
772 772
773 -- ---------------------------- 773 -- ----------------------------
774 -- Records of member_experience_record 774 -- Records of member_experience_record
@@ -883,7 +883,7 @@ CREATE TABLE `member_level_record` ( @@ -883,7 +883,7 @@ CREATE TABLE `member_level_record` (
883 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', 883 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
884 PRIMARY KEY (`id`) USING BTREE, 884 PRIMARY KEY (`id`) USING BTREE,
885 INDEX `idx_user_id`(`user_id` ASC) USING BTREE COMMENT '会员等级记录-用户编号' 885 INDEX `idx_user_id`(`user_id` ASC) USING BTREE COMMENT '会员等级记录-用户编号'
886 -) ENGINE = InnoDB AUTO_INCREMENT = 19 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '会员等级记录'; 886 +) ENGINE = InnoDB AUTO_INCREMENT = 20 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '会员等级记录';
887 887
888 -- ---------------------------- 888 -- ----------------------------
889 -- Records of member_level_record 889 -- Records of member_level_record
@@ -913,7 +913,7 @@ CREATE TABLE `member_point_record` ( @@ -913,7 +913,7 @@ CREATE TABLE `member_point_record` (
913 PRIMARY KEY (`id`) USING BTREE, 913 PRIMARY KEY (`id`) USING BTREE,
914 INDEX `index_userId`(`user_id` ASC) USING BTREE, 914 INDEX `index_userId`(`user_id` ASC) USING BTREE,
915 INDEX `index_title`(`title` ASC) USING BTREE 915 INDEX `index_title`(`title` ASC) USING BTREE
916 -) ENGINE = InnoDB AUTO_INCREMENT = 59 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '用户积分记录'; 916 +) ENGINE = InnoDB AUTO_INCREMENT = 60 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '用户积分记录';
917 917
918 -- ---------------------------- 918 -- ----------------------------
919 -- Records of member_point_record 919 -- Records of member_point_record
@@ -1540,7 +1540,7 @@ CREATE TABLE `system_error_code` ( @@ -1540,7 +1540,7 @@ CREATE TABLE `system_error_code` (
1540 `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', 1540 `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
1541 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', 1541 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
1542 PRIMARY KEY (`id`) USING BTREE 1542 PRIMARY KEY (`id`) USING BTREE
1543 -) ENGINE = InnoDB AUTO_INCREMENT = 5932 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '错误码表'; 1543 +) ENGINE = InnoDB AUTO_INCREMENT = 5933 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '错误码表';
1544 1544
1545 -- ---------------------------- 1545 -- ----------------------------
1546 -- Records of system_error_code 1546 -- Records of system_error_code
@@ -1569,7 +1569,7 @@ CREATE TABLE `system_login_log` ( @@ -1569,7 +1569,7 @@ CREATE TABLE `system_login_log` (
1569 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', 1569 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
1570 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', 1570 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
1571 PRIMARY KEY (`id`) USING BTREE 1571 PRIMARY KEY (`id`) USING BTREE
1572 -) ENGINE = InnoDB AUTO_INCREMENT = 2582 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '系统访问记录'; 1572 +) ENGINE = InnoDB AUTO_INCREMENT = 2599 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '系统访问记录';
1573 1573
1574 -- ---------------------------- 1574 -- ----------------------------
1575 -- Records of system_login_log 1575 -- Records of system_login_log
@@ -1634,7 +1634,7 @@ CREATE TABLE `system_mail_log` ( @@ -1634,7 +1634,7 @@ CREATE TABLE `system_mail_log` (
1634 `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', 1634 `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
1635 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', 1635 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
1636 PRIMARY KEY (`id`) USING BTREE 1636 PRIMARY KEY (`id`) USING BTREE
1637 -) ENGINE = InnoDB AUTO_INCREMENT = 354 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '邮件日志表'; 1637 +) ENGINE = InnoDB AUTO_INCREMENT = 355 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '邮件日志表';
1638 1638
1639 -- ---------------------------- 1639 -- ----------------------------
1640 -- Records of system_mail_log 1640 -- Records of system_mail_log
@@ -2283,7 +2283,7 @@ CREATE TABLE `system_notify_template` ( @@ -2283,7 +2283,7 @@ CREATE TABLE `system_notify_template` (
2283 `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', 2283 `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
2284 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', 2284 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
2285 PRIMARY KEY (`id`) USING BTREE 2285 PRIMARY KEY (`id`) USING BTREE
2286 -) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '站内信模板表'; 2286 +) ENGINE = InnoDB AUTO_INCREMENT = 6 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '站内信模板表';
2287 2287
2288 -- ---------------------------- 2288 -- ----------------------------
2289 -- Records of system_notify_template 2289 -- Records of system_notify_template
@@ -2311,7 +2311,7 @@ CREATE TABLE `system_oauth2_access_token` ( @@ -2311,7 +2311,7 @@ CREATE TABLE `system_oauth2_access_token` (
2311 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', 2311 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
2312 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', 2312 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
2313 PRIMARY KEY (`id`) USING BTREE 2313 PRIMARY KEY (`id`) USING BTREE
2314 -) ENGINE = InnoDB AUTO_INCREMENT = 3056 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'OAuth2 访问令牌'; 2314 +) ENGINE = InnoDB AUTO_INCREMENT = 3063 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'OAuth2 访问令牌';
2315 2315
2316 -- ---------------------------- 2316 -- ----------------------------
2317 -- Records of system_oauth2_access_token 2317 -- Records of system_oauth2_access_token
@@ -2433,7 +2433,7 @@ CREATE TABLE `system_oauth2_refresh_token` ( @@ -2433,7 +2433,7 @@ CREATE TABLE `system_oauth2_refresh_token` (
2433 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', 2433 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
2434 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', 2434 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
2435 PRIMARY KEY (`id`) USING BTREE 2435 PRIMARY KEY (`id`) USING BTREE
2436 -) ENGINE = InnoDB AUTO_INCREMENT = 1063 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'OAuth2 刷新令牌'; 2436 +) ENGINE = InnoDB AUTO_INCREMENT = 1070 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'OAuth2 刷新令牌';
2437 2437
2438 -- ---------------------------- 2438 -- ----------------------------
2439 -- Records of system_oauth2_refresh_token 2439 -- Records of system_oauth2_refresh_token
@@ -3481,7 +3481,7 @@ CREATE TABLE `system_sms_code` ( @@ -3481,7 +3481,7 @@ CREATE TABLE `system_sms_code` (
3481 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', 3481 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
3482 PRIMARY KEY (`id`) USING BTREE, 3482 PRIMARY KEY (`id`) USING BTREE,
3483 INDEX `idx_mobile`(`mobile` ASC) USING BTREE COMMENT '手机号' 3483 INDEX `idx_mobile`(`mobile` ASC) USING BTREE COMMENT '手机号'
3484 -) ENGINE = InnoDB AUTO_INCREMENT = 530 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '手机验证码'; 3484 +) ENGINE = InnoDB AUTO_INCREMENT = 531 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '手机验证码';
3485 3485
3486 -- ---------------------------- 3486 -- ----------------------------
3487 -- Records of system_sms_code 3487 -- Records of system_sms_code
@@ -3575,6 +3575,33 @@ INSERT INTO `system_sms_template` (`id`, `type`, `status`, `code`, `name`, `cont @@ -3575,6 +3575,33 @@ INSERT INTO `system_sms_template` (`id`, `type`, `status`, `code`, `name`, `cont
3575 COMMIT; 3575 COMMIT;
3576 3576
3577 -- ---------------------------- 3577 -- ----------------------------
  3578 +-- Table structure for system_social_client
  3579 +-- ----------------------------
  3580 +DROP TABLE IF EXISTS `system_social_client`;
  3581 +CREATE TABLE `system_social_client` (
  3582 + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号',
  3583 + `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '应用名',
  3584 + `social_type` tinyint NOT NULL COMMENT '社交平台的类型',
  3585 + `user_type` tinyint NOT NULL COMMENT '用户类型',
  3586 + `client_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '客户端编号',
  3587 + `client_secret` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '客户端密钥',
  3588 + `status` tinyint NOT NULL COMMENT '状态',
  3589 + `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者',
  3590 + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  3591 + `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者',
  3592 + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  3593 + `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
  3594 + `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
  3595 + PRIMARY KEY (`id`) USING BTREE
  3596 +) ENGINE = InnoDB AUTO_INCREMENT = 43 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '社交客户端表';
  3597 +
  3598 +-- ----------------------------
  3599 +-- Records of system_social_client
  3600 +-- ----------------------------
  3601 +BEGIN;
  3602 +COMMIT;
  3603 +
  3604 +-- ----------------------------
3578 -- Table structure for system_social_user 3605 -- Table structure for system_social_user
3579 -- ---------------------------- 3606 -- ----------------------------
3580 DROP TABLE IF EXISTS `system_social_user`; 3607 DROP TABLE IF EXISTS `system_social_user`;
@@ -3596,7 +3623,7 @@ CREATE TABLE `system_social_user` ( @@ -3596,7 +3623,7 @@ CREATE TABLE `system_social_user` (
3596 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', 3623 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
3597 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', 3624 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
3598 PRIMARY KEY (`id`) USING BTREE 3625 PRIMARY KEY (`id`) USING BTREE
3599 -) ENGINE = InnoDB AUTO_INCREMENT = 21 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '社交用户表'; 3626 +) ENGINE = InnoDB AUTO_INCREMENT = 25 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '社交用户表';
3600 3627
3601 -- ---------------------------- 3628 -- ----------------------------
3602 -- Records of system_social_user 3629 -- Records of system_social_user
@@ -3621,7 +3648,7 @@ CREATE TABLE `system_social_user_bind` ( @@ -3621,7 +3648,7 @@ CREATE TABLE `system_social_user_bind` (
3621 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', 3648 `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
3622 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', 3649 `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号',
3623 PRIMARY KEY (`id`) USING BTREE 3650 PRIMARY KEY (`id`) USING BTREE
3624 -) ENGINE = InnoDB AUTO_INCREMENT = 76 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '社交绑定表'; 3651 +) ENGINE = InnoDB AUTO_INCREMENT = 79 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '社交绑定表';
3625 3652
3626 -- ---------------------------- 3653 -- ----------------------------
3627 -- Records of system_social_user_bind 3654 -- Records of system_social_user_bind
@@ -3797,7 +3824,7 @@ CREATE TABLE `system_users` ( @@ -3797,7 +3824,7 @@ CREATE TABLE `system_users` (
3797 -- Records of system_users 3824 -- Records of system_users
3798 -- ---------------------------- 3825 -- ----------------------------
3799 BEGIN; 3826 BEGIN;
3800 -INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1, 'admin', '$2a$10$mRMIYLDtRHlf6.9ipiqH1.Z.bh/R9dO9d5iHiGYPigi6r5KOoR2Wm', '芋道源码', '管理员', 103, '[1]', 'aoteman@126.com', '15612345678', 1, 'http://test.yudao.iocoder.cn/e1fdd7271685ec143a0900681606406621717a666ad0b2798b096df41422b32f.png', 0, '0:0:0:0:0:0:0:1', '2023-10-17 21:03:03', 'admin', '2021-01-05 17:03:47', NULL, '2023-10-17 21:03:03', b'0', 1); 3827 +INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (1, 'admin', '$2a$10$mRMIYLDtRHlf6.9ipiqH1.Z.bh/R9dO9d5iHiGYPigi6r5KOoR2Wm', '芋道源码', '管理员', 103, '[1]', 'aoteman@126.com', '15612345678', 1, 'http://test.yudao.iocoder.cn/e1fdd7271685ec143a0900681606406621717a666ad0b2798b096df41422b32f.png', 0, '0:0:0:0:0:0:0:1', '2023-10-18 22:31:35', 'admin', '2021-01-05 17:03:47', NULL, '2023-10-18 22:31:35', b'0', 1);
3801 INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (100, 'yudao', '$2a$10$11U48RhyJ5pSBYWSn12AD./ld671.ycSzJHbyrtpeoMeYiw31eo8a', '芋道', '不要吓我', 104, '[1]', 'yudao@iocoder.cn', '15601691300', 1, '', 1, '127.0.0.1', '2022-07-09 23:03:33', '', '2021-01-07 09:07:17', NULL, '2022-07-09 23:03:33', b'0', 1); 3828 INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (100, 'yudao', '$2a$10$11U48RhyJ5pSBYWSn12AD./ld671.ycSzJHbyrtpeoMeYiw31eo8a', '芋道', '不要吓我', 104, '[1]', 'yudao@iocoder.cn', '15601691300', 1, '', 1, '127.0.0.1', '2022-07-09 23:03:33', '', '2021-01-07 09:07:17', NULL, '2022-07-09 23:03:33', b'0', 1);
3802 INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (103, 'yuanma', '$2a$10$YMpimV4T6BtDhIaA8jSW.u8UTGBeGhc/qwXP4oxoMr4mOw9.qttt6', '源码', NULL, 106, NULL, 'yuanma@iocoder.cn', '15601701300', 0, '', 0, '127.0.0.1', '2022-07-08 01:26:27', '', '2021-01-13 23:50:35', NULL, '2022-07-08 01:26:27', b'0', 1); 3829 INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (103, 'yuanma', '$2a$10$YMpimV4T6BtDhIaA8jSW.u8UTGBeGhc/qwXP4oxoMr4mOw9.qttt6', '源码', NULL, 106, NULL, 'yuanma@iocoder.cn', '15601701300', 0, '', 0, '127.0.0.1', '2022-07-08 01:26:27', '', '2021-01-13 23:50:35', NULL, '2022-07-08 01:26:27', b'0', 1);
3803 INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (104, 'test', '$2a$10$GP8zvqHB//TekuzYZSBYAuBQJiNq1.fxQVDYJ.uBCOnWCtDVKE4H6', '测试号', NULL, 107, '[1,2]', '111@qq.com', '15601691200', 1, '', 0, '0:0:0:0:0:0:0:1', '2023-09-24 18:21:19', '', '2021-01-21 02:13:53', NULL, '2023-09-24 18:21:19', b'0', 1); 3830 INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (104, 'test', '$2a$10$GP8zvqHB//TekuzYZSBYAuBQJiNq1.fxQVDYJ.uBCOnWCtDVKE4H6', '测试号', NULL, 107, '[1,2]', '111@qq.com', '15601691200', 1, '', 0, '0:0:0:0:0:0:0:1', '2023-09-24 18:21:19', '', '2021-01-21 02:13:53', NULL, '2023-09-24 18:21:19', b'0', 1);
@@ -3805,7 +3832,7 @@ INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, @@ -3805,7 +3832,7 @@ INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`,
3805 INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (108, 'admin108', '$2a$10$y6mfvKoNYL1GXWak8nYwVOH.kCWqjactkzdoIDgiKl93WN3Ejg.Lu', '芋艿', NULL, NULL, NULL, '', '15601691300', 0, '', 0, '', NULL, '1', '2022-02-20 23:00:50', '1', '2022-02-27 08:26:53', b'0', 119); 3832 INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (108, 'admin108', '$2a$10$y6mfvKoNYL1GXWak8nYwVOH.kCWqjactkzdoIDgiKl93WN3Ejg.Lu', '芋艿', NULL, NULL, NULL, '', '15601691300', 0, '', 0, '', NULL, '1', '2022-02-20 23:00:50', '1', '2022-02-27 08:26:53', b'0', 119);
3806 INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (109, 'admin109', '$2a$10$JAqvH0tEc0I7dfDVBI7zyuB4E3j.uH6daIjV53.vUS6PknFkDJkuK', '芋艿', NULL, NULL, NULL, '', '15601691300', 0, '', 0, '', NULL, '1', '2022-02-20 23:11:50', '1', '2022-02-27 08:26:56', b'0', 120); 3833 INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (109, 'admin109', '$2a$10$JAqvH0tEc0I7dfDVBI7zyuB4E3j.uH6daIjV53.vUS6PknFkDJkuK', '芋艿', NULL, NULL, NULL, '', '15601691300', 0, '', 0, '', NULL, '1', '2022-02-20 23:11:50', '1', '2022-02-27 08:26:56', b'0', 120);
3807 INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (110, 'admin110', '$2a$10$mRMIYLDtRHlf6.9ipiqH1.Z.bh/R9dO9d5iHiGYPigi6r5KOoR2Wm', '小王', NULL, NULL, NULL, '', '15601691300', 0, '', 0, '127.0.0.1', '2022-09-25 22:47:33', '1', '2022-02-22 00:56:14', NULL, '2022-09-25 22:47:33', b'0', 121); 3834 INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (110, 'admin110', '$2a$10$mRMIYLDtRHlf6.9ipiqH1.Z.bh/R9dO9d5iHiGYPigi6r5KOoR2Wm', '小王', NULL, NULL, NULL, '', '15601691300', 0, '', 0, '127.0.0.1', '2022-09-25 22:47:33', '1', '2022-02-22 00:56:14', NULL, '2022-09-25 22:47:33', b'0', 121);
3808 -INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (111, 'test', '$2a$10$mExveopHUx9Q4QiLtAzhDeH3n4/QlNLzEsM4AqgxKrU.ciUZDXZCy', '测试用户', NULL, NULL, '[]', '', '', 0, '', 0, '', NULL, '110', '2022-02-23 13:14:33', '110', '2022-02-23 13:14:33', b'0', 121); 3835 +INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (111, 'test', '$2a$10$mRMIYLDtRHlf6.9ipiqH1.Z.bh/R9dO9d5iHiGYPigi6r5KOoR2Wm', '测试用户', NULL, NULL, '[]', '', '', 0, '', 0, '0:0:0:0:0:0:0:1', '2023-10-18 23:31:51', '110', '2022-02-23 13:14:33', NULL, '2023-10-18 23:31:51', b'0', 121);
3809 INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (112, 'newobject', '$2a$10$3alwklxqfq8/hKoW6oUV0OJp0IdQpBDauLy4633SpUjrRsStl6kMa', '新对象', NULL, 100, '[]', '', '', 1, '', 0, '0:0:0:0:0:0:0:1', '2023-02-10 13:48:13', '1', '2022-02-23 19:08:03', NULL, '2023-02-10 13:48:13', b'0', 1); 3836 INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (112, 'newobject', '$2a$10$3alwklxqfq8/hKoW6oUV0OJp0IdQpBDauLy4633SpUjrRsStl6kMa', '新对象', NULL, 100, '[]', '', '', 1, '', 0, '0:0:0:0:0:0:0:1', '2023-02-10 13:48:13', '1', '2022-02-23 19:08:03', NULL, '2023-02-10 13:48:13', b'0', 1);
3810 INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (113, 'aoteman', '$2a$10$0acJOIk2D25/oC87nyclE..0lzeu9DtQ/n3geP4fkun/zIVRhHJIO', '芋道', NULL, NULL, NULL, '', '15601691300', 0, '', 0, '127.0.0.1', '2022-03-19 18:38:51', '1', '2022-03-07 21:37:58', NULL, '2022-03-19 18:38:51', b'0', 122); 3837 INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (113, 'aoteman', '$2a$10$0acJOIk2D25/oC87nyclE..0lzeu9DtQ/n3geP4fkun/zIVRhHJIO', '芋道', NULL, NULL, NULL, '', '15601691300', 0, '', 0, '127.0.0.1', '2022-03-19 18:38:51', '1', '2022-03-07 21:37:58', NULL, '2022-03-19 18:38:51', b'0', 122);
3811 INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (114, 'hrmgr', '$2a$10$TR4eybBioGRhBmDBWkqWLO6NIh3mzYa8KBKDDB5woiGYFVlRAi.fu', 'hr 小姐姐', NULL, NULL, '[3]', '', '', 0, '', 0, '127.0.0.1', '2022-03-19 22:15:43', '1', '2022-03-19 21:50:58', NULL, '2022-03-19 22:15:43', b'0', 1); 3838 INSERT INTO `system_users` (`id`, `username`, `password`, `nickname`, `remark`, `dept_id`, `post_ids`, `email`, `mobile`, `sex`, `avatar`, `status`, `login_ip`, `login_date`, `creator`, `create_time`, `updater`, `update_time`, `deleted`, `tenant_id`) VALUES (114, 'hrmgr', '$2a$10$TR4eybBioGRhBmDBWkqWLO6NIh3mzYa8KBKDDB5woiGYFVlRAi.fu', 'hr 小姐姐', NULL, NULL, '[3]', '', '', 0, '', 0, '127.0.0.1', '2022-03-19 22:15:43', '1', '2022-03-19 21:50:58', NULL, '2022-03-19 22:15:43', b'0', 1);
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/transfer/PayTransferUnifiedReqDTO.java
@@ -51,7 +51,9 @@ public class PayTransferUnifiedReqDTO { @@ -51,7 +51,9 @@ public class PayTransferUnifiedReqDTO {
51 private String title; 51 private String title;
52 52
53 /** 53 /**
54 - * 收款方信息,转账类型不同,收款方信息不同 54 + * 收款方信息。
  55 + *
  56 + * 转账类型 {@link #type} 不同,收款方信息不同
55 */ 57 */
56 @NotEmpty(message = "收款方信息 不能为空") 58 @NotEmpty(message = "收款方信息 不能为空")
57 private Map<String, String> payeeInfo; 59 private Map<String, String> payeeInfo;
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayTransferClient.java
@@ -22,6 +22,7 @@ import lombok.extern.slf4j.Slf4j; @@ -22,6 +22,7 @@ import lombok.extern.slf4j.Slf4j;
22 import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.BAD_REQUEST; 22 import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.BAD_REQUEST;
23 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception0; 23 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception0;
24 24
  25 +// TODO @jason:看看能不能融合到 AbstractAlipayPayClient 中。
25 /** 26 /**
26 * 支付宝转账的 PayClient 实现类 27 * 支付宝转账的 PayClient 实现类
27 * 28 *
@@ -29,6 +30,7 @@ import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionU @@ -29,6 +30,7 @@ import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionU
29 */ 30 */
30 @Slf4j 31 @Slf4j
31 public class AlipayTransferClient extends AbstractAlipayPayClient { 32 public class AlipayTransferClient extends AbstractAlipayPayClient {
  33 + // TODO @jason:方法之间,要有空格噢
32 public AlipayTransferClient(Long channelId, AlipayPayClientConfig config) { 34 public AlipayTransferClient(Long channelId, AlipayPayClientConfig config) {
33 super(channelId, PayChannelEnum.ALIPAY_TRANSFER.getCode(), config); 35 super(channelId, PayChannelEnum.ALIPAY_TRANSFER.getCode(), config);
34 } 36 }
@@ -49,16 +51,17 @@ public class AlipayTransferClient extends AbstractAlipayPayClient { @@ -49,16 +51,17 @@ public class AlipayTransferClient extends AbstractAlipayPayClient {
49 model.setOrderTitle(reqDTO.getTitle()); // 转账业务的标题,用于在支付宝用户的账单里显示。 51 model.setOrderTitle(reqDTO.getTitle()); // 转账业务的标题,用于在支付宝用户的账单里显示。
50 model.setOutBizNo(reqDTO.getOutTransferNo()); 52 model.setOutBizNo(reqDTO.getOutTransferNo());
51 model.setProductCode("TRANS_ACCOUNT_NO_PWD"); // 销售产品码。单笔无密转账固定为 TRANS_ACCOUNT_NO_PWD 53 model.setProductCode("TRANS_ACCOUNT_NO_PWD"); // 销售产品码。单笔无密转账固定为 TRANS_ACCOUNT_NO_PWD
52 - model.setBizScene("DIRECT_TRANSFER"); // 业务场景 单笔无密转账固定为 DIRECT_TRANSFER。 54 + model.setBizScene("DIRECT_TRANSFER"); // 业务场景 单笔无密转账固定为 DIRECT_TRANSFER
53 model.setBusinessParams(JsonUtils.toJsonString(reqDTO.getChannelExtras())); 55 model.setBusinessParams(JsonUtils.toJsonString(reqDTO.getChannelExtras()));
54 PayTransferTypeEnum transferType = PayTransferTypeEnum.ofType(reqDTO.getType()); 56 PayTransferTypeEnum transferType = PayTransferTypeEnum.ofType(reqDTO.getType());
55 - switch(transferType){  
56 - case WX_BALANCE :  
57 - case WALLET_BALANCE : { 57 + switch(transferType) {
  58 + case WX_BALANCE:
  59 + case WALLET_BALANCE: {
58 log.error("[doUnifiedTransfer],支付宝转账不支持的转账类型{}", transferType); 60 log.error("[doUnifiedTransfer],支付宝转账不支持的转账类型{}", transferType);
59 throw new UnsupportedOperationException(String.format("支付宝转账不支持转账类型: %s",transferType.getName())); 61 throw new UnsupportedOperationException(String.format("支付宝转账不支持转账类型: %s",transferType.getName()));
60 } 62 }
61 - case ALIPAY_BALANCE : { 63 + // TODO @jason:是不是不用传递 transferType 参数哈?因为应该已经明确是支付宝啦?
  64 + case ALIPAY_BALANCE: {
62 // ② 个性化的参数 65 // ② 个性化的参数
63 Participant payeeInfo = new Participant(); 66 Participant payeeInfo = new Participant();
64 payeeInfo.setIdentityType("ALIPAY_LOGON_ID"); 67 payeeInfo.setIdentityType("ALIPAY_LOGON_ID");
@@ -90,7 +93,7 @@ public class AlipayTransferClient extends AbstractAlipayPayClient { @@ -90,7 +93,7 @@ public class AlipayTransferClient extends AbstractAlipayPayClient {
90 return PayTransferRespDTO.successOf(response.getOrderId(), parseTime(response.getTransDate()), 93 return PayTransferRespDTO.successOf(response.getOrderId(), parseTime(response.getTransDate()),
91 response.getOutBizNo(), response); 94 response.getOutBizNo(), response);
92 } 95 }
93 - case BANK_CARD : { 96 + case BANK_CARD: {
94 Participant payeeInfo = new Participant(); 97 Participant payeeInfo = new Participant();
95 payeeInfo.setIdentityType("BANKCARD_ACCOUNT"); 98 payeeInfo.setIdentityType("BANKCARD_ACCOUNT");
96 throw new UnsupportedOperationException("待实现"); 99 throw new UnsupportedOperationException("待实现");
@@ -100,4 +103,5 @@ public class AlipayTransferClient extends AbstractAlipayPayClient { @@ -100,4 +103,5 @@ public class AlipayTransferClient extends AbstractAlipayPayClient {
100 } 103 }
101 } 104 }
102 } 105 }
  106 +
103 } 107 }
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/mock/MockPayClient.java
@@ -70,4 +70,5 @@ public class MockPayClient extends AbstractPayClient&lt;NonePayClientConfig&gt; { @@ -70,4 +70,5 @@ public class MockPayClient extends AbstractPayClient&lt;NonePayClientConfig&gt; {
70 protected PayTransferRespDTO doUnifiedTransfer(PayTransferUnifiedReqDTO reqDTO) { 70 protected PayTransferRespDTO doUnifiedTransfer(PayTransferUnifiedReqDTO reqDTO) {
71 throw new UnsupportedOperationException("待实现"); 71 throw new UnsupportedOperationException("待实现");
72 } 72 }
  73 +
73 } 74 }
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/channel/PayChannelEnum.java
@@ -28,6 +28,7 @@ public enum PayChannelEnum { @@ -28,6 +28,7 @@ public enum PayChannelEnum {
28 ALIPAY_APP("alipay_app", "支付宝App 支付", AlipayPayClientConfig.class), 28 ALIPAY_APP("alipay_app", "支付宝App 支付", AlipayPayClientConfig.class),
29 ALIPAY_QR("alipay_qr", "支付宝扫码支付", AlipayPayClientConfig.class), 29 ALIPAY_QR("alipay_qr", "支付宝扫码支付", AlipayPayClientConfig.class),
30 ALIPAY_BAR("alipay_bar", "支付宝条码支付", AlipayPayClientConfig.class), 30 ALIPAY_BAR("alipay_bar", "支付宝条码支付", AlipayPayClientConfig.class),
  31 + // TODO @jason:是不是按照微信聊的,合并回 ALIPAY_PC;因为支付宝、微信都是多种支付方式,选择其中的一种即可;
31 ALIPAY_TRANSFER("alipay_transfer", "支付宝转账", AlipayPayClientConfig.class), 32 ALIPAY_TRANSFER("alipay_transfer", "支付宝转账", AlipayPayClientConfig.class),
32 33
33 MOCK("mock", "模拟支付", NonePayClientConfig.class), 34 MOCK("mock", "模拟支付", NonePayClientConfig.class),
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/transfer/PayTransferStatusRespEnum.java
@@ -18,10 +18,10 @@ public enum PayTransferStatusRespEnum { @@ -18,10 +18,10 @@ public enum PayTransferStatusRespEnum {
18 18
19 /** 19 /**
20 * TODO 转账到银行卡. 会有T+0 T+1 到账的请情况。 还未实现 20 * TODO 转账到银行卡. 会有T+0 T+1 到账的请情况。 还未实现
  21 + * TODO @jason:可以看看其它开源项目,针对这个场景,处理策略是怎么样的?例如说,每天主动轮询?这个状态的单子?
21 */ 22 */
22 IN_PROGRESS(10, "转账进行中"), 23 IN_PROGRESS(10, "转账进行中"),
23 24
24 -  
25 SUCCESS(20, "转账成功"), 25 SUCCESS(20, "转账成功"),
26 /** 26 /**
27 * 转账关闭 (失败,或者其它情况) 27 * 转账关闭 (失败,或者其它情况)
yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/transfer/PayTransferTypeEnum.java
@@ -15,6 +15,7 @@ import java.util.Arrays; @@ -15,6 +15,7 @@ import java.util.Arrays;
15 @AllArgsConstructor 15 @AllArgsConstructor
16 @Getter 16 @Getter
17 public enum PayTransferTypeEnum implements IntArrayValuable { 17 public enum PayTransferTypeEnum implements IntArrayValuable {
  18 +
18 ALIPAY_BALANCE(1, "支付宝余额"), 19 ALIPAY_BALANCE(1, "支付宝余额"),
19 WX_BALANCE(2, "微信余额"), 20 WX_BALANCE(2, "微信余额"),
20 BANK_CARD(3, "银行卡"), 21 BANK_CARD(3, "银行卡"),
@@ -33,7 +34,9 @@ public enum PayTransferTypeEnum implements IntArrayValuable { @@ -33,7 +34,9 @@ public enum PayTransferTypeEnum implements IntArrayValuable {
33 return ARRAYS; 34 return ARRAYS;
34 } 35 }
35 36
  37 + // TODO @jason:是不是 typeOf 更符合预期哈?
36 public static PayTransferTypeEnum ofType(Integer type) { 38 public static PayTransferTypeEnum ofType(Integer type) {
37 return ArrayUtil.firstMatch(item -> item.getType().equals(type), values()); 39 return ArrayUtil.firstMatch(item -> item.getType().equals(type), values());
38 } 40 }
  41 +
39 } 42 }
yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/query/MPJLambdaWrapperX.java 0 → 100644
  1 +package cn.iocoder.yudao.framework.mybatis.core.query;
  2 +
  3 +import cn.hutool.core.util.ArrayUtil;
  4 +import cn.hutool.core.util.ObjectUtil;
  5 +import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils;
  6 +import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
  7 +import com.github.yulichang.toolkit.MPJWrappers;
  8 +import com.github.yulichang.wrapper.MPJLambdaWrapper;
  9 +import org.springframework.util.StringUtils;
  10 +
  11 +import java.util.Collection;
  12 +import java.util.function.Consumer;
  13 +
  14 +/**
  15 + * 拓展 MyBatis Plus Join QueryWrapper 类,主要增加如下功能:
  16 + * <p>
  17 + * 1. 拼接条件的方法,增加 xxxIfPresent 方法,用于判断值不存在的时候,不要拼接到条件中。
  18 + *
  19 + * @param <T> 数据类型
  20 + */
  21 +public class MPJLambdaWrapperX<T> extends MPJLambdaWrapper<T> {
  22 +
  23 + public MPJLambdaWrapperX<T> likeIfPresent(SFunction<T, ?> column, String val) {
  24 + MPJWrappers.lambdaJoin().like(column, val);
  25 + if (StringUtils.hasText(val)) {
  26 + return (MPJLambdaWrapperX<T>) super.like(column, val);
  27 + }
  28 + return this;
  29 + }
  30 +
  31 + public MPJLambdaWrapperX<T> inIfPresent(SFunction<T, ?> column, Collection<?> values) {
  32 + if (ObjectUtil.isAllNotEmpty(values) && !ArrayUtil.isEmpty(values)) {
  33 + return (MPJLambdaWrapperX<T>) super.in(column, values);
  34 + }
  35 + return this;
  36 + }
  37 +
  38 + public MPJLambdaWrapperX<T> inIfPresent(SFunction<T, ?> column, Object... values) {
  39 + if (ObjectUtil.isAllNotEmpty(values) && !ArrayUtil.isEmpty(values)) {
  40 + return (MPJLambdaWrapperX<T>) super.in(column, values);
  41 + }
  42 + return this;
  43 + }
  44 +
  45 + public MPJLambdaWrapperX<T> eqIfPresent(SFunction<T, ?> column, Object val) {
  46 + if (ObjectUtil.isNotEmpty(val)) {
  47 + return (MPJLambdaWrapperX<T>) super.eq(column, val);
  48 + }
  49 + return this;
  50 + }
  51 +
  52 + public MPJLambdaWrapperX<T> neIfPresent(SFunction<T, ?> column, Object val) {
  53 + if (ObjectUtil.isNotEmpty(val)) {
  54 + return (MPJLambdaWrapperX<T>) super.ne(column, val);
  55 + }
  56 + return this;
  57 + }
  58 +
  59 + public MPJLambdaWrapperX<T> gtIfPresent(SFunction<T, ?> column, Object val) {
  60 + if (val != null) {
  61 + return (MPJLambdaWrapperX<T>) super.gt(column, val);
  62 + }
  63 + return this;
  64 + }
  65 +
  66 + public MPJLambdaWrapperX<T> geIfPresent(SFunction<T, ?> column, Object val) {
  67 + if (val != null) {
  68 + return (MPJLambdaWrapperX<T>) super.ge(column, val);
  69 + }
  70 + return this;
  71 + }
  72 +
  73 + public MPJLambdaWrapperX<T> ltIfPresent(SFunction<T, ?> column, Object val) {
  74 + if (val != null) {
  75 + return (MPJLambdaWrapperX<T>) super.lt(column, val);
  76 + }
  77 + return this;
  78 + }
  79 +
  80 + public MPJLambdaWrapperX<T> leIfPresent(SFunction<T, ?> column, Object val) {
  81 + if (val != null) {
  82 + return (MPJLambdaWrapperX<T>) super.le(column, val);
  83 + }
  84 + return this;
  85 + }
  86 +
  87 + public MPJLambdaWrapperX<T> betweenIfPresent(SFunction<T, ?> column, Object val1, Object val2) {
  88 + if (val1 != null && val2 != null) {
  89 + return (MPJLambdaWrapperX<T>) super.between(column, val1, val2);
  90 + }
  91 + if (val1 != null) {
  92 + return (MPJLambdaWrapperX<T>) ge(column, val1);
  93 + }
  94 + if (val2 != null) {
  95 + return (MPJLambdaWrapperX<T>) le(column, val2);
  96 + }
  97 + return this;
  98 + }
  99 +
  100 + public MPJLambdaWrapperX<T> betweenIfPresent(SFunction<T, ?> column, Object[] values) {
  101 + Object val1 = ArrayUtils.get(values, 0);
  102 + Object val2 = ArrayUtils.get(values, 1);
  103 + return betweenIfPresent(column, val1, val2);
  104 + }
  105 +
  106 + // ========== 重写父类方法,方便链式调用 ==========
  107 +
  108 + @Override
  109 + public <X> MPJLambdaWrapperX<T> eq(boolean condition, SFunction<X, ?> column, Object val) {
  110 + super.eq(condition, column, val);
  111 + return this;
  112 + }
  113 +
  114 + @Override
  115 + public <X> MPJLambdaWrapperX<T> eq(SFunction<X, ?> column, Object val) {
  116 + super.eq(column, val);
  117 + return this;
  118 + }
  119 +
  120 + @Override
  121 + public <X> MPJLambdaWrapperX<T> orderByDesc(SFunction<X, ?> column) {
  122 + //noinspection unchecked
  123 + super.orderByDesc(true, column);
  124 + return this;
  125 + }
  126 +
  127 + @Override
  128 + public MPJLambdaWrapperX<T> last(String lastSql) {
  129 + super.last(lastSql);
  130 + return this;
  131 + }
  132 +
  133 + @Override
  134 + public <X> MPJLambdaWrapperX<T> in(SFunction<X, ?> column, Collection<?> coll) {
  135 + super.in(column, coll);
  136 + return this;
  137 + }
  138 +
  139 + @Override
  140 + public MPJLambdaWrapperX<T> selectAll(Class<?> clazz) {
  141 + super.selectAll(clazz);
  142 + return this;
  143 + }
  144 +
  145 + @Override
  146 + public MPJLambdaWrapperX<T> selectAll(Class<?> clazz, String prefix) {
  147 + super.selectAll(clazz, prefix);
  148 + return this;
  149 + }
  150 +
  151 + @Override
  152 + public <S> MPJLambdaWrapperX<T> selectAs(SFunction<S, ?> column, String alias) {
  153 + super.selectAs(column, alias);
  154 + return this;
  155 + }
  156 +
  157 + @Override
  158 + public <E> MPJLambdaWrapperX<T> selectAs(String column, SFunction<E, ?> alias) {
  159 + super.selectAs(column, alias);
  160 + return this;
  161 + }
  162 +
  163 + @Override
  164 + public <S, X> MPJLambdaWrapperX<T> selectAs(SFunction<S, ?> column, SFunction<X, ?> alias) {
  165 + super.selectAs(column, alias);
  166 + return this;
  167 + }
  168 +
  169 + @Override
  170 + public <E, X> MPJLambdaWrapperX<T> selectAs(String index, SFunction<E, ?> column, SFunction<X, ?> alias) {
  171 + super.selectAs(index, column, alias);
  172 + return this;
  173 + }
  174 +
  175 + @Override
  176 + public <E> MPJLambdaWrapperX<T> selectAsClass(Class<E> source, Class<?> tag) {
  177 + super.selectAsClass(source, tag);
  178 + return this;
  179 + }
  180 +
  181 + @Override
  182 + public <E, F> MPJLambdaWrapperX<T> selectSub(Class<E> clazz, Consumer<MPJLambdaWrapper<E>> consumer, SFunction<F, ?> alias) {
  183 + super.selectSub(clazz, consumer, alias);
  184 + return this;
  185 + }
  186 +
  187 + @Override
  188 + public <E, F> MPJLambdaWrapperX<T> selectSub(Class<E> clazz, String st, Consumer<MPJLambdaWrapper<E>> consumer, SFunction<F, ?> alias) {
  189 + super.selectSub(clazz, st, consumer, alias);
  190 + return this;
  191 + }
  192 +
  193 + @Override
  194 + public <S> MPJLambdaWrapperX<T> selectCount(SFunction<S, ?> column) {
  195 + super.selectCount(column);
  196 + return this;
  197 + }
  198 +
  199 + @Override
  200 + public MPJLambdaWrapperX<T> selectCount(Object column, String alias) {
  201 + super.selectCount(column, alias);
  202 + return this;
  203 + }
  204 +
  205 + @Override
  206 + public <X> MPJLambdaWrapperX<T> selectCount(Object column, SFunction<X, ?> alias) {
  207 + super.selectCount(column, alias);
  208 + return this;
  209 + }
  210 +
  211 + @Override
  212 + public <S, X> MPJLambdaWrapperX<T> selectCount(SFunction<S, ?> column, String alias) {
  213 + super.selectCount(column, alias);
  214 + return this;
  215 + }
  216 +
  217 + @Override
  218 + public <S, X> MPJLambdaWrapperX<T> selectCount(SFunction<S, ?> column, SFunction<X, ?> alias) {
  219 + super.selectCount(column, alias);
  220 + return this;
  221 + }
  222 +
  223 + @Override
  224 + public <S> MPJLambdaWrapperX<T> selectSum(SFunction<S, ?> column) {
  225 + super.selectSum(column);
  226 + return this;
  227 + }
  228 +
  229 + @Override
  230 + public <S, X> MPJLambdaWrapperX<T> selectSum(SFunction<S, ?> column, String alias) {
  231 + super.selectSum(column, alias);
  232 + return this;
  233 + }
  234 +
  235 + @Override
  236 + public <S, X> MPJLambdaWrapperX<T> selectSum(SFunction<S, ?> column, SFunction<X, ?> alias) {
  237 + super.selectSum(column, alias);
  238 + return this;
  239 + }
  240 +
  241 + @Override
  242 + public <S> MPJLambdaWrapperX<T> selectMax(SFunction<S, ?> column) {
  243 + super.selectMax(column);
  244 + return this;
  245 + }
  246 +
  247 + @Override
  248 + public <S, X> MPJLambdaWrapperX<T> selectMax(SFunction<S, ?> column, String alias) {
  249 + super.selectMax(column, alias);
  250 + return this;
  251 + }
  252 +
  253 + @Override
  254 + public <S, X> MPJLambdaWrapperX<T> selectMax(SFunction<S, ?> column, SFunction<X, ?> alias) {
  255 + super.selectMax(column, alias);
  256 + return this;
  257 + }
  258 +
  259 + @Override
  260 + public <S> MPJLambdaWrapperX<T> selectMin(SFunction<S, ?> column) {
  261 + super.selectMin(column);
  262 + return this;
  263 + }
  264 +
  265 + @Override
  266 + public <S, X> MPJLambdaWrapperX<T> selectMin(SFunction<S, ?> column, String alias) {
  267 + super.selectMin(column, alias);
  268 + return this;
  269 + }
  270 +
  271 + @Override
  272 + public <S, X> MPJLambdaWrapperX<T> selectMin(SFunction<S, ?> column, SFunction<X, ?> alias) {
  273 + super.selectMin(column, alias);
  274 + return this;
  275 + }
  276 +
  277 + @Override
  278 + public <S> MPJLambdaWrapperX<T> selectAvg(SFunction<S, ?> column) {
  279 + super.selectAvg(column);
  280 + return this;
  281 + }
  282 +
  283 + @Override
  284 + public <S, X> MPJLambdaWrapperX<T> selectAvg(SFunction<S, ?> column, String alias) {
  285 + super.selectAvg(column, alias);
  286 + return this;
  287 + }
  288 +
  289 + @Override
  290 + public <S, X> MPJLambdaWrapperX<T> selectAvg(SFunction<S, ?> column, SFunction<X, ?> alias) {
  291 + super.selectAvg(column, alias);
  292 + return this;
  293 + }
  294 +
  295 + @Override
  296 + public <S> MPJLambdaWrapperX<T> selectLen(SFunction<S, ?> column) {
  297 + super.selectLen(column);
  298 + return this;
  299 + }
  300 +
  301 + @Override
  302 + public <S, X> MPJLambdaWrapperX<T> selectLen(SFunction<S, ?> column, String alias) {
  303 + super.selectLen(column, alias);
  304 + return this;
  305 + }
  306 +
  307 + @Override
  308 + public <S, X> MPJLambdaWrapperX<T> selectLen(SFunction<S, ?> column, SFunction<X, ?> alias) {
  309 + super.selectLen(column, alias);
  310 + return this;
  311 + }
  312 +
  313 +}
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/activity/AppActivityController.java
@@ -46,7 +46,7 @@ public class AppActivityController { @@ -46,7 +46,7 @@ public class AppActivityController {
46 @Parameter(name = "spuId", description = "商品编号", required = true) 46 @Parameter(name = "spuId", description = "商品编号", required = true)
47 public CommonResult<List<AppActivityRespVO>> getActivityListBySpuId(@RequestParam("spuId") Long spuId) { 47 public CommonResult<List<AppActivityRespVO>> getActivityListBySpuId(@RequestParam("spuId") Long spuId) {
48 // 每种活动,只返回一个 48 // 每种活动,只返回一个
49 - return success(getAppActivityRespVOList(Collections.singletonList(spuId))); 49 + return success(getAppActivityList(Collections.singletonList(spuId)));
50 } 50 }
51 51
52 @GetMapping("/list-by-spu-ids") 52 @GetMapping("/list-by-spu-ids")
@@ -57,16 +57,17 @@ public class AppActivityController { @@ -57,16 +57,17 @@ public class AppActivityController {
57 return success(MapUtil.empty()); 57 return success(MapUtil.empty());
58 } 58 }
59 // 每种活动,只返回一个;key 为 SPU 编号 59 // 每种活动,只返回一个;key 为 SPU 编号
60 - return success(convertMultiMap(getAppActivityRespVOList(spuIds), AppActivityRespVO::getSpuId)); 60 + return success(convertMultiMap(getAppActivityList(spuIds), AppActivityRespVO::getSpuId));
61 } 61 }
62 62
63 - private List<AppActivityRespVO> getAppActivityRespVOList(Collection<Long> spuIds) { 63 + private List<AppActivityRespVO> getAppActivityList(Collection<Long> spuIds) {
64 if (CollUtil.isEmpty(spuIds)) { 64 if (CollUtil.isEmpty(spuIds)) {
65 return new ArrayList<>(); 65 return new ArrayList<>();
66 } 66 }
67 LocalDateTime now = LocalDateTime.now(); 67 LocalDateTime now = LocalDateTime.now();
68 List<AppActivityRespVO> activityList = new ArrayList<>(); 68 List<AppActivityRespVO> activityList = new ArrayList<>();
69 - // 拼团活动-获取开启的且开始的且没有结束的活动 69 +
  70 + // 1. 拼团活动 - 获取开启的且开始的且没有结束的活动
70 List<CombinationActivityDO> combinationActivities = combinationActivityService.getCombinationActivityBySpuIdsAndStatusAndDateTimeLt( 71 List<CombinationActivityDO> combinationActivities = combinationActivityService.getCombinationActivityBySpuIdsAndStatusAndDateTimeLt(
71 spuIds, CommonStatusEnum.ENABLE.getStatus(), now); 72 spuIds, CommonStatusEnum.ENABLE.getStatus(), now);
72 if (CollUtil.isNotEmpty(combinationActivities)) { 73 if (CollUtil.isNotEmpty(combinationActivities)) {
@@ -76,7 +77,8 @@ public class AppActivityController { @@ -76,7 +77,8 @@ public class AppActivityController {
76 .setSpuId(item.getSpuId()).setStartTime(item.getStartTime()).setEndTime(item.getEndTime())); 77 .setSpuId(item.getSpuId()).setStartTime(item.getStartTime()).setEndTime(item.getEndTime()));
77 }); 78 });
78 } 79 }
79 - // 秒杀活动-获取开启的且开始的且没有结束的活动 80 +
  81 + // 2. 秒杀活动 - 获取开启的且开始的且没有结束的活动
80 List<SeckillActivityDO> seckillActivities = seckillActivityService.getSeckillActivityBySpuIdsAndStatusAndDateTimeLt( 82 List<SeckillActivityDO> seckillActivities = seckillActivityService.getSeckillActivityBySpuIdsAndStatusAndDateTimeLt(
81 spuIds, CommonStatusEnum.ENABLE.getStatus(), now); 83 spuIds, CommonStatusEnum.ENABLE.getStatus(), now);
82 if (CollUtil.isNotEmpty(seckillActivities)) { 84 if (CollUtil.isNotEmpty(seckillActivities)) {
@@ -86,7 +88,8 @@ public class AppActivityController { @@ -86,7 +88,8 @@ public class AppActivityController {
86 .setSpuId(item.getSpuId()).setStartTime(item.getStartTime()).setEndTime(item.getEndTime())); 88 .setSpuId(item.getSpuId()).setStartTime(item.getStartTime()).setEndTime(item.getEndTime()));
87 }); 89 });
88 } 90 }
89 - // 砍价活动-获取开启的且开始的且没有结束的活动 91 +
  92 + // 3. 砍价活动 - 获取开启的且开始的且没有结束的活动
90 List<BargainActivityDO> bargainActivities = bargainActivityService.getBargainActivityBySpuIdsAndStatusAndDateTimeLt( 93 List<BargainActivityDO> bargainActivities = bargainActivityService.getBargainActivityBySpuIdsAndStatusAndDateTimeLt(
91 spuIds, CommonStatusEnum.ENABLE.getStatus(), now); 94 spuIds, CommonStatusEnum.ENABLE.getStatus(), now);
92 if (CollUtil.isNotEmpty(bargainActivities)) { 95 if (CollUtil.isNotEmpty(bargainActivities)) {
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/article/AppArticleCategoryController.java
@@ -32,7 +32,7 @@ public class AppArticleCategoryController { @@ -32,7 +32,7 @@ public class AppArticleCategoryController {
32 public CommonResult<List<AppArticleCategoryRespVO>> getArticleCategoryList() { 32 public CommonResult<List<AppArticleCategoryRespVO>> getArticleCategoryList() {
33 List<ArticleCategoryDO> categoryList = articleCategoryService.getArticleCategoryListByStatus( 33 List<ArticleCategoryDO> categoryList = articleCategoryService.getArticleCategoryListByStatus(
34 CommonStatusEnum.ENABLE.getStatus()); 34 CommonStatusEnum.ENABLE.getStatus());
35 - categoryList.sort(Comparator.comparing(ArticleCategoryDO::getSort).reversed()); // 按 sort 降序排列 35 + categoryList.sort(Comparator.comparing(ArticleCategoryDO::getSort)); // 按 sort 降序排列
36 return success(ArticleCategoryConvert.INSTANCE.convertList04(categoryList)); 36 return success(ArticleCategoryConvert.INSTANCE.convertList04(categoryList));
37 } 37 }
38 38
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/article/AppArticleController.java
@@ -56,10 +56,12 @@ public class AppArticleController { @@ -56,10 +56,12 @@ public class AppArticleController {
56 return success(ArticleConvert.INSTANCE.convert01(articleService.getArticle(id))); 56 return success(ArticleConvert.INSTANCE.convert01(articleService.getArticle(id)));
57 } 57 }
58 58
  59 + // TODO @puhui999:add-browse-count 噢;前端 uniapp 也要接下;就是打开文章的时候,调用下这个接口;
59 @PutMapping("/add-browseCount") 60 @PutMapping("/add-browseCount")
60 @Operation(summary = "增加文章浏览量") 61 @Operation(summary = "增加文章浏览量")
61 @Parameter(name = "id", description = "文章编号", example = "1024") 62 @Parameter(name = "id", description = "文章编号", example = "1024")
62 public CommonResult<Boolean> addBrowseCount(@RequestParam("id") Long id) { 63 public CommonResult<Boolean> addBrowseCount(@RequestParam("id") Long id) {
  64 + // TODO @puhui999:addArticleBrowseCount
63 articleService.addBrowseCount(id); 65 articleService.addBrowseCount(id);
64 return success(true); 66 return success(true);
65 } 67 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/combination/CombinationActivityConvert.java
@@ -204,9 +204,6 @@ public interface CombinationActivityConvert { @@ -204,9 +204,6 @@ public interface CombinationActivityConvert {
204 return respVO; 204 return respVO;
205 } 205 }
206 206
207 - @Mapping(target = "id", ignore = true)  
208 - CombinationRecordDO convert5(CombinationRecordDO headRecord);  
209 -  
210 /** 207 /**
211 * 转换生成虚拟成团虚拟记录 208 * 转换生成虚拟成团虚拟记录
212 * 209 *
@@ -214,21 +211,19 @@ public interface CombinationActivityConvert { @@ -214,21 +211,19 @@ public interface CombinationActivityConvert {
214 * @return 虚拟记录列表 211 * @return 虚拟记录列表
215 */ 212 */
216 default List<CombinationRecordDO> convertVirtualRecordList(CombinationRecordDO headRecord) { 213 default List<CombinationRecordDO> convertVirtualRecordList(CombinationRecordDO headRecord) {
217 - List<CombinationRecordDO> createRecords = new ArrayList<>();  
218 - // 计算需要创建的虚拟成团记录数量  
219 int count = headRecord.getUserSize() - headRecord.getUserCount(); 214 int count = headRecord.getUserSize() - headRecord.getUserCount();
  215 + List<CombinationRecordDO> createRecords = new ArrayList<>(count);
220 for (int i = 0; i < count; i++) { 216 for (int i = 0; i < count; i++) {
221 // 基础信息和团长保持一致 217 // 基础信息和团长保持一致
222 CombinationRecordDO newRecord = convert5(headRecord); 218 CombinationRecordDO newRecord = convert5(headRecord);
223 // 虚拟信息 219 // 虚拟信息
224 - newRecord.setCount(0);  
225 - newRecord.setUserId(0L);  
226 - newRecord.setNickname("");  
227 - newRecord.setAvatar("");  
228 - newRecord.setOrderId(0L); 220 + newRecord.setCount(0) // 会单独更新下,在后续的 Service 逻辑里
  221 + .setUserId(0L).setNickname("").setAvatar("").setOrderId(0L);
229 createRecords.add(newRecord); 222 createRecords.add(newRecord);
230 } 223 }
231 return createRecords; 224 return createRecords;
232 } 225 }
  226 + @Mapping(target = "id", ignore = true)
  227 + CombinationRecordDO convert5(CombinationRecordDO headRecord);
233 228
234 } 229 }
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/bargain/BargainActivityMapper.java
@@ -102,6 +102,7 @@ public interface BargainActivityMapper extends BaseMapperX&lt;BargainActivityDO&gt; { @@ -102,6 +102,7 @@ public interface BargainActivityMapper extends BaseMapperX&lt;BargainActivityDO&gt; {
102 .groupBy("spu_id")); 102 .groupBy("spu_id"));
103 } 103 }
104 104
  105 + // TODO @puhui999:是不是只要 endTime 小于就可以啦;
105 /** 106 /**
106 * 获取指定活动编号的活动列表且 107 * 获取指定活动编号的活动列表且
107 * 开始时间和结束时间小于给定时间 dateTime 的活动列表 108 * 开始时间和结束时间小于给定时间 dateTime 的活动列表
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/article/ArticleServiceImpl.java
@@ -10,7 +10,6 @@ import cn.iocoder.yudao.module.promotion.dal.dataobject.article.ArticleCategoryD @@ -10,7 +10,6 @@ import cn.iocoder.yudao.module.promotion.dal.dataobject.article.ArticleCategoryD
10 import cn.iocoder.yudao.module.promotion.dal.dataobject.article.ArticleDO; 10 import cn.iocoder.yudao.module.promotion.dal.dataobject.article.ArticleDO;
11 import cn.iocoder.yudao.module.promotion.dal.mysql.article.ArticleMapper; 11 import cn.iocoder.yudao.module.promotion.dal.mysql.article.ArticleMapper;
12 import org.springframework.stereotype.Service; 12 import org.springframework.stereotype.Service;
13 -import org.springframework.transaction.annotation.Transactional;  
14 import org.springframework.validation.annotation.Validated; 13 import org.springframework.validation.annotation.Validated;
15 14
16 import javax.annotation.Resource; 15 import javax.annotation.Resource;
@@ -112,12 +111,10 @@ public class ArticleServiceImpl implements ArticleService { @@ -112,12 +111,10 @@ public class ArticleServiceImpl implements ArticleService {
112 } 111 }
113 112
114 @Override 113 @Override
115 - @Transactional(rollbackFor = Exception.class)  
116 public void addBrowseCount(Long id) { 114 public void addBrowseCount(Long id) {
117 // 校验文章是否存在 115 // 校验文章是否存在
118 validateArticleExists(id); 116 validateArticleExists(id);
119 -  
120 - // 增加浏览次数 TODO 先简单做,用户规模不大,只 +1 117 + // 增加浏览次数
121 articleMapper.updateBrowseCount(id); 118 articleMapper.updateBrowseCount(id);
122 } 119 }
123 120
yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationRecordServiceImpl.java
@@ -369,6 +369,7 @@ public class CombinationRecordServiceImpl implements CombinationRecordService { @@ -369,6 +369,7 @@ public class CombinationRecordServiceImpl implements CombinationRecordService {
369 keyValue.setValue(keyValue.getValue() + 1); 369 keyValue.setValue(keyValue.getValue() + 1);
370 } 370 }
371 } catch (Exception ignored) { // 处理异常继续循环 371 } catch (Exception ignored) { // 处理异常继续循环
  372 + // TODO @puhui999:拼团过期 or 虚拟成团 可以改成 expireCombinationRecord;因为找方法更容易一些;
372 log.error("[拼团过期 or 虚拟成团][record({}) 处理异常,请进行处理!record 数据是:{}]", 373 log.error("[拼团过期 or 虚拟成团][record({}) 处理异常,请进行处理!record 数据是:{}]",
373 record.getId(), JsonUtils.toJsonString(record)); 374 record.getId(), JsonUtils.toJsonString(record));
374 } 375 }
@@ -383,10 +384,10 @@ public class CombinationRecordServiceImpl implements CombinationRecordService { @@ -383,10 +384,10 @@ public class CombinationRecordServiceImpl implements CombinationRecordService {
383 */ 384 */
384 @Transactional(rollbackFor = Exception.class) 385 @Transactional(rollbackFor = Exception.class)
385 public void handleExpireRecord(CombinationRecordDO headRecord) { 386 public void handleExpireRecord(CombinationRecordDO headRecord) {
386 - // 1.更新拼团记录 387 + // 1. 更新拼团记录
387 List<CombinationRecordDO> headAndRecords = updateBatchCombinationRecords(headRecord, 388 List<CombinationRecordDO> headAndRecords = updateBatchCombinationRecords(headRecord,
388 CombinationRecordStatusEnum.FAILED); 389 CombinationRecordStatusEnum.FAILED);
389 - // 2.订单取消 390 + // 2. 订单取消
390 headAndRecords.forEach(item -> tradeOrderApi.cancelPaidOrder(item.getUserId(), item.getOrderId())); 391 headAndRecords.forEach(item -> tradeOrderApi.cancelPaidOrder(item.getUserId(), item.getOrderId()));
391 } 392 }
392 393
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/TradeOrderController.java
@@ -24,8 +24,11 @@ import org.springframework.web.bind.annotation.*; @@ -24,8 +24,11 @@ import org.springframework.web.bind.annotation.*;
24 import javax.annotation.Resource; 24 import javax.annotation.Resource;
25 import java.util.List; 25 import java.util.List;
26 import java.util.Map; 26 import java.util.Map;
  27 +import java.util.Objects;
  28 +import java.util.Set;
27 29
28 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; 30 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  31 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
29 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; 32 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
30 33
31 @Tag(name = "管理后台 - 交易订单") 34 @Tag(name = "管理后台 - 交易订单")
@@ -56,7 +59,9 @@ public class TradeOrderController { @@ -56,7 +59,9 @@ public class TradeOrderController {
56 } 59 }
57 60
58 // 查询用户信息 61 // 查询用户信息
59 - Map<Long, MemberUserRespDTO> userMap = memberUserApi.getUserMap(convertSet(pageResult.getList(), TradeOrderDO::getUserId)); 62 + Set<Long> userIds = CollUtil.unionDistinct(convertList(pageResult.getList(), TradeOrderDO::getUserId),
  63 + convertList(pageResult.getList(), TradeOrderDO::getBrokerageUserId, Objects::nonNull));
  64 + Map<Long, MemberUserRespDTO> userMap = memberUserApi.getUserMap(userIds);
60 // 查询订单项 65 // 查询订单项
61 List<TradeOrderItemDO> orderItems = tradeOrderQueryService.getOrderItemListByOrderId( 66 List<TradeOrderItemDO> orderItems = tradeOrderQueryService.getOrderItemListByOrderId(
62 convertSet(pageResult.getList(), TradeOrderDO::getId)); 67 convertSet(pageResult.getList(), TradeOrderDO::getId));
@@ -64,6 +69,13 @@ public class TradeOrderController { @@ -64,6 +69,13 @@ public class TradeOrderController {
64 return success(TradeOrderConvert.INSTANCE.convertPage(pageResult, orderItems, userMap)); 69 return success(TradeOrderConvert.INSTANCE.convertPage(pageResult, orderItems, userMap));
65 } 70 }
66 71
  72 + @GetMapping("/summary")
  73 + @Operation(summary = "获得交易订单统计")
  74 + @PreAuthorize("@ss.hasPermission('trade:order:query')")
  75 + public CommonResult<TradeOrderSummaryRespVO> getOrderSummary(TradeOrderPageReqVO reqVO) {
  76 + return success(tradeOrderQueryService.getOrderSummary(reqVO));
  77 + }
  78 +
67 @GetMapping("/get-detail") 79 @GetMapping("/get-detail")
68 @Operation(summary = "获得交易订单详情") 80 @Operation(summary = "获得交易订单详情")
69 @Parameter(name = "id", description = "订单编号", required = true, example = "1") 81 @Parameter(name = "id", description = "订单编号", required = true, example = "1")
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderBaseVO.java
@@ -145,4 +145,7 @@ public class TradeOrderBaseVO { @@ -145,4 +145,7 @@ public class TradeOrderBaseVO {
145 @Schema(description = "VIP 减免金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "888") 145 @Schema(description = "VIP 减免金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "888")
146 private Integer vipPrice; 146 private Integer vipPrice;
147 147
  148 + @Schema(description = "推广人编号", example = "1")
  149 + private Long brokerageUserId;
  150 +
148 } 151 }
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderPageItemRespVO.java
1 package cn.iocoder.yudao.module.trade.controller.admin.order.vo; 1 package cn.iocoder.yudao.module.trade.controller.admin.order.vo;
2 2
3 -import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; 3 +import cn.iocoder.yudao.module.trade.controller.admin.base.member.user.MemberUserRespVO;
4 import cn.iocoder.yudao.module.trade.controller.admin.base.product.property.ProductPropertyValueDetailRespVO; 4 import cn.iocoder.yudao.module.trade.controller.admin.base.product.property.ProductPropertyValueDetailRespVO;
5 import io.swagger.v3.oas.annotations.media.Schema; 5 import io.swagger.v3.oas.annotations.media.Schema;
6 import lombok.Data; 6 import lombok.Data;
@@ -14,24 +14,20 @@ public class TradeOrderPageItemRespVO extends TradeOrderBaseVO { @@ -14,24 +14,20 @@ public class TradeOrderPageItemRespVO extends TradeOrderBaseVO {
14 @Schema(description = "收件人地区名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "上海 上海市 普陀区") 14 @Schema(description = "收件人地区名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "上海 上海市 普陀区")
15 private String receiverAreaName; 15 private String receiverAreaName;
16 16
17 - /**  
18 - * 订单项列表  
19 - */ 17 + @Schema(description = "订单项列表", requiredMode = Schema.RequiredMode.REQUIRED)
20 private List<Item> items; 18 private List<Item> items;
21 19
22 - // TODO @xiaobai:使用 MemberUserRespVO 返回哈;DTO 不直接给前端  
23 - /**  
24 - * 用户信息  
25 - */  
26 - private MemberUserRespDTO user; 20 + @Schema(description = "用户信息", requiredMode = Schema.RequiredMode.REQUIRED)
  21 + private MemberUserRespVO user;
  22 +
  23 + @Schema(description = "推广人信息")
  24 + private MemberUserRespVO brokerageUser;
27 25
28 @Schema(description = "管理后台 - 交易订单的分页项的订单项目") 26 @Schema(description = "管理后台 - 交易订单的分页项的订单项目")
29 @Data 27 @Data
30 public static class Item extends TradeOrderItemBaseVO { 28 public static class Item extends TradeOrderItemBaseVO {
31 29
32 - /**  
33 - * 属性数组  
34 - */ 30 + @Schema(description = "属性列表", requiredMode = Schema.RequiredMode.REQUIRED)
35 private List<ProductPropertyValueDetailRespVO> properties; 31 private List<ProductPropertyValueDetailRespVO> properties;
36 32
37 } 33 }
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderSummaryRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.trade.controller.admin.order.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.Data;
  5 +
  6 +@Schema(description = "管理后台 - 交易订单统计 Response VO")
  7 +@Data
  8 +public class TradeOrderSummaryRespVO {
  9 +
  10 + @Schema(description = "订单数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  11 + private Long orderCount;
  12 +
  13 + @Schema(description = "订单金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  14 + private Long orderPayPrice;
  15 +
  16 + @Schema(description = "退款单数", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  17 + private Long afterSaleCount;
  18 +
  19 + @Schema(description = "退款金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  20 + private Long afterSalePrice;
  21 +
  22 +}
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java
@@ -124,13 +124,17 @@ public interface TradeOrderConvert { @@ -124,13 +124,17 @@ public interface TradeOrderConvert {
124 TradeOrderPageItemRespVO orderVO = convert(order, xOrderItems); 124 TradeOrderPageItemRespVO orderVO = convert(order, xOrderItems);
125 // 处理收货地址 125 // 处理收货地址
126 orderVO.setReceiverAreaName(AreaUtils.format(order.getReceiverAreaId())); 126 orderVO.setReceiverAreaName(AreaUtils.format(order.getReceiverAreaId()));
127 - // 增加用户昵称  
128 - orderVO.setUser(memberUserMap.get(orderVO.getUserId())); 127 + // 增加用户信息
  128 + orderVO.setUser(convertUser(memberUserMap.get(orderVO.getUserId())));
  129 + // 增加推广人信息
  130 + orderVO.setBrokerageUser(convertUser(memberUserMap.get(orderVO.getBrokerageUserId())));
129 return orderVO; 131 return orderVO;
130 }); 132 });
131 return new PageResult<>(orderVOs, pageResult.getTotal()); 133 return new PageResult<>(orderVOs, pageResult.getTotal());
132 } 134 }
133 135
  136 + MemberUserRespVO convertUser(MemberUserRespDTO memberUserRespDTO);
  137 +
134 TradeOrderPageItemRespVO convert(TradeOrderDO order, List<TradeOrderItemDO> items); 138 TradeOrderPageItemRespVO convert(TradeOrderDO order, List<TradeOrderItemDO> items);
135 139
136 ProductPropertyValueDetailRespVO convert(ProductPropertyValueDetailRespDTO bean); 140 ProductPropertyValueDetailRespVO convert(ProductPropertyValueDetailRespDTO bean);
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/order/TradeOrderMapper.java
@@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.trade.dal.mysql.order; @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.trade.dal.mysql.order;
3 import cn.iocoder.yudao.framework.common.pojo.PageResult; 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; 4 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
5 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; 5 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
  6 +import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX;
6 import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderPageReqVO; 7 import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderPageReqVO;
7 import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderPageReqVO; 8 import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderPageReqVO;
8 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; 9 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
@@ -11,6 +12,7 @@ import org.apache.ibatis.annotations.Mapper; @@ -11,6 +12,7 @@ import org.apache.ibatis.annotations.Mapper;
11 12
12 import java.time.LocalDateTime; 13 import java.time.LocalDateTime;
13 import java.util.List; 14 import java.util.List;
  15 +import java.util.Map;
14 import java.util.Set; 16 import java.util.Set;
15 17
16 @Mapper 18 @Mapper
@@ -42,6 +44,27 @@ public interface TradeOrderMapper extends BaseMapperX&lt;TradeOrderDO&gt; { @@ -42,6 +44,27 @@ public interface TradeOrderMapper extends BaseMapperX&lt;TradeOrderDO&gt; {
42 .orderByDesc(TradeOrderDO::getId)); 44 .orderByDesc(TradeOrderDO::getId));
43 } 45 }
44 46
  47 + // TODO @疯狂:如果用 map 返回,要不这里直接用 TradeOrderSummaryRespVO 返回?也算合理,就当 sql 查询出这么个玩意~~
  48 + default List<Map<String, Object>> selectOrderSummaryGroupByRefundStatus(TradeOrderPageReqVO reqVO, Set<Long> userIds) {
  49 + return selectMaps(new MPJLambdaWrapperX<TradeOrderDO>()
  50 + .selectAs(TradeOrderDO::getRefundStatus, TradeOrderDO::getRefundStatus) // 售后状态
  51 + .selectCount(TradeOrderDO::getId, "count") // 售后状态对应的数量
  52 + .selectSum(TradeOrderDO::getPayPrice, "price") // 售后状态对应的支付金额
  53 + .likeIfPresent(TradeOrderDO::getNo, reqVO.getNo())
  54 + .eqIfPresent(TradeOrderDO::getUserId, reqVO.getUserId())
  55 + .eqIfPresent(TradeOrderDO::getDeliveryType, reqVO.getDeliveryType())
  56 + .inIfPresent(TradeOrderDO::getUserId, userIds)
  57 + .eqIfPresent(TradeOrderDO::getType, reqVO.getType())
  58 + .eqIfPresent(TradeOrderDO::getStatus, reqVO.getStatus())
  59 + .eqIfPresent(TradeOrderDO::getPayChannelCode, reqVO.getPayChannelCode())
  60 + .eqIfPresent(TradeOrderDO::getTerminal, reqVO.getTerminal())
  61 + .eqIfPresent(TradeOrderDO::getLogisticsId, reqVO.getLogisticsId())
  62 + .inIfPresent(TradeOrderDO::getPickUpStoreId, reqVO.getPickUpStoreIds())
  63 + .likeIfPresent(TradeOrderDO::getPickUpVerifyCode, reqVO.getPickUpVerifyCode())
  64 + .betweenIfPresent(TradeOrderDO::getCreateTime, reqVO.getCreateTime())
  65 + .groupBy(TradeOrderDO::getRefundStatus)); // 按售后状态分组
  66 + }
  67 +
45 default PageResult<TradeOrderDO> selectPage(AppTradeOrderPageReqVO reqVO, Long userId) { 68 default PageResult<TradeOrderDO> selectPage(AppTradeOrderPageReqVO reqVO, Long userId) {
46 return selectPage(reqVO, new LambdaQueryWrapperX<TradeOrderDO>() 69 return selectPage(reqVO, new LambdaQueryWrapperX<TradeOrderDO>()
47 .eq(TradeOrderDO::getUserId, userId) 70 .eq(TradeOrderDO::getUserId, userId)
@@ -92,7 +115,7 @@ public interface TradeOrderMapper extends BaseMapperX&lt;TradeOrderDO&gt; { @@ -92,7 +115,7 @@ public interface TradeOrderMapper extends BaseMapperX&lt;TradeOrderDO&gt; {
92 default TradeOrderDO selectOneByPickUpVerifyCode(String pickUpVerifyCode) { 115 default TradeOrderDO selectOneByPickUpVerifyCode(String pickUpVerifyCode) {
93 return selectOne(TradeOrderDO::getPickUpVerifyCode, pickUpVerifyCode); 116 return selectOne(TradeOrderDO::getPickUpVerifyCode, pickUpVerifyCode);
94 } 117 }
95 - 118 +
96 default TradeOrderDO selectByUserIdAndCombinationActivityIdAndStatus(Long userId, Long combinationActivityId, Integer status) { 119 default TradeOrderDO selectByUserIdAndCombinationActivityIdAndStatus(Long userId, Long combinationActivityId, Integer status) {
97 return selectOne(new LambdaQueryWrapperX<TradeOrderDO>() 120 return selectOne(new LambdaQueryWrapperX<TradeOrderDO>()
98 .eq(TradeOrderDO::getUserId, userId) 121 .eq(TradeOrderDO::getUserId, userId)
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/order/core/aop/TradeOrderLogAspect.java
@@ -58,10 +58,6 @@ public class TradeOrderLogAspect { @@ -58,10 +58,6 @@ public class TradeOrderLogAspect {
58 */ 58 */
59 private static final ThreadLocal<Map<String, Object>> EXTS = new ThreadLocal<>(); 59 private static final ThreadLocal<Map<String, Object>> EXTS = new ThreadLocal<>();
60 60
61 - public TradeOrderLogAspect() {  
62 - System.out.println();  
63 - }  
64 -  
65 @Resource 61 @Resource
66 private TradeOrderLogService orderLogService; 62 private TradeOrderLogService orderLogService;
67 63
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderQueryService.java
@@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.trade.service.order; @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.trade.service.order;
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.trade.controller.admin.order.vo.TradeOrderPageReqVO; 4 import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderPageReqVO;
  5 +import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderSummaryRespVO;
5 import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderPageReqVO; 6 import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderPageReqVO;
6 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; 7 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
7 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; 8 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO;
@@ -65,6 +66,14 @@ public interface TradeOrderQueryService { @@ -65,6 +66,14 @@ public interface TradeOrderQueryService {
65 PageResult<TradeOrderDO> getOrderPage(TradeOrderPageReqVO reqVO); 66 PageResult<TradeOrderDO> getOrderPage(TradeOrderPageReqVO reqVO);
66 67
67 /** 68 /**
  69 + * 获得订单统计
  70 + *
  71 + * @param reqVO 请求参数
  72 + * @return 订单统计
  73 + */
  74 + TradeOrderSummaryRespVO getOrderSummary(TradeOrderPageReqVO reqVO);
  75 +
  76 + /**
68 * 【会员】获得交易订单分页 77 * 【会员】获得交易订单分页
69 * 78 *
70 * @param userId 用户编号 79 * @param userId 用户编号
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderQueryServiceImpl.java
1 package cn.iocoder.yudao.module.trade.service.order; 1 package cn.iocoder.yudao.module.trade.service.order;
2 2
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
  4 +import cn.hutool.core.map.MapUtil;
4 import cn.hutool.core.util.ObjectUtil; 5 import cn.hutool.core.util.ObjectUtil;
5 import cn.hutool.core.util.StrUtil; 6 import cn.hutool.core.util.StrUtil;
6 import cn.hutool.extra.spring.SpringUtil; 7 import cn.hutool.extra.spring.SpringUtil;
@@ -8,6 +9,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; @@ -8,6 +9,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
8 import cn.iocoder.yudao.module.member.api.user.MemberUserApi; 9 import cn.iocoder.yudao.module.member.api.user.MemberUserApi;
9 import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; 10 import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO;
10 import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderPageReqVO; 11 import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderPageReqVO;
  12 +import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderSummaryRespVO;
11 import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderPageReqVO; 13 import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderPageReqVO;
12 import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressDO; 14 import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressDO;
13 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; 15 import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
@@ -15,6 +17,7 @@ import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; @@ -15,6 +17,7 @@ import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO;
15 import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderItemMapper; 17 import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderItemMapper;
16 import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderMapper; 18 import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderMapper;
17 import cn.iocoder.yudao.module.trade.dal.redis.RedisKeyConstants; 19 import cn.iocoder.yudao.module.trade.dal.redis.RedisKeyConstants;
  20 +import cn.iocoder.yudao.module.trade.enums.order.TradeOrderRefundStatusEnum;
18 import cn.iocoder.yudao.module.trade.enums.order.TradeOrderStatusEnum; 21 import cn.iocoder.yudao.module.trade.enums.order.TradeOrderStatusEnum;
19 import cn.iocoder.yudao.module.trade.framework.delivery.core.client.ExpressClientFactory; 22 import cn.iocoder.yudao.module.trade.framework.delivery.core.client.ExpressClientFactory;
20 import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.ExpressTrackQueryReqDTO; 23 import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.ExpressTrackQueryReqDTO;
@@ -85,24 +88,57 @@ public class TradeOrderQueryServiceImpl implements TradeOrderQueryService { @@ -85,24 +88,57 @@ public class TradeOrderQueryServiceImpl implements TradeOrderQueryService {
85 88
86 @Override 89 @Override
87 public PageResult<TradeOrderDO> getOrderPage(TradeOrderPageReqVO reqVO) { 90 public PageResult<TradeOrderDO> getOrderPage(TradeOrderPageReqVO reqVO) {
  91 + // 根据用户查询条件构建用户编号列表
  92 + Set<Long> userIds = buildQueryConditionUserIds(reqVO);
  93 + if (userIds == null) { // 没查询到用户,说明肯定也没他的订单
  94 + return PageResult.empty();
  95 + }
  96 + // 分页查询
  97 + return tradeOrderMapper.selectPage(reqVO, userIds);
  98 + }
  99 +
  100 + private Set<Long> buildQueryConditionUserIds(TradeOrderPageReqVO reqVO) {
88 // 获得 userId 相关的查询 101 // 获得 userId 相关的查询
89 Set<Long> userIds = new HashSet<>(); 102 Set<Long> userIds = new HashSet<>();
90 if (StrUtil.isNotEmpty(reqVO.getUserMobile())) { 103 if (StrUtil.isNotEmpty(reqVO.getUserMobile())) {
91 MemberUserRespDTO user = memberUserApi.getUserByMobile(reqVO.getUserMobile()); 104 MemberUserRespDTO user = memberUserApi.getUserByMobile(reqVO.getUserMobile());
92 if (user == null) { // 没查询到用户,说明肯定也没他的订单 105 if (user == null) { // 没查询到用户,说明肯定也没他的订单
93 - return new PageResult<>(); 106 + return null;
94 } 107 }
95 userIds.add(user.getId()); 108 userIds.add(user.getId());
96 } 109 }
97 if (StrUtil.isNotEmpty(reqVO.getUserNickname())) { 110 if (StrUtil.isNotEmpty(reqVO.getUserNickname())) {
98 List<MemberUserRespDTO> users = memberUserApi.getUserListByNickname(reqVO.getUserNickname()); 111 List<MemberUserRespDTO> users = memberUserApi.getUserListByNickname(reqVO.getUserNickname());
99 if (CollUtil.isEmpty(users)) { // 没查询到用户,说明肯定也没他的订单 112 if (CollUtil.isEmpty(users)) { // 没查询到用户,说明肯定也没他的订单
100 - return new PageResult<>(); 113 + return null;
101 } 114 }
102 userIds.addAll(convertSet(users, MemberUserRespDTO::getId)); 115 userIds.addAll(convertSet(users, MemberUserRespDTO::getId));
103 } 116 }
104 - // 分页查询  
105 - return tradeOrderMapper.selectPage(reqVO, userIds); 117 + return userIds;
  118 + }
  119 +
  120 + @Override
  121 + public TradeOrderSummaryRespVO getOrderSummary(TradeOrderPageReqVO reqVO) {
  122 + // 根据用户查询条件构建用户编号列表
  123 + Set<Long> userIds = buildQueryConditionUserIds(reqVO);
  124 + if (userIds == null) { // 没查询到用户,说明肯定也没他的订单
  125 + return new TradeOrderSummaryRespVO();
  126 + }
  127 + // 查询每个售后状态对应的数量、金额
  128 + List<Map<String, Object>> list = tradeOrderMapper.selectOrderSummaryGroupByRefundStatus(reqVO, null);
  129 +
  130 + TradeOrderSummaryRespVO vo = new TradeOrderSummaryRespVO().setAfterSaleCount(0L).setAfterSalePrice(0L);
  131 + for (Map<String, Object> map : list) {
  132 + Long count = MapUtil.getLong(map, "count", 0L);
  133 + Long price = MapUtil.getLong(map, "price", 0L);
  134 + // 未退款的计入订单,部分退款、全部退款计入售后
  135 + if (TradeOrderRefundStatusEnum.NONE.getStatus().equals(MapUtil.getInt(map, "refundStatus"))) {
  136 + vo.setOrderCount(count).setOrderPayPrice(price);
  137 + } else {
  138 + vo.setAfterSaleCount(vo.getAfterSaleCount() + count).setAfterSalePrice(vo.getAfterSalePrice() + price);
  139 + }
  140 + }
  141 + return vo;
106 } 142 }
107 143
108 @Override 144 @Override
yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/ErrorCodeConstants.java
@@ -19,7 +19,6 @@ public interface ErrorCodeConstants { @@ -19,7 +19,6 @@ public interface ErrorCodeConstants {
19 ErrorCode AUTH_LOGIN_BAD_CREDENTIALS = new ErrorCode(1_004_003_000, "登录失败,账号密码不正确"); 19 ErrorCode AUTH_LOGIN_BAD_CREDENTIALS = new ErrorCode(1_004_003_000, "登录失败,账号密码不正确");
20 ErrorCode AUTH_LOGIN_USER_DISABLED = new ErrorCode(1_004_003_001, "登录失败,账号被禁用"); 20 ErrorCode AUTH_LOGIN_USER_DISABLED = new ErrorCode(1_004_003_001, "登录失败,账号被禁用");
21 ErrorCode AUTH_THIRD_LOGIN_NOT_BIND = new ErrorCode(1_004_003_005, "未绑定账号,需要进行绑定"); 21 ErrorCode AUTH_THIRD_LOGIN_NOT_BIND = new ErrorCode(1_004_003_005, "未绑定账号,需要进行绑定");
22 - ErrorCode AUTH_WEIXIN_MINI_APP_PHONE_CODE_ERROR = new ErrorCode(1_004_003_006, "获得手机号失败");  
23 ErrorCode AUTH_MOBILE_USED = new ErrorCode(1_004_003_007, "手机号已经被使用"); 22 ErrorCode AUTH_MOBILE_USED = new ErrorCode(1_004_003_007, "手机号已经被使用");
24 23
25 // ========== 用户收件地址 1-004-004-000 ========== 24 // ========== 用户收件地址 1-004-004-000 ==========
yudao-module-member/yudao-module-member-biz/pom.xml
@@ -43,10 +43,6 @@ @@ -43,10 +43,6 @@
43 <groupId>cn.iocoder.boot</groupId> 43 <groupId>cn.iocoder.boot</groupId>
44 <artifactId>yudao-spring-boot-starter-biz-tenant</artifactId> 44 <artifactId>yudao-spring-boot-starter-biz-tenant</artifactId>
45 </dependency> 45 </dependency>
46 - <dependency>  
47 - <groupId>cn.iocoder.boot</groupId>  
48 - <artifactId>yudao-spring-boot-starter-biz-weixin</artifactId>  
49 - </dependency>  
50 46
51 <!-- Web 相关 --> 47 <!-- Web 相关 -->
52 <dependency> 48 <dependency>
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/AppAuthController.http
@@ -59,3 +59,8 @@ tenant-id: {{appTenentId}} @@ -59,3 +59,8 @@ tenant-id: {{appTenentId}}
59 POST {{appApi}}/member/auth/refresh-token?refreshToken=bc43d929094849a28b3a69f6e6940d70 59 POST {{appApi}}/member/auth/refresh-token?refreshToken=bc43d929094849a28b3a69f6e6940d70
60 Content-Type: application/json 60 Content-Type: application/json
61 tenant-id: {{appTenentId}} 61 tenant-id: {{appTenentId}}
  62 +
  63 +### 请求 /auth/create-weixin-jsapi-signature 接口 => 成功
  64 +POST {{appApi}}/member/auth/create-weixin-jsapi-signature?url=http://www.iocoder.cn
  65 +Authorization: Bearer {{appToken}}
  66 +tenant-id: {{appTenentId}}
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/AppAuthController.java
1 package cn.iocoder.yudao.module.member.controller.app.auth; 1 package cn.iocoder.yudao.module.member.controller.app.auth;
2 2
3 import cn.hutool.core.util.StrUtil; 3 import cn.hutool.core.util.StrUtil;
  4 +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
4 import cn.iocoder.yudao.framework.common.pojo.CommonResult; 5 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
5 import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; 6 import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
6 import cn.iocoder.yudao.framework.security.config.SecurityProperties; 7 import cn.iocoder.yudao.framework.security.config.SecurityProperties;
7 import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; 8 import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
8 import cn.iocoder.yudao.module.member.controller.app.auth.vo.*; 9 import cn.iocoder.yudao.module.member.controller.app.auth.vo.*;
  10 +import cn.iocoder.yudao.module.member.convert.auth.AuthConvert;
9 import cn.iocoder.yudao.module.member.service.auth.MemberAuthService; 11 import cn.iocoder.yudao.module.member.service.auth.MemberAuthService;
  12 +import cn.iocoder.yudao.module.system.api.social.SocialClientApi;
  13 +import cn.iocoder.yudao.module.system.api.social.dto.SocialWxJsapiSignatureRespDTO;
10 import io.swagger.v3.oas.annotations.Operation; 14 import io.swagger.v3.oas.annotations.Operation;
11 import io.swagger.v3.oas.annotations.Parameter; 15 import io.swagger.v3.oas.annotations.Parameter;
12 import io.swagger.v3.oas.annotations.Parameters; 16 import io.swagger.v3.oas.annotations.Parameters;
@@ -34,6 +38,9 @@ public class AppAuthController { @@ -34,6 +38,9 @@ public class AppAuthController {
34 private MemberAuthService authService; 38 private MemberAuthService authService;
35 39
36 @Resource 40 @Resource
  41 + private SocialClientApi socialClientApi;
  42 +
  43 + @Resource
37 private SecurityProperties securityProperties; 44 private SecurityProperties securityProperties;
38 45
39 @PostMapping("/login") 46 @PostMapping("/login")
@@ -109,4 +116,13 @@ public class AppAuthController { @@ -109,4 +116,13 @@ public class AppAuthController {
109 return success(authService.weixinMiniAppLogin(reqVO)); 116 return success(authService.weixinMiniAppLogin(reqVO));
110 } 117 }
111 118
  119 + @PostMapping("/create-weixin-jsapi-signature")
  120 + @Operation(summary = "创建微信 JS SDK 初始化所需的签名",
  121 + description = "参考 https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html 文档")
  122 + public CommonResult<SocialWxJsapiSignatureRespDTO> createWeixinMpJsapiSignature(@RequestParam("url") String url) {
  123 + SocialWxJsapiSignatureRespDTO signature = socialClientApi.createWxMpJsapiSignature(
  124 + UserTypeEnum.MEMBER.getValue(), url);
  125 + return success(AuthConvert.INSTANCE.convert(signature));
  126 + }
  127 +
112 } 128 }
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AuthWeixinJsapiSignatureRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.member.controller.app.auth.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.AllArgsConstructor;
  5 +import lombok.Builder;
  6 +import lombok.Data;
  7 +import lombok.NoArgsConstructor;
  8 +
  9 +@Schema(description = "用户 APP - 微信公众号 JSAPI 签名 Response VO")
  10 +@Data
  11 +@NoArgsConstructor
  12 +@AllArgsConstructor
  13 +@Builder
  14 +public class AuthWeixinJsapiSignatureRespVO {
  15 +
  16 + @Schema(description = "微信公众号的 appId", requiredMode = Schema.RequiredMode.REQUIRED, example = "hello")
  17 + private String appId;
  18 +
  19 + @Schema(description = "匿名串", requiredMode = Schema.RequiredMode.REQUIRED, example = "world")
  20 + private String nonceStr;
  21 +
  22 + @Schema(description = "时间戳", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
  23 + private Long timestamp;
  24 +
  25 + @Schema(description = "URL", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn")
  26 + private String url;
  27 +
  28 + @Schema(description = "签名", requiredMode = Schema.RequiredMode.REQUIRED, example = "阿巴阿巴")
  29 + private String signature;
  30 +
  31 +}
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/auth/AuthConvert.java
@@ -9,6 +9,7 @@ import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeUseReqDTO; @@ -9,6 +9,7 @@ import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeUseReqDTO;
9 import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeValidateReqDTO; 9 import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeValidateReqDTO;
10 import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO; 10 import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO;
11 import cn.iocoder.yudao.module.system.api.social.dto.SocialUserUnbindReqDTO; 11 import cn.iocoder.yudao.module.system.api.social.dto.SocialUserUnbindReqDTO;
  12 +import cn.iocoder.yudao.module.system.api.social.dto.SocialWxJsapiSignatureRespDTO;
12 import cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum; 13 import cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum;
13 import org.mapstruct.Mapper; 14 import org.mapstruct.Mapper;
14 import org.mapstruct.factory.Mappers; 15 import org.mapstruct.factory.Mappers;
@@ -29,4 +30,6 @@ public interface AuthConvert { @@ -29,4 +30,6 @@ public interface AuthConvert {
29 30
30 SmsCodeValidateReqDTO convert(AppAuthSmsValidateReqVO bean); 31 SmsCodeValidateReqDTO convert(AppAuthSmsValidateReqVO bean);
31 32
  33 + SocialWxJsapiSignatureRespDTO convert(SocialWxJsapiSignatureRespDTO bean);
  34 +
32 } 35 }
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/auth/MemberAuthServiceImpl.java
1 package cn.iocoder.yudao.module.member.service.auth; 1 package cn.iocoder.yudao.module.member.service.auth;
2 2
3 -import cn.binarywang.wx.miniapp.api.WxMaService;  
4 -import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;  
5 import cn.hutool.core.lang.Assert; 3 import cn.hutool.core.lang.Assert;
6 import cn.hutool.core.util.ObjectUtil; 4 import cn.hutool.core.util.ObjectUtil;
7 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; 5 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
@@ -19,9 +17,11 @@ import cn.iocoder.yudao.module.system.api.oauth2.OAuth2TokenApi; @@ -19,9 +17,11 @@ import cn.iocoder.yudao.module.system.api.oauth2.OAuth2TokenApi;
19 import cn.iocoder.yudao.module.system.api.oauth2.dto.OAuth2AccessTokenCreateReqDTO; 17 import cn.iocoder.yudao.module.system.api.oauth2.dto.OAuth2AccessTokenCreateReqDTO;
20 import cn.iocoder.yudao.module.system.api.oauth2.dto.OAuth2AccessTokenRespDTO; 18 import cn.iocoder.yudao.module.system.api.oauth2.dto.OAuth2AccessTokenRespDTO;
21 import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi; 19 import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi;
  20 +import cn.iocoder.yudao.module.system.api.social.SocialClientApi;
22 import cn.iocoder.yudao.module.system.api.social.SocialUserApi; 21 import cn.iocoder.yudao.module.system.api.social.SocialUserApi;
23 import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO; 22 import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO;
24 import cn.iocoder.yudao.module.system.api.social.dto.SocialUserRespDTO; 23 import cn.iocoder.yudao.module.system.api.social.dto.SocialUserRespDTO;
  24 +import cn.iocoder.yudao.module.system.api.social.dto.SocialWxPhoneNumberInfoRespDTO;
25 import cn.iocoder.yudao.module.system.enums.logger.LoginLogTypeEnum; 25 import cn.iocoder.yudao.module.system.enums.logger.LoginLogTypeEnum;
26 import cn.iocoder.yudao.module.system.enums.logger.LoginResultEnum; 26 import cn.iocoder.yudao.module.system.enums.logger.LoginResultEnum;
27 import cn.iocoder.yudao.module.system.enums.oauth2.OAuth2ClientConstants; 27 import cn.iocoder.yudao.module.system.enums.oauth2.OAuth2ClientConstants;
@@ -56,10 +56,9 @@ public class MemberAuthServiceImpl implements MemberAuthService { @@ -56,10 +56,9 @@ public class MemberAuthServiceImpl implements MemberAuthService {
56 @Resource 56 @Resource
57 private SocialUserApi socialUserApi; 57 private SocialUserApi socialUserApi;
58 @Resource 58 @Resource
59 - private OAuth2TokenApi oauth2TokenApi;  
60 - 59 + private SocialClientApi socialClientApi;
61 @Resource 60 @Resource
62 - private WxMaService wxMaService; 61 + private OAuth2TokenApi oauth2TokenApi;
63 62
64 @Override 63 @Override
65 public AppAuthLoginRespVO login(AppAuthLoginReqVO reqVO) { 64 public AppAuthLoginRespVO login(AppAuthLoginReqVO reqVO) {
@@ -121,15 +120,13 @@ public class MemberAuthServiceImpl implements MemberAuthService { @@ -121,15 +120,13 @@ public class MemberAuthServiceImpl implements MemberAuthService {
121 @Override 120 @Override
122 public AppAuthLoginRespVO weixinMiniAppLogin(AppAuthWeixinMiniAppLoginReqVO reqVO) { 121 public AppAuthLoginRespVO weixinMiniAppLogin(AppAuthWeixinMiniAppLoginReqVO reqVO) {
123 // 获得对应的手机号信息 122 // 获得对应的手机号信息
124 - // TODO @芋艿:需要弱化微信小程序的依赖,通过 system 获取手机号  
125 - WxMaPhoneNumberInfo phoneNumberInfo;  
126 - try {  
127 - phoneNumberInfo = wxMaService.getUserService().getPhoneNoInfo(reqVO.getPhoneCode());  
128 - } catch (Exception exception) {  
129 - throw exception(AUTH_WEIXIN_MINI_APP_PHONE_CODE_ERROR);  
130 - } 123 + SocialWxPhoneNumberInfoRespDTO phoneNumberInfo = socialClientApi.getWxMaPhoneNumberInfo(
  124 + UserTypeEnum.MEMBER.getValue(), reqVO.getPhoneCode());
  125 + Assert.notNull(phoneNumberInfo, "获得手机信息失败,结果为空");
  126 +
131 // 获得获得注册用户 127 // 获得获得注册用户
132 - MemberUserDO user = userService.createUserIfAbsent(phoneNumberInfo.getPurePhoneNumber(), getClientIP(), TerminalEnum.WECHAT_MINI_PROGRAM.getTerminal()); 128 + MemberUserDO user = userService.createUserIfAbsent(phoneNumberInfo.getPurePhoneNumber(),
  129 + getClientIP(), TerminalEnum.WECHAT_MINI_PROGRAM.getTerminal());
133 Assert.notNull(user, "获取用户失败,结果为空"); 130 Assert.notNull(user, "获取用户失败,结果为空");
134 131
135 // 绑定社交用户 132 // 绑定社交用户
@@ -154,7 +151,7 @@ public class MemberAuthServiceImpl implements MemberAuthService { @@ -154,7 +151,7 @@ public class MemberAuthServiceImpl implements MemberAuthService {
154 151
155 @Override 152 @Override
156 public String getSocialAuthorizeUrl(Integer type, String redirectUri) { 153 public String getSocialAuthorizeUrl(Integer type, String redirectUri) {
157 - return socialUserApi.getAuthorizeUrl(type, redirectUri); 154 + return socialClientApi.getAuthorizeUrl(type, UserTypeEnum.MEMBER.getValue(), redirectUri);
158 } 155 }
159 156
160 private MemberUserDO login0(String mobile, String password) { 157 private MemberUserDO login0(String mobile, String password) {
yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/PayTransferApi.java
@@ -18,4 +18,5 @@ public interface PayTransferApi { @@ -18,4 +18,5 @@ public interface PayTransferApi {
18 * @return 转账单编号 18 * @return 转账单编号
19 */ 19 */
20 Long createTransfer(@Valid PayTransferCreateReqDTO reqDTO); 20 Long createTransfer(@Valid PayTransferCreateReqDTO reqDTO);
  21 +
21 } 22 }
yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferCreateReqDTO.java
@@ -23,6 +23,7 @@ public class PayTransferCreateReqDTO { @@ -23,6 +23,7 @@ public class PayTransferCreateReqDTO {
23 * 类型 23 * 类型
24 */ 24 */
25 @NotNull(message = "转账类型不能为空") 25 @NotNull(message = "转账类型不能为空")
  26 + // TODO @jason:枚举的校验
26 private Integer type; 27 private Integer type;
27 28
28 /** 29 /**
@@ -34,9 +35,11 @@ public class PayTransferCreateReqDTO { @@ -34,9 +35,11 @@ public class PayTransferCreateReqDTO {
34 /** 35 /**
35 * 转账金额,单位:分 36 * 转账金额,单位:分
36 */ 37 */
  38 + // TODO @jason:这个金额是不是非空哈
37 @Min(value = 1, message = "转账金额必须大于零") 39 @Min(value = 1, message = "转账金额必须大于零")
38 private Integer price; 40 private Integer price;
39 41
  42 + // TODO @jason:这个标题,是不是不允许空呀
40 /** 43 /**
41 * 转账标题 44 * 转账标题
42 */ 45 */
@@ -44,4 +47,5 @@ public class PayTransferCreateReqDTO { @@ -44,4 +47,5 @@ public class PayTransferCreateReqDTO {
44 47
45 @NotEmpty(message = "收款方信息不能为空") 48 @NotEmpty(message = "收款方信息不能为空")
46 private Map<String, String> payeeInfo; 49 private Map<String, String> payeeInfo;
  50 +
47 } 51 }
yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/ErrorCodeConstants.java
@@ -27,8 +27,6 @@ public interface ErrorCodeConstants { @@ -27,8 +27,6 @@ public interface ErrorCodeConstants {
27 ErrorCode PAY_ORDER_IS_EXPIRED = new ErrorCode(1_007_002_003, "支付订单已经过期"); 27 ErrorCode PAY_ORDER_IS_EXPIRED = new ErrorCode(1_007_002_003, "支付订单已经过期");
28 ErrorCode PAY_ORDER_SUBMIT_CHANNEL_ERROR = new ErrorCode(1_007_002_004, "发起支付报错,错误码:{},错误提示:{}"); 28 ErrorCode PAY_ORDER_SUBMIT_CHANNEL_ERROR = new ErrorCode(1_007_002_004, "发起支付报错,错误码:{},错误提示:{}");
29 ErrorCode PAY_ORDER_REFUND_FAIL_STATUS_ERROR = new ErrorCode(1_007_002_005, "支付订单退款失败,原因:状态不是已支付或已退款"); 29 ErrorCode PAY_ORDER_REFUND_FAIL_STATUS_ERROR = new ErrorCode(1_007_002_005, "支付订单退款失败,原因:状态不是已支付或已退款");
30 - ErrorCode ORDER_UPDATE_PRICE_FAIL_PAID = new ErrorCode(1_007_002_006, "支付订单调价失败,原因:支付订单已付款,不能调价");  
31 - ErrorCode ORDER_UPDATE_PRICE_FAIL_EQUAL = new ErrorCode(1_007_002_007, "支付订单调价失败,原因:价格没有变化");  
32 30
33 // ========== ORDER 模块(拓展单) 1-007-003-000 ========== 31 // ========== ORDER 模块(拓展单) 1-007-003-000 ==========
34 ErrorCode PAY_ORDER_EXTENSION_NOT_FOUND = new ErrorCode(1_007_003_000, "支付交易拓展单不存在"); 32 ErrorCode PAY_ORDER_EXTENSION_NOT_FOUND = new ErrorCode(1_007_003_000, "支付交易拓展单不存在");
@@ -64,6 +62,7 @@ public interface ErrorCodeConstants { @@ -64,6 +62,7 @@ public interface ErrorCodeConstants {
64 ErrorCode WALLET_RECHARGE_PACKAGE_AND_PRICE_IS_EMPTY = new ErrorCode(1_007_008_011, "充值金额和充钱套餐不能同时为空"); 62 ErrorCode WALLET_RECHARGE_PACKAGE_AND_PRICE_IS_EMPTY = new ErrorCode(1_007_008_011, "充值金额和充钱套餐不能同时为空");
65 ErrorCode WALLET_RECHARGE_PACKAGE_NOT_FOUND = new ErrorCode(1_007_008_012, "钱包充值套餐不存在"); 63 ErrorCode WALLET_RECHARGE_PACKAGE_NOT_FOUND = new ErrorCode(1_007_008_012, "钱包充值套餐不存在");
66 ErrorCode WALLET_RECHARGE_PACKAGE_IS_DISABLE = new ErrorCode(1_007_008_013, "钱包充值套餐已禁用"); 64 ErrorCode WALLET_RECHARGE_PACKAGE_IS_DISABLE = new ErrorCode(1_007_008_013, "钱包充值套餐已禁用");
  65 +
67 // ========== 转账模块 1-007-009-000 ========== 66 // ========== 转账模块 1-007-009-000 ==========
68 ErrorCode PAY_TRANSFER_SUBMIT_CHANNEL_ERROR = new ErrorCode(1_007_009_000, "发起转账报错,错误码:{},错误提示:{}"); 67 ErrorCode PAY_TRANSFER_SUBMIT_CHANNEL_ERROR = new ErrorCode(1_007_009_000, "发起转账报错,错误码:{},错误提示:{}");
69 ErrorCode PAY_TRANSFER_ALIPAY_LOGIN_ID_IS_EMPTY = new ErrorCode(1_007_009_001, "支付宝登录 ID 不能为空"); 68 ErrorCode PAY_TRANSFER_ALIPAY_LOGIN_ID_IS_EMPTY = new ErrorCode(1_007_009_001, "支付宝登录 ID 不能为空");
yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/transfer/PayTransferStatusEnum.java
@@ -24,7 +24,13 @@ public enum PayTransferStatusEnum { @@ -24,7 +24,13 @@ public enum PayTransferStatusEnum {
24 */ 24 */
25 CLOSED(30, "转账关闭"); 25 CLOSED(30, "转账关闭");
26 26
  27 + /**
  28 + * 状态
  29 + */
27 private final Integer status; 30 private final Integer status;
  31 + /**
  32 + * 状态名
  33 + */
28 private final String name; 34 private final String name;
29 35
30 public static boolean isSuccess(Integer status) { 36 public static boolean isSuccess(Integer status) {
@@ -45,4 +51,5 @@ public enum PayTransferStatusEnum { @@ -45,4 +51,5 @@ public enum PayTransferStatusEnum {
45 public static boolean isPendingStatus(Integer status) { 51 public static boolean isPendingStatus(Integer status) {
46 return Objects.equals(status, WAITING.getStatus()) || Objects.equals(status, IN_PROGRESS.status); 52 return Objects.equals(status, WAITING.getStatus()) || Objects.equals(status, IN_PROGRESS.status);
47 } 53 }
  54 +
48 } 55 }
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/PayTransferApiImpl.java
@@ -5,14 +5,18 @@ import org.springframework.stereotype.Service; @@ -5,14 +5,18 @@ import org.springframework.stereotype.Service;
5 import org.springframework.validation.annotation.Validated; 5 import org.springframework.validation.annotation.Validated;
6 6
7 /** 7 /**
  8 + * 转账单 API 实现类
  9 + *
8 * @author jason 10 * @author jason
9 */ 11 */
10 @Service 12 @Service
11 @Validated 13 @Validated
12 public class PayTransferApiImpl implements PayTransferApi { 14 public class PayTransferApiImpl implements PayTransferApi {
  15 +
13 @Override 16 @Override
14 public Long createTransfer(PayTransferCreateReqDTO reqDTO) { 17 public Long createTransfer(PayTransferCreateReqDTO reqDTO) {
15 - 18 + // TODO @jason:貌似没实现噢
16 return null; 19 return null;
17 } 20 }
18 -} 21 +
  22 +}
19 \ No newline at end of file 23 \ No newline at end of file
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/vo/transfer/PayDemoTransferCreateReqVO.java
@@ -17,6 +17,7 @@ import java.util.Map; @@ -17,6 +17,7 @@ import java.util.Map;
17 @Data 17 @Data
18 public class PayDemoTransferCreateReqVO { 18 public class PayDemoTransferCreateReqVO {
19 19
  20 + // TODO @jason:这个字段,是不是叫 type 就好了。
20 @Schema(description = "转账类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") 21 @Schema(description = "转账类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
21 @NotNull(message = "转账类型不能为空") 22 @NotNull(message = "转账类型不能为空")
22 @InEnum(PayTransferTypeEnum.class) 23 @InEnum(PayTransferTypeEnum.class)
@@ -26,7 +27,9 @@ public class PayDemoTransferCreateReqVO { @@ -26,7 +27,9 @@ public class PayDemoTransferCreateReqVO {
26 @Min(value = 1, message = "转账金额必须大于零") 27 @Min(value = 1, message = "转账金额必须大于零")
27 private Integer price; 28 private Integer price;
28 29
  30 + // TODO @jason:感觉这个动态字段,晚点改;可能要讨论下怎么搞好;
29 @Schema(description = "收款方信息", requiredMode = Schema.RequiredMode.REQUIRED, example = "{'ALIPAY_LOGON_ID':'xxxx'}") 31 @Schema(description = "收款方信息", requiredMode = Schema.RequiredMode.REQUIRED, example = "{'ALIPAY_LOGON_ID':'xxxx'}")
30 @NotEmpty(message = "收款方信息不能为空") 32 @NotEmpty(message = "收款方信息不能为空")
31 private Map<String, String> payeeInfo; 33 private Map<String, String> payeeInfo;
  34 +
32 } 35 }
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/transfer/PayTransferController.java
@@ -29,8 +29,10 @@ public class PayTransferController { @@ -29,8 +29,10 @@ public class PayTransferController {
29 29
30 @PostMapping("/submit") 30 @PostMapping("/submit")
31 @Operation(summary = "提交转账订单") 31 @Operation(summary = "提交转账订单")
  32 + // TODO @jason:权限的设置
32 public CommonResult<PayTransferSubmitRespVO> submitPayTransfer(@Valid @RequestBody PayTransferSubmitReqVO reqVO) { 33 public CommonResult<PayTransferSubmitRespVO> submitPayTransfer(@Valid @RequestBody PayTransferSubmitReqVO reqVO) {
33 PayTransferSubmitRespVO respVO = payTransferService.submitTransfer(reqVO, getClientIP()); 34 PayTransferSubmitRespVO respVO = payTransferService.submitTransfer(reqVO, getClientIP());
34 return success(respVO); 35 return success(respVO);
35 } 36 }
  37 +
36 } 38 }
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/transfer/vo/PayTransferSubmitReqVO.java
@@ -21,4 +21,5 @@ public class PayTransferSubmitReqVO { @@ -21,4 +21,5 @@ public class PayTransferSubmitReqVO {
21 21
22 @Schema(description = "转账渠道的额外参数") 22 @Schema(description = "转账渠道的额外参数")
23 private Map<String, String> channelExtras; 23 private Map<String, String> channelExtras;
  24 +
24 } 25 }
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/transfer/vo/PayTransferSubmitRespVO.java
@@ -9,4 +9,5 @@ public class PayTransferSubmitRespVO { @@ -9,4 +9,5 @@ public class PayTransferSubmitRespVO {
9 9
10 @Schema(description = "转账状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") // 参见 PayTransferStatusEnum 枚举 10 @Schema(description = "转账状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") // 参见 PayTransferStatusEnum 枚举
11 private Integer status; 11 private Integer status;
  12 +
12 } 13 }
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/PayWalletRechargeController.java
@@ -57,4 +57,5 @@ public class PayWalletRechargeController { @@ -57,4 +57,5 @@ public class PayWalletRechargeController {
57 Long.valueOf(notifyReqDTO.getMerchantOrderId()), notifyReqDTO.getPayRefundId()); 57 Long.valueOf(notifyReqDTO.getMerchantOrderId()), notifyReqDTO.getPayRefundId());
58 return success(true); 58 return success(true);
59 } 59 }
  60 +
60 } 61 }
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/PayWalletTransactionController.java
@@ -32,9 +32,11 @@ public class PayWalletTransactionController { @@ -32,9 +32,11 @@ public class PayWalletTransactionController {
32 32
33 @GetMapping("/page") 33 @GetMapping("/page")
34 @Operation(summary = "获得钱包流水分页") 34 @Operation(summary = "获得钱包流水分页")
  35 + // TODO @jason:权限校验,缺一个
35 public CommonResult<PageResult<PayWalletTransactionRespVO>> getWalletTransactionPage( 36 public CommonResult<PageResult<PayWalletTransactionRespVO>> getWalletTransactionPage(
36 @Valid PayWalletTransactionPageReqVO pageReqVO) { 37 @Valid PayWalletTransactionPageReqVO pageReqVO) {
37 PageResult<PayWalletTransactionDO> result = payWalletTransactionService.getWalletTransactionPage(pageReqVO); 38 PageResult<PayWalletTransactionDO> result = payWalletTransactionService.getWalletTransactionPage(pageReqVO);
38 return success(PayWalletTransactionConvert.INSTANCE.convertPage2(result)); 39 return success(PayWalletTransactionConvert.INSTANCE.convertPage2(result));
39 } 40 }
  41 +
40 } 42 }
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/vo/rechargepackage/WalletRechargePackageBaseVO.java
@@ -6,7 +6,7 @@ import lombok.Data; @@ -6,7 +6,7 @@ import lombok.Data;
6 import javax.validation.constraints.NotNull; 6 import javax.validation.constraints.NotNull;
7 7
8 /** 8 /**
9 - * 套餐充值 Base VO,提供给添加、修改、详细的子 VO 使用 9 + * 充值套餐 Base VO,提供给添加、修改、详细的子 VO 使用
10 * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 10 * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
11 */ 11 */
12 @Data 12 @Data
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/vo/rechargepackage/WalletRechargePackageCreateReqVO.java
@@ -5,7 +5,7 @@ import lombok.Data; @@ -5,7 +5,7 @@ import lombok.Data;
5 import lombok.EqualsAndHashCode; 5 import lombok.EqualsAndHashCode;
6 import lombok.ToString; 6 import lombok.ToString;
7 7
8 -@Schema(description = "管理后台 - 套餐充值创建 Request VO") 8 +@Schema(description = "管理后台 - 充值套餐创建 Request VO")
9 @Data 9 @Data
10 @EqualsAndHashCode(callSuper = true) 10 @EqualsAndHashCode(callSuper = true)
11 @ToString(callSuper = true) 11 @ToString(callSuper = true)
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/vo/rechargepackage/WalletRechargePackagePageReqVO.java
@@ -11,7 +11,7 @@ import java.time.LocalDateTime; @@ -11,7 +11,7 @@ import java.time.LocalDateTime;
11 11
12 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; 12 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
13 13
14 -@Schema(description = "管理后台 - 套餐充值分页 Request VO") 14 +@Schema(description = "管理后台 - 充值套餐分页 Request VO")
15 @Data 15 @Data
16 @EqualsAndHashCode(callSuper = true) 16 @EqualsAndHashCode(callSuper = true)
17 @ToString(callSuper = true) 17 @ToString(callSuper = true)
@@ -20,6 +20,8 @@ public class WalletRechargePackagePageReqVO extends PageParam { @@ -20,6 +20,8 @@ public class WalletRechargePackagePageReqVO extends PageParam {
20 @Schema(description = "套餐名", example = "李四") 20 @Schema(description = "套餐名", example = "李四")
21 private String name; 21 private String name;
22 22
  23 + // TODO @jason:payPrice 和 bonusPrice 可以去掉。。。一般太少检索啦;
  24 +
23 @Schema(description = "支付金额", example = "16454") 25 @Schema(description = "支付金额", example = "16454")
24 private Integer payPrice; 26 private Integer payPrice;
25 27
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/vo/rechargepackage/WalletRechargePackageRespVO.java
@@ -4,7 +4,7 @@ import io.swagger.v3.oas.annotations.media.Schema; @@ -4,7 +4,7 @@ import io.swagger.v3.oas.annotations.media.Schema;
4 import lombok.*; 4 import lombok.*;
5 import java.time.LocalDateTime; 5 import java.time.LocalDateTime;
6 6
7 -@Schema(description = "管理后台 - 套餐充值 Response VO") 7 +@Schema(description = "管理后台 - 充值套餐 Response VO")
8 @Data 8 @Data
9 @EqualsAndHashCode(callSuper = true) 9 @EqualsAndHashCode(callSuper = true)
10 @ToString(callSuper = true) 10 @ToString(callSuper = true)
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/vo/rechargepackage/WalletRechargePackageUpdateReqVO.java
@@ -7,7 +7,7 @@ import lombok.ToString; @@ -7,7 +7,7 @@ import lombok.ToString;
7 7
8 import javax.validation.constraints.NotNull; 8 import javax.validation.constraints.NotNull;
9 9
10 -@Schema(description = "管理后台 - 套餐充值更新 Request VO") 10 +@Schema(description = "管理后台 - 充值套餐更新 Request VO")
11 @Data 11 @Data
12 @EqualsAndHashCode(callSuper = true) 12 @EqualsAndHashCode(callSuper = true)
13 @ToString(callSuper = true) 13 @ToString(callSuper = true)
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/vo/transaction/PayWalletTransactionPageReqVO.java
@@ -10,4 +10,5 @@ public class PayWalletTransactionPageReqVO extends PageParam { @@ -10,4 +10,5 @@ public class PayWalletTransactionPageReqVO extends PageParam {
10 10
11 @Schema(description = "钱包编号", example = "1") 11 @Schema(description = "钱包编号", example = "1")
12 private Long walletId; 12 private Long walletId;
  13 +
13 } 14 }
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/vo/transaction/PayWalletTransactionRespVO.java
@@ -29,4 +29,7 @@ public class PayWalletTransactionRespVO { @@ -29,4 +29,7 @@ public class PayWalletTransactionRespVO {
29 29
30 @Schema(description = "交易时间", requiredMode = Schema.RequiredMode.REQUIRED) 30 @Schema(description = "交易时间", requiredMode = Schema.RequiredMode.REQUIRED)
31 private LocalDateTime createTime; 31 private LocalDateTime createTime;
  32 +
  33 + // TODO @jason:merchantOrderId 字段,需要在 PayWalletTransaction 存储下;然后,前端也返回下这个字段,界面也展示下商户名
  34 +
32 } 35 }
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/vo/wallet/PayWalletPageReqVO.java
1 package cn.iocoder.yudao.module.pay.controller.admin.wallet.vo.wallet; 1 package cn.iocoder.yudao.module.pay.controller.admin.wallet.vo.wallet;
2 2
  3 +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
  4 +import cn.iocoder.yudao.framework.common.validation.InEnum;
3 import lombok.*; 5 import lombok.*;
4 import io.swagger.v3.oas.annotations.media.Schema; 6 import io.swagger.v3.oas.annotations.media.Schema;
5 import cn.iocoder.yudao.framework.common.pojo.PageParam; 7 import cn.iocoder.yudao.framework.common.pojo.PageParam;
@@ -18,6 +20,7 @@ public class PayWalletPageReqVO extends PageParam { @@ -18,6 +20,7 @@ public class PayWalletPageReqVO extends PageParam {
18 private Long userId; 20 private Long userId;
19 21
20 @Schema(description = "用户类型", example = "1") 22 @Schema(description = "用户类型", example = "1")
  23 + @InEnum(UserTypeEnum.class)
21 private Integer userType; 24 private Integer userType;
22 25
23 @Schema(description = "创建时间") 26 @Schema(description = "创建时间")
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/vo/wallet/PayWalletRespVO.java
@@ -19,4 +19,6 @@ public class PayWalletRespVO extends PayWalletBaseVO { @@ -19,4 +19,6 @@ public class PayWalletRespVO extends PayWalletBaseVO {
19 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) 19 @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
20 private LocalDateTime createTime; 20 private LocalDateTime createTime;
21 21
  22 + // TODO @jason:要不把用户昵称 + avatar 也读取下?
  23 +
22 } 24 }
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/vo/recharge/AppPayWalletRechargeCreateReqVO.java
@@ -13,7 +13,9 @@ public class AppPayWalletRechargeCreateReqVO { @@ -13,7 +13,9 @@ public class AppPayWalletRechargeCreateReqVO {
13 @Min(value = 1, message = "支付金额必须大于零") 13 @Min(value = 1, message = "支付金额必须大于零")
14 private Integer payPrice; 14 private Integer payPrice;
15 15
16 -  
17 @Schema(description = "充值套餐编号", example = "1024") 16 @Schema(description = "充值套餐编号", example = "1024")
18 private Long packageId; 17 private Long packageId;
  18 +
  19 + // TODO @jaosn:写个 AssertTrue 的校验方法,payPrice 和 packageId 必须二选一
  20 +
19 } 21 }
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/wallet/PayWalletConvert.java
@@ -14,7 +14,8 @@ public interface PayWalletConvert { @@ -14,7 +14,8 @@ public interface PayWalletConvert {
14 14
15 AppPayWalletRespVO convert(PayWalletDO bean); 15 AppPayWalletRespVO convert(PayWalletDO bean);
16 16
17 - PayWalletRespVO convert02(PayWalletDO wallet); 17 + PayWalletRespVO convert02(PayWalletDO bean);
18 18
19 PageResult<PayWalletRespVO> convertPage(PageResult<PayWalletDO> page); 19 PageResult<PayWalletRespVO> convertPage(PageResult<PayWalletDO> page);
  20 +
20 } 21 }
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/demo/PayDemoTransferDO.java
@@ -20,6 +20,7 @@ import java.util.Map; @@ -20,6 +20,7 @@ import java.util.Map;
20 @KeySequence("pay_demo_transfer_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 20 @KeySequence("pay_demo_transfer_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
21 @Data 21 @Data
22 public class PayDemoTransferDO extends BaseDO { 22 public class PayDemoTransferDO extends BaseDO {
  23 +
23 /** 24 /**
24 * 订单编号 25 * 订单编号
25 */ 26 */
@@ -41,6 +42,7 @@ public class PayDemoTransferDO extends BaseDO { @@ -41,6 +42,7 @@ public class PayDemoTransferDO extends BaseDO {
41 */ 42 */
42 private Integer type; 43 private Integer type;
43 44
  45 + // TODO @jason:要不字段还是弄成正确的平铺开?
44 /** 46 /**
45 * 收款人信息,不同类型和渠道不同 47 * 收款人信息,不同类型和渠道不同
46 */ 48 */
@@ -66,4 +68,5 @@ public class PayDemoTransferDO extends BaseDO { @@ -66,4 +68,5 @@ public class PayDemoTransferDO extends BaseDO {
66 * 转账支付时间 68 * 转账支付时间
67 */ 69 */
68 private LocalDateTime transferTime; 70 private LocalDateTime transferTime;
  71 +
69 } 72 }
70 \ No newline at end of file 73 \ No newline at end of file
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/transfer/PayTransferDO.java
1 package cn.iocoder.yudao.module.pay.dal.dataobject.transfer; 1 package cn.iocoder.yudao.module.pay.dal.dataobject.transfer;
2 2
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.framework.pay.core.enums.channel.PayChannelEnum;
  5 +import cn.iocoder.yudao.framework.pay.core.enums.transfer.PayTransferStatusRespEnum;
  6 +import cn.iocoder.yudao.framework.pay.core.enums.transfer.PayTransferTypeEnum;
  7 +import cn.iocoder.yudao.module.pay.dal.dataobject.app.PayAppDO;
  8 +import cn.iocoder.yudao.module.pay.dal.dataobject.channel.PayChannelDO;
4 import com.baomidou.mybatisplus.annotation.KeySequence; 9 import com.baomidou.mybatisplus.annotation.KeySequence;
5 import com.baomidou.mybatisplus.annotation.TableField; 10 import com.baomidou.mybatisplus.annotation.TableField;
6 import com.baomidou.mybatisplus.annotation.TableId; 11 import com.baomidou.mybatisplus.annotation.TableId;
@@ -26,70 +31,76 @@ public class PayTransferDO extends BaseDO { @@ -26,70 +31,76 @@ public class PayTransferDO extends BaseDO {
26 */ 31 */
27 @TableId 32 @TableId
28 private Long id; 33 private Long id;
29 - 34 + /**
  35 + * 应用编号
  36 + *
  37 + * 关联 {@link PayAppDO#getId()}
  38 + */
  39 + private Long appId;
  40 + /**
  41 + * 转账渠道编号
  42 + *
  43 + * 关联 {@link PayChannelDO#getId()}
  44 + */
  45 + private Long channelId;
  46 + /**
  47 + * 转账渠道编码
  48 + *
  49 + * 枚举 {@link PayChannelEnum}
  50 + */
  51 + private String channelCode;
30 /** 52 /**
31 * 类型 53 * 类型
  54 + *
  55 + * 枚举 {@link PayTransferTypeEnum}
32 */ 56 */
33 private Integer type; 57 private Integer type;
34 58
35 - /**  
36 - * 应用编号  
37 - */  
38 - private Long appId; 59 + // ========== 商户相关字段 ==========
39 60
40 /** 61 /**
41 * 商户订单编号 62 * 商户订单编号
  63 + *
  64 + * 例如说,内部系统 A 的订单号,需要保证每个 PayAppDO 唯一
42 */ 65 */
43 private String merchantOrderId; 66 private String merchantOrderId;
44 -  
45 - /**  
46 - * 转账金额,单位:分  
47 - */  
48 - private Integer price;  
49 - 67 + // TODO @jason:这个字段,要不要改成 subject。。。和 payorderdo 保持一致;哈哈哈,我也忘记为啥当时选了这个名字了。。。
50 /** 68 /**
51 * 转账标题 69 * 转账标题
52 */ 70 */
53 private String title; 71 private String title;
54 72
  73 + // ========== 转账相关字段 ==========
55 /** 74 /**
56 - * 收款人信息,不同类型和渠道不同 75 + * 转账金额,单位:分
57 */ 76 */
58 - @TableField(typeHandler = JacksonTypeHandler.class)  
59 - private Map<String, String> payeeInfo;  
60 - 77 + private Integer price;
61 /** 78 /**
62 * 转账状态 79 * 转账状态
  80 + *
  81 + * 枚举 {@link PayTransferStatusRespEnum}
63 */ 82 */
64 private Integer status; 83 private Integer status;
65 -  
66 /** 84 /**
67 * 订单转账成功时间 85 * 订单转账成功时间
68 - *  
69 */ 86 */
70 private LocalDateTime successTime; 87 private LocalDateTime successTime;
71 -  
72 /** 88 /**
73 * 转账成功的转账拓展单编号 89 * 转账成功的转账拓展单编号
74 * 90 *
75 * 关联 {@link PayTransferExtensionDO#getId()} 91 * 关联 {@link PayTransferExtensionDO#getId()}
76 */ 92 */
77 private Long extensionId; 93 private Long extensionId;
78 -  
79 /** 94 /**
80 * 转账成功的转账拓展单号 95 * 转账成功的转账拓展单号
81 * 96 *
82 * 关联 {@link PayTransferExtensionDO#getNo()} 97 * 关联 {@link PayTransferExtensionDO#getNo()}
83 */ 98 */
84 private String no; 99 private String no;
85 -  
86 /** 100 /**
87 - * 转账渠道编号 101 + * 收款人信息,不同类型和渠道不同
88 */ 102 */
89 - private Long channelId; 103 + @TableField(typeHandler = JacksonTypeHandler.class)
  104 + private Map<String, String> payeeInfo;
90 105
91 - /**  
92 - * 转账渠道编码  
93 - */  
94 - private String channelCode;  
95 } 106 }
96 \ No newline at end of file 107 \ No newline at end of file
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/transfer/PayTransferExtensionDO.java
@@ -10,6 +10,7 @@ import lombok.Data; @@ -10,6 +10,7 @@ import lombok.Data;
10 10
11 import java.util.Map; 11 import java.util.Map;
12 12
  13 +// TODO @jason:转账是不是类似 refund,不用拓展单呀?支付做拓展单的原因,是因为它存在不确定性,可以切换多种;转账和退款,都是明确方式的;
13 /** 14 /**
14 * 转账拓展单 DO 15 * 转账拓展单 DO
15 * 16 *
@@ -61,4 +62,5 @@ public class PayTransferExtensionDO extends BaseDO { @@ -61,4 +62,5 @@ public class PayTransferExtensionDO extends BaseDO {
61 * 支付渠道异步通知的内容 62 * 支付渠道异步通知的内容
62 */ 63 */
63 private String channelNotifyData; 64 private String channelNotifyData;
  65 +
64 } 66 }
65 \ No newline at end of file 67 \ No newline at end of file
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/wallet/PayWalletRechargeDO.java
@@ -42,7 +42,6 @@ public class PayWalletRechargeDO extends BaseDO { @@ -42,7 +42,6 @@ public class PayWalletRechargeDO extends BaseDO {
42 * 实际支付金额 42 * 实际支付金额
43 */ 43 */
44 private Integer payPrice; 44 private Integer payPrice;
45 -  
46 /** 45 /**
47 * 钱包赠送金额 46 * 钱包赠送金额
48 */ 47 */
@@ -50,8 +49,10 @@ public class PayWalletRechargeDO extends BaseDO { @@ -50,8 +49,10 @@ public class PayWalletRechargeDO extends BaseDO {
50 49
51 /** 50 /**
52 * 充值套餐编号 51 * 充值套餐编号
  52 + *
  53 + * 关联 {@link PayWalletRechargeDO#getPackageId()} 字段
53 */ 54 */
54 - private Long packageId; 55 + private Long packageId;
55 56
56 /** 57 /**
57 * 是否已支付 58 * 是否已支付
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/wallet/PayWalletRechargePackageDO.java
@@ -9,7 +9,7 @@ import lombok.Data; @@ -9,7 +9,7 @@ import lombok.Data;
9 /** 9 /**
10 * 会员钱包充值套餐 DO 10 * 会员钱包充值套餐 DO
11 * 11 *
12 - * 通过套餐充值时,可以赠送一定金额; 12 + * 通过充值套餐时,可以赠送一定金额;
13 * 13 *
14 * @author 芋道源码 14 * @author 芋道源码
15 */ 15 */
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/demo/PayDemoTransferMapper.java
@@ -7,8 +7,4 @@ import org.apache.ibatis.annotations.Mapper; @@ -7,8 +7,4 @@ import org.apache.ibatis.annotations.Mapper;
7 @Mapper 7 @Mapper
8 public interface PayDemoTransferMapper extends BaseMapperX<PayDemoTransferDO> { 8 public interface PayDemoTransferMapper extends BaseMapperX<PayDemoTransferDO> {
9 9
10 -}  
11 -  
12 -  
13 -  
14 - 10 +}
15 \ No newline at end of file 11 \ No newline at end of file
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/transfer/PayTransferExtensionMapper.java
@@ -14,10 +14,11 @@ public interface PayTransferExtensionMapper extends BaseMapperX&lt;PayTransferExten @@ -14,10 +14,11 @@ public interface PayTransferExtensionMapper extends BaseMapperX&lt;PayTransferExten
14 return selectOne(PayTransferExtensionDO::getNo, no); 14 return selectOne(PayTransferExtensionDO::getNo, no);
15 } 15 }
16 16
17 - default int updateByIdAndStatus(Long id, List<Integer> status, PayTransferExtensionDO updateObj){ 17 + default int updateByIdAndStatus(Long id, List<Integer> whereStatuses, PayTransferExtensionDO updateObj) {
18 return update(updateObj, new LambdaQueryWrapper<PayTransferExtensionDO>() 18 return update(updateObj, new LambdaQueryWrapper<PayTransferExtensionDO>()
19 - .eq(PayTransferExtensionDO::getId, id).in(PayTransferExtensionDO::getStatus, status)); 19 + .eq(PayTransferExtensionDO::getId, id).in(PayTransferExtensionDO::getStatus, whereStatuses));
20 } 20 }
  21 +
21 } 22 }
22 23
23 24
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/transfer/PayTransferMapper.java
@@ -14,6 +14,7 @@ public interface PayTransferMapper extends BaseMapperX&lt;PayTransferDO&gt; { @@ -14,6 +14,7 @@ public interface PayTransferMapper extends BaseMapperX&lt;PayTransferDO&gt; {
14 return update(updateObj, new LambdaQueryWrapper<PayTransferDO>() 14 return update(updateObj, new LambdaQueryWrapper<PayTransferDO>()
15 .eq(PayTransferDO::getId, id).in(PayTransferDO::getStatus, status)); 15 .eq(PayTransferDO::getId, id).in(PayTransferDO::getStatus, status));
16 } 16 }
  17 +
17 } 18 }
18 19
19 20
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/wallet/PayWalletMapper.java
@@ -70,6 +70,7 @@ public interface PayWalletMapper extends BaseMapperX&lt;PayWalletDO&gt; { @@ -70,6 +70,7 @@ public interface PayWalletMapper extends BaseMapperX&lt;PayWalletDO&gt; {
70 70
71 /** 71 /**
72 * 冻结钱包部分余额 72 * 冻结钱包部分余额
  73 + *
73 * @param id 钱包 id 74 * @param id 钱包 id
74 * @param price 冻结金额 75 * @param price 冻结金额
75 */ 76 */
@@ -84,6 +85,7 @@ public interface PayWalletMapper extends BaseMapperX&lt;PayWalletDO&gt; { @@ -84,6 +85,7 @@ public interface PayWalletMapper extends BaseMapperX&lt;PayWalletDO&gt; {
84 85
85 /** 86 /**
86 * 解冻钱包余额 87 * 解冻钱包余额
  88 + *
87 * @param id 钱包 id 89 * @param id 钱包 id
88 * @param price 解冻金额 90 * @param price 解冻金额
89 */ 91 */
@@ -98,6 +100,7 @@ public interface PayWalletMapper extends BaseMapperX&lt;PayWalletDO&gt; { @@ -98,6 +100,7 @@ public interface PayWalletMapper extends BaseMapperX&lt;PayWalletDO&gt; {
98 100
99 /** 101 /**
100 * 当充值退款时, 更新钱包 102 * 当充值退款时, 更新钱包
  103 + *
101 * @param id 钱包 id 104 * @param id 钱包 id
102 * @param price 退款金额 105 * @param price 退款金额
103 */ 106 */
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/wallet/PayWalletRechargeMapper.java
@@ -18,8 +18,4 @@ public interface PayWalletRechargeMapper extends BaseMapperX&lt;PayWalletRechargeDO @@ -18,8 +18,4 @@ public interface PayWalletRechargeMapper extends BaseMapperX&lt;PayWalletRechargeDO
18 .eq(PayWalletRechargeDO::getId, id).eq(PayWalletRechargeDO::getRefundStatus, whereRefundStatus)); 18 .eq(PayWalletRechargeDO::getId, id).eq(PayWalletRechargeDO::getRefundStatus, whereRefundStatus));
19 } 19 }
20 20
21 -}  
22 -  
23 -  
24 -  
25 - 21 +}
26 \ No newline at end of file 22 \ No newline at end of file
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/wallet/PayWalletRechargePackageMapper.java
@@ -12,6 +12,7 @@ import org.apache.ibatis.annotations.Mapper; @@ -12,6 +12,7 @@ import org.apache.ibatis.annotations.Mapper;
12 public interface PayWalletRechargePackageMapper extends BaseMapperX<PayWalletRechargePackageDO> { 12 public interface PayWalletRechargePackageMapper extends BaseMapperX<PayWalletRechargePackageDO> {
13 13
14 default PageResult<PayWalletRechargePackageDO> selectPage(WalletRechargePackagePageReqVO reqVO) { 14 default PageResult<PayWalletRechargePackageDO> selectPage(WalletRechargePackagePageReqVO reqVO) {
  15 + // TODO @jason:排序按照充值金额
15 return selectPage(reqVO, new LambdaQueryWrapperX<PayWalletRechargePackageDO>() 16 return selectPage(reqVO, new LambdaQueryWrapperX<PayWalletRechargePackageDO>()
16 .likeIfPresent(PayWalletRechargePackageDO::getName, reqVO.getName()) 17 .likeIfPresent(PayWalletRechargePackageDO::getName, reqVO.getName())
17 .eqIfPresent(PayWalletRechargePackageDO::getPayPrice, reqVO.getPayPrice()) 18 .eqIfPresent(PayWalletRechargePackageDO::getPayPrice, reqVO.getPayPrice())
@@ -20,8 +21,5 @@ public interface PayWalletRechargePackageMapper extends BaseMapperX&lt;PayWalletRec @@ -20,8 +21,5 @@ public interface PayWalletRechargePackageMapper extends BaseMapperX&lt;PayWalletRec
20 .betweenIfPresent(PayWalletRechargePackageDO::getCreateTime, reqVO.getCreateTime()) 21 .betweenIfPresent(PayWalletRechargePackageDO::getCreateTime, reqVO.getCreateTime())
21 .orderByDesc(PayWalletRechargePackageDO::getId)); 22 .orderByDesc(PayWalletRechargePackageDO::getId));
22 } 23 }
23 -}  
24 -  
25 -  
26 -  
27 24
  25 +}
28 \ No newline at end of file 26 \ No newline at end of file
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/framework/pay/core/WalletPayClient.java
@@ -180,4 +180,5 @@ public class WalletPayClient extends AbstractPayClient&lt;NonePayClientConfig&gt; { @@ -180,4 +180,5 @@ public class WalletPayClient extends AbstractPayClient&lt;NonePayClientConfig&gt; {
180 public PayTransferRespDTO doUnifiedTransfer(PayTransferUnifiedReqDTO reqDTO) { 180 public PayTransferRespDTO doUnifiedTransfer(PayTransferUnifiedReqDTO reqDTO) {
181 throw new UnsupportedOperationException("待实现"); 181 throw new UnsupportedOperationException("待实现");
182 } 182 }
  183 +
183 } 184 }
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoTransferServiceImpl.java
@@ -64,6 +64,7 @@ public class PayDemoTransferServiceImpl implements PayDemoTransferService { @@ -64,6 +64,7 @@ public class PayDemoTransferServiceImpl implements PayDemoTransferService {
64 return demoTransfer.getId(); 64 return demoTransfer.getId();
65 } 65 }
66 66
  67 + // TODO @jason:可以参考 AppBrokerageWithdrawCreateReqVO 搞下字段哈,进行校验
67 private void validatePayeeInfo(Integer transferType, Map<String, String> payeeInfo) { 68 private void validatePayeeInfo(Integer transferType, Map<String, String> payeeInfo) {
68 PayTransferTypeEnum transferTypeEnum = ofType(transferType); 69 PayTransferTypeEnum transferTypeEnum = ofType(transferType);
69 switch (transferTypeEnum) { 70 switch (transferTypeEnum) {
@@ -83,4 +84,5 @@ public class PayDemoTransferServiceImpl implements PayDemoTransferService { @@ -83,4 +84,5 @@ public class PayDemoTransferServiceImpl implements PayDemoTransferService {
83 } 84 }
84 } 85 }
85 } 86 }
  87 +
86 } 88 }
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferService.java
@@ -7,6 +7,8 @@ import cn.iocoder.yudao.module.pay.controller.admin.transfer.vo.PayTransferSubmi @@ -7,6 +7,8 @@ import cn.iocoder.yudao.module.pay.controller.admin.transfer.vo.PayTransferSubmi
7 import javax.validation.Valid; 7 import javax.validation.Valid;
8 8
9 /** 9 /**
  10 + * 转账 Service 接口
  11 + *
10 * @author jason 12 * @author jason
11 */ 13 */
12 public interface PayTransferService { 14 public interface PayTransferService {
@@ -29,4 +31,5 @@ public interface PayTransferService { @@ -29,4 +31,5 @@ public interface PayTransferService {
29 * @return 转账单编号 31 * @return 转账单编号
30 */ 32 */
31 Long createTransfer(@Valid PayTransferCreateReqDTO reqDTO); 33 Long createTransfer(@Valid PayTransferCreateReqDTO reqDTO);
  34 +
32 } 35 }
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferServiceImpl.java
@@ -34,7 +34,10 @@ import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionU @@ -34,7 +34,10 @@ import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionU
34 import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.*; 34 import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.*;
35 import static cn.iocoder.yudao.module.pay.enums.transfer.PayTransferStatusEnum.*; 35 import static cn.iocoder.yudao.module.pay.enums.transfer.PayTransferStatusEnum.*;
36 36
  37 +// TODO @jason:等彻底实现完,单测写写;
37 /** 38 /**
  39 + * 转账 Service 实现类
  40 + *
38 * @author jason 41 * @author jason
39 */ 42 */
40 @Service 43 @Service
@@ -47,10 +50,12 @@ public class PayTransferServiceImpl implements PayTransferService { @@ -47,10 +50,12 @@ public class PayTransferServiceImpl implements PayTransferService {
47 private PayTransferMapper transferMapper; 50 private PayTransferMapper transferMapper;
48 @Resource 51 @Resource
49 private PayTransferExtensionMapper transferExtensionMapper; 52 private PayTransferExtensionMapper transferExtensionMapper;
  53 +
50 @Resource 54 @Resource
51 private PayAppService appService; 55 private PayAppService appService;
52 @Resource 56 @Resource
53 private PayChannelService channelService; 57 private PayChannelService channelService;
  58 +
54 @Resource 59 @Resource
55 private PayNoRedisDAO noRedisDAO; 60 private PayNoRedisDAO noRedisDAO;
56 61
@@ -64,7 +69,7 @@ public class PayTransferServiceImpl implements PayTransferService { @@ -64,7 +69,7 @@ public class PayTransferServiceImpl implements PayTransferService {
64 PayChannelDO channel = validateChannelCanSubmit(transfer.getAppId(), reqVO.getChannelCode()); 69 PayChannelDO channel = validateChannelCanSubmit(transfer.getAppId(), reqVO.getChannelCode());
65 PayClient client = channelService.getPayClient(channel.getId()); 70 PayClient client = channelService.getPayClient(channel.getId());
66 71
67 - // 2 新增转账拓展单 72 + // 2. 新增转账拓展单
68 String no = noRedisDAO.generate(TRANSFER_NO_PREFIX); 73 String no = noRedisDAO.generate(TRANSFER_NO_PREFIX);
69 PayTransferExtensionDO transferExtension = new PayTransferExtensionDO().setNo(no) 74 PayTransferExtensionDO transferExtension = new PayTransferExtensionDO().setNo(no)
70 .setTransferId(transfer.getId()).setChannelId(channel.getId()) 75 .setTransferId(transfer.getId()).setChannelId(channel.getId())
@@ -112,8 +117,9 @@ public class PayTransferServiceImpl implements PayTransferService { @@ -112,8 +117,9 @@ public class PayTransferServiceImpl implements PayTransferService {
112 notifyTransferClosed(channel, notify); 117 notifyTransferClosed(channel, notify);
113 } 118 }
114 // WAITING 状态无需处理 119 // WAITING 状态无需处理
115 - // TODO IN_PROGRESS 待处理 120 + // TODO IN_PROGRESS 待处理
116 } 121 }
  122 +
117 private void notifyTransferSuccess(PayChannelDO channel, PayTransferRespDTO notify) { 123 private void notifyTransferSuccess(PayChannelDO channel, PayTransferRespDTO notify) {
118 // 1. 更新 PayTransferExtensionDO 转账成功 124 // 1. 更新 PayTransferExtensionDO 转账成功
119 PayTransferExtensionDO transferExtension = updateTransferExtensionSuccess(notify); 125 PayTransferExtensionDO transferExtension = updateTransferExtensionSuccess(notify);
@@ -121,7 +127,7 @@ public class PayTransferServiceImpl implements PayTransferService { @@ -121,7 +127,7 @@ public class PayTransferServiceImpl implements PayTransferService {
121 // 2. 更新 PayTransferDO 转账成功 127 // 2. 更新 PayTransferDO 转账成功
122 Boolean transferred = updateTransferSuccess(channel,transferExtension, notify); 128 Boolean transferred = updateTransferSuccess(channel,transferExtension, notify);
123 if (transferred) { 129 if (transferred) {
124 - return ; 130 + return;
125 } 131 }
126 // 3. TODO 插入转账通知记录 132 // 3. TODO 插入转账通知记录
127 } 133 }
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletRechargePackageService.java
@@ -31,7 +31,7 @@ public interface PayWalletRechargePackageService { @@ -31,7 +31,7 @@ public interface PayWalletRechargePackageService {
31 PayWalletRechargePackageDO validWalletRechargePackage(Long packageId); 31 PayWalletRechargePackageDO validWalletRechargePackage(Long packageId);
32 32
33 /** 33 /**
34 - * 创建套餐充值 34 + * 创建充值套餐
35 * 35 *
36 * @param createReqVO 创建信息 36 * @param createReqVO 创建信息
37 * @return 编号 37 * @return 编号
@@ -39,33 +39,25 @@ public interface PayWalletRechargePackageService { @@ -39,33 +39,25 @@ public interface PayWalletRechargePackageService {
39 Long createWalletRechargePackage(@Valid WalletRechargePackageCreateReqVO createReqVO); 39 Long createWalletRechargePackage(@Valid WalletRechargePackageCreateReqVO createReqVO);
40 40
41 /** 41 /**
42 - * 更新套餐充值 42 + * 更新充值套餐
43 * 43 *
44 * @param updateReqVO 更新信息 44 * @param updateReqVO 更新信息
45 */ 45 */
46 void updateWalletRechargePackage(@Valid WalletRechargePackageUpdateReqVO updateReqVO); 46 void updateWalletRechargePackage(@Valid WalletRechargePackageUpdateReqVO updateReqVO);
47 47
48 -  
49 /** 48 /**
50 - * 删除套餐充值 49 + * 删除充值套餐
51 * 50 *
52 * @param id 编号 51 * @param id 编号
53 */ 52 */
54 void deleteWalletRechargePackage(Long id); 53 void deleteWalletRechargePackage(Long id);
55 54
56 /** 55 /**
57 - * 获得套餐充值列表  
58 - *  
59 - * @param ids 编号  
60 - * @return 套餐充值列表  
61 - */  
62 - List<PayWalletRechargePackageDO> getWalletRechargePackageList(Collection<Long> ids);  
63 -  
64 - /**  
65 - * 获得套餐充值分页 56 + * 获得充值套餐分页
66 * 57 *
67 * @param pageReqVO 分页查询 58 * @param pageReqVO 分页查询
68 - * @return 套餐充值分页 59 + * @return 充值套餐分页
69 */ 60 */
70 PageResult<PayWalletRechargePackageDO> getWalletRechargePackagePage(WalletRechargePackagePageReqVO pageReqVO); 61 PageResult<PayWalletRechargePackageDO> getWalletRechargePackagePage(WalletRechargePackagePageReqVO pageReqVO);
  62 +
71 } 63 }
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletRechargePackageServiceImpl.java
@@ -57,6 +57,7 @@ public class PayWalletRechargePackageServiceImpl implements PayWalletRechargePac @@ -57,6 +57,7 @@ public class PayWalletRechargePackageServiceImpl implements PayWalletRechargePac
57 return walletRechargePackage.getId(); 57 return walletRechargePackage.getId();
58 } 58 }
59 59
  60 + // TODO @jason:校验下,套餐名唯一
60 @Override 61 @Override
61 public void updateWalletRechargePackage(WalletRechargePackageUpdateReqVO updateReqVO) { 62 public void updateWalletRechargePackage(WalletRechargePackageUpdateReqVO updateReqVO) {
62 // 校验存在 63 // 校验存在
@@ -81,14 +82,6 @@ public class PayWalletRechargePackageServiceImpl implements PayWalletRechargePac @@ -81,14 +82,6 @@ public class PayWalletRechargePackageServiceImpl implements PayWalletRechargePac
81 } 82 }
82 83
83 @Override 84 @Override
84 - public List<PayWalletRechargePackageDO> getWalletRechargePackageList(Collection<Long> ids) {  
85 - if (CollUtil.isEmpty(ids)) {  
86 - return ListUtil.empty();  
87 - }  
88 - return walletRechargePackageMapper.selectBatchIds(ids);  
89 - }  
90 -  
91 - @Override  
92 public PageResult<PayWalletRechargePackageDO> getWalletRechargePackagePage(WalletRechargePackagePageReqVO pageReqVO) { 85 public PageResult<PayWalletRechargePackageDO> getWalletRechargePackagePage(WalletRechargePackagePageReqVO pageReqVO) {
93 return walletRechargePackageMapper.selectPage(pageReqVO); 86 return walletRechargePackageMapper.selectPage(pageReqVO);
94 } 87 }
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletRechargeServiceImpl.java
@@ -44,7 +44,7 @@ import static cn.iocoder.yudao.module.pay.enums.refund.PayRefundStatusEnum.*; @@ -44,7 +44,7 @@ import static cn.iocoder.yudao.module.pay.enums.refund.PayRefundStatusEnum.*;
44 public class PayWalletRechargeServiceImpl implements PayWalletRechargeService { 44 public class PayWalletRechargeServiceImpl implements PayWalletRechargeService {
45 45
46 /** 46 /**
47 - * TODO 放到 配置文件中 47 + * TODO 芋艿:放到 payconfig
48 */ 48 */
49 private static final Long WALLET_PAY_APP_ID = 8L; 49 private static final Long WALLET_PAY_APP_ID = 8L;
50 50
@@ -65,13 +65,14 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService { @@ -65,13 +65,14 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService {
65 @Transactional(rollbackFor = Exception.class) 65 @Transactional(rollbackFor = Exception.class)
66 public PayWalletRechargeDO createWalletRecharge(Long userId, Integer userType, 66 public PayWalletRechargeDO createWalletRecharge(Long userId, Integer userType,
67 AppPayWalletRechargeCreateReqVO reqVO) { 67 AppPayWalletRechargeCreateReqVO reqVO) {
68 - // 1.1 校验参数 68 + // 1.1 校验参数 TODO @jason:AppPayWalletRechargeCreateReqVO 看下校验;
69 if (Objects.isNull(reqVO.getPayPrice()) && Objects.isNull(reqVO.getPackageId())) { 69 if (Objects.isNull(reqVO.getPayPrice()) && Objects.isNull(reqVO.getPackageId())) {
70 throw exception(WALLET_RECHARGE_PACKAGE_AND_PRICE_IS_EMPTY); 70 throw exception(WALLET_RECHARGE_PACKAGE_AND_PRICE_IS_EMPTY);
71 } 71 }
72 - // 1.2 新增钱包充值记录  
73 - int payPrice ;  
74 - int bonusPrice = 0 ; 72 +
  73 + // 1.1 计算充值金额
  74 + int payPrice;
  75 + int bonusPrice = 0;
75 if (Objects.nonNull(reqVO.getPackageId())) { 76 if (Objects.nonNull(reqVO.getPackageId())) {
76 PayWalletRechargePackageDO rechargePackage = payWalletRechargePackageService.validWalletRechargePackage(reqVO.getPackageId()); 77 PayWalletRechargePackageDO rechargePackage = payWalletRechargePackageService.validWalletRechargePackage(reqVO.getPackageId());
77 payPrice = rechargePackage.getPayPrice(); 78 payPrice = rechargePackage.getPayPrice();
@@ -79,23 +80,22 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService { @@ -79,23 +80,22 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService {
79 } else { 80 } else {
80 payPrice = reqVO.getPayPrice(); 81 payPrice = reqVO.getPayPrice();
81 } 82 }
82 - 83 + // 1.2 插入充值记录
83 PayWalletDO wallet = payWalletService.getOrCreateWallet(userId, userType); 84 PayWalletDO wallet = payWalletService.getOrCreateWallet(userId, userType);
84 - PayWalletRechargeDO walletRecharge = INSTANCE.convert(wallet.getId(), payPrice, bonusPrice, reqVO.getPackageId());  
85 - walletRechargeMapper.insert(walletRecharge); 85 + PayWalletRechargeDO recharge = INSTANCE.convert(wallet.getId(), payPrice, bonusPrice, reqVO.getPackageId());
  86 + walletRechargeMapper.insert(recharge);
86 87
87 // 2.1 创建支付单 88 // 2.1 创建支付单
88 Long payOrderId = payOrderService.createOrder(new PayOrderCreateReqDTO() 89 Long payOrderId = payOrderService.createOrder(new PayOrderCreateReqDTO()
89 - .setAppId(WALLET_PAY_APP_ID).setUserIp(getClientIP())  
90 - .setMerchantOrderId(walletRecharge.getId().toString()) // 业务的订单编号  
91 - .setSubject(WALLET_RECHARGE_ORDER_SUBJECT).setBody("").setPrice(walletRecharge.getPayPrice())  
92 - .setExpireTime(addTime(Duration.ofHours(2L)))); 90 + .setAppId(WALLET_PAY_APP_ID).setUserIp(getClientIP()) // TODO @jason:clientIp 从 controller 传递进来噢
  91 + .setMerchantOrderId(recharge.getId().toString()) // 业务的订单编号
  92 + .setSubject(WALLET_RECHARGE_ORDER_SUBJECT).setBody("")
  93 + .setPrice(recharge.getPayPrice())
  94 + .setExpireTime(addTime(Duration.ofHours(2L)))); // TODO @芋艿:支付超时时间
93 // 2.2 更新钱包充值记录中支付订单 95 // 2.2 更新钱包充值记录中支付订单
94 - walletRechargeMapper.updateById(new PayWalletRechargeDO().setPayOrderId(payOrderId)  
95 - .setId(walletRecharge.getId()));  
96 -  
97 - walletRecharge.setPayOrderId(payOrderId);  
98 - return walletRecharge; 96 + walletRechargeMapper.updateById(new PayWalletRechargeDO().setId(recharge.getId()).setPayOrderId(payOrderId));
  97 + recharge.setPayOrderId(payOrderId);
  98 + return recharge;
99 } 99 }
100 100
101 @Override 101 @Override
@@ -136,9 +136,11 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService { @@ -136,9 +136,11 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService {
136 } 136 }
137 // 1.2 校验钱包充值是否可以发起退款 137 // 1.2 校验钱包充值是否可以发起退款
138 PayWalletDO wallet = validateWalletRechargeCanRefund(walletRecharge); 138 PayWalletDO wallet = validateWalletRechargeCanRefund(walletRecharge);
139 - // 2 冻结退款的余额, 暂时只处理赠送的余额也全部退回 139 +
  140 + // 2. 冻结退款的余额,暂时只处理赠送的余额也全部退回
140 payWalletService.freezePrice(wallet.getId(), walletRecharge.getTotalPrice()); 141 payWalletService.freezePrice(wallet.getId(), walletRecharge.getTotalPrice());
141 - // 3 创建退款单 142 +
  143 + // 3. 创建退款单
142 String walletRechargeId = String.valueOf(id); 144 String walletRechargeId = String.valueOf(id);
143 String refundId = walletRechargeId + "-refund"; 145 String refundId = walletRechargeId + "-refund";
144 Long payRefundId = payRefundService.createPayRefund(new PayRefundCreateReqDTO() 146 Long payRefundId = payRefundService.createPayRefund(new PayRefundCreateReqDTO()
@@ -146,7 +148,9 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService { @@ -146,7 +148,9 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService {
146 .setMerchantOrderId(walletRechargeId) 148 .setMerchantOrderId(walletRechargeId)
147 .setMerchantRefundId(refundId) 149 .setMerchantRefundId(refundId)
148 .setReason("想退钱").setPrice(walletRecharge.getPayPrice())); 150 .setReason("想退钱").setPrice(walletRecharge.getPayPrice()));
149 - // 4 更新充值记录退款单号 151 +
  152 + // 4. 更新充值记录退款单号
  153 + // TODO @jaosn:一般新建这种 update 对象,建议是,第一个 set id 属性,容易知道以它为更新
150 walletRechargeMapper.updateById(new PayWalletRechargeDO().setPayRefundId(payRefundId) 154 walletRechargeMapper.updateById(new PayWalletRechargeDO().setPayRefundId(payRefundId)
151 .setRefundStatus(WAITING.getStatus()).setId(walletRecharge.getId())); 155 .setRefundStatus(WAITING.getStatus()).setId(walletRecharge.getId()));
152 } 156 }
@@ -229,6 +233,7 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService { @@ -229,6 +233,7 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService {
229 if (wallet.getBalance() < walletRecharge.getTotalPrice()) { 233 if (wallet.getBalance() < walletRecharge.getTotalPrice()) {
230 throw exception(WALLET_RECHARGE_REFUND_BALANCE_NOT_ENOUGH); 234 throw exception(WALLET_RECHARGE_REFUND_BALANCE_NOT_ENOUGH);
231 } 235 }
  236 + // TODO @芋艿:需要考虑下,赠送的金额,会不会导致提现超过;
232 return wallet; 237 return wallet;
233 } 238 }
234 239
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletService.java
@@ -90,6 +90,7 @@ public interface PayWalletService { @@ -90,6 +90,7 @@ public interface PayWalletService {
90 */ 90 */
91 void freezePrice(Long id, Integer price); 91 void freezePrice(Long id, Integer price);
92 92
  93 + // TODO @jason:unfreeze 是单词哈,f 不用大写
93 /** 94 /**
94 * 解冻钱包余额 95 * 解冻钱包余额
95 * 96 *
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletServiceImpl.java
@@ -109,6 +109,7 @@ public class PayWalletServiceImpl implements PayWalletService { @@ -109,6 +109,7 @@ public class PayWalletServiceImpl implements PayWalletService {
109 if (walletTransaction == null) { 109 if (walletTransaction == null) {
110 throw exception(WALLET_TRANSACTION_NOT_FOUND); 110 throw exception(WALLET_TRANSACTION_NOT_FOUND);
111 } 111 }
  112 + // 2. 校验退款是否存在
112 PayWalletTransactionDO refundTransaction = walletTransactionService.getWalletTransaction( 113 PayWalletTransactionDO refundTransaction = walletTransactionService.getWalletTransaction(
113 String.valueOf(refundId), PAYMENT_REFUND); 114 String.valueOf(refundId), PAYMENT_REFUND);
114 if (refundTransaction != null) { 115 if (refundTransaction != null) {
@@ -128,7 +129,7 @@ public class PayWalletServiceImpl implements PayWalletService { @@ -128,7 +129,7 @@ public class PayWalletServiceImpl implements PayWalletService {
128 } 129 }
129 130
130 // 2.1 扣除余额 131 // 2.1 扣除余额
131 - int updateCounts = 0 ; 132 + int updateCounts;
132 switch (bizType) { 133 switch (bizType) {
133 case PAYMENT: { 134 case PAYMENT: {
134 updateCounts = walletMapper.updateWhenConsumption(payWallet.getId(), price); 135 updateCounts = walletMapper.updateWhenConsumption(payWallet.getId(), price);
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/social/SocialClientApi.java 0 → 100644
  1 +package cn.iocoder.yudao.module.system.api.social;
  2 +
  3 +import cn.iocoder.yudao.module.system.api.social.dto.SocialWxJsapiSignatureRespDTO;
  4 +import cn.iocoder.yudao.module.system.api.social.dto.SocialWxPhoneNumberInfoRespDTO;
  5 +import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum;
  6 +
  7 +/**
  8 + * 社交应用的 API 接口
  9 + *
  10 + * @author 芋道源码
  11 + */
  12 +public interface SocialClientApi {
  13 +
  14 + /**
  15 + * 获得社交平台的授权 URL
  16 + *
  17 + * @param type 社交平台的类型 {@link SocialTypeEnum}
  18 + * @param userType 用户类型
  19 + * @param redirectUri 重定向 URL
  20 + * @return 社交平台的授权 URL
  21 + */
  22 + String getAuthorizeUrl(Integer type, Integer userType, String redirectUri);
  23 +
  24 + /**
  25 + * 创建微信公众号 JS SDK 初始化所需的签名
  26 + *
  27 + * @param userType 用户类型
  28 + * @param url 访问的 URL 地址
  29 + * @return 签名
  30 + */
  31 + SocialWxJsapiSignatureRespDTO createWxMpJsapiSignature(Integer userType, String url);
  32 +
  33 + /**
  34 + * 获得微信小程序的手机信息
  35 + *
  36 + * @param userType 用户类型
  37 + * @param phoneCode 手机授权码
  38 + * @return 手机信息
  39 + */
  40 + SocialWxPhoneNumberInfoRespDTO getWxMaPhoneNumberInfo(Integer userType, String phoneCode);
  41 +
  42 +}
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/social/SocialUserApi.java
@@ -4,7 +4,6 @@ import cn.iocoder.yudao.framework.common.exception.ServiceException; @@ -4,7 +4,6 @@ import cn.iocoder.yudao.framework.common.exception.ServiceException;
4 import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO; 4 import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO;
5 import cn.iocoder.yudao.module.system.api.social.dto.SocialUserRespDTO; 5 import cn.iocoder.yudao.module.system.api.social.dto.SocialUserRespDTO;
6 import cn.iocoder.yudao.module.system.api.social.dto.SocialUserUnbindReqDTO; 6 import cn.iocoder.yudao.module.system.api.social.dto.SocialUserUnbindReqDTO;
7 -import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum;  
8 7
9 import javax.validation.Valid; 8 import javax.validation.Valid;
10 9
@@ -16,15 +15,6 @@ import javax.validation.Valid; @@ -16,15 +15,6 @@ import javax.validation.Valid;
16 public interface SocialUserApi { 15 public interface SocialUserApi {
17 16
18 /** 17 /**
19 - * 获得社交平台的授权 URL  
20 - *  
21 - * @param type 社交平台的类型 {@link SocialTypeEnum}  
22 - * @param redirectUri 重定向 URL  
23 - * @return 社交平台的授权 URL  
24 - */  
25 - String getAuthorizeUrl(Integer type, String redirectUri);  
26 -  
27 - /**  
28 * 绑定社交用户 18 * 绑定社交用户
29 * 19 *
30 * @param reqDTO 绑定信息 20 * @param reqDTO 绑定信息
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/social/dto/SocialUserBindReqDTO.java
@@ -37,7 +37,7 @@ public class SocialUserBindReqDTO { @@ -37,7 +37,7 @@ public class SocialUserBindReqDTO {
37 */ 37 */
38 @InEnum(SocialTypeEnum.class) 38 @InEnum(SocialTypeEnum.class)
39 @NotNull(message = "社交平台的类型不能为空") 39 @NotNull(message = "社交平台的类型不能为空")
40 - private Integer type; 40 + private Integer socialType;
41 /** 41 /**
42 * 授权码 42 * 授权码
43 */ 43 */
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/social/dto/SocialUserUnbindReqDTO.java
@@ -33,12 +33,12 @@ public class SocialUserUnbindReqDTO { @@ -33,12 +33,12 @@ public class SocialUserUnbindReqDTO {
33 */ 33 */
34 @InEnum(SocialTypeEnum.class) 34 @InEnum(SocialTypeEnum.class)
35 @NotNull(message = "社交平台的类型不能为空") 35 @NotNull(message = "社交平台的类型不能为空")
36 - private Integer type; 36 + private Integer socialType;
37 37
38 /** 38 /**
39 - * 社交平台的 unionId 39 + * 社交平台的 openid
40 */ 40 */
41 - @NotEmpty(message = "社交平台的 unionId 不能为空")  
42 - private String unionId; 41 + @NotEmpty(message = "社交平台的 openid 不能为空")
  42 + private String openid;
43 43
44 } 44 }
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/social/dto/SocialWxJsapiSignatureRespDTO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.system.api.social.dto;
  2 +
  3 +import lombok.Data;
  4 +
  5 +/**
  6 + * 微信公众号 JSAPI 签名 Response DTO
  7 + *
  8 + * @author 芋道源码
  9 + */
  10 +@Data
  11 +public class SocialWxJsapiSignatureRespDTO {
  12 +
  13 + /**
  14 + * 微信公众号的 appId
  15 + */
  16 + private String appId;
  17 + /**
  18 + * 匿名串
  19 + */
  20 + private String nonceStr;
  21 + /**
  22 + * 时间戳
  23 + */
  24 + private Long timestamp;
  25 + /**
  26 + * URL
  27 + */
  28 + private String url;
  29 + /**
  30 + * 签名
  31 + */
  32 + private String signature;
  33 +
  34 +}
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/social/dto/SocialWxPhoneNumberInfoRespDTO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.system.api.social.dto;
  2 +
  3 +import lombok.Data;
  4 +
  5 +/**
  6 + * 微信小程序的手机信息 Response DTO
  7 + *
  8 + * @author 芋道源码
  9 + */
  10 +@Data
  11 +public class SocialWxPhoneNumberInfoRespDTO {
  12 +
  13 + /**
  14 + * 用户绑定的手机号(国外手机号会有区号)
  15 + */
  16 + private String phoneNumber;
  17 +
  18 + /**
  19 + * 没有区号的手机号
  20 + */
  21 + private String purePhoneNumber;
  22 + /**
  23 + * 区号
  24 + */
  25 + private String countryCode;
  26 +
  27 +}
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java
@@ -119,6 +119,8 @@ public interface ErrorCodeConstants { @@ -119,6 +119,8 @@ public interface ErrorCodeConstants {
119 ErrorCode SOCIAL_USER_UNBIND_NOT_SELF = new ErrorCode(1_002_018_001, "社交解绑失败,非当前用户绑定"); 119 ErrorCode SOCIAL_USER_UNBIND_NOT_SELF = new ErrorCode(1_002_018_001, "社交解绑失败,非当前用户绑定");
120 ErrorCode SOCIAL_USER_NOT_FOUND = new ErrorCode(1_002_018_002, "社交授权失败,找不到对应的用户"); 120 ErrorCode SOCIAL_USER_NOT_FOUND = new ErrorCode(1_002_018_002, "社交授权失败,找不到对应的用户");
121 121
  122 + ErrorCode SOCIAL_APP_WEIXIN_MINI_APP_PHONE_CODE_ERROR = new ErrorCode(1_002_018_103, "获得手机号失败");
  123 +
122 // ========== 系统敏感词 1-002-019-000 ========= 124 // ========== 系统敏感词 1-002-019-000 =========
123 ErrorCode SENSITIVE_WORD_NOT_EXISTS = new ErrorCode(1_002_019_000, "系统敏感词在所有标签中都不存在"); 125 ErrorCode SENSITIVE_WORD_NOT_EXISTS = new ErrorCode(1_002_019_000, "系统敏感词在所有标签中都不存在");
124 ErrorCode SENSITIVE_WORD_EXISTS = new ErrorCode(1_002_019_001, "系统敏感词已在标签中存在"); 126 ErrorCode SENSITIVE_WORD_EXISTS = new ErrorCode(1_002_019_001, "系统敏感词已在标签中存在");
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/social/SocialTypeEnum.java
@@ -18,33 +18,39 @@ public enum SocialTypeEnum implements IntArrayValuable { @@ -18,33 +18,39 @@ public enum SocialTypeEnum implements IntArrayValuable {
18 18
19 /** 19 /**
20 * Gitee 20 * Gitee
21 - * 文档链接:https://gitee.com/api/v5/oauth_doc#/ 21 + *
  22 + * @see <a href="https://gitee.com/api/v5/oauth_doc#/">接入文档</a>
22 */ 23 */
23 GITEE(10, "GITEE"), 24 GITEE(10, "GITEE"),
24 /** 25 /**
25 * 钉钉 26 * 钉钉
26 - * 文档链接:https://developers.dingtalk.com/document/app/obtain-identity-credentials 27 + *
  28 + * @see <a href="https://developers.dingtalk.com/document/app/obtain-identity-credentials">接入文档</a>
27 */ 29 */
28 DINGTALK(20, "DINGTALK"), 30 DINGTALK(20, "DINGTALK"),
29 31
30 /** 32 /**
31 * 企业微信 33 * 企业微信
32 - * 文档链接:https://xkcoding.com/2019/08/06/use-justauth-integration-wechat-enterprise.html 34 + *
  35 + * @see <a href="https://xkcoding.com/2019/08/06/use-justauth-integration-wechat-enterprise.html">接入文档</a>
33 */ 36 */
34 WECHAT_ENTERPRISE(30, "WECHAT_ENTERPRISE"), 37 WECHAT_ENTERPRISE(30, "WECHAT_ENTERPRISE"),
35 /** 38 /**
36 * 微信公众平台 - 移动端 H5 39 * 微信公众平台 - 移动端 H5
37 - * 文档链接:https://www.cnblogs.com/juewuzhe/p/11905461.html 40 + *
  41 + * @see <a href="https://www.cnblogs.com/juewuzhe/p/11905461.html">接入文档</a>
38 */ 42 */
39 WECHAT_MP(31, "WECHAT_MP"), 43 WECHAT_MP(31, "WECHAT_MP"),
40 /** 44 /**
41 * 微信开放平台 - 网站应用 PC 端扫码授权登录 45 * 微信开放平台 - 网站应用 PC 端扫码授权登录
42 - * 文档链接:https://justauth.wiki/guide/oauth/wechat_open/#_2-申请开发者资质认证 46 + *
  47 + * @see <a href="https://justauth.wiki/guide/oauth/wechat_open/#_2-申请开发者资质认证">接入文档</a>
43 */ 48 */
44 WECHAT_OPEN(32, "WECHAT_OPEN"), 49 WECHAT_OPEN(32, "WECHAT_OPEN"),
45 /** 50 /**
46 * 微信小程序 51 * 微信小程序
47 - * 文档链接:https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html 52 + *
  53 + * @see <a href="https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html">接入文档</a>
48 */ 54 */
49 WECHAT_MINI_APP(34, "WECHAT_MINI_APP"), 55 WECHAT_MINI_APP(34, "WECHAT_MINI_APP"),
50 ; 56 ;
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/social/SocialClientApiImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.system.api.social;
  2 +
  3 +import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
  4 +import cn.iocoder.yudao.module.system.api.social.dto.SocialWxJsapiSignatureRespDTO;
  5 +import cn.iocoder.yudao.module.system.api.social.dto.SocialWxPhoneNumberInfoRespDTO;
  6 +import cn.iocoder.yudao.module.system.convert.social.SocialClientConvert;
  7 +import cn.iocoder.yudao.module.system.service.social.SocialClientService;
  8 +import me.chanjar.weixin.common.bean.WxJsapiSignature;
  9 +import org.springframework.stereotype.Service;
  10 +import org.springframework.validation.annotation.Validated;
  11 +
  12 +import javax.annotation.Resource;
  13 +
  14 +/**
  15 + * 社交应用的 API 实现类
  16 + *
  17 + * @author 芋道源码
  18 + */
  19 +@Service
  20 +@Validated
  21 +public class SocialClientApiImpl implements SocialClientApi {
  22 +
  23 + @Resource
  24 + private SocialClientService socialClientService;
  25 +
  26 + @Override
  27 + public String getAuthorizeUrl(Integer type, Integer userType, String redirectUri) {
  28 + return socialClientService.getAuthorizeUrl(type, userType, redirectUri);
  29 + }
  30 +
  31 + @Override
  32 + public SocialWxJsapiSignatureRespDTO createWxMpJsapiSignature(Integer userType, String url) {
  33 + WxJsapiSignature signature = socialClientService.createWxMpJsapiSignature(userType, url);
  34 + return SocialClientConvert.INSTANCE.convert(signature);
  35 + }
  36 +
  37 + @Override
  38 + public SocialWxPhoneNumberInfoRespDTO getWxMaPhoneNumberInfo(Integer userType, String phoneCode) {
  39 + WxMaPhoneNumberInfo info = socialClientService.getWxMaPhoneNumberInfo(userType, phoneCode);
  40 + return SocialClientConvert.INSTANCE.convert(info);
  41 + }
  42 +
  43 +}
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/social/SocialUserApiImpl.java
@@ -22,11 +22,6 @@ public class SocialUserApiImpl implements SocialUserApi { @@ -22,11 +22,6 @@ public class SocialUserApiImpl implements SocialUserApi {
22 private SocialUserService socialUserService; 22 private SocialUserService socialUserService;
23 23
24 @Override 24 @Override
25 - public String getAuthorizeUrl(Integer type, String redirectUri) {  
26 - return socialUserService.getAuthorizeUrl(type, redirectUri);  
27 - }  
28 -  
29 - @Override  
30 public String bindSocialUser(SocialUserBindReqDTO reqDTO) { 25 public String bindSocialUser(SocialUserBindReqDTO reqDTO) {
31 return socialUserService.bindSocialUser(reqDTO); 26 return socialUserService.bindSocialUser(reqDTO);
32 } 27 }
@@ -34,7 +29,7 @@ public class SocialUserApiImpl implements SocialUserApi { @@ -34,7 +29,7 @@ public class SocialUserApiImpl implements SocialUserApi {
34 @Override 29 @Override
35 public void unbindSocialUser(SocialUserUnbindReqDTO reqDTO) { 30 public void unbindSocialUser(SocialUserUnbindReqDTO reqDTO) {
36 socialUserService.unbindSocialUser(reqDTO.getUserId(), reqDTO.getUserType(), 31 socialUserService.unbindSocialUser(reqDTO.getUserId(), reqDTO.getUserType(),
37 - reqDTO.getType(), reqDTO.getUnionId()); 32 + reqDTO.getSocialType(), reqDTO.getOpenid());
38 } 33 }
39 34
40 @Override 35 @Override
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/AuthController.java
@@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.system.controller.admin.auth; @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.system.controller.admin.auth;
3 import cn.hutool.core.collection.CollUtil; 3 import cn.hutool.core.collection.CollUtil;
4 import cn.hutool.core.util.StrUtil; 4 import cn.hutool.core.util.StrUtil;
5 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; 5 import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  6 +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
6 import cn.iocoder.yudao.framework.common.pojo.CommonResult; 7 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
7 import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; 8 import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
8 import cn.iocoder.yudao.framework.security.config.SecurityProperties; 9 import cn.iocoder.yudao.framework.security.config.SecurityProperties;
@@ -16,7 +17,7 @@ import cn.iocoder.yudao.module.system.service.auth.AdminAuthService; @@ -16,7 +17,7 @@ import cn.iocoder.yudao.module.system.service.auth.AdminAuthService;
16 import cn.iocoder.yudao.module.system.service.permission.MenuService; 17 import cn.iocoder.yudao.module.system.service.permission.MenuService;
17 import cn.iocoder.yudao.module.system.service.permission.PermissionService; 18 import cn.iocoder.yudao.module.system.service.permission.PermissionService;
18 import cn.iocoder.yudao.module.system.service.permission.RoleService; 19 import cn.iocoder.yudao.module.system.service.permission.RoleService;
19 -import cn.iocoder.yudao.module.system.service.social.SocialUserService; 20 +import cn.iocoder.yudao.module.system.service.social.SocialClientService;
20 import cn.iocoder.yudao.module.system.service.user.AdminUserService; 21 import cn.iocoder.yudao.module.system.service.user.AdminUserService;
21 import io.swagger.v3.oas.annotations.Operation; 22 import io.swagger.v3.oas.annotations.Operation;
22 import io.swagger.v3.oas.annotations.Parameter; 23 import io.swagger.v3.oas.annotations.Parameter;
@@ -57,7 +58,7 @@ public class AuthController { @@ -57,7 +58,7 @@ public class AuthController {
57 @Resource 58 @Resource
58 private PermissionService permissionService; 59 private PermissionService permissionService;
59 @Resource 60 @Resource
60 - private SocialUserService socialUserService; 61 + private SocialClientService socialClientService;
61 62
62 @Resource 63 @Resource
63 private SecurityProperties securityProperties; 64 private SecurityProperties securityProperties;
@@ -147,7 +148,7 @@ public class AuthController { @@ -147,7 +148,7 @@ public class AuthController {
147 }) 148 })
148 public CommonResult<String> socialLogin(@RequestParam("type") Integer type, 149 public CommonResult<String> socialLogin(@RequestParam("type") Integer type,
149 @RequestParam("redirectUri") String redirectUri) { 150 @RequestParam("redirectUri") String redirectUri) {
150 - return CommonResult.success(socialUserService.getAuthorizeUrl(type, redirectUri)); 151 + return success(socialClientService.getAuthorizeUrl(type, UserTypeEnum.ADMIN.getValue(), redirectUri));
151 } 152 }
152 153
153 @PostMapping("/social-login") 154 @PostMapping("/social-login")
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/package-info.java deleted
1 -/**  
2 - * 占位,避免 package 无法提交到 Git 仓库  
3 - */  
4 -package cn.iocoder.yudao.module.system.controller.app;  
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/weixin/AppWxMpController.http deleted
1 -### 请求 /login 接口 => 成功  
2 -POST {{appApi}}/system/wx-mp/create-jsapi-signature?url=http://www.iocoder.cn  
3 -Authorization: Bearer {{appToken}}  
4 -tenant-id: {{appTenentId}}  
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/weixin/AppWxMpController.java deleted
1 -package cn.iocoder.yudao.module.system.controller.app.weixin;  
2 -  
3 -import cn.iocoder.yudao.framework.common.pojo.CommonResult;  
4 -import io.swagger.v3.oas.annotations.tags.Tag;  
5 -import io.swagger.v3.oas.annotations.Operation;  
6 -import lombok.extern.slf4j.Slf4j;  
7 -import me.chanjar.weixin.common.bean.WxJsapiSignature;  
8 -import me.chanjar.weixin.common.error.WxErrorException;  
9 -import me.chanjar.weixin.mp.api.WxMpService;  
10 -import org.springframework.validation.annotation.Validated;  
11 -import org.springframework.web.bind.annotation.PostMapping;  
12 -import org.springframework.web.bind.annotation.RequestMapping;  
13 -import org.springframework.web.bind.annotation.RequestParam;  
14 -import org.springframework.web.bind.annotation.RestController;  
15 -  
16 -import javax.annotation.Resource;  
17 -  
18 -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;  
19 -  
20 -@Tag(name = "微信公众号")  
21 -@RestController  
22 -@RequestMapping("/system/wx-mp")  
23 -@Validated  
24 -@Slf4j  
25 -public class AppWxMpController {  
26 -  
27 - @Resource  
28 - private WxMpService mpService;  
29 -  
30 - // TODO @芋艿:需要额外考虑个问题;多租户下,如果每个小程序一个微信公众号,则会存在多个 appid;  
31 - @PostMapping("/create-jsapi-signature")  
32 - @Operation(summary = "创建微信 JS SDK 初始化所需的签名",  
33 - description = "参考 https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html 文档")  
34 - public CommonResult<WxJsapiSignature> createJsapiSignature(@RequestParam("url") String url) throws WxErrorException {  
35 - return success(mpService.createJsapiSignature(url));  
36 - }  
37 -  
38 -}  
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/social/SocialClientConvert.java 0 → 100644
  1 +package cn.iocoder.yudao.module.system.convert.social;
  2 +
  3 +import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
  4 +import cn.iocoder.yudao.module.system.api.social.dto.SocialWxJsapiSignatureRespDTO;
  5 +import cn.iocoder.yudao.module.system.api.social.dto.SocialWxPhoneNumberInfoRespDTO;
  6 +import me.chanjar.weixin.common.bean.WxJsapiSignature;
  7 +import org.mapstruct.Mapper;
  8 +import org.mapstruct.factory.Mappers;
  9 +
  10 +@Mapper
  11 +public interface SocialClientConvert {
  12 +
  13 + SocialClientConvert INSTANCE = Mappers.getMapper(SocialClientConvert.class);
  14 +
  15 + SocialWxJsapiSignatureRespDTO convert(WxJsapiSignature bean);
  16 +
  17 + SocialWxPhoneNumberInfoRespDTO convert(WxMaPhoneNumberInfo bean);
  18 +
  19 +}
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/social/SocialClientDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.system.dal.dataobject.social;
  2 +
  3 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  4 +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
  5 +import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO;
  6 +import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum;
  7 +import com.baomidou.mybatisplus.annotation.KeySequence;
  8 +import com.baomidou.mybatisplus.annotation.TableId;
  9 +import com.baomidou.mybatisplus.annotation.TableName;
  10 +import com.xingyuv.jushauth.config.AuthConfig;
  11 +import lombok.*;
  12 +
  13 +/**
  14 + * 社交客户端 DO
  15 + *
  16 + * 对应 {@link AuthConfig} 配置,满足不同租户,有自己的客户端配置,实现社交(三方)登录
  17 + *
  18 + * @author 芋道源码
  19 + */
  20 +@TableName(value = "system_social_client", autoResultMap = true)
  21 +@KeySequence("system_social_client_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
  22 +@Data
  23 +@EqualsAndHashCode(callSuper = true)
  24 +@Builder
  25 +@NoArgsConstructor
  26 +@AllArgsConstructor
  27 +public class SocialClientDO extends TenantBaseDO {
  28 +
  29 + /**
  30 + * 编号,自增
  31 + */
  32 + @TableId
  33 + private Long id;
  34 + /**
  35 + * 应用名
  36 + */
  37 + private String name;
  38 + /**
  39 + * 社交类型
  40 + *
  41 + * 枚举 {@link SocialTypeEnum}
  42 + */
  43 + private Integer socialType;
  44 + /**
  45 + * 用户类型
  46 + *
  47 + * 目的:不同用户类型,对应不同的小程序,需要自己的配置
  48 + *
  49 + * 枚举 {@link UserTypeEnum}
  50 + */
  51 + private Integer userType;
  52 + /**
  53 + * 状态
  54 + *
  55 + * 枚举 {@link CommonStatusEnum}
  56 + */
  57 + private Integer status;
  58 +
  59 + /**
  60 + * 客户端 id
  61 + */
  62 + private String clientId;
  63 + /**
  64 + * 客户端 Secret
  65 + */
  66 + private String clientSecret;
  67 +
  68 +}
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/social/SocialClientMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.system.dal.mysql.social;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  4 +import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialClientDO;
  5 +import org.apache.ibatis.annotations.Mapper;
  6 +
  7 +@Mapper
  8 +public interface SocialClientMapper extends BaseMapperX<SocialClientDO> {
  9 +
  10 + default SocialClientDO selectBySocialTypeAndUserType(Integer socialType, Integer userType) {
  11 + return selectOne(SocialClientDO::getSocialType, socialType,
  12 + SocialClientDO::getUserType, userType);
  13 + }
  14 +
  15 +}
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialClientService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.system.service.social;
  2 +
  3 +import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
  4 +import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum;
  5 +import com.xingyuv.jushauth.model.AuthUser;
  6 +import me.chanjar.weixin.common.bean.WxJsapiSignature;
  7 +
  8 +/**
  9 + * 社交应用 Service 接口
  10 + *
  11 + * @author 芋道源码
  12 + */
  13 +public interface SocialClientService {
  14 +
  15 + /**
  16 + * 获得社交平台的授权 URL
  17 + *
  18 + * @param socialType 社交平台的类型 {@link SocialTypeEnum}
  19 + * @param userType 用户类型
  20 + * @param redirectUri 重定向 URL
  21 + * @return 社交平台的授权 URL
  22 + */
  23 + String getAuthorizeUrl(Integer socialType, Integer userType, String redirectUri);
  24 +
  25 + /**
  26 + * 请求社交平台,获得授权的用户
  27 + *
  28 + * @param socialType 社交平台的类型
  29 + * @param userType 用户类型
  30 + * @param code 授权码
  31 + * @param state 授权 state
  32 + * @return 授权的用户
  33 + */
  34 + AuthUser getAuthUser(Integer socialType, Integer userType, String code, String state);
  35 +
  36 + // =================== 微信公众号独有 ===================
  37 +
  38 + /**
  39 + * 创建微信公众号的 JS SDK 初始化所需的签名
  40 + *
  41 + * @param userType 用户类型
  42 + * @param url 访问的 URL 地址
  43 + * @return 签名
  44 + */
  45 + WxJsapiSignature createWxMpJsapiSignature(Integer userType, String url);
  46 +
  47 + // =================== 微信小程序独有 ===================
  48 +
  49 + /**
  50 + * 获得微信小程序的手机信息
  51 + *
  52 + * @param userType 用户类型
  53 + * @param phoneCode 手机授权码
  54 + * @return 手机信息
  55 + */
  56 + WxMaPhoneNumberInfo getWxMaPhoneNumberInfo(Integer userType, String phoneCode);
  57 +
  58 +}
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialClientServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.system.service.social;
  2 +
  3 +import cn.binarywang.wx.miniapp.api.WxMaService;
  4 +import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl;
  5 +import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
  6 +import cn.binarywang.wx.miniapp.config.impl.WxMaRedisBetterConfigImpl;
  7 +import cn.hutool.core.bean.BeanUtil;
  8 +import cn.hutool.core.lang.Assert;
  9 +import cn.hutool.core.util.ReflectUtil;
  10 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
  11 +import cn.iocoder.yudao.framework.common.util.cache.CacheUtils;
  12 +import cn.iocoder.yudao.framework.common.util.http.HttpUtils;
  13 +import cn.iocoder.yudao.framework.social.core.YudaoAuthRequestFactory;
  14 +import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialClientDO;
  15 +import cn.iocoder.yudao.module.system.dal.mysql.social.SocialClientMapper;
  16 +import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum;
  17 +import com.binarywang.spring.starter.wxjava.miniapp.properties.WxMaProperties;
  18 +import com.binarywang.spring.starter.wxjava.mp.properties.WxMpProperties;
  19 +import com.google.common.cache.CacheLoader;
  20 +import com.google.common.cache.LoadingCache;
  21 +import com.xingyuv.jushauth.config.AuthConfig;
  22 +import com.xingyuv.jushauth.model.AuthCallback;
  23 +import com.xingyuv.jushauth.model.AuthResponse;
  24 +import com.xingyuv.jushauth.model.AuthUser;
  25 +import com.xingyuv.jushauth.request.AuthRequest;
  26 +import com.xingyuv.jushauth.utils.AuthStateUtils;
  27 +import lombok.SneakyThrows;
  28 +import lombok.extern.slf4j.Slf4j;
  29 +import me.chanjar.weixin.common.bean.WxJsapiSignature;
  30 +import me.chanjar.weixin.common.error.WxErrorException;
  31 +import me.chanjar.weixin.common.redis.RedisTemplateWxRedisOps;
  32 +import me.chanjar.weixin.mp.api.WxMpService;
  33 +import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
  34 +import me.chanjar.weixin.mp.config.impl.WxMpRedisConfigImpl;
  35 +import org.springframework.data.redis.core.StringRedisTemplate;
  36 +import org.springframework.stereotype.Service;
  37 +
  38 +import javax.annotation.Resource;
  39 +import java.time.Duration;
  40 +import java.util.Objects;
  41 +
  42 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  43 +import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString;
  44 +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.SOCIAL_APP_WEIXIN_MINI_APP_PHONE_CODE_ERROR;
  45 +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.SOCIAL_USER_AUTH_FAILURE;
  46 +
  47 +/**
  48 + * 社交应用 Service 实现类
  49 + *
  50 + * @author 芋道源码
  51 + */
  52 +@Service
  53 +@Slf4j
  54 +public class SocialClientServiceImpl implements SocialClientService {
  55 +
  56 + @Resource // 由于自定义了 YudaoAuthRequestFactory 无法覆盖默认的 AuthRequestFactory,所以只能注入它
  57 + private YudaoAuthRequestFactory yudaoAuthRequestFactory;
  58 +
  59 + @Resource
  60 + private WxMpService wxMpService;
  61 + @Resource
  62 + private WxMpProperties wxMpProperties;
  63 + @Resource
  64 + private StringRedisTemplate stringRedisTemplate; // WxMpService 需要使用到,所以在 Service 注入了它
  65 + /**
  66 + * 缓存 WxMpService 对象
  67 + *
  68 + * key:使用微信公众号的 appId + secret 拼接,即 {@link SocialClientDO} 的 clientId 和 clientSecret 属性。
  69 + * 为什么 key 使用这种格式?因为 {@link SocialClientDO} 在管理后台可以变更,通过这个 key 存储它的单例。
  70 + *
  71 + * 为什么要做 WxMpService 缓存?因为 WxMpService 构建成本比较大,所以尽量保证它是单例。
  72 + */
  73 + private final LoadingCache<String, WxMpService> wxMpServiceCache = CacheUtils.buildAsyncReloadingCache(
  74 + Duration.ofSeconds(10L),
  75 + new CacheLoader<String, WxMpService>() {
  76 +
  77 + @Override
  78 + public WxMpService load(String key) {
  79 + String[] keys = key.split(":");
  80 + return buildWxMpService(keys[0], keys[1]);
  81 + }
  82 +
  83 + });
  84 +
  85 + @Resource
  86 + private WxMaService wxMaService;
  87 + @Resource
  88 + private WxMaProperties wxMaProperties;
  89 + /**
  90 + * 缓存 WxMaService 对象
  91 + *
  92 + * 说明同 {@link #wxMpServiceCache} 变量
  93 + */
  94 + private final LoadingCache<String, WxMaService> wxMaServiceCache = CacheUtils.buildAsyncReloadingCache(
  95 + Duration.ofSeconds(10L),
  96 + new CacheLoader<String, WxMaService>() {
  97 +
  98 + @Override
  99 + public WxMaService load(String key) {
  100 + String[] keys = key.split(":");
  101 + return buildWxMaService(keys[0], keys[1]);
  102 + }
  103 +
  104 + });
  105 +
  106 + @Resource
  107 + private SocialClientMapper socialClientMapper;
  108 +
  109 + @Override
  110 + public String getAuthorizeUrl(Integer socialType, Integer userType, String redirectUri) {
  111 + // 获得对应的 AuthRequest 实现
  112 + AuthRequest authRequest = buildAuthRequest(socialType, userType);
  113 + // 生成跳转地址
  114 + String authorizeUri = authRequest.authorize(AuthStateUtils.createState());
  115 + return HttpUtils.replaceUrlQuery(authorizeUri, "redirect_uri", redirectUri);
  116 + }
  117 +
  118 + @Override
  119 + public AuthUser getAuthUser(Integer socialType, Integer userType, String code, String state) {
  120 + // 构建请求
  121 + AuthRequest authRequest = buildAuthRequest(socialType, userType);
  122 + AuthCallback authCallback = AuthCallback.builder().code(code).state(state).build();
  123 + // 执行请求
  124 + AuthResponse<?> authResponse = authRequest.login(authCallback);
  125 + log.info("[getAuthUser][请求社交平台 type({}) request({}) response({})]", socialType,
  126 + toJsonString(authCallback), toJsonString(authResponse));
  127 + if (!authResponse.ok()) {
  128 + throw exception(SOCIAL_USER_AUTH_FAILURE, authResponse.getMsg());
  129 + }
  130 + return (AuthUser) authResponse.getData();
  131 + }
  132 +
  133 + /**
  134 + * 构建 AuthRequest 对象,支持多租户配置
  135 + *
  136 + * @param socialType 社交类型
  137 + * @param userType 用户类型
  138 + * @return AuthRequest 对象
  139 + */
  140 + private AuthRequest buildAuthRequest(Integer socialType, Integer userType) {
  141 + // 1. 先查找默认的配置项,从 application-*.yaml 中读取
  142 + AuthRequest request = yudaoAuthRequestFactory.get(SocialTypeEnum.valueOfType(socialType).getSource());
  143 + Assert.notNull(request, String.format("社交平台(%d) 不存在", socialType));
  144 + // 2. 查询 DB 的配置项,如果存在则进行覆盖
  145 + SocialClientDO client = socialClientMapper.selectBySocialTypeAndUserType(socialType, userType);
  146 + if (client != null && Objects.equals(client.getStatus(), CommonStatusEnum.ENABLE.getStatus())) {
  147 + // 2.1 构造新的 AuthConfig 对象
  148 + AuthConfig authConfig = (AuthConfig) ReflectUtil.getFieldValue(request, "config");
  149 + AuthConfig newAuthConfig = ReflectUtil.newInstance(authConfig.getClass());
  150 + BeanUtil.copyProperties(authConfig, newAuthConfig);
  151 + // 2.2 修改对应的 clientId + clientSecret 密钥
  152 + newAuthConfig.setClientId(client.getClientId());
  153 + newAuthConfig.setClientSecret(client.getClientSecret());
  154 + // 2.3 设置会 request 里,进行后续使用
  155 + ReflectUtil.setFieldValue(request, "config", newAuthConfig);
  156 + }
  157 + return request;
  158 + }
  159 +
  160 + // =================== 微信公众号独有 ===================
  161 +
  162 + @Override
  163 + @SneakyThrows
  164 + public WxJsapiSignature createWxMpJsapiSignature(Integer userType, String url) {
  165 + WxMpService service = getWxMpService(userType);
  166 + return service.createJsapiSignature(url);
  167 + }
  168 +
  169 + /**
  170 + * 获得 clientId + clientSecret 对应的 WxMpService 对象
  171 + *
  172 + * @param userType 用户类型
  173 + * @return WxMpService 对象
  174 + */
  175 + private WxMpService getWxMpService(Integer userType) {
  176 + // 第一步,查询 DB 的配置项,获得对应的 WxMpService 对象
  177 + SocialClientDO client = socialClientMapper.selectBySocialTypeAndUserType(
  178 + SocialTypeEnum.WECHAT_MP.getType(), userType);
  179 + if (client != null && Objects.equals(client.getStatus(), CommonStatusEnum.ENABLE.getStatus())) {
  180 + return wxMpServiceCache.getUnchecked(client.getClientId() + ":" + client.getClientSecret());
  181 + }
  182 + // 第二步,不存在 DB 配置项,则使用 application-*.yaml 对应的 WxMpService 对象
  183 + return wxMpService;
  184 + }
  185 +
  186 + /**
  187 + * 创建 clientId + clientSecret 对应的 WxMpService 对象
  188 + *
  189 + * @param clientId 微信公众号 appId
  190 + * @param clientSecret 微信公众号 secret
  191 + * @return WxMpService 对象
  192 + */
  193 + private WxMpService buildWxMpService(String clientId, String clientSecret) {
  194 + // 第一步,创建 WxMpRedisConfigImpl 对象
  195 + WxMpRedisConfigImpl configStorage = new WxMpRedisConfigImpl(
  196 + new RedisTemplateWxRedisOps(stringRedisTemplate),
  197 + wxMpProperties.getConfigStorage().getKeyPrefix());
  198 + configStorage.setAppId(clientId);
  199 + configStorage.setSecret(clientSecret);
  200 +
  201 + // 第二步,创建 WxMpService 对象
  202 + WxMpService service = new WxMpServiceImpl();
  203 + service.setWxMpConfigStorage(configStorage);
  204 + return service;
  205 + }
  206 +
  207 + // =================== 微信小程序独有 ===================
  208 +
  209 + @Override
  210 + public WxMaPhoneNumberInfo getWxMaPhoneNumberInfo(Integer userType, String phoneCode) {
  211 + WxMaService service = getWxMaService(userType);
  212 + try {
  213 + return service.getUserService().getPhoneNoInfo(phoneCode);
  214 + } catch (WxErrorException e) {
  215 + log.error("[getPhoneNoInfo][userType({}) phoneCode({}) 获得手机号失败]", userType, phoneCode, e);
  216 + throw exception(SOCIAL_APP_WEIXIN_MINI_APP_PHONE_CODE_ERROR);
  217 + }
  218 + }
  219 +
  220 + /**
  221 + * 获得 clientId + clientSecret 对应的 WxMpService 对象
  222 + *
  223 + * @param userType 用户类型
  224 + * @return WxMpService 对象
  225 + */
  226 + private WxMaService getWxMaService(Integer userType) {
  227 + // 第一步,查询 DB 的配置项,获得对应的 WxMaService 对象
  228 + SocialClientDO client = socialClientMapper.selectBySocialTypeAndUserType(
  229 + SocialTypeEnum.WECHAT_MINI_APP.getType(), userType);
  230 + if (client != null && Objects.equals(client.getStatus(), CommonStatusEnum.ENABLE.getStatus())) {
  231 + return wxMaServiceCache.getUnchecked(client.getClientId() + ":" + client.getClientSecret());
  232 + }
  233 + // 第二步,不存在 DB 配置项,则使用 application-*.yaml 对应的 WxMaService 对象
  234 + return wxMaService;
  235 + }
  236 +
  237 + /**
  238 + * 创建 clientId + clientSecret 对应的 WxMaService 对象
  239 + *
  240 + * @param clientId 微信小程序 appId
  241 + * @param clientSecret 微信小程序 secret
  242 + * @return WxMaService 对象
  243 + */
  244 + private WxMaService buildWxMaService(String clientId, String clientSecret) {
  245 + // 第一步,创建 WxMaRedisBetterConfigImpl 对象
  246 + WxMaRedisBetterConfigImpl configStorage = new WxMaRedisBetterConfigImpl(
  247 + new RedisTemplateWxRedisOps(stringRedisTemplate),
  248 + wxMaProperties.getConfigStorage().getKeyPrefix());
  249 + configStorage.setAppid(clientId);
  250 + configStorage.setSecret(clientSecret);
  251 +
  252 + // 第二步,创建 WxMpService 对象
  253 + WxMaService service = new WxMaServiceImpl();
  254 + service.setWxMaConfig(configStorage);
  255 + return service;
  256 + }
  257 +
  258 +}
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialUserService.java
@@ -7,7 +7,6 @@ import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialUserDO; @@ -7,7 +7,6 @@ import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialUserDO;
7 import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum; 7 import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum;
8 8
9 import javax.validation.Valid; 9 import javax.validation.Valid;
10 -import javax.validation.constraints.NotNull;  
11 import java.util.List; 10 import java.util.List;
12 11
13 /** 12 /**
@@ -18,27 +17,6 @@ import java.util.List; @@ -18,27 +17,6 @@ import java.util.List;
18 public interface SocialUserService { 17 public interface SocialUserService {
19 18
20 /** 19 /**
21 - * 获得社交平台的授权 URL  
22 - *  
23 - * @param type 社交平台的类型 {@link SocialTypeEnum}  
24 - * @param redirectUri 重定向 URL  
25 - * @return 社交平台的授权 URL  
26 - */  
27 - String getAuthorizeUrl(Integer type, String redirectUri);  
28 -  
29 - /**  
30 - * 授权获得对应的社交用户  
31 - * 如果授权失败,则会抛出 {@link ServiceException} 异常  
32 - *  
33 - * @param type 社交平台的类型 {@link SocialTypeEnum}  
34 - * @param code 授权码  
35 - * @param state state  
36 - * @return 授权用户  
37 - */  
38 - @NotNull  
39 - SocialUserDO authSocialUser(Integer type, String code, String state);  
40 -  
41 - /**  
42 * 获得指定用户的社交用户列表 20 * 获得指定用户的社交用户列表
43 * 21 *
44 * @param userId 用户编号 22 * @param userId 用户编号
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialUserServiceImpl.java
@@ -2,8 +2,7 @@ package cn.iocoder.yudao.module.system.service.social; @@ -2,8 +2,7 @@ package cn.iocoder.yudao.module.system.service.social;
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.util.http.HttpUtils;  
6 -import cn.iocoder.yudao.framework.social.core.YudaoAuthRequestFactory; 5 +import cn.iocoder.yudao.framework.common.exception.ServiceException;
7 import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO; 6 import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO;
8 import cn.iocoder.yudao.module.system.api.social.dto.SocialUserRespDTO; 7 import cn.iocoder.yudao.module.system.api.social.dto.SocialUserRespDTO;
9 import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialUserBindDO; 8 import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialUserBindDO;
@@ -11,24 +10,22 @@ import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialUserDO; @@ -11,24 +10,22 @@ import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialUserDO;
11 import cn.iocoder.yudao.module.system.dal.mysql.social.SocialUserBindMapper; 10 import cn.iocoder.yudao.module.system.dal.mysql.social.SocialUserBindMapper;
12 import cn.iocoder.yudao.module.system.dal.mysql.social.SocialUserMapper; 11 import cn.iocoder.yudao.module.system.dal.mysql.social.SocialUserMapper;
13 import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum; 12 import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum;
14 -import com.xingyuv.jushauth.model.AuthCallback;  
15 -import com.xingyuv.jushauth.model.AuthResponse;  
16 import com.xingyuv.jushauth.model.AuthUser; 13 import com.xingyuv.jushauth.model.AuthUser;
17 -import com.xingyuv.jushauth.request.AuthRequest;  
18 -import com.xingyuv.jushauth.utils.AuthStateUtils;  
19 import lombok.extern.slf4j.Slf4j; 14 import lombok.extern.slf4j.Slf4j;
20 import org.springframework.stereotype.Service; 15 import org.springframework.stereotype.Service;
21 import org.springframework.transaction.annotation.Transactional; 16 import org.springframework.transaction.annotation.Transactional;
22 import org.springframework.validation.annotation.Validated; 17 import org.springframework.validation.annotation.Validated;
23 18
24 import javax.annotation.Resource; 19 import javax.annotation.Resource;
  20 +import javax.validation.constraints.NotNull;
25 import java.util.Collections; 21 import java.util.Collections;
26 import java.util.List; 22 import java.util.List;
27 23
28 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; 24 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
29 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; 25 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
30 import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString; 26 import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString;
31 -import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; 27 +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.AUTH_THIRD_LOGIN_NOT_BIND;
  28 +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.SOCIAL_USER_NOT_FOUND;
32 29
33 /** 30 /**
34 * 社交用户 Service 实现类 31 * 社交用户 Service 实现类
@@ -40,51 +37,13 @@ import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; @@ -40,51 +37,13 @@ import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
40 @Slf4j 37 @Slf4j
41 public class SocialUserServiceImpl implements SocialUserService { 38 public class SocialUserServiceImpl implements SocialUserService {
42 39
43 - @Resource// 由于自定义了 YudaoAuthRequestFactory 无法覆盖默认的 AuthRequestFactory,所以只能注入它  
44 - private YudaoAuthRequestFactory yudaoAuthRequestFactory;  
45 -  
46 @Resource 40 @Resource
47 private SocialUserBindMapper socialUserBindMapper; 41 private SocialUserBindMapper socialUserBindMapper;
48 @Resource 42 @Resource
49 private SocialUserMapper socialUserMapper; 43 private SocialUserMapper socialUserMapper;
50 44
51 - @Override  
52 - public String getAuthorizeUrl(Integer type, String redirectUri) {  
53 - // 获得对应的 AuthRequest 实现  
54 - AuthRequest authRequest = yudaoAuthRequestFactory.get(SocialTypeEnum.valueOfType(type).getSource());  
55 - // 生成跳转地址  
56 - String authorizeUri = authRequest.authorize(AuthStateUtils.createState());  
57 - return HttpUtils.replaceUrlQuery(authorizeUri, "redirect_uri", redirectUri);  
58 - }  
59 -  
60 - @Override  
61 - public SocialUserDO authSocialUser(Integer type, String code, String state) {  
62 - // 优先从 DB 中获取,因为 code 有且可以使用一次。  
63 - // 在社交登录时,当未绑定 User 时,需要绑定登录,此时需要 code 使用两次  
64 - SocialUserDO socialUser = socialUserMapper.selectByTypeAndCodeAnState(type, code, state);  
65 - if (socialUser != null) {  
66 - return socialUser;  
67 - }  
68 -  
69 - // 请求获取  
70 - AuthUser authUser = getAuthUser(type, code, state);  
71 - Assert.notNull(authUser, "三方用户不能为空");  
72 -  
73 - // 保存到 DB 中  
74 - socialUser = socialUserMapper.selectByTypeAndOpenid(type, authUser.getUuid());  
75 - if (socialUser == null) {  
76 - socialUser = new SocialUserDO();  
77 - }  
78 - socialUser.setType(type).setCode(code).setState(state) // 需要保存 code + state 字段,保证后续可查询  
79 - .setOpenid(authUser.getUuid()).setToken(authUser.getToken().getAccessToken()).setRawTokenInfo((toJsonString(authUser.getToken())))  
80 - .setNickname(authUser.getNickname()).setAvatar(authUser.getAvatar()).setRawUserInfo(toJsonString(authUser.getRawUserInfo()));  
81 - if (socialUser.getId() == null) {  
82 - socialUserMapper.insert(socialUser);  
83 - } else {  
84 - socialUserMapper.updateById(socialUser);  
85 - }  
86 - return socialUser;  
87 - } 45 + @Resource
  46 + private SocialClientService socialClientService;
88 47
89 @Override 48 @Override
90 public List<SocialUserDO> getSocialUserList(Long userId, Integer userType) { 49 public List<SocialUserDO> getSocialUserList(Long userId, Integer userType) {
@@ -101,7 +60,8 @@ public class SocialUserServiceImpl implements SocialUserService { @@ -101,7 +60,8 @@ public class SocialUserServiceImpl implements SocialUserService {
101 @Transactional 60 @Transactional
102 public String bindSocialUser(SocialUserBindReqDTO reqDTO) { 61 public String bindSocialUser(SocialUserBindReqDTO reqDTO) {
103 // 获得社交用户 62 // 获得社交用户
104 - SocialUserDO socialUser = authSocialUser(reqDTO.getType(), reqDTO.getCode(), reqDTO.getState()); 63 + SocialUserDO socialUser = authSocialUser(reqDTO.getSocialType(), reqDTO.getUserType(),
  64 + reqDTO.getCode(), reqDTO.getState());
105 Assert.notNull(socialUser, "社交用户不能为空"); 65 Assert.notNull(socialUser, "社交用户不能为空");
106 66
107 // 社交用户可能之前绑定过别的用户,需要进行解绑 67 // 社交用户可能之前绑定过别的用户,需要进行解绑
@@ -134,7 +94,7 @@ public class SocialUserServiceImpl implements SocialUserService { @@ -134,7 +94,7 @@ public class SocialUserServiceImpl implements SocialUserService {
134 @Override 94 @Override
135 public SocialUserRespDTO getSocialUser(Integer userType, Integer type, String code, String state) { 95 public SocialUserRespDTO getSocialUser(Integer userType, Integer type, String code, String state) {
136 // 获得社交用户 96 // 获得社交用户
137 - SocialUserDO socialUser = authSocialUser(type, code, state); 97 + SocialUserDO socialUser = authSocialUser(type, userType, code, state);
138 Assert.notNull(socialUser, "社交用户不能为空"); 98 Assert.notNull(socialUser, "社交用户不能为空");
139 99
140 // 如果未绑定的社交用户,则无法自动登录,进行报错 100 // 如果未绑定的社交用户,则无法自动登录,进行报错
@@ -146,24 +106,44 @@ public class SocialUserServiceImpl implements SocialUserService { @@ -146,24 +106,44 @@ public class SocialUserServiceImpl implements SocialUserService {
146 return new SocialUserRespDTO(socialUser.getOpenid(), socialUserBind.getUserId()); 106 return new SocialUserRespDTO(socialUser.getOpenid(), socialUserBind.getUserId());
147 } 107 }
148 108
  109 + // TODO 芋艿:调整下单测
149 /** 110 /**
150 - * 请求社交平台,获得授权的用户 111 + * 授权获得对应的社交用户
  112 + * 如果授权失败,则会抛出 {@link ServiceException} 异常
151 * 113 *
152 - * @param type 社交平台的类型 114 + * @param type 社交平台的类型 {@link SocialTypeEnum}
  115 + * @param userType 用户类型
153 * @param code 授权码 116 * @param code 授权码
154 - * @param state 授权 state  
155 - * @return 授权的用户 117 + * @param state state
  118 + * @return 授权用户
156 */ 119 */
157 - private AuthUser getAuthUser(Integer type, String code, String state) {  
158 - AuthRequest authRequest = yudaoAuthRequestFactory.get(SocialTypeEnum.valueOfType(type).getSource());  
159 - AuthCallback authCallback = AuthCallback.builder().code(code).state(state).build();  
160 - AuthResponse<?> authResponse = authRequest.login(authCallback);  
161 - log.info("[getAuthUser][请求社交平台 type({}) request({}) response({})]", type,  
162 - toJsonString(authCallback), toJsonString(authResponse));  
163 - if (!authResponse.ok()) {  
164 - throw exception(SOCIAL_USER_AUTH_FAILURE, authResponse.getMsg()); 120 + @NotNull
  121 + public SocialUserDO authSocialUser(Integer type, Integer userType, String code, String state) {
  122 + // 优先从 DB 中获取,因为 code 有且可以使用一次。
  123 + // 在社交登录时,当未绑定 User 时,需要绑定登录,此时需要 code 使用两次
  124 + SocialUserDO socialUser = socialUserMapper.selectByTypeAndCodeAnState(type, code, state);
  125 + if (socialUser != null) {
  126 + return socialUser;
165 } 127 }
166 - return (AuthUser) authResponse.getData(); 128 +
  129 + // 请求获取
  130 + AuthUser authUser = socialClientService.getAuthUser(type, userType, code, state);
  131 + Assert.notNull(authUser, "三方用户不能为空");
  132 +
  133 + // 保存到 DB 中
  134 + socialUser = socialUserMapper.selectByTypeAndOpenid(type, authUser.getUuid());
  135 + if (socialUser == null) {
  136 + socialUser = new SocialUserDO();
  137 + }
  138 + socialUser.setType(type).setCode(code).setState(state) // 需要保存 code + state 字段,保证后续可查询
  139 + .setOpenid(authUser.getUuid()).setToken(authUser.getToken().getAccessToken()).setRawTokenInfo((toJsonString(authUser.getToken())))
  140 + .setNickname(authUser.getNickname()).setAvatar(authUser.getAvatar()).setRawUserInfo(toJsonString(authUser.getRawUserInfo()));
  141 + if (socialUser.getId() == null) {
  142 + socialUserMapper.insert(socialUser);
  143 + } else {
  144 + socialUserMapper.updateById(socialUser);
  145 + }
  146 + return socialUser;
167 } 147 }
168 148
169 } 149 }