Commit 3976011af0d9090160a739e72bfd0b2895e8ec6b
Merge remote-tracking branch 'yudao/feature/mall_product' into feature/mall_product
Showing
36 changed files
with
314 additions
and
201 deletions
sql/mysql/pay_wallet.sql
| @@ -8,8 +8,8 @@ CREATE TABLE `pay_wallet` | @@ -8,8 +8,8 @@ CREATE TABLE `pay_wallet` | ||
| 8 | `user_id` bigint NOT NULL COMMENT '用户编号', | 8 | `user_id` bigint NOT NULL COMMENT '用户编号', |
| 9 | `user_type` tinyint NOT NULL DEFAULT 0 COMMENT '用户类型', | 9 | `user_type` tinyint NOT NULL DEFAULT 0 COMMENT '用户类型', |
| 10 | `balance` int NOT NULL DEFAULT 0 COMMENT '余额,单位分', | 10 | `balance` int NOT NULL DEFAULT 0 COMMENT '余额,单位分', |
| 11 | - `total_expense` bigint NOT NULL DEFAULT 0 COMMENT '累计支出,单位分', | ||
| 12 | - `total_recharge` bigint NOT NULL DEFAULT 0 COMMENT '累计充值,单位分', | 11 | + `total_expense` int NOT NULL DEFAULT 0 COMMENT '累计支出,单位分', |
| 12 | + `total_recharge` int NOT NULL DEFAULT 0 COMMENT '累计充值,单位分', | ||
| 13 | `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者', | 13 | `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者', |
| 14 | `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', | 14 | `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', |
| 15 | `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者', | 15 | `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者', |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/api/brokerage/BrokerageApiImpl.java
| @@ -27,7 +27,7 @@ public class BrokerageApiImpl implements BrokerageApi { | @@ -27,7 +27,7 @@ public class BrokerageApiImpl implements BrokerageApi { | ||
| 27 | 27 | ||
| 28 | @Override | 28 | @Override |
| 29 | public boolean bindUser(Long userId, Long bindUserId, Boolean isNewUser) { | 29 | public boolean bindUser(Long userId, Long bindUserId, Boolean isNewUser) { |
| 30 | - return brokerageUserService.bindUser(userId, bindUserId, isNewUser); | 30 | + return brokerageUserService.bindBrokerageUser(userId, bindUserId, isNewUser); |
| 31 | } | 31 | } |
| 32 | 32 | ||
| 33 | } | 33 | } |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/brokerage/user/vo/BrokerageUserRespVO.java
| @@ -19,7 +19,6 @@ public class BrokerageUserRespVO extends BrokerageUserBaseVO { | @@ -19,7 +19,6 @@ public class BrokerageUserRespVO extends BrokerageUserBaseVO { | ||
| 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 | - | ||
| 23 | // ========== 用户信息 ========== | 22 | // ========== 用户信息 ========== |
| 24 | 23 | ||
| 25 | @Schema(description = "用户头像", example = "https://www.iocoder.cn/xxx.png") | 24 | @Schema(description = "用户头像", example = "https://www.iocoder.cn/xxx.png") |
| @@ -27,7 +26,6 @@ public class BrokerageUserRespVO extends BrokerageUserBaseVO { | @@ -27,7 +26,6 @@ public class BrokerageUserRespVO extends BrokerageUserBaseVO { | ||
| 27 | @Schema(description = "用户昵称", example = "李四") | 26 | @Schema(description = "用户昵称", example = "李四") |
| 28 | private String nickname; | 27 | private String nickname; |
| 29 | 28 | ||
| 30 | - | ||
| 31 | // ========== 推广信息 ========== | 29 | // ========== 推广信息 ========== |
| 32 | 30 | ||
| 33 | @Schema(description = "推广用户数量(一级)", example = "20019") | 31 | @Schema(description = "推广用户数量(一级)", example = "20019") |
| @@ -37,7 +35,6 @@ public class BrokerageUserRespVO extends BrokerageUserBaseVO { | @@ -37,7 +35,6 @@ public class BrokerageUserRespVO extends BrokerageUserBaseVO { | ||
| 37 | @Schema(description = "推广订单金额", example = "20019") | 35 | @Schema(description = "推广订单金额", example = "20019") |
| 38 | private Integer brokerageOrderPrice; | 36 | private Integer brokerageOrderPrice; |
| 39 | 37 | ||
| 40 | - | ||
| 41 | // ========== 提现信息 ========== | 38 | // ========== 提现信息 ========== |
| 42 | 39 | ||
| 43 | @Schema(description = "已提现金额", example = "20019") | 40 | @Schema(description = "已提现金额", example = "20019") |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/AppBrokerageRecordController.java
| @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.trade.controller.app.brokerage; | @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.trade.controller.app.brokerage; | ||
| 3 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; | 3 | import cn.iocoder.yudao.framework.common.pojo.CommonResult; |
| 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 4 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 5 | import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated; | 5 | import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated; |
| 6 | +import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.record.AppBrokerageProductPriceRespVO; | ||
| 6 | import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.record.AppBrokerageRecordPageReqVO; | 7 | import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.record.AppBrokerageRecordPageReqVO; |
| 7 | import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.record.AppBrokerageRecordRespVO; | 8 | import cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.record.AppBrokerageRecordRespVO; |
| 8 | import io.swagger.v3.oas.annotations.Operation; | 9 | import io.swagger.v3.oas.annotations.Operation; |
| @@ -11,6 +12,7 @@ import lombok.extern.slf4j.Slf4j; | @@ -11,6 +12,7 @@ import lombok.extern.slf4j.Slf4j; | ||
| 11 | import org.springframework.validation.annotation.Validated; | 12 | import org.springframework.validation.annotation.Validated; |
| 12 | import org.springframework.web.bind.annotation.GetMapping; | 13 | import org.springframework.web.bind.annotation.GetMapping; |
| 13 | import org.springframework.web.bind.annotation.RequestMapping; | 14 | import org.springframework.web.bind.annotation.RequestMapping; |
| 15 | +import org.springframework.web.bind.annotation.RequestParam; | ||
| 14 | import org.springframework.web.bind.annotation.RestController; | 16 | import org.springframework.web.bind.annotation.RestController; |
| 15 | 17 | ||
| 16 | import javax.validation.Valid; | 18 | import javax.validation.Valid; |
| @@ -40,4 +42,14 @@ public class AppBrokerageRecordController { | @@ -40,4 +42,14 @@ public class AppBrokerageRecordController { | ||
| 40 | return success(new PageResult<>(asList(vo1, vo2), 10L)); | 42 | return success(new PageResult<>(asList(vo1, vo2), 10L)); |
| 41 | } | 43 | } |
| 42 | 44 | ||
| 45 | + @GetMapping("/get-product-brokerage-price") | ||
| 46 | + @Operation(summary = "获得商品的分销金额") | ||
| 47 | + public CommonResult<AppBrokerageProductPriceRespVO> getProductBrokeragePrice(@RequestParam("spuId") Long spuId) { | ||
| 48 | + AppBrokerageProductPriceRespVO respVO = new AppBrokerageProductPriceRespVO(); | ||
| 49 | + respVO.setEnabled(true); // TODO @疯狂:需要开启分销 + 人允许分销 | ||
| 50 | + respVO.setBrokerageMinPrice(1); | ||
| 51 | + respVO.setBrokerageMaxPrice(2); | ||
| 52 | + return success(respVO); | ||
| 53 | + } | ||
| 54 | + | ||
| 43 | } | 55 | } |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/AppBrokerageUserController.java
| @@ -37,11 +37,19 @@ public class AppBrokerageUserController { | @@ -37,11 +37,19 @@ public class AppBrokerageUserController { | ||
| 37 | @PreAuthenticated | 37 | @PreAuthenticated |
| 38 | public CommonResult<AppBrokerageUserRespVO> getBrokerageUser() { | 38 | public CommonResult<AppBrokerageUserRespVO> getBrokerageUser() { |
| 39 | AppBrokerageUserRespVO respVO = new AppBrokerageUserRespVO() | 39 | AppBrokerageUserRespVO respVO = new AppBrokerageUserRespVO() |
| 40 | + .setBrokerageEnabled(true) | ||
| 40 | .setPrice(2000) | 41 | .setPrice(2000) |
| 41 | .setFrozenPrice(3000); | 42 | .setFrozenPrice(3000); |
| 42 | return success(respVO); | 43 | return success(respVO); |
| 43 | } | 44 | } |
| 44 | 45 | ||
| 46 | + @PutMapping("/bind") | ||
| 47 | + @Operation(summary = "绑定推广员") | ||
| 48 | + @PreAuthenticated | ||
| 49 | + public CommonResult<Boolean> bindBrokerageUser(@Valid @RequestBody AppBrokerageUserBindReqVO reqVO) { | ||
| 50 | + return success(brokerageUserService.bindBrokerageUser(getLoginUserId(), reqVO.getBindUserId(), false)); | ||
| 51 | + } | ||
| 52 | + | ||
| 45 | // TODO 芋艿:临时 mock => | 53 | // TODO 芋艿:临时 mock => |
| 46 | @GetMapping("/get-summary") | 54 | @GetMapping("/get-summary") |
| 47 | @Operation(summary = "获得个人分销统计") | 55 | @Operation(summary = "获得个人分销统计") |
| @@ -49,7 +57,7 @@ public class AppBrokerageUserController { | @@ -49,7 +57,7 @@ public class AppBrokerageUserController { | ||
| 49 | public CommonResult<AppBrokerageUserMySummaryRespVO> getBrokerageUserSummary() { | 57 | public CommonResult<AppBrokerageUserMySummaryRespVO> getBrokerageUserSummary() { |
| 50 | AppBrokerageUserMySummaryRespVO respVO = new AppBrokerageUserMySummaryRespVO() | 58 | AppBrokerageUserMySummaryRespVO respVO = new AppBrokerageUserMySummaryRespVO() |
| 51 | .setYesterdayPrice(1) | 59 | .setYesterdayPrice(1) |
| 52 | - .setPrice(2) | 60 | + .setBrokeragePrice(2) |
| 53 | .setFrozenPrice(3) | 61 | .setFrozenPrice(3) |
| 54 | .setWithdrawPrice(4) | 62 | .setWithdrawPrice(4) |
| 55 | .setFirstBrokerageUserCount(166) | 63 | .setFirstBrokerageUserCount(166) |
| @@ -84,16 +92,16 @@ public class AppBrokerageUserController { | @@ -84,16 +92,16 @@ public class AppBrokerageUserController { | ||
| 84 | public CommonResult<PageResult<AppBrokerageUserRankByPriceRespVO>> getBrokerageUserChildSummaryPageByPrice(AppBrokerageUserRankPageReqVO pageReqVO) { | 92 | public CommonResult<PageResult<AppBrokerageUserRankByPriceRespVO>> getBrokerageUserChildSummaryPageByPrice(AppBrokerageUserRankPageReqVO pageReqVO) { |
| 85 | AppBrokerageUserRankByPriceRespVO vo1 = new AppBrokerageUserRankByPriceRespVO() | 93 | AppBrokerageUserRankByPriceRespVO vo1 = new AppBrokerageUserRankByPriceRespVO() |
| 86 | .setId(1L).setNickname("芋1**艿").setAvatar("http://www.iocoder.cn/images/common/wechat_mp_2017_07_31_bak.jpg") | 94 | .setId(1L).setNickname("芋1**艿").setAvatar("http://www.iocoder.cn/images/common/wechat_mp_2017_07_31_bak.jpg") |
| 87 | - .setPrice(10); | 95 | + .setBrokeragePrice(10); |
| 88 | AppBrokerageUserRankByPriceRespVO vo2 = new AppBrokerageUserRankByPriceRespVO() | 96 | AppBrokerageUserRankByPriceRespVO vo2 = new AppBrokerageUserRankByPriceRespVO() |
| 89 | .setId(2L).setNickname("芋2**艿").setAvatar("http://www.iocoder.cn/images/common/wechat_mp_2017_07_31_bak.jpg") | 97 | .setId(2L).setNickname("芋2**艿").setAvatar("http://www.iocoder.cn/images/common/wechat_mp_2017_07_31_bak.jpg") |
| 90 | - .setPrice(6); | 98 | + .setBrokeragePrice(6); |
| 91 | AppBrokerageUserRankByPriceRespVO vo3 = new AppBrokerageUserRankByPriceRespVO() | 99 | AppBrokerageUserRankByPriceRespVO vo3 = new AppBrokerageUserRankByPriceRespVO() |
| 92 | .setId(3L).setNickname("芋3**艿").setAvatar("http://www.iocoder.cn/images/common/wechat_mp_2017_07_31_bak.jpg") | 100 | .setId(3L).setNickname("芋3**艿").setAvatar("http://www.iocoder.cn/images/common/wechat_mp_2017_07_31_bak.jpg") |
| 93 | - .setPrice(4); | 101 | + .setBrokeragePrice(4); |
| 94 | AppBrokerageUserRankByPriceRespVO vo4 = new AppBrokerageUserRankByPriceRespVO() | 102 | AppBrokerageUserRankByPriceRespVO vo4 = new AppBrokerageUserRankByPriceRespVO() |
| 95 | .setId(3L).setNickname("芋3**艿").setAvatar("http://www.iocoder.cn/images/common/wechat_mp_2017_07_31_bak.jpg") | 103 | .setId(3L).setNickname("芋3**艿").setAvatar("http://www.iocoder.cn/images/common/wechat_mp_2017_07_31_bak.jpg") |
| 96 | - .setPrice(4); | 104 | + .setBrokeragePrice(4); |
| 97 | return success(new PageResult<>(asList(vo1, vo2, vo3, vo4), 10L)); | 105 | return success(new PageResult<>(asList(vo1, vo2, vo3, vo4), 10L)); |
| 98 | } | 106 | } |
| 99 | 107 | ||
| @@ -105,11 +113,11 @@ public class AppBrokerageUserController { | @@ -105,11 +113,11 @@ public class AppBrokerageUserController { | ||
| 105 | AppBrokerageUserChildSummaryPageReqVO pageReqVO) { | 113 | AppBrokerageUserChildSummaryPageReqVO pageReqVO) { |
| 106 | AppBrokerageUserChildSummaryRespVO vo1 = new AppBrokerageUserChildSummaryRespVO() | 114 | AppBrokerageUserChildSummaryRespVO vo1 = new AppBrokerageUserChildSummaryRespVO() |
| 107 | .setId(1L).setNickname("芋1**艿").setAvatar("http://www.iocoder.cn/images/common/wechat_mp_2017_07_31_bak.jpg") | 115 | .setId(1L).setNickname("芋1**艿").setAvatar("http://www.iocoder.cn/images/common/wechat_mp_2017_07_31_bak.jpg") |
| 108 | - .setPrice(10).setPrice(20).setBrokerageOrderCount(30) | 116 | + .setBrokeragePrice(10).setBrokeragePrice(20).setBrokerageOrderCount(30) |
| 109 | .setBrokerageTime(LocalDateTime.now()); | 117 | .setBrokerageTime(LocalDateTime.now()); |
| 110 | AppBrokerageUserChildSummaryRespVO vo2 = new AppBrokerageUserChildSummaryRespVO() | 118 | AppBrokerageUserChildSummaryRespVO vo2 = new AppBrokerageUserChildSummaryRespVO() |
| 111 | .setId(1L).setNickname("芋2**艿").setAvatar("http://www.iocoder.cn/images/common/wechat_mp_2017_07_31_bak.jpg") | 119 | .setId(1L).setNickname("芋2**艿").setAvatar("http://www.iocoder.cn/images/common/wechat_mp_2017_07_31_bak.jpg") |
| 112 | - .setPrice(20).setPrice(30).setBrokerageOrderCount(40) | 120 | + .setBrokeragePrice(20).setBrokeragePrice(30).setBrokerageOrderCount(40) |
| 113 | .setBrokerageTime(LocalDateTime.now()); | 121 | .setBrokerageTime(LocalDateTime.now()); |
| 114 | return success(new PageResult<>(asList(vo1, vo2), 10L)); | 122 | return success(new PageResult<>(asList(vo1, vo2), 10L)); |
| 115 | } | 123 | } |
| @@ -118,15 +126,9 @@ public class AppBrokerageUserController { | @@ -118,15 +126,9 @@ public class AppBrokerageUserController { | ||
| 118 | @GetMapping("/get-rank-by-price") | 126 | @GetMapping("/get-rank-by-price") |
| 119 | @Operation(summary = "获得分销用户排行(基于佣金)") | 127 | @Operation(summary = "获得分销用户排行(基于佣金)") |
| 120 | @Parameter(name = "times", description = "时间段", required = true) | 128 | @Parameter(name = "times", description = "时间段", required = true) |
| 121 | - public CommonResult<Integer> getBrokerageUserRankByPrice( | 129 | + public CommonResult<Integer> bindBrokerageUser( |
| 122 | @RequestParam("times") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) LocalDateTime[] times) { | 130 | @RequestParam("times") @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) LocalDateTime[] times) { |
| 123 | return success(1); | 131 | return success(1); |
| 124 | } | 132 | } |
| 125 | 133 | ||
| 126 | - @PutMapping("/bind-user") | ||
| 127 | - @Operation(summary = "绑定推广员") | ||
| 128 | - public CommonResult<Boolean> getBrokerageUserRankByPrice(@Valid AppBrokerageUserBindReqVO reqVO) { | ||
| 129 | - return success(brokerageUserService.bindUser(getLoginUserId(), reqVO.getBindUserId(), false)); | ||
| 130 | - } | ||
| 131 | - | ||
| 132 | } | 134 | } |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/record/AppBrokerageProductPriceRespVO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.trade.controller.app.brokerage.vo.record; | ||
| 2 | + | ||
| 3 | +import io.swagger.v3.oas.annotations.media.Schema; | ||
| 4 | +import lombok.Data; | ||
| 5 | + | ||
| 6 | +@Schema(description = "用户 App - 商品的分销金额 Response VO") | ||
| 7 | +@Data | ||
| 8 | +public class AppBrokerageProductPriceRespVO { | ||
| 9 | + | ||
| 10 | + @Schema(description = "是否开启", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") | ||
| 11 | + private Boolean enabled; | ||
| 12 | + | ||
| 13 | + @Schema(description = "分销最小金额,单位:分", example = "100") | ||
| 14 | + private Integer brokerageMinPrice; | ||
| 15 | + | ||
| 16 | + @Schema(description = "分销最大金额,单位:分", example = "100") | ||
| 17 | + private Integer brokerageMaxPrice; | ||
| 18 | + | ||
| 19 | +} |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/user/AppBrokerageUserChildSummaryRespVO.java
| @@ -19,7 +19,7 @@ public class AppBrokerageUserChildSummaryRespVO { | @@ -19,7 +19,7 @@ public class AppBrokerageUserChildSummaryRespVO { | ||
| 19 | private String avatar; | 19 | private String avatar; |
| 20 | 20 | ||
| 21 | @Schema(description = "佣金金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "10") | 21 | @Schema(description = "佣金金额,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "10") |
| 22 | - private Integer price; | 22 | + private Integer brokeragePrice; |
| 23 | 23 | ||
| 24 | @Schema(description = "分销订单数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "20") | 24 | @Schema(description = "分销订单数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "20") |
| 25 | private Integer brokerageOrderCount; | 25 | private Integer brokerageOrderCount; |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/user/AppBrokerageUserMySummaryRespVO.java
| @@ -14,7 +14,7 @@ public class AppBrokerageUserMySummaryRespVO { | @@ -14,7 +14,7 @@ public class AppBrokerageUserMySummaryRespVO { | ||
| 14 | private Integer withdrawPrice; | 14 | private Integer withdrawPrice; |
| 15 | 15 | ||
| 16 | @Schema(description = "可用的佣金,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "2408") | 16 | @Schema(description = "可用的佣金,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "2408") |
| 17 | - private Integer price; | 17 | + private Integer brokeragePrice; |
| 18 | 18 | ||
| 19 | @Schema(description = "冻结的佣金,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "234") | 19 | @Schema(description = "冻结的佣金,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "234") |
| 20 | private Integer frozenPrice; | 20 | private Integer frozenPrice; |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/user/AppBrokerageUserRankByPriceRespVO.java
| @@ -17,6 +17,6 @@ public class AppBrokerageUserRankByPriceRespVO { | @@ -17,6 +17,6 @@ public class AppBrokerageUserRankByPriceRespVO { | ||
| 17 | private String avatar; | 17 | private String avatar; |
| 18 | 18 | ||
| 19 | @Schema(description = "佣金金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "10") | 19 | @Schema(description = "佣金金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "10") |
| 20 | - private Integer price; | 20 | + private Integer brokeragePrice; |
| 21 | 21 | ||
| 22 | } | 22 | } |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/app/brokerage/vo/user/AppBrokerageUserRespVO.java
| @@ -7,6 +7,9 @@ import lombok.Data; | @@ -7,6 +7,9 @@ import lombok.Data; | ||
| 7 | @Data | 7 | @Data |
| 8 | public class AppBrokerageUserRespVO { | 8 | public class AppBrokerageUserRespVO { |
| 9 | 9 | ||
| 10 | + @Schema(description = "是否有分销资格", requiredMode = Schema.RequiredMode.REQUIRED, example = "true") | ||
| 11 | + private Boolean brokerageEnabled; | ||
| 12 | + | ||
| 10 | @Schema(description = "可用的佣金,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "2408") | 13 | @Schema(description = "可用的佣金,单位:分", requiredMode = Schema.RequiredMode.REQUIRED, example = "2408") |
| 11 | private Integer price; | 14 | private Integer price; |
| 12 | 15 |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/brokerage/record/BrokerageRecordConvert.java
| @@ -41,7 +41,7 @@ public interface BrokerageRecordConvert { | @@ -41,7 +41,7 @@ public interface BrokerageRecordConvert { | ||
| 41 | : BrokerageRecordStatusEnum.SETTLEMENT.getStatus(); | 41 | : BrokerageRecordStatusEnum.SETTLEMENT.getStatus(); |
| 42 | return new BrokerageRecordDO().setUserId(user.getId()) | 42 | return new BrokerageRecordDO().setUserId(user.getId()) |
| 43 | .setBizType(bizType.getType()).setBizId(bizId) | 43 | .setBizType(bizType.getType()).setBizId(bizId) |
| 44 | - .setPrice(brokeragePrice).setTotalPrice(user.getPrice()) | 44 | + .setPrice(brokeragePrice).setTotalPrice(user.getBrokeragePrice()) |
| 45 | .setTitle(title) | 45 | .setTitle(title) |
| 46 | .setDescription(StrUtil.format(bizType.getDescription(), String.valueOf(brokeragePrice / 100.0))) | 46 | .setDescription(StrUtil.format(bizType.getDescription(), String.valueOf(brokeragePrice / 100.0))) |
| 47 | .setStatus(status).setFrozenDays(brokerageFrozenDays).setUnfreezeTime(unfreezeTime); | 47 | .setStatus(status).setFrozenDays(brokerageFrozenDays).setUnfreezeTime(unfreezeTime); |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/dataobject/brokerage/user/BrokerageUserDO.java
| @@ -43,7 +43,7 @@ public class BrokerageUserDO extends BaseDO { | @@ -43,7 +43,7 @@ public class BrokerageUserDO extends BaseDO { | ||
| 43 | private LocalDateTime bindUserTime; | 43 | private LocalDateTime bindUserTime; |
| 44 | 44 | ||
| 45 | /** | 45 | /** |
| 46 | - * 推广资格 | 46 | + * 是否有分销资格 |
| 47 | */ | 47 | */ |
| 48 | private Boolean brokerageEnabled; | 48 | private Boolean brokerageEnabled; |
| 49 | /** | 49 | /** |
| @@ -54,7 +54,7 @@ public class BrokerageUserDO extends BaseDO { | @@ -54,7 +54,7 @@ public class BrokerageUserDO extends BaseDO { | ||
| 54 | /** | 54 | /** |
| 55 | * 可用佣金 | 55 | * 可用佣金 |
| 56 | */ | 56 | */ |
| 57 | - private Integer price; | 57 | + private Integer brokeragePrice; |
| 58 | /** | 58 | /** |
| 59 | * 冻结佣金 | 59 | * 冻结佣金 |
| 60 | */ | 60 | */ |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/user/BrokerageUserService.java
| @@ -103,6 +103,6 @@ public interface BrokerageUserService { | @@ -103,6 +103,6 @@ public interface BrokerageUserService { | ||
| 103 | * @param isNewUser 是否为新用户 | 103 | * @param isNewUser 是否为新用户 |
| 104 | * @return 是否绑定 | 104 | * @return 是否绑定 |
| 105 | */ | 105 | */ |
| 106 | - boolean bindUser(Long userId, Long bindUserId, Boolean isNewUser); | 106 | + boolean bindBrokerageUser(Long userId, Long bindUserId, Boolean isNewUser); |
| 107 | 107 | ||
| 108 | } | 108 | } |
yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/brokerage/user/BrokerageUserServiceImpl.java
| @@ -135,7 +135,7 @@ public class BrokerageUserServiceImpl implements BrokerageUserService { | @@ -135,7 +135,7 @@ public class BrokerageUserServiceImpl implements BrokerageUserService { | ||
| 135 | 135 | ||
| 136 | // TODO @疯狂:因为现在 user 会存在使用验证码直接注册,所以 isNewUser 不太好传递;我们是不是可以约定绑定的时间,createTime 在 30 秒内,就认为新用户; | 136 | // TODO @疯狂:因为现在 user 会存在使用验证码直接注册,所以 isNewUser 不太好传递;我们是不是可以约定绑定的时间,createTime 在 30 秒内,就认为新用户; |
| 137 | @Override | 137 | @Override |
| 138 | - public boolean bindUser(Long userId, Long bindUserId, Boolean isNewUser) { | 138 | + public boolean bindBrokerageUser(Long userId, Long bindUserId, Boolean isNewUser) { |
| 139 | // TODO @疯狂:userId 为空,搞到参数校验里哇; | 139 | // TODO @疯狂:userId 为空,搞到参数校验里哇; |
| 140 | if (userId == null) { | 140 | if (userId == null) { |
| 141 | throw exception(0); | 141 | throw exception(0); |
| @@ -146,7 +146,7 @@ public class BrokerageUserServiceImpl implements BrokerageUserService { | @@ -146,7 +146,7 @@ public class BrokerageUserServiceImpl implements BrokerageUserService { | ||
| 146 | BrokerageUserDO brokerageUser = brokerageUserMapper.selectById(userId); | 146 | BrokerageUserDO brokerageUser = brokerageUserMapper.selectById(userId); |
| 147 | if (brokerageUser == null) { // 分销用户不存在的情况:1. 新注册;2. 旧数据;3. 分销功能关闭后又打开 | 147 | if (brokerageUser == null) { // 分销用户不存在的情况:1. 新注册;2. 旧数据;3. 分销功能关闭后又打开 |
| 148 | isNewBrokerageUser = true; | 148 | isNewBrokerageUser = true; |
| 149 | - brokerageUser = new BrokerageUserDO().setId(userId).setBrokerageEnabled(false).setPrice(0).setFrozenPrice(0); | 149 | + brokerageUser = new BrokerageUserDO().setId(userId).setBrokerageEnabled(false).setBrokeragePrice(0).setFrozenPrice(0); |
| 150 | } | 150 | } |
| 151 | 151 | ||
| 152 | // 2.1 校验能否绑定 | 152 | // 2.1 校验能否绑定 |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/AppAuthController.http
| @@ -28,6 +28,17 @@ tenant-id: {{appTenentId}} | @@ -28,6 +28,17 @@ tenant-id: {{appTenentId}} | ||
| 28 | "code": 9999 | 28 | "code": 9999 |
| 29 | } | 29 | } |
| 30 | 30 | ||
| 31 | +### 请求 /social-login 接口 => 成功 | ||
| 32 | +POST {{appApi}}/member/auth/social-login | ||
| 33 | +Content-Type: application/json | ||
| 34 | +tenant-id: {{appTenentId}} | ||
| 35 | + | ||
| 36 | +{ | ||
| 37 | + "type": 34, | ||
| 38 | + "code": "0e1oc9000CTjFQ1oim200bhtb61oc90g", | ||
| 39 | + "state": "default" | ||
| 40 | +} | ||
| 41 | + | ||
| 31 | ### 请求 /weixin-mini-app-login 接口 => 成功 | 42 | ### 请求 /weixin-mini-app-login 接口 => 成功 |
| 32 | POST {{appApi}}/member/auth/weixin-mini-app-login | 43 | POST {{appApi}}/member/auth/weixin-mini-app-login |
| 33 | Content-Type: application/json | 44 | Content-Type: application/json |
| @@ -38,7 +49,6 @@ tenant-id: {{appTenentId}} | @@ -38,7 +49,6 @@ tenant-id: {{appTenentId}} | ||
| 38 | "loginCode": "001frTkl21JUf94VGxol2hSlff1frTkR" | 49 | "loginCode": "001frTkl21JUf94VGxol2hSlff1frTkR" |
| 39 | } | 50 | } |
| 40 | 51 | ||
| 41 | - | ||
| 42 | ### 请求 /logout 接口 => 成功 | 52 | ### 请求 /logout 接口 => 成功 |
| 43 | POST {{appApi}}/member/auth/logout | 53 | POST {{appApi}}/member/auth/logout |
| 44 | Content-Type: application/json | 54 | Content-Type: application/json |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AppAuthLoginRespVO.java
| @@ -27,4 +27,12 @@ public class AppAuthLoginRespVO { | @@ -27,4 +27,12 @@ public class AppAuthLoginRespVO { | ||
| 27 | @Schema(description = "过期时间", requiredMode = Schema.RequiredMode.REQUIRED) | 27 | @Schema(description = "过期时间", requiredMode = Schema.RequiredMode.REQUIRED) |
| 28 | private LocalDateTime expiresTime; | 28 | private LocalDateTime expiresTime; |
| 29 | 29 | ||
| 30 | + /** | ||
| 31 | + * 仅社交登录、社交绑定时会返回 | ||
| 32 | + * | ||
| 33 | + * 为什么需要返回?微信公众号、微信小程序支付需要传递 openid 给支付接口 | ||
| 34 | + */ | ||
| 35 | + @Schema(description = "社交用户 openid", example = "qq768") | ||
| 36 | + private String openid; | ||
| 37 | + | ||
| 30 | } | 38 | } |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/auth/AuthConvert.java
| @@ -25,7 +25,7 @@ public interface AuthConvert { | @@ -25,7 +25,7 @@ public interface AuthConvert { | ||
| 25 | SmsCodeUseReqDTO convert(AppMemberUserResetPasswordReqVO reqVO, SmsSceneEnum scene, String usedIp); | 25 | SmsCodeUseReqDTO convert(AppMemberUserResetPasswordReqVO reqVO, SmsSceneEnum scene, String usedIp); |
| 26 | SmsCodeUseReqDTO convert(AppAuthSmsLoginReqVO reqVO, Integer scene, String usedIp); | 26 | SmsCodeUseReqDTO convert(AppAuthSmsLoginReqVO reqVO, Integer scene, String usedIp); |
| 27 | 27 | ||
| 28 | - AppAuthLoginRespVO convert(OAuth2AccessTokenRespDTO bean); | 28 | + AppAuthLoginRespVO convert(OAuth2AccessTokenRespDTO bean, String openid); |
| 29 | 29 | ||
| 30 | SmsCodeValidateReqDTO convert(AppAuthSmsValidateReqVO bean); | 30 | SmsCodeValidateReqDTO convert(AppAuthSmsValidateReqVO bean); |
| 31 | 31 |
yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/auth/MemberAuthServiceImpl.java
| @@ -20,6 +20,7 @@ import cn.iocoder.yudao.module.system.api.oauth2.dto.OAuth2AccessTokenRespDTO; | @@ -20,6 +20,7 @@ import cn.iocoder.yudao.module.system.api.oauth2.dto.OAuth2AccessTokenRespDTO; | ||
| 20 | import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi; | 20 | import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi; |
| 21 | import cn.iocoder.yudao.module.system.api.social.SocialUserApi; | 21 | import cn.iocoder.yudao.module.system.api.social.SocialUserApi; |
| 22 | import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO; | 22 | import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO; |
| 23 | +import cn.iocoder.yudao.module.system.api.social.dto.SocialUserRespDTO; | ||
| 23 | import cn.iocoder.yudao.module.system.enums.logger.LoginLogTypeEnum; | 24 | import cn.iocoder.yudao.module.system.enums.logger.LoginLogTypeEnum; |
| 24 | import cn.iocoder.yudao.module.system.enums.logger.LoginResultEnum; | 25 | import cn.iocoder.yudao.module.system.enums.logger.LoginResultEnum; |
| 25 | import cn.iocoder.yudao.module.system.enums.oauth2.OAuth2ClientConstants; | 26 | import cn.iocoder.yudao.module.system.enums.oauth2.OAuth2ClientConstants; |
| @@ -65,13 +66,14 @@ public class MemberAuthServiceImpl implements MemberAuthService { | @@ -65,13 +66,14 @@ public class MemberAuthServiceImpl implements MemberAuthService { | ||
| 65 | MemberUserDO user = login0(reqVO.getMobile(), reqVO.getPassword()); | 66 | MemberUserDO user = login0(reqVO.getMobile(), reqVO.getPassword()); |
| 66 | 67 | ||
| 67 | // 如果 socialType 非空,说明需要绑定社交用户 | 68 | // 如果 socialType 非空,说明需要绑定社交用户 |
| 69 | + String openid = null; | ||
| 68 | if (reqVO.getSocialType() != null) { | 70 | if (reqVO.getSocialType() != null) { |
| 69 | - socialUserApi.bindSocialUser(new SocialUserBindReqDTO(user.getId(), getUserType().getValue(), | 71 | + openid = socialUserApi.bindSocialUser(new SocialUserBindReqDTO(user.getId(), getUserType().getValue(), |
| 70 | reqVO.getSocialType(), reqVO.getSocialCode(), reqVO.getSocialState())); | 72 | reqVO.getSocialType(), reqVO.getSocialCode(), reqVO.getSocialState())); |
| 71 | } | 73 | } |
| 72 | 74 | ||
| 73 | // 创建 Token 令牌,记录登录日志 | 75 | // 创建 Token 令牌,记录登录日志 |
| 74 | - return createTokenAfterLoginSuccess(user, reqVO.getMobile(), LoginLogTypeEnum.LOGIN_MOBILE); | 76 | + return createTokenAfterLoginSuccess(user, reqVO.getMobile(), LoginLogTypeEnum.LOGIN_MOBILE, openid); |
| 75 | } | 77 | } |
| 76 | 78 | ||
| 77 | @Override | 79 | @Override |
| @@ -86,32 +88,33 @@ public class MemberAuthServiceImpl implements MemberAuthService { | @@ -86,32 +88,33 @@ public class MemberAuthServiceImpl implements MemberAuthService { | ||
| 86 | Assert.notNull(user, "获取用户失败,结果为空"); | 88 | Assert.notNull(user, "获取用户失败,结果为空"); |
| 87 | 89 | ||
| 88 | // 如果 socialType 非空,说明需要绑定社交用户 | 90 | // 如果 socialType 非空,说明需要绑定社交用户 |
| 91 | + String openid = null; | ||
| 89 | if (reqVO.getSocialType() != null) { | 92 | if (reqVO.getSocialType() != null) { |
| 90 | - socialUserApi.bindSocialUser(new SocialUserBindReqDTO(user.getId(), getUserType().getValue(), | 93 | + openid = socialUserApi.bindSocialUser(new SocialUserBindReqDTO(user.getId(), getUserType().getValue(), |
| 91 | reqVO.getSocialType(), reqVO.getSocialCode(), reqVO.getSocialState())); | 94 | reqVO.getSocialType(), reqVO.getSocialCode(), reqVO.getSocialState())); |
| 92 | } | 95 | } |
| 93 | 96 | ||
| 94 | // 创建 Token 令牌,记录登录日志 | 97 | // 创建 Token 令牌,记录登录日志 |
| 95 | - return createTokenAfterLoginSuccess(user, reqVO.getMobile(), LoginLogTypeEnum.LOGIN_SMS); | 98 | + return createTokenAfterLoginSuccess(user, reqVO.getMobile(), LoginLogTypeEnum.LOGIN_SMS, openid); |
| 96 | } | 99 | } |
| 97 | 100 | ||
| 98 | @Override | 101 | @Override |
| 99 | public AppAuthLoginRespVO socialLogin(AppAuthSocialLoginReqVO reqVO) { | 102 | public AppAuthLoginRespVO socialLogin(AppAuthSocialLoginReqVO reqVO) { |
| 100 | // 使用 code 授权码,进行登录。然后,获得到绑定的用户编号 | 103 | // 使用 code 授权码,进行登录。然后,获得到绑定的用户编号 |
| 101 | - Long userId = socialUserApi.getBindUserId(UserTypeEnum.MEMBER.getValue(), reqVO.getType(), | 104 | + SocialUserRespDTO socialUser = socialUserApi.getSocialUser(UserTypeEnum.MEMBER.getValue(), reqVO.getType(), |
| 102 | reqVO.getCode(), reqVO.getState()); | 105 | reqVO.getCode(), reqVO.getState()); |
| 103 | - if (userId == null) { | 106 | + if (socialUser == null) { |
| 104 | throw exception(AUTH_THIRD_LOGIN_NOT_BIND); | 107 | throw exception(AUTH_THIRD_LOGIN_NOT_BIND); |
| 105 | } | 108 | } |
| 106 | 109 | ||
| 107 | // 自动登录 | 110 | // 自动登录 |
| 108 | - MemberUserDO user = userService.getUser(userId); | 111 | + MemberUserDO user = userService.getUser(socialUser.getUserId()); |
| 109 | if (user == null) { | 112 | if (user == null) { |
| 110 | throw exception(USER_NOT_EXISTS); | 113 | throw exception(USER_NOT_EXISTS); |
| 111 | } | 114 | } |
| 112 | 115 | ||
| 113 | // 创建 Token 令牌,记录登录日志 | 116 | // 创建 Token 令牌,记录登录日志 |
| 114 | - return createTokenAfterLoginSuccess(user, user.getMobile(), LoginLogTypeEnum.LOGIN_SOCIAL); | 117 | + return createTokenAfterLoginSuccess(user, user.getMobile(), LoginLogTypeEnum.LOGIN_SOCIAL, socialUser.getOpenid()); |
| 115 | } | 118 | } |
| 116 | 119 | ||
| 117 | @Override | 120 | @Override |
| @@ -129,14 +132,15 @@ public class MemberAuthServiceImpl implements MemberAuthService { | @@ -129,14 +132,15 @@ public class MemberAuthServiceImpl implements MemberAuthService { | ||
| 129 | Assert.notNull(user, "获取用户失败,结果为空"); | 132 | Assert.notNull(user, "获取用户失败,结果为空"); |
| 130 | 133 | ||
| 131 | // 绑定社交用户 | 134 | // 绑定社交用户 |
| 132 | - socialUserApi.bindSocialUser(new SocialUserBindReqDTO(user.getId(), getUserType().getValue(), | 135 | + String openid = socialUserApi.bindSocialUser(new SocialUserBindReqDTO(user.getId(), getUserType().getValue(), |
| 133 | SocialTypeEnum.WECHAT_MINI_APP.getType(), reqVO.getLoginCode(), "")); | 136 | SocialTypeEnum.WECHAT_MINI_APP.getType(), reqVO.getLoginCode(), "")); |
| 134 | 137 | ||
| 135 | // 创建 Token 令牌,记录登录日志 | 138 | // 创建 Token 令牌,记录登录日志 |
| 136 | - return createTokenAfterLoginSuccess(user, user.getMobile(), LoginLogTypeEnum.LOGIN_SOCIAL); | 139 | + return createTokenAfterLoginSuccess(user, user.getMobile(), LoginLogTypeEnum.LOGIN_SOCIAL, openid); |
| 137 | } | 140 | } |
| 138 | 141 | ||
| 139 | - private AppAuthLoginRespVO createTokenAfterLoginSuccess(MemberUserDO user, String mobile, LoginLogTypeEnum logType) { | 142 | + private AppAuthLoginRespVO createTokenAfterLoginSuccess(MemberUserDO user, String mobile, |
| 143 | + LoginLogTypeEnum logType, String openid) { | ||
| 140 | // 插入登陆日志 | 144 | // 插入登陆日志 |
| 141 | createLoginLog(user.getId(), mobile, logType, LoginResultEnum.SUCCESS); | 145 | createLoginLog(user.getId(), mobile, logType, LoginResultEnum.SUCCESS); |
| 142 | // 创建 Token 令牌 | 146 | // 创建 Token 令牌 |
| @@ -144,7 +148,7 @@ public class MemberAuthServiceImpl implements MemberAuthService { | @@ -144,7 +148,7 @@ public class MemberAuthServiceImpl implements MemberAuthService { | ||
| 144 | .setUserId(user.getId()).setUserType(getUserType().getValue()) | 148 | .setUserId(user.getId()).setUserType(getUserType().getValue()) |
| 145 | .setClientId(OAuth2ClientConstants.CLIENT_ID_DEFAULT)); | 149 | .setClientId(OAuth2ClientConstants.CLIENT_ID_DEFAULT)); |
| 146 | // 构建返回结果 | 150 | // 构建返回结果 |
| 147 | - return AuthConvert.INSTANCE.convert(accessTokenRespDTO); | 151 | + return AuthConvert.INSTANCE.convert(accessTokenRespDTO, openid); |
| 148 | } | 152 | } |
| 149 | 153 | ||
| 150 | @Override | 154 | @Override |
| @@ -231,7 +235,7 @@ public class MemberAuthServiceImpl implements MemberAuthService { | @@ -231,7 +235,7 @@ public class MemberAuthServiceImpl implements MemberAuthService { | ||
| 231 | public AppAuthLoginRespVO refreshToken(String refreshToken) { | 235 | public AppAuthLoginRespVO refreshToken(String refreshToken) { |
| 232 | OAuth2AccessTokenRespDTO accessTokenDO = oauth2TokenApi.refreshAccessToken(refreshToken, | 236 | OAuth2AccessTokenRespDTO accessTokenDO = oauth2TokenApi.refreshAccessToken(refreshToken, |
| 233 | OAuth2ClientConstants.CLIENT_ID_DEFAULT); | 237 | OAuth2ClientConstants.CLIENT_ID_DEFAULT); |
| 234 | - return AuthConvert.INSTANCE.convert(accessTokenDO); | 238 | + return AuthConvert.INSTANCE.convert(accessTokenDO, null); |
| 235 | } | 239 | } |
| 236 | 240 | ||
| 237 | private void createLogoutLog(Long userId) { | 241 | private void createLogoutLog(Long userId) { |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/vo/wallet/AppPayWalletRespVO.java
| @@ -11,9 +11,9 @@ public class AppPayWalletRespVO { | @@ -11,9 +11,9 @@ public class AppPayWalletRespVO { | ||
| 11 | private Integer balance; | 11 | private Integer balance; |
| 12 | 12 | ||
| 13 | @Schema(description = "累计支出, 单位分", requiredMode = Schema.RequiredMode.REQUIRED, example = "1000") | 13 | @Schema(description = "累计支出, 单位分", requiredMode = Schema.RequiredMode.REQUIRED, example = "1000") |
| 14 | - private Long totalExpense; | 14 | + private Integer totalExpense; |
| 15 | 15 | ||
| 16 | @Schema(description = "累计充值, 单位分", requiredMode = Schema.RequiredMode.REQUIRED, example = "2000") | 16 | @Schema(description = "累计充值, 单位分", requiredMode = Schema.RequiredMode.REQUIRED, example = "2000") |
| 17 | - private Long totalRecharge; | 17 | + private Integer totalRecharge; |
| 18 | 18 | ||
| 19 | } | 19 | } |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/wallet/PayWalletTransactionConvert.java
| @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.pay.convert.wallet; | @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.pay.convert.wallet; | ||
| 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; | 3 | import cn.iocoder.yudao.framework.common.pojo.PageResult; |
| 4 | import cn.iocoder.yudao.module.pay.controller.app.wallet.vo.transaction.AppPayWalletTransactionRespVO; | 4 | import cn.iocoder.yudao.module.pay.controller.app.wallet.vo.transaction.AppPayWalletTransactionRespVO; |
| 5 | import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO; | 5 | import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO; |
| 6 | +import cn.iocoder.yudao.module.pay.service.wallet.bo.CreateWalletTransactionBO; | ||
| 6 | import org.mapstruct.Mapper; | 7 | import org.mapstruct.Mapper; |
| 7 | import org.mapstruct.factory.Mappers; | 8 | import org.mapstruct.factory.Mappers; |
| 8 | 9 | ||
| @@ -12,4 +13,7 @@ public interface PayWalletTransactionConvert { | @@ -12,4 +13,7 @@ public interface PayWalletTransactionConvert { | ||
| 12 | PayWalletTransactionConvert INSTANCE = Mappers.getMapper(PayWalletTransactionConvert.class); | 13 | PayWalletTransactionConvert INSTANCE = Mappers.getMapper(PayWalletTransactionConvert.class); |
| 13 | 14 | ||
| 14 | PageResult<AppPayWalletTransactionRespVO> convertPage(PageResult<PayWalletTransactionDO> page); | 15 | PageResult<AppPayWalletTransactionRespVO> convertPage(PageResult<PayWalletTransactionDO> page); |
| 16 | + | ||
| 17 | + PayWalletTransactionDO convert(CreateWalletTransactionBO bean); | ||
| 18 | + | ||
| 15 | } | 19 | } |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/wallet/PayWalletDO.java
| @@ -37,8 +37,6 @@ public class PayWalletDO extends BaseDO { | @@ -37,8 +37,6 @@ public class PayWalletDO extends BaseDO { | ||
| 37 | */ | 37 | */ |
| 38 | private Integer userType; | 38 | private Integer userType; |
| 39 | 39 | ||
| 40 | - // TODO @jason:三个都搞 integer?应该要统一哈 | ||
| 41 | - | ||
| 42 | /** | 40 | /** |
| 43 | * 余额,单位分 | 41 | * 余额,单位分 |
| 44 | */ | 42 | */ |
| @@ -47,10 +45,10 @@ public class PayWalletDO extends BaseDO { | @@ -47,10 +45,10 @@ public class PayWalletDO extends BaseDO { | ||
| 47 | /** | 45 | /** |
| 48 | * 累计支出,单位分 | 46 | * 累计支出,单位分 |
| 49 | */ | 47 | */ |
| 50 | - private Long totalExpense; | 48 | + private Integer totalExpense; |
| 51 | /** | 49 | /** |
| 52 | * 累计充值,单位分 | 50 | * 累计充值,单位分 |
| 53 | */ | 51 | */ |
| 54 | - private Long totalRecharge; | 52 | + private Integer totalRecharge; |
| 55 | 53 | ||
| 56 | } | 54 | } |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/wallet/PayWalletMapper.java
| @@ -3,8 +3,7 @@ package cn.iocoder.yudao.module.pay.dal.mysql.wallet; | @@ -3,8 +3,7 @@ package cn.iocoder.yudao.module.pay.dal.mysql.wallet; | ||
| 3 | 3 | ||
| 4 | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; | 4 | import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; |
| 5 | import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO; | 5 | import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO; |
| 6 | -import cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum; | ||
| 7 | -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | 6 | +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; |
| 8 | import org.apache.ibatis.annotations.Mapper; | 7 | import org.apache.ibatis.annotations.Mapper; |
| 9 | 8 | ||
| 10 | @Mapper | 9 | @Mapper |
| @@ -15,56 +14,33 @@ public interface PayWalletMapper extends BaseMapperX<PayWalletDO> { | @@ -15,56 +14,33 @@ public interface PayWalletMapper extends BaseMapperX<PayWalletDO> { | ||
| 15 | PayWalletDO::getUserType, userType); | 14 | PayWalletDO::getUserType, userType); |
| 16 | } | 15 | } |
| 17 | 16 | ||
| 18 | - // TODO @jason:减少时,需要 update price -= ? where price >= ?,避免并发问题。现在基于 price 来过滤,虽然也能解决并发问题,但是冲突概率会高一点;可以看到 TradeBrokerageUserMapper 的做法; | ||
| 19 | /** | 17 | /** |
| 20 | - * 当余额减少时候更新 | 18 | + * 当消费退款时候, 更新钱包 |
| 21 | * | 19 | * |
| 22 | - * @param bizType 业务类型 | ||
| 23 | - * @param balance 当前余额 | ||
| 24 | - * @param totalRecharge 当前累计充值 | ||
| 25 | - * @param totalExpense 当前累计支出 | ||
| 26 | - * @param price 支出的金额 | 20 | + * @param price 消费金额 |
| 27 | * @param id 钱包 id | 21 | * @param id 钱包 id |
| 28 | */ | 22 | */ |
| 29 | - default int updateWhenDecBalance(PayWalletBizTypeEnum bizType, Integer balance, Long totalRecharge, | ||
| 30 | - Long totalExpense, Integer price, Long id) { | ||
| 31 | - // TODO @jason:这种偏判断的,最红放在 service 层;mapper 可以写多个方法; | ||
| 32 | - PayWalletDO updateDO = new PayWalletDO().setBalance(balance - price); | ||
| 33 | - if(bizType == PayWalletBizTypeEnum.PAYMENT){ | ||
| 34 | - updateDO.setTotalExpense(totalExpense + price); | ||
| 35 | - } | ||
| 36 | - if (bizType == PayWalletBizTypeEnum.RECHARGE_REFUND) { | ||
| 37 | - updateDO.setTotalRecharge(totalRecharge - price); | ||
| 38 | - } | ||
| 39 | - return update(updateDO, | ||
| 40 | - new LambdaQueryWrapper<PayWalletDO>().eq(PayWalletDO::getId, id) | ||
| 41 | - .eq(PayWalletDO::getBalance, balance) | ||
| 42 | - .ge(PayWalletDO::getBalance, price)); | 23 | + default int updateWhenConsumptionRefund(Integer price, Long id){ |
| 24 | + LambdaUpdateWrapper<PayWalletDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<PayWalletDO>() | ||
| 25 | + .setSql(" balance = balance + " + price | ||
| 26 | + + ", total_expense = total_expense - " + price) | ||
| 27 | + .eq(PayWalletDO::getId, id); | ||
| 28 | + return update(null, lambdaUpdateWrapper); | ||
| 43 | } | 29 | } |
| 44 | 30 | ||
| 45 | - // TODO @jason:类似上面的修改建议哈; | ||
| 46 | /** | 31 | /** |
| 47 | - * 当余额增加时候更新 | 32 | + * 当消费时候, 更新钱包 |
| 48 | * | 33 | * |
| 49 | - * @param bizType 业务类型 | ||
| 50 | - * @param balance 当前余额 | ||
| 51 | - * @param totalRecharge 当前累计充值 | ||
| 52 | - * @param totalExpense 当前累计支出 | ||
| 53 | - * @param price 金额 | 34 | + * @param price 消费金额 |
| 54 | * @param id 钱包 id | 35 | * @param id 钱包 id |
| 55 | */ | 36 | */ |
| 56 | - default int updateWhenIncBalance(PayWalletBizTypeEnum bizType, Integer balance, Long totalRecharge, | ||
| 57 | - Long totalExpense, Integer price, Long id) { | ||
| 58 | - PayWalletDO updateDO = new PayWalletDO().setBalance(balance + price); | ||
| 59 | - if (bizType == PayWalletBizTypeEnum.PAYMENT_REFUND) { | ||
| 60 | - updateDO.setTotalExpense(totalExpense - price); | ||
| 61 | - } | ||
| 62 | - if (bizType == PayWalletBizTypeEnum.RECHARGE) { | ||
| 63 | - updateDO.setTotalExpense(totalRecharge + price); | ||
| 64 | - } | ||
| 65 | - return update(updateDO, | ||
| 66 | - new LambdaQueryWrapper<PayWalletDO>().eq(PayWalletDO::getId, id) | ||
| 67 | - .eq(PayWalletDO::getBalance, balance)); | 37 | + default int updateWhenConsumption(Integer price, Long id){ |
| 38 | + LambdaUpdateWrapper<PayWalletDO> lambdaUpdateWrapper = new LambdaUpdateWrapper<PayWalletDO>() | ||
| 39 | + .setSql(" balance = balance - " + price | ||
| 40 | + + ", total_expense = total_expense + " + price) | ||
| 41 | + .eq(PayWalletDO::getId, id) | ||
| 42 | + .ge(PayWalletDO::getBalance, price); // cas 逻辑 | ||
| 43 | + return update(null, lambdaUpdateWrapper); | ||
| 68 | } | 44 | } |
| 69 | } | 45 | } |
| 70 | 46 |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/framework/pay/wallet/WalletPayClient.java
| @@ -62,13 +62,12 @@ public class WalletPayClient extends AbstractPayClient<NonePayClientConfig> { | @@ -62,13 +62,12 @@ public class WalletPayClient extends AbstractPayClient<NonePayClientConfig> { | ||
| 62 | @Override | 62 | @Override |
| 63 | protected PayOrderRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) { | 63 | protected PayOrderRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) { |
| 64 | try { | 64 | try { |
| 65 | - // TODO @jason:直接 getLong 和 getInt 会不会更简洁哈 | ||
| 66 | - String userId = MapUtil.getStr(reqDTO.getChannelExtras(), USER_ID_KEY); | ||
| 67 | - String userType = MapUtil.getStr(reqDTO.getChannelExtras(), USER_TYPE_KEY); | ||
| 68 | - Assert.notEmpty(userId, "用户 id 不能为空"); | ||
| 69 | - Assert.notEmpty(userType, "用户类型不能为空"); | ||
| 70 | - PayWalletTransactionDO transaction = wallService.orderPay(Long.valueOf(userId), Integer.valueOf(userType), | ||
| 71 | - reqDTO.getOutTradeNo(), reqDTO.getPrice()); | 65 | + Long userId = MapUtil.getLong(reqDTO.getChannelExtras(), USER_ID_KEY); |
| 66 | + Integer userType = MapUtil.getInt(reqDTO.getChannelExtras(), USER_TYPE_KEY); | ||
| 67 | + Assert.notNull(userId, "用户 id 不能为空"); | ||
| 68 | + Assert.notNull(userType, "用户类型不能为空"); | ||
| 69 | + PayWalletTransactionDO transaction = wallService.orderPay(userId, userType, reqDTO.getOutTradeNo(), | ||
| 70 | + reqDTO.getPrice()); | ||
| 72 | return PayOrderRespDTO.successOf(transaction.getNo(), transaction.getCreator(), | 71 | return PayOrderRespDTO.successOf(transaction.getNo(), transaction.getCreator(), |
| 73 | transaction.getCreateTime(), | 72 | transaction.getCreateTime(), |
| 74 | reqDTO.getOutTradeNo(), transaction); | 73 | reqDTO.getOutTradeNo(), transaction); |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletServiceImpl.java
| @@ -6,10 +6,10 @@ import cn.iocoder.yudao.module.pay.dal.dataobject.refund.PayRefundDO; | @@ -6,10 +6,10 @@ import cn.iocoder.yudao.module.pay.dal.dataobject.refund.PayRefundDO; | ||
| 6 | import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO; | 6 | import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO; |
| 7 | import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO; | 7 | import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO; |
| 8 | import cn.iocoder.yudao.module.pay.dal.mysql.wallet.PayWalletMapper; | 8 | import cn.iocoder.yudao.module.pay.dal.mysql.wallet.PayWalletMapper; |
| 9 | -import cn.iocoder.yudao.module.pay.dal.redis.no.PayNoRedisDAO; | ||
| 10 | import cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum; | 9 | import cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum; |
| 11 | import cn.iocoder.yudao.module.pay.service.order.PayOrderService; | 10 | import cn.iocoder.yudao.module.pay.service.order.PayOrderService; |
| 12 | import cn.iocoder.yudao.module.pay.service.refund.PayRefundService; | 11 | import cn.iocoder.yudao.module.pay.service.refund.PayRefundService; |
| 12 | +import cn.iocoder.yudao.module.pay.service.wallet.bo.CreateWalletTransactionBO; | ||
| 13 | import lombok.extern.slf4j.Slf4j; | 13 | import lombok.extern.slf4j.Slf4j; |
| 14 | import org.springframework.context.annotation.Lazy; | 14 | import org.springframework.context.annotation.Lazy; |
| 15 | import org.springframework.stereotype.Service; | 15 | import org.springframework.stereotype.Service; |
| @@ -18,7 +18,6 @@ import org.springframework.transaction.annotation.Transactional; | @@ -18,7 +18,6 @@ import org.springframework.transaction.annotation.Transactional; | ||
| 18 | import javax.annotation.Resource; | 18 | import javax.annotation.Resource; |
| 19 | import java.time.LocalDateTime; | 19 | import java.time.LocalDateTime; |
| 20 | 20 | ||
| 21 | -import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.TOO_MANY_REQUESTS; | ||
| 22 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | 21 | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |
| 23 | import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.*; | 22 | import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.*; |
| 24 | import static cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum.PAYMENT; | 23 | import static cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum.PAYMENT; |
| @@ -33,21 +32,9 @@ import static cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum.PAYM | @@ -33,21 +32,9 @@ import static cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum.PAYM | ||
| 33 | @Slf4j | 32 | @Slf4j |
| 34 | public class PayWalletServiceImpl implements PayWalletService { | 33 | public class PayWalletServiceImpl implements PayWalletService { |
| 35 | 34 | ||
| 36 | - /** | ||
| 37 | - * 余额支付的 no 前缀 | ||
| 38 | - */ | ||
| 39 | - private static final String WALLET_PAY_NO_PREFIX = "WP"; | ||
| 40 | - /** | ||
| 41 | - * 余额退款的 no 前缀 | ||
| 42 | - */ | ||
| 43 | - private static final String WALLET_REFUND_NO_PREFIX = "WR"; | ||
| 44 | - | ||
| 45 | @Resource | 35 | @Resource |
| 46 | private PayWalletMapper walletMapper; | 36 | private PayWalletMapper walletMapper; |
| 47 | @Resource | 37 | @Resource |
| 48 | - private PayNoRedisDAO noRedisDAO; | ||
| 49 | - | ||
| 50 | - @Resource | ||
| 51 | private PayWalletTransactionService walletTransactionService; | 38 | private PayWalletTransactionService walletTransactionService; |
| 52 | @Resource | 39 | @Resource |
| 53 | @Lazy | 40 | @Lazy |
| @@ -61,7 +48,7 @@ public class PayWalletServiceImpl implements PayWalletService { | @@ -61,7 +48,7 @@ public class PayWalletServiceImpl implements PayWalletService { | ||
| 61 | PayWalletDO wallet = walletMapper.selectByUserIdAndType(userId, userType); | 48 | PayWalletDO wallet = walletMapper.selectByUserIdAndType(userId, userType); |
| 62 | if (wallet == null) { | 49 | if (wallet == null) { |
| 63 | wallet = new PayWalletDO().setUserId(userId).setUserType(userType) | 50 | wallet = new PayWalletDO().setUserId(userId).setUserType(userType) |
| 64 | - .setBalance(0).setTotalExpense(0L).setTotalRecharge(0L); | 51 | + .setBalance(0).setTotalExpense(0).setTotalRecharge(0); |
| 65 | wallet.setCreateTime(LocalDateTime.now()); | 52 | wallet.setCreateTime(LocalDateTime.now()); |
| 66 | walletMapper.insert(wallet); | 53 | walletMapper.insert(wallet); |
| 67 | } | 54 | } |
| @@ -125,70 +112,54 @@ public class PayWalletServiceImpl implements PayWalletService { | @@ -125,70 +112,54 @@ public class PayWalletServiceImpl implements PayWalletService { | ||
| 125 | @Override | 112 | @Override |
| 126 | public PayWalletTransactionDO reduceWalletBalance(Long userId, Integer userType, | 113 | public PayWalletTransactionDO reduceWalletBalance(Long userId, Integer userType, |
| 127 | Long bizId, PayWalletBizTypeEnum bizType, Integer price) { | 114 | Long bizId, PayWalletBizTypeEnum bizType, Integer price) { |
| 128 | - // 1.1 获取钱包 | 115 | + // 1. 获取钱包 |
| 129 | PayWalletDO payWallet = getOrCreateWallet(userId, userType); | 116 | PayWalletDO payWallet = getOrCreateWallet(userId, userType); |
| 130 | - // 1.2 判断余额是否足够 | ||
| 131 | - int afterBalance = payWallet.getBalance() - price; | ||
| 132 | - if (afterBalance < 0) { | ||
| 133 | - throw exception(WALLET_BALANCE_NOT_ENOUGH); | ||
| 134 | - } | ||
| 135 | 117 | ||
| 136 | - // TODO jason:建议基于 where price >= 来做哈;然后抛出 WALLET_BALANCE_NOT_ENOUGH | ||
| 137 | // 2.1 扣除余额 | 118 | // 2.1 扣除余额 |
| 138 | - int number = walletMapper.updateWhenDecBalance(bizType, payWallet.getBalance(), | ||
| 139 | - payWallet.getTotalRecharge(), payWallet.getTotalExpense(), price, payWallet.getId()); | ||
| 140 | - if (number == 0) { | ||
| 141 | - throw exception(TOO_MANY_REQUESTS); | 119 | + int updateCounts = 0 ; |
| 120 | + switch (bizType) { | ||
| 121 | + case PAYMENT: { | ||
| 122 | + updateCounts = walletMapper.updateWhenConsumption(price, payWallet.getId()); | ||
| 123 | + break; | ||
| 124 | + } | ||
| 125 | + case RECHARGE_REFUND: { | ||
| 126 | + // TODO | ||
| 127 | + break; | ||
| 128 | + } | ||
| 129 | + } | ||
| 130 | + if (updateCounts == 0) { | ||
| 131 | + throw exception(WALLET_BALANCE_NOT_ENOUGH); | ||
| 142 | } | 132 | } |
| 143 | - | ||
| 144 | // 2.2 生成钱包流水 | 133 | // 2.2 生成钱包流水 |
| 145 | - // TODO @jason:walletNo 交给 payWalletTransactionService 自己生成哈; | ||
| 146 | - String walletNo = generateWalletNo(bizType); | ||
| 147 | - PayWalletTransactionDO walletTransaction = new PayWalletTransactionDO().setWalletId(payWallet.getId()) | ||
| 148 | - .setNo(walletNo).setPrice(-price).setBalance(afterBalance) | ||
| 149 | - .setBizId(String.valueOf(bizId)).setBizType(bizType.getType()).setTitle(bizType.getDescription()); | ||
| 150 | - // TODO @jason:是不是可以 createWalletTransaction 搞个 bo 参数,然后 PayWalletTransactionDO 交回给 walletTransactionService 更好;然后把参数简化下 | ||
| 151 | - walletTransactionService.createWalletTransaction(walletTransaction); | ||
| 152 | - return walletTransaction; | 134 | + Integer afterBalance = payWallet.getBalance() - price; |
| 135 | + CreateWalletTransactionBO bo = new CreateWalletTransactionBO().setWalletId(payWallet.getId()) | ||
| 136 | + .setPrice(-price).setBalance(afterBalance).setBizId(String.valueOf(bizId)) | ||
| 137 | + .setBizType(bizType.getType()).setTitle(bizType.getDescription()); | ||
| 138 | + return walletTransactionService.createWalletTransaction(bo); | ||
| 153 | } | 139 | } |
| 154 | 140 | ||
| 155 | @Override | 141 | @Override |
| 156 | public PayWalletTransactionDO addWalletBalance(Long userId, Integer userType, | 142 | public PayWalletTransactionDO addWalletBalance(Long userId, Integer userType, |
| 157 | Long bizId, PayWalletBizTypeEnum bizType, Integer price) { | 143 | Long bizId, PayWalletBizTypeEnum bizType, Integer price) { |
| 158 | - // 1.1 获取钱包 | 144 | + // 1. 获取钱包 |
| 159 | PayWalletDO payWallet = getOrCreateWallet(userId, userType); | 145 | PayWalletDO payWallet = getOrCreateWallet(userId, userType); |
| 160 | - | ||
| 161 | - // 2.1 增加余额 | ||
| 162 | - // TODO @jason:类似上面的思路哈; | ||
| 163 | - int number = walletMapper.updateWhenIncBalance(bizType, payWallet.getBalance(), payWallet.getTotalRecharge(), | ||
| 164 | - payWallet.getTotalExpense(), price, payWallet.getId()); | ||
| 165 | - if (number == 0) { | ||
| 166 | - throw exception(TOO_MANY_REQUESTS); | ||
| 167 | - } | ||
| 168 | - | ||
| 169 | - // 2.2 生成钱包流水 | ||
| 170 | - String walletNo = generateWalletNo(bizType); | ||
| 171 | - PayWalletTransactionDO newWalletTransaction = new PayWalletTransactionDO().setWalletId(payWallet.getId()) | ||
| 172 | - .setNo(walletNo).setPrice(price).setBalance(payWallet.getBalance()+price) | ||
| 173 | - .setBizId(String.valueOf(bizId)).setBizType(bizType.getType()) | ||
| 174 | - .setTitle(bizType.getDescription()); | ||
| 175 | - walletTransactionService.createWalletTransaction(newWalletTransaction); | ||
| 176 | - return newWalletTransaction; | ||
| 177 | - } | ||
| 178 | - | ||
| 179 | - private String generateWalletNo(PayWalletBizTypeEnum bizType) { | ||
| 180 | - // TODO @jason:对于余额来说,是不是直接 W+序号就行了,它其实不关注业务;;;不然就耦合啦 | ||
| 181 | - String no = ""; | ||
| 182 | - switch(bizType){ | ||
| 183 | - case PAYMENT: | ||
| 184 | - no = noRedisDAO.generate(WALLET_PAY_NO_PREFIX); | 146 | + switch (bizType) { |
| 147 | + case PAYMENT_REFUND: { | ||
| 148 | + // 更新退款 | ||
| 149 | + walletMapper.updateWhenConsumptionRefund(price, payWallet.getId()); | ||
| 185 | break; | 150 | break; |
| 186 | - case PAYMENT_REFUND: | ||
| 187 | - no = noRedisDAO.generate(WALLET_REFUND_NO_PREFIX); | 151 | + } |
| 152 | + case RECHARGE: { | ||
| 153 | + //TODO | ||
| 188 | break; | 154 | break; |
| 189 | - default : | 155 | + } |
| 190 | } | 156 | } |
| 191 | - return no; | 157 | + |
| 158 | + // 2. 生成钱包流水 | ||
| 159 | + CreateWalletTransactionBO bo = new CreateWalletTransactionBO().setWalletId(payWallet.getId()) | ||
| 160 | + .setPrice(price).setBalance(payWallet.getBalance()+price).setBizId(String.valueOf(bizId)) | ||
| 161 | + .setBizType(bizType.getType()).setTitle(bizType.getDescription()); | ||
| 162 | + return walletTransactionService.createWalletTransaction(bo); | ||
| 192 | } | 163 | } |
| 193 | 164 | ||
| 194 | } | 165 | } |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletTransactionService.java
| @@ -4,6 +4,9 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; | @@ -4,6 +4,9 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||
| 4 | import cn.iocoder.yudao.module.pay.controller.app.wallet.vo.transaction.AppPayWalletTransactionPageReqVO; | 4 | import cn.iocoder.yudao.module.pay.controller.app.wallet.vo.transaction.AppPayWalletTransactionPageReqVO; |
| 5 | import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO; | 5 | import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO; |
| 6 | import cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum; | 6 | import cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum; |
| 7 | +import cn.iocoder.yudao.module.pay.service.wallet.bo.CreateWalletTransactionBO; | ||
| 8 | + | ||
| 9 | +import javax.validation.Valid; | ||
| 7 | 10 | ||
| 8 | /** | 11 | /** |
| 9 | * 钱包余额流水 Service 接口 | 12 | * 钱包余额流水 Service 接口 |
| @@ -25,10 +28,10 @@ public interface PayWalletTransactionService { | @@ -25,10 +28,10 @@ public interface PayWalletTransactionService { | ||
| 25 | /** | 28 | /** |
| 26 | * 新增钱包余额流水 | 29 | * 新增钱包余额流水 |
| 27 | * | 30 | * |
| 28 | - * @param payWalletTransaction 余额流水 | ||
| 29 | - * @return id | 31 | + * @param bo 创建钱包流水 bo |
| 32 | + * @return 新建的钱包 do | ||
| 30 | */ | 33 | */ |
| 31 | - Long createWalletTransaction(PayWalletTransactionDO payWalletTransaction); | 34 | + PayWalletTransactionDO createWalletTransaction(@Valid CreateWalletTransactionBO bo); |
| 32 | 35 | ||
| 33 | /** | 36 | /** |
| 34 | * 根据 no,获取钱包余流水 | 37 | * 根据 no,获取钱包余流水 |
| @@ -45,4 +48,5 @@ public interface PayWalletTransactionService { | @@ -45,4 +48,5 @@ public interface PayWalletTransactionService { | ||
| 45 | * @return 钱包流水 | 48 | * @return 钱包流水 |
| 46 | */ | 49 | */ |
| 47 | PayWalletTransactionDO getWalletTransaction(String bizId, PayWalletBizTypeEnum type); | 50 | PayWalletTransactionDO getWalletTransaction(String bizId, PayWalletBizTypeEnum type); |
| 51 | + | ||
| 48 | } | 52 | } |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletTransactionServiceImpl.java
| @@ -2,10 +2,13 @@ package cn.iocoder.yudao.module.pay.service.wallet; | @@ -2,10 +2,13 @@ package cn.iocoder.yudao.module.pay.service.wallet; | ||
| 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.pay.controller.app.wallet.vo.transaction.AppPayWalletTransactionPageReqVO; | 4 | import cn.iocoder.yudao.module.pay.controller.app.wallet.vo.transaction.AppPayWalletTransactionPageReqVO; |
| 5 | +import cn.iocoder.yudao.module.pay.convert.wallet.PayWalletTransactionConvert; | ||
| 5 | import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO; | 6 | import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletDO; |
| 6 | import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO; | 7 | import cn.iocoder.yudao.module.pay.dal.dataobject.wallet.PayWalletTransactionDO; |
| 7 | import cn.iocoder.yudao.module.pay.dal.mysql.wallet.PayWalletTransactionMapper; | 8 | import cn.iocoder.yudao.module.pay.dal.mysql.wallet.PayWalletTransactionMapper; |
| 9 | +import cn.iocoder.yudao.module.pay.dal.redis.no.PayNoRedisDAO; | ||
| 8 | import cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum; | 10 | import cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum; |
| 11 | +import cn.iocoder.yudao.module.pay.service.wallet.bo.CreateWalletTransactionBO; | ||
| 9 | import lombok.extern.slf4j.Slf4j; | 12 | import lombok.extern.slf4j.Slf4j; |
| 10 | import org.springframework.stereotype.Service; | 13 | import org.springframework.stereotype.Service; |
| 11 | 14 | ||
| @@ -20,10 +23,17 @@ import javax.annotation.Resource; | @@ -20,10 +23,17 @@ import javax.annotation.Resource; | ||
| 20 | @Slf4j | 23 | @Slf4j |
| 21 | public class PayWalletTransactionServiceImpl implements PayWalletTransactionService { | 24 | public class PayWalletTransactionServiceImpl implements PayWalletTransactionService { |
| 22 | 25 | ||
| 26 | + /** | ||
| 27 | + * 钱包流水的 no 前缀 | ||
| 28 | + */ | ||
| 29 | + private static final String WALLET_NO_PREFIX = "W"; | ||
| 30 | + | ||
| 23 | @Resource | 31 | @Resource |
| 24 | private PayWalletService payWalletService; | 32 | private PayWalletService payWalletService; |
| 25 | @Resource | 33 | @Resource |
| 26 | private PayWalletTransactionMapper payWalletTransactionMapper; | 34 | private PayWalletTransactionMapper payWalletTransactionMapper; |
| 35 | + @Resource | ||
| 36 | + private PayNoRedisDAO noRedisDAO; | ||
| 27 | 37 | ||
| 28 | @Override | 38 | @Override |
| 29 | public PageResult<PayWalletTransactionDO> getWalletTransactionPage(Long userId, Integer userType, | 39 | public PageResult<PayWalletTransactionDO> getWalletTransactionPage(Long userId, Integer userType, |
| @@ -33,9 +43,11 @@ public class PayWalletTransactionServiceImpl implements PayWalletTransactionServ | @@ -33,9 +43,11 @@ public class PayWalletTransactionServiceImpl implements PayWalletTransactionServ | ||
| 33 | } | 43 | } |
| 34 | 44 | ||
| 35 | @Override | 45 | @Override |
| 36 | - public Long createWalletTransaction(PayWalletTransactionDO payWalletTransaction) { | ||
| 37 | - payWalletTransactionMapper.insert(payWalletTransaction); | ||
| 38 | - return payWalletTransaction.getId(); | 46 | + public PayWalletTransactionDO createWalletTransaction(CreateWalletTransactionBO bo) { |
| 47 | + PayWalletTransactionDO transaction = PayWalletTransactionConvert.INSTANCE.convert(bo) | ||
| 48 | + .setNo(noRedisDAO.generate(WALLET_NO_PREFIX)); | ||
| 49 | + payWalletTransactionMapper.insert(transaction); | ||
| 50 | + return transaction; | ||
| 39 | } | 51 | } |
| 40 | 52 | ||
| 41 | @Override | 53 | @Override |
| @@ -47,4 +59,5 @@ public class PayWalletTransactionServiceImpl implements PayWalletTransactionServ | @@ -47,4 +59,5 @@ public class PayWalletTransactionServiceImpl implements PayWalletTransactionServ | ||
| 47 | public PayWalletTransactionDO getWalletTransaction(String bizId, PayWalletBizTypeEnum type) { | 59 | public PayWalletTransactionDO getWalletTransaction(String bizId, PayWalletBizTypeEnum type) { |
| 48 | return payWalletTransactionMapper.selectByBiz(bizId, type.getType()); | 60 | return payWalletTransactionMapper.selectByBiz(bizId, type.getType()); |
| 49 | } | 61 | } |
| 62 | + | ||
| 50 | } | 63 | } |
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/bo/CreateWalletTransactionBO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.pay.service.wallet.bo; | ||
| 2 | + | ||
| 3 | +import cn.iocoder.yudao.module.pay.enums.member.PayWalletBizTypeEnum; | ||
| 4 | +import lombok.Data; | ||
| 5 | + | ||
| 6 | +/** | ||
| 7 | + * 创建钱包流水 BO | ||
| 8 | + * | ||
| 9 | + * @author jason | ||
| 10 | + */ | ||
| 11 | +@Data | ||
| 12 | +public class CreateWalletTransactionBO { | ||
| 13 | + | ||
| 14 | + // TODO @jason:bo 的话,最好加个参数校验哈; | ||
| 15 | + | ||
| 16 | + /** | ||
| 17 | + * 钱包编号 | ||
| 18 | + * | ||
| 19 | + */ | ||
| 20 | + private Long walletId; | ||
| 21 | + | ||
| 22 | + /** | ||
| 23 | + * 交易金额,单位分 | ||
| 24 | + * | ||
| 25 | + * 正值表示余额增加,负值表示余额减少 | ||
| 26 | + */ | ||
| 27 | + private Integer price; | ||
| 28 | + | ||
| 29 | + /** | ||
| 30 | + * 交易后余额,单位分 | ||
| 31 | + */ | ||
| 32 | + private Integer balance; | ||
| 33 | + | ||
| 34 | + /** | ||
| 35 | + * 关联业务分类 | ||
| 36 | + * | ||
| 37 | + * 枚举 {@link PayWalletBizTypeEnum#getType()} | ||
| 38 | + */ | ||
| 39 | + private Integer bizType; | ||
| 40 | + | ||
| 41 | + /** | ||
| 42 | + * 关联业务编号 | ||
| 43 | + */ | ||
| 44 | + private String bizId; | ||
| 45 | + | ||
| 46 | + /** | ||
| 47 | + * 流水说明 | ||
| 48 | + */ | ||
| 49 | + private String title; | ||
| 50 | +} |
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/social/SocialUserApi.java
| @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.system.api.social; | @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.system.api.social; | ||
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.common.exception.ServiceException; | 3 | 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.SocialUserUnbindReqDTO; | 6 | import cn.iocoder.yudao.module.system.api.social.dto.SocialUserUnbindReqDTO; |
| 6 | import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum; | 7 | import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum; |
| 7 | 8 | ||
| @@ -27,8 +28,9 @@ public interface SocialUserApi { | @@ -27,8 +28,9 @@ public interface SocialUserApi { | ||
| 27 | * 绑定社交用户 | 28 | * 绑定社交用户 |
| 28 | * | 29 | * |
| 29 | * @param reqDTO 绑定信息 | 30 | * @param reqDTO 绑定信息 |
| 31 | + * @return 社交用户 openid | ||
| 30 | */ | 32 | */ |
| 31 | - void bindSocialUser(@Valid SocialUserBindReqDTO reqDTO); | 33 | + String bindSocialUser(@Valid SocialUserBindReqDTO reqDTO); |
| 32 | 34 | ||
| 33 | /** | 35 | /** |
| 34 | * 取消绑定社交用户 | 36 | * 取消绑定社交用户 |
| @@ -38,16 +40,17 @@ public interface SocialUserApi { | @@ -38,16 +40,17 @@ public interface SocialUserApi { | ||
| 38 | void unbindSocialUser(@Valid SocialUserUnbindReqDTO reqDTO); | 40 | void unbindSocialUser(@Valid SocialUserUnbindReqDTO reqDTO); |
| 39 | 41 | ||
| 40 | /** | 42 | /** |
| 41 | - * 获得社交用户的绑定用户编号 | ||
| 42 | - * 注意,返回的是 MemberUser 或者 AdminUser 的 id 编号! | 43 | + * 获得社交用户 |
| 44 | + * | ||
| 43 | * 在认证信息不正确的情况下,也会抛出 {@link ServiceException} 业务异常 | 45 | * 在认证信息不正确的情况下,也会抛出 {@link ServiceException} 业务异常 |
| 44 | * | 46 | * |
| 45 | * @param userType 用户类型 | 47 | * @param userType 用户类型 |
| 46 | * @param type 社交平台的类型 | 48 | * @param type 社交平台的类型 |
| 47 | * @param code 授权码 | 49 | * @param code 授权码 |
| 48 | * @param state state | 50 | * @param state state |
| 49 | - * @return 绑定用户编号 | 51 | + * @return 社交用户 |
| 50 | */ | 52 | */ |
| 51 | - Long getBindUserId(Integer userType, Integer type, String code, String state); | 53 | + SocialUserRespDTO getSocialUser(Integer userType, Integer type, |
| 54 | + String code, String state); | ||
| 52 | 55 | ||
| 53 | } | 56 | } |
yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/social/dto/SocialUserRespDTO.java
0 → 100644
| 1 | +package cn.iocoder.yudao.module.system.api.social.dto; | ||
| 2 | + | ||
| 3 | +import lombok.AllArgsConstructor; | ||
| 4 | +import lombok.Data; | ||
| 5 | +import lombok.NoArgsConstructor; | ||
| 6 | + | ||
| 7 | +/** | ||
| 8 | + * 社交用户 Response DTO | ||
| 9 | + * | ||
| 10 | + * @author 芋道源码 | ||
| 11 | + */ | ||
| 12 | +@Data | ||
| 13 | +@NoArgsConstructor | ||
| 14 | +@AllArgsConstructor | ||
| 15 | +public class SocialUserRespDTO { | ||
| 16 | + | ||
| 17 | + /** | ||
| 18 | + * 社交用户 openid | ||
| 19 | + */ | ||
| 20 | + private String openid; | ||
| 21 | + | ||
| 22 | + /** | ||
| 23 | + * 关联的用户编号 | ||
| 24 | + */ | ||
| 25 | + private Long userId; | ||
| 26 | + | ||
| 27 | +} |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/social/SocialUserApiImpl.java
| 1 | package cn.iocoder.yudao.module.system.api.social; | 1 | package cn.iocoder.yudao.module.system.api.social; |
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO; | 3 | import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO; |
| 4 | +import cn.iocoder.yudao.module.system.api.social.dto.SocialUserRespDTO; | ||
| 4 | import cn.iocoder.yudao.module.system.api.social.dto.SocialUserUnbindReqDTO; | 5 | import cn.iocoder.yudao.module.system.api.social.dto.SocialUserUnbindReqDTO; |
| 5 | import cn.iocoder.yudao.module.system.service.social.SocialUserService; | 6 | import cn.iocoder.yudao.module.system.service.social.SocialUserService; |
| 6 | import org.springframework.stereotype.Service; | 7 | import org.springframework.stereotype.Service; |
| @@ -26,8 +27,8 @@ public class SocialUserApiImpl implements SocialUserApi { | @@ -26,8 +27,8 @@ public class SocialUserApiImpl implements SocialUserApi { | ||
| 26 | } | 27 | } |
| 27 | 28 | ||
| 28 | @Override | 29 | @Override |
| 29 | - public void bindSocialUser(SocialUserBindReqDTO reqDTO) { | ||
| 30 | - socialUserService.bindSocialUser(reqDTO); | 30 | + public String bindSocialUser(SocialUserBindReqDTO reqDTO) { |
| 31 | + return socialUserService.bindSocialUser(reqDTO); | ||
| 31 | } | 32 | } |
| 32 | 33 | ||
| 33 | @Override | 34 | @Override |
| @@ -37,8 +38,8 @@ public class SocialUserApiImpl implements SocialUserApi { | @@ -37,8 +38,8 @@ public class SocialUserApiImpl implements SocialUserApi { | ||
| 37 | } | 38 | } |
| 38 | 39 | ||
| 39 | @Override | 40 | @Override |
| 40 | - public Long getBindUserId(Integer userType, Integer type, String code, String state) { | ||
| 41 | - return socialUserService.getBindUserId(userType, type, code, state); | 41 | + public SocialUserRespDTO getSocialUser(Integer userType, Integer type, String code, String state) { |
| 42 | + return socialUserService.getSocialUser(userType, type, code, state); | ||
| 42 | } | 43 | } |
| 43 | 44 | ||
| 44 | } | 45 | } |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/auth/AdminAuthServiceImpl.java
| @@ -9,6 +9,7 @@ import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils; | @@ -9,6 +9,7 @@ import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils; | ||
| 9 | import cn.iocoder.yudao.module.system.api.logger.dto.LoginLogCreateReqDTO; | 9 | import cn.iocoder.yudao.module.system.api.logger.dto.LoginLogCreateReqDTO; |
| 10 | import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi; | 10 | import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi; |
| 11 | import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO; | 11 | import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO; |
| 12 | +import cn.iocoder.yudao.module.system.api.social.dto.SocialUserRespDTO; | ||
| 12 | import cn.iocoder.yudao.module.system.controller.admin.auth.vo.*; | 13 | import cn.iocoder.yudao.module.system.controller.admin.auth.vo.*; |
| 13 | import cn.iocoder.yudao.module.system.convert.auth.AuthConvert; | 14 | import cn.iocoder.yudao.module.system.convert.auth.AuthConvert; |
| 14 | import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO; | 15 | import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO; |
| @@ -155,14 +156,14 @@ public class AdminAuthServiceImpl implements AdminAuthService { | @@ -155,14 +156,14 @@ public class AdminAuthServiceImpl implements AdminAuthService { | ||
| 155 | @Override | 156 | @Override |
| 156 | public AuthLoginRespVO socialLogin(AuthSocialLoginReqVO reqVO) { | 157 | public AuthLoginRespVO socialLogin(AuthSocialLoginReqVO reqVO) { |
| 157 | // 使用 code 授权码,进行登录。然后,获得到绑定的用户编号 | 158 | // 使用 code 授权码,进行登录。然后,获得到绑定的用户编号 |
| 158 | - Long userId = socialUserService.getBindUserId(UserTypeEnum.ADMIN.getValue(), reqVO.getType(), | 159 | + SocialUserRespDTO socialUser = socialUserService.getSocialUser(UserTypeEnum.ADMIN.getValue(), reqVO.getType(), |
| 159 | reqVO.getCode(), reqVO.getState()); | 160 | reqVO.getCode(), reqVO.getState()); |
| 160 | - if (userId == null) { | 161 | + if (socialUser == null) { |
| 161 | throw exception(AUTH_THIRD_LOGIN_NOT_BIND); | 162 | throw exception(AUTH_THIRD_LOGIN_NOT_BIND); |
| 162 | } | 163 | } |
| 163 | 164 | ||
| 164 | // 获得用户 | 165 | // 获得用户 |
| 165 | - AdminUserDO user = userService.getUser(userId); | 166 | + AdminUserDO user = userService.getUser(socialUser.getUserId()); |
| 166 | if (user == null) { | 167 | if (user == null) { |
| 167 | throw exception(USER_NOT_EXISTS); | 168 | throw exception(USER_NOT_EXISTS); |
| 168 | } | 169 | } |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialUserService.java
| @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.system.service.social; | @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.system.service.social; | ||
| 2 | 2 | ||
| 3 | import cn.iocoder.yudao.framework.common.exception.ServiceException; | 3 | 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.dal.dataobject.social.SocialUserDO; | 6 | import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialUserDO; |
| 6 | import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum; | 7 | import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum; |
| 7 | 8 | ||
| @@ -50,8 +51,9 @@ public interface SocialUserService { | @@ -50,8 +51,9 @@ public interface SocialUserService { | ||
| 50 | * 绑定社交用户 | 51 | * 绑定社交用户 |
| 51 | * | 52 | * |
| 52 | * @param reqDTO 绑定信息 | 53 | * @param reqDTO 绑定信息 |
| 54 | + * @return 社交用户 openid | ||
| 53 | */ | 55 | */ |
| 54 | - void bindSocialUser(@Valid SocialUserBindReqDTO reqDTO); | 56 | + String bindSocialUser(@Valid SocialUserBindReqDTO reqDTO); |
| 55 | 57 | ||
| 56 | /** | 58 | /** |
| 57 | * 取消绑定社交用户 | 59 | * 取消绑定社交用户 |
| @@ -64,15 +66,16 @@ public interface SocialUserService { | @@ -64,15 +66,16 @@ public interface SocialUserService { | ||
| 64 | void unbindSocialUser(Long userId, Integer userType, Integer type, String openid); | 66 | void unbindSocialUser(Long userId, Integer userType, Integer type, String openid); |
| 65 | 67 | ||
| 66 | /** | 68 | /** |
| 67 | - * 获得社交用户的绑定用户编号 | ||
| 68 | - * 注意,返回的是 MemberUser 或者 AdminUser 的 id 编号! | 69 | + * 获得社交用户 |
| 70 | + * | ||
| 69 | * 在认证信息不正确的情况下,也会抛出 {@link ServiceException} 业务异常 | 71 | * 在认证信息不正确的情况下,也会抛出 {@link ServiceException} 业务异常 |
| 70 | * | 72 | * |
| 71 | * @param userType 用户类型 | 73 | * @param userType 用户类型 |
| 72 | * @param type 社交平台的类型 | 74 | * @param type 社交平台的类型 |
| 73 | * @param code 授权码 | 75 | * @param code 授权码 |
| 74 | * @param state state | 76 | * @param state state |
| 75 | - * @return 绑定用户编号 | 77 | + * @return 社交用户 |
| 76 | */ | 78 | */ |
| 77 | - Long getBindUserId(Integer userType, Integer type, String code, String state); | 79 | + SocialUserRespDTO getSocialUser(Integer userType, Integer type, String code, String state); |
| 80 | + | ||
| 78 | } | 81 | } |
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialUserServiceImpl.java
| @@ -5,6 +5,7 @@ import cn.hutool.core.lang.Assert; | @@ -5,6 +5,7 @@ import cn.hutool.core.lang.Assert; | ||
| 5 | import cn.iocoder.yudao.framework.common.util.http.HttpUtils; | 5 | import cn.iocoder.yudao.framework.common.util.http.HttpUtils; |
| 6 | import cn.iocoder.yudao.framework.social.core.YudaoAuthRequestFactory; | 6 | import cn.iocoder.yudao.framework.social.core.YudaoAuthRequestFactory; |
| 7 | import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO; | 7 | import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO; |
| 8 | +import cn.iocoder.yudao.module.system.api.social.dto.SocialUserRespDTO; | ||
| 8 | import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialUserBindDO; | 9 | import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialUserBindDO; |
| 9 | import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialUserDO; | 10 | import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialUserDO; |
| 10 | import cn.iocoder.yudao.module.system.dal.mysql.social.SocialUserBindMapper; | 11 | import cn.iocoder.yudao.module.system.dal.mysql.social.SocialUserBindMapper; |
| @@ -98,7 +99,7 @@ public class SocialUserServiceImpl implements SocialUserService { | @@ -98,7 +99,7 @@ public class SocialUserServiceImpl implements SocialUserService { | ||
| 98 | 99 | ||
| 99 | @Override | 100 | @Override |
| 100 | @Transactional | 101 | @Transactional |
| 101 | - public void bindSocialUser(SocialUserBindReqDTO reqDTO) { | 102 | + public String bindSocialUser(SocialUserBindReqDTO reqDTO) { |
| 102 | // 获得社交用户 | 103 | // 获得社交用户 |
| 103 | SocialUserDO socialUser = authSocialUser(reqDTO.getType(), reqDTO.getCode(), reqDTO.getState()); | 104 | SocialUserDO socialUser = authSocialUser(reqDTO.getType(), reqDTO.getCode(), reqDTO.getState()); |
| 104 | Assert.notNull(socialUser, "社交用户不能为空"); | 105 | Assert.notNull(socialUser, "社交用户不能为空"); |
| @@ -115,6 +116,7 @@ public class SocialUserServiceImpl implements SocialUserService { | @@ -115,6 +116,7 @@ public class SocialUserServiceImpl implements SocialUserService { | ||
| 115 | .userId(reqDTO.getUserId()).userType(reqDTO.getUserType()) | 116 | .userId(reqDTO.getUserId()).userType(reqDTO.getUserType()) |
| 116 | .socialUserId(socialUser.getId()).socialType(socialUser.getType()).build(); | 117 | .socialUserId(socialUser.getId()).socialType(socialUser.getType()).build(); |
| 117 | socialUserBindMapper.insert(socialUserBind); | 118 | socialUserBindMapper.insert(socialUserBind); |
| 119 | + return socialUser.getOpenid(); | ||
| 118 | } | 120 | } |
| 119 | 121 | ||
| 120 | @Override | 122 | @Override |
| @@ -130,7 +132,7 @@ public class SocialUserServiceImpl implements SocialUserService { | @@ -130,7 +132,7 @@ public class SocialUserServiceImpl implements SocialUserService { | ||
| 130 | } | 132 | } |
| 131 | 133 | ||
| 132 | @Override | 134 | @Override |
| 133 | - public Long getBindUserId(Integer userType, Integer type, String code, String state) { | 135 | + public SocialUserRespDTO getSocialUser(Integer userType, Integer type, String code, String state) { |
| 134 | // 获得社交用户 | 136 | // 获得社交用户 |
| 135 | SocialUserDO socialUser = authSocialUser(type, code, state); | 137 | SocialUserDO socialUser = authSocialUser(type, code, state); |
| 136 | Assert.notNull(socialUser, "社交用户不能为空"); | 138 | Assert.notNull(socialUser, "社交用户不能为空"); |
| @@ -141,7 +143,7 @@ public class SocialUserServiceImpl implements SocialUserService { | @@ -141,7 +143,7 @@ public class SocialUserServiceImpl implements SocialUserService { | ||
| 141 | if (socialUserBind == null) { | 143 | if (socialUserBind == null) { |
| 142 | throw exception(AUTH_THIRD_LOGIN_NOT_BIND); | 144 | throw exception(AUTH_THIRD_LOGIN_NOT_BIND); |
| 143 | } | 145 | } |
| 144 | - return socialUserBind.getUserId(); | 146 | + return new SocialUserRespDTO(socialUser.getOpenid(), socialUserBind.getUserId()); |
| 145 | } | 147 | } |
| 146 | 148 | ||
| 147 | /** | 149 | /** |
yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/auth/AdminAuthServiceImplTest.java
| @@ -6,6 +6,7 @@ import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; | @@ -6,6 +6,7 @@ import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; | ||
| 6 | import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; | 6 | import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; |
| 7 | import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi; | 7 | import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi; |
| 8 | import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO; | 8 | import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO; |
| 9 | +import cn.iocoder.yudao.module.system.api.social.dto.SocialUserRespDTO; | ||
| 9 | import cn.iocoder.yudao.module.system.controller.admin.auth.vo.*; | 10 | import cn.iocoder.yudao.module.system.controller.admin.auth.vo.*; |
| 10 | import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO; | 11 | import cn.iocoder.yudao.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO; |
| 11 | import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; | 12 | import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO; |
| @@ -235,8 +236,8 @@ public class AdminAuthServiceImplTest extends BaseDbUnitTest { | @@ -235,8 +236,8 @@ public class AdminAuthServiceImplTest extends BaseDbUnitTest { | ||
| 235 | AuthSocialLoginReqVO reqVO = randomPojo(AuthSocialLoginReqVO.class); | 236 | AuthSocialLoginReqVO reqVO = randomPojo(AuthSocialLoginReqVO.class); |
| 236 | // mock 方法(绑定的用户编号) | 237 | // mock 方法(绑定的用户编号) |
| 237 | Long userId = 1L; | 238 | Long userId = 1L; |
| 238 | - when(socialUserService.getBindUserId(eq(UserTypeEnum.ADMIN.getValue()), eq(reqVO.getType()), | ||
| 239 | - eq(reqVO.getCode()), eq(reqVO.getState()))).thenReturn(userId); | 239 | + when(socialUserService.getSocialUser(eq(UserTypeEnum.ADMIN.getValue()), eq(reqVO.getType()), |
| 240 | + eq(reqVO.getCode()), eq(reqVO.getState()))).thenReturn(new SocialUserRespDTO(randomString(), userId)); | ||
| 240 | // mock(用户) | 241 | // mock(用户) |
| 241 | AdminUserDO user = randomPojo(AdminUserDO.class, o -> o.setId(userId)); | 242 | AdminUserDO user = randomPojo(AdminUserDO.class, o -> o.setId(userId)); |
| 242 | when(userService.getUser(eq(userId))).thenReturn(user); | 243 | when(userService.getUser(eq(userId))).thenReturn(user); |
yudao-module-system/yudao-module-system-biz/src/test/java/cn/iocoder/yudao/module/system/service/social/SocialUserServiceImplTest.java
| @@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; | @@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; | ||
| 4 | import cn.iocoder.yudao.framework.social.core.YudaoAuthRequestFactory; | 4 | import cn.iocoder.yudao.framework.social.core.YudaoAuthRequestFactory; |
| 5 | import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; | 5 | import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; |
| 6 | import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO; | 6 | import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO; |
| 7 | +import cn.iocoder.yudao.module.system.api.social.dto.SocialUserRespDTO; | ||
| 7 | import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialUserBindDO; | 8 | import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialUserBindDO; |
| 8 | import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialUserDO; | 9 | import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialUserDO; |
| 9 | import cn.iocoder.yudao.module.system.dal.mysql.social.SocialUserBindMapper; | 10 | import cn.iocoder.yudao.module.system.dal.mysql.social.SocialUserBindMapper; |
| @@ -195,10 +196,11 @@ public class SocialUserServiceImplTest extends BaseDbUnitTest { | @@ -195,10 +196,11 @@ public class SocialUserServiceImplTest extends BaseDbUnitTest { | ||
| 195 | .setSocialType(SocialTypeEnum.GITEE.getType()).setSocialUserId(socialUser.getId())); | 196 | .setSocialType(SocialTypeEnum.GITEE.getType()).setSocialUserId(socialUser.getId())); |
| 196 | 197 | ||
| 197 | // 调用 | 198 | // 调用 |
| 198 | - socialUserService.bindSocialUser(reqDTO); | 199 | + String openid = socialUserService.bindSocialUser(reqDTO); |
| 199 | // 断言 | 200 | // 断言 |
| 200 | List<SocialUserBindDO> socialUserBinds = socialUserBindMapper.selectList(); | 201 | List<SocialUserBindDO> socialUserBinds = socialUserBindMapper.selectList(); |
| 201 | assertEquals(1, socialUserBinds.size()); | 202 | assertEquals(1, socialUserBinds.size()); |
| 203 | + assertEquals(socialUser.getOpenid(), openid); | ||
| 202 | } | 204 | } |
| 203 | 205 | ||
| 204 | @Test | 206 | @Test |
| @@ -232,25 +234,26 @@ public class SocialUserServiceImplTest extends BaseDbUnitTest { | @@ -232,25 +234,26 @@ public class SocialUserServiceImplTest extends BaseDbUnitTest { | ||
| 232 | } | 234 | } |
| 233 | 235 | ||
| 234 | @Test | 236 | @Test |
| 235 | - public void testGetBindUserId() { | 237 | + public void testGetSocialUser() { |
| 236 | // 准备参数 | 238 | // 准备参数 |
| 237 | Integer userType = UserTypeEnum.ADMIN.getValue(); | 239 | Integer userType = UserTypeEnum.ADMIN.getValue(); |
| 238 | Integer type = SocialTypeEnum.GITEE.getType(); | 240 | Integer type = SocialTypeEnum.GITEE.getType(); |
| 239 | String code = "tudou"; | 241 | String code = "tudou"; |
| 240 | String state = "yuanma"; | 242 | String state = "yuanma"; |
| 241 | // mock 社交用户 | 243 | // mock 社交用户 |
| 242 | - SocialUserDO socialUser = randomPojo(SocialUserDO.class).setType(type).setCode(code).setState(state); | ||
| 243 | - socialUserMapper.insert(socialUser); | 244 | + SocialUserDO socialUserDO = randomPojo(SocialUserDO.class).setType(type).setCode(code).setState(state); |
| 245 | + socialUserMapper.insert(socialUserDO); | ||
| 244 | // mock 社交用户的绑定 | 246 | // mock 社交用户的绑定 |
| 245 | Long userId = randomLong(); | 247 | Long userId = randomLong(); |
| 246 | SocialUserBindDO socialUserBind = randomPojo(SocialUserBindDO.class).setUserType(userType).setUserId(userId) | 248 | SocialUserBindDO socialUserBind = randomPojo(SocialUserBindDO.class).setUserType(userType).setUserId(userId) |
| 247 | - .setSocialType(type).setSocialUserId(socialUser.getId()); | 249 | + .setSocialType(type).setSocialUserId(socialUserDO.getId()); |
| 248 | socialUserBindMapper.insert(socialUserBind); | 250 | socialUserBindMapper.insert(socialUserBind); |
| 249 | 251 | ||
| 250 | // 调用 | 252 | // 调用 |
| 251 | - Long result = socialUserService.getBindUserId(userType, type, code, state); | 253 | + SocialUserRespDTO socialUser = socialUserService.getSocialUser(userType, type, code, state); |
| 252 | // 断言 | 254 | // 断言 |
| 253 | - assertEquals(userId, result); | 255 | + assertEquals(userId, socialUser.getUserId()); |
| 256 | + assertEquals(socialUserDO.getOpenid(), socialUser.getOpenid()); | ||
| 254 | } | 257 | } |
| 255 | 258 | ||
| 256 | } | 259 | } |
yudao-server/src/main/resources/application-local.yaml
| @@ -173,8 +173,10 @@ wx: | @@ -173,8 +173,10 @@ wx: | ||
| 173 | key-prefix: wx # Redis Key 的前缀 | 173 | key-prefix: wx # Redis Key 的前缀 |
| 174 | http-client-type: HttpClient # 采用 HttpClient 请求微信公众号平台 | 174 | http-client-type: HttpClient # 采用 HttpClient 请求微信公众号平台 |
| 175 | miniapp: # 小程序配置(必填),参见 https://github.com/Wechat-Group/WxJava/blob/develop/spring-boot-starters/wx-java-miniapp-spring-boot-starter/README.md 文档 | 175 | miniapp: # 小程序配置(必填),参见 https://github.com/Wechat-Group/WxJava/blob/develop/spring-boot-starters/wx-java-miniapp-spring-boot-starter/README.md 文档 |
| 176 | - appid: wx62056c0d5e8db250 | ||
| 177 | - secret: 333ae72f41552af1e998fe1f54e1584a | 176 | +# appid: wx62056c0d5e8db250 |
| 177 | +# secret: 333ae72f41552af1e998fe1f54e1584a | ||
| 178 | + appid: wx63c280fe3248a3e7 # wenhualian的接口测试号 | ||
| 179 | + secret: 6f270509224a7ae1296bbf1c8cb97aed | ||
| 178 | config-storage: | 180 | config-storage: |
| 179 | type: RedisTemplate # 采用 RedisTemplate 操作 Redis,会自动从 Spring 中获取 | 181 | type: RedisTemplate # 采用 RedisTemplate 操作 Redis,会自动从 Spring 中获取 |
| 180 | key-prefix: wa # Redis Key 的前缀 | 182 | key-prefix: wa # Redis Key 的前缀 |