From 0612a13cce78906b13b56e311c508bb491063b1e Mon Sep 17 00:00:00 2001 From: owen Date: Tue, 17 Oct 2023 23:18:08 +0800 Subject: [PATCH 1/7] =?UTF-8?q?=E4=BA=A4=E6=98=93=EF=BC=9A=E6=A0=B8?= =?UTF-8?q?=E9=94=80=E8=AE=A2=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sql/mysql/mall.sql | 5 +- .../mybatis/core/query/MPJLambdaWrapperX.java | 313 ++++++++++++++++++ .../admin/order/TradeOrderController.java | 14 +- .../admin/order/vo/TradeOrderBaseVO.java | 3 + .../order/vo/TradeOrderPageItemRespVO.java | 20 +- .../order/vo/TradeOrderSummaryRespVO.java | 22 ++ .../convert/order/TradeOrderConvert.java | 8 +- .../dal/mysql/order/TradeOrderMapper.java | 22 ++ .../service/order/TradeOrderQueryService.java | 9 + .../order/TradeOrderQueryServiceImpl.java | 44 ++- 10 files changed, 440 insertions(+), 20 deletions(-) create mode 100644 yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/query/MPJLambdaWrapperX.java create mode 100644 yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderSummaryRespVO.java diff --git a/sql/mysql/mall.sql b/sql/mysql/mall.sql index 558ec66f0..cddfb73df 100644 --- a/sql/mysql/mall.sql +++ b/sql/mysql/mall.sql @@ -1,2 +1,5 @@ INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, component_name) -VALUES ('商城首页', '', 2, 1, 2362, 'home', 'ep:home-filled', 'mall/home/index', 'MallHome'); \ No newline at end of file +VALUES ('商城首页', '', 2, 1, 2362, 'home', 'ep:home-filled', 'mall/home/index', 'MallHome'); + +INSERT INTO system_menu (name, permission, type, sort, parent_id, path, icon, component, component_name) +VALUES ('核销订单', '', 2, 2, 2166, 'pick-up-order', 'ep:list', 'mall/trade/delivery/pickUpOrder/index', 'PickUpOrder'); \ No newline at end of file diff --git a/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/query/MPJLambdaWrapperX.java b/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/query/MPJLambdaWrapperX.java new file mode 100644 index 000000000..7950a2f96 --- /dev/null +++ b/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/query/MPJLambdaWrapperX.java @@ -0,0 +1,313 @@ +package cn.iocoder.yudao.framework.mybatis.core.query; + +import cn.hutool.core.util.ArrayUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils; +import com.baomidou.mybatisplus.core.toolkit.support.SFunction; +import com.github.yulichang.toolkit.MPJWrappers; +import com.github.yulichang.wrapper.MPJLambdaWrapper; +import org.springframework.util.StringUtils; + +import java.util.Collection; +import java.util.function.Consumer; + +/** + * 拓展 MyBatis Plus Join QueryWrapper 类,主要增加如下功能: + *

+ * 1. 拼接条件的方法,增加 xxxIfPresent 方法,用于判断值不存在的时候,不要拼接到条件中。 + * + * @param 数据类型 + */ +public class MPJLambdaWrapperX extends MPJLambdaWrapper { + + public MPJLambdaWrapperX likeIfPresent(SFunction column, String val) { + MPJWrappers.lambdaJoin().like(column, val); + if (StringUtils.hasText(val)) { + return (MPJLambdaWrapperX) super.like(column, val); + } + return this; + } + + public MPJLambdaWrapperX inIfPresent(SFunction column, Collection values) { + if (ObjectUtil.isAllNotEmpty(values) && !ArrayUtil.isEmpty(values)) { + return (MPJLambdaWrapperX) super.in(column, values); + } + return this; + } + + public MPJLambdaWrapperX inIfPresent(SFunction column, Object... values) { + if (ObjectUtil.isAllNotEmpty(values) && !ArrayUtil.isEmpty(values)) { + return (MPJLambdaWrapperX) super.in(column, values); + } + return this; + } + + public MPJLambdaWrapperX eqIfPresent(SFunction column, Object val) { + if (ObjectUtil.isNotEmpty(val)) { + return (MPJLambdaWrapperX) super.eq(column, val); + } + return this; + } + + public MPJLambdaWrapperX neIfPresent(SFunction column, Object val) { + if (ObjectUtil.isNotEmpty(val)) { + return (MPJLambdaWrapperX) super.ne(column, val); + } + return this; + } + + public MPJLambdaWrapperX gtIfPresent(SFunction column, Object val) { + if (val != null) { + return (MPJLambdaWrapperX) super.gt(column, val); + } + return this; + } + + public MPJLambdaWrapperX geIfPresent(SFunction column, Object val) { + if (val != null) { + return (MPJLambdaWrapperX) super.ge(column, val); + } + return this; + } + + public MPJLambdaWrapperX ltIfPresent(SFunction column, Object val) { + if (val != null) { + return (MPJLambdaWrapperX) super.lt(column, val); + } + return this; + } + + public MPJLambdaWrapperX leIfPresent(SFunction column, Object val) { + if (val != null) { + return (MPJLambdaWrapperX) super.le(column, val); + } + return this; + } + + public MPJLambdaWrapperX betweenIfPresent(SFunction column, Object val1, Object val2) { + if (val1 != null && val2 != null) { + return (MPJLambdaWrapperX) super.between(column, val1, val2); + } + if (val1 != null) { + return (MPJLambdaWrapperX) ge(column, val1); + } + if (val2 != null) { + return (MPJLambdaWrapperX) le(column, val2); + } + return this; + } + + public MPJLambdaWrapperX betweenIfPresent(SFunction column, Object[] values) { + Object val1 = ArrayUtils.get(values, 0); + Object val2 = ArrayUtils.get(values, 1); + return betweenIfPresent(column, val1, val2); + } + + // ========== 重写父类方法,方便链式调用 ========== + + @Override + public MPJLambdaWrapperX eq(boolean condition, SFunction column, Object val) { + super.eq(condition, column, val); + return this; + } + + @Override + public MPJLambdaWrapperX eq(SFunction column, Object val) { + super.eq(column, val); + return this; + } + + @Override + public MPJLambdaWrapperX orderByDesc(SFunction column) { + //noinspection unchecked + super.orderByDesc(true, column); + return this; + } + + @Override + public MPJLambdaWrapperX last(String lastSql) { + super.last(lastSql); + return this; + } + + @Override + public MPJLambdaWrapperX in(SFunction column, Collection coll) { + super.in(column, coll); + return this; + } + + @Override + public MPJLambdaWrapperX selectAll(Class clazz) { + super.selectAll(clazz); + return this; + } + + @Override + public MPJLambdaWrapperX selectAll(Class clazz, String prefix) { + super.selectAll(clazz, prefix); + return this; + } + + @Override + public MPJLambdaWrapperX selectAs(SFunction column, String alias) { + super.selectAs(column, alias); + return this; + } + + @Override + public MPJLambdaWrapperX selectAs(String column, SFunction alias) { + super.selectAs(column, alias); + return this; + } + + @Override + public MPJLambdaWrapperX selectAs(SFunction column, SFunction alias) { + super.selectAs(column, alias); + return this; + } + + @Override + public MPJLambdaWrapperX selectAs(String index, SFunction column, SFunction alias) { + super.selectAs(index, column, alias); + return this; + } + + @Override + public MPJLambdaWrapperX selectAsClass(Class source, Class tag) { + super.selectAsClass(source, tag); + return this; + } + + @Override + public MPJLambdaWrapperX selectSub(Class clazz, Consumer> consumer, SFunction alias) { + super.selectSub(clazz, consumer, alias); + return this; + } + + @Override + public MPJLambdaWrapperX selectSub(Class clazz, String st, Consumer> consumer, SFunction alias) { + super.selectSub(clazz, st, consumer, alias); + return this; + } + + @Override + public MPJLambdaWrapperX selectCount(SFunction column) { + super.selectCount(column); + return this; + } + + @Override + public MPJLambdaWrapperX selectCount(Object column, String alias) { + super.selectCount(column, alias); + return this; + } + + @Override + public MPJLambdaWrapperX selectCount(Object column, SFunction alias) { + super.selectCount(column, alias); + return this; + } + + @Override + public MPJLambdaWrapperX selectCount(SFunction column, String alias) { + super.selectCount(column, alias); + return this; + } + + @Override + public MPJLambdaWrapperX selectCount(SFunction column, SFunction alias) { + super.selectCount(column, alias); + return this; + } + + @Override + public MPJLambdaWrapperX selectSum(SFunction column) { + super.selectSum(column); + return this; + } + + @Override + public MPJLambdaWrapperX selectSum(SFunction column, String alias) { + super.selectSum(column, alias); + return this; + } + + @Override + public MPJLambdaWrapperX selectSum(SFunction column, SFunction alias) { + super.selectSum(column, alias); + return this; + } + + @Override + public MPJLambdaWrapperX selectMax(SFunction column) { + super.selectMax(column); + return this; + } + + @Override + public MPJLambdaWrapperX selectMax(SFunction column, String alias) { + super.selectMax(column, alias); + return this; + } + + @Override + public MPJLambdaWrapperX selectMax(SFunction column, SFunction alias) { + super.selectMax(column, alias); + return this; + } + + @Override + public MPJLambdaWrapperX selectMin(SFunction column) { + super.selectMin(column); + return this; + } + + @Override + public MPJLambdaWrapperX selectMin(SFunction column, String alias) { + super.selectMin(column, alias); + return this; + } + + @Override + public MPJLambdaWrapperX selectMin(SFunction column, SFunction alias) { + super.selectMin(column, alias); + return this; + } + + @Override + public MPJLambdaWrapperX selectAvg(SFunction column) { + super.selectAvg(column); + return this; + } + + @Override + public MPJLambdaWrapperX selectAvg(SFunction column, String alias) { + super.selectAvg(column, alias); + return this; + } + + @Override + public MPJLambdaWrapperX selectAvg(SFunction column, SFunction alias) { + super.selectAvg(column, alias); + return this; + } + + @Override + public MPJLambdaWrapperX selectLen(SFunction column) { + super.selectLen(column); + return this; + } + + @Override + public MPJLambdaWrapperX selectLen(SFunction column, String alias) { + super.selectLen(column, alias); + return this; + } + + @Override + public MPJLambdaWrapperX selectLen(SFunction column, SFunction alias) { + super.selectLen(column, alias); + return this; + } + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/TradeOrderController.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/TradeOrderController.java index e1dbfaf9a..e2650be43 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/TradeOrderController.java +++ b/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.*; import javax.annotation.Resource; import java.util.List; import java.util.Map; +import java.util.Objects; +import java.util.Set; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; @Tag(name = "管理后台 - 交易订单") @@ -56,7 +59,9 @@ public class TradeOrderController { } // 查询用户信息 - Map userMap = memberUserApi.getUserMap(convertSet(pageResult.getList(), TradeOrderDO::getUserId)); + Set userIds = CollUtil.unionDistinct(convertList(pageResult.getList(), TradeOrderDO::getUserId), + convertList(pageResult.getList(), TradeOrderDO::getBrokerageUserId, Objects::nonNull)); + Map userMap = memberUserApi.getUserMap(userIds); // 查询订单项 List orderItems = tradeOrderQueryService.getOrderItemListByOrderId( convertSet(pageResult.getList(), TradeOrderDO::getId)); @@ -64,6 +69,13 @@ public class TradeOrderController { return success(TradeOrderConvert.INSTANCE.convertPage(pageResult, orderItems, userMap)); } + @GetMapping("/summary") + @Operation(summary = "获得交易订单统计") + @PreAuthorize("@ss.hasPermission('trade:order:query')") + public CommonResult getOrderSummary(TradeOrderPageReqVO reqVO) { + return success(tradeOrderQueryService.getOrderSummary(reqVO)); + } + @GetMapping("/get-detail") @Operation(summary = "获得交易订单详情") @Parameter(name = "id", description = "订单编号", required = true, example = "1") diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderBaseVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderBaseVO.java index 29875c8da..88f5b0cd4 100755 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderBaseVO.java +++ b/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 { @Schema(description = "VIP 减免金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "888") private Integer vipPrice; + @Schema(description = "推广人编号", example = "1") + private Long brokerageUserId; + } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderPageItemRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderPageItemRespVO.java index b0def5a83..704067ed0 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderPageItemRespVO.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderPageItemRespVO.java @@ -1,6 +1,6 @@ package cn.iocoder.yudao.module.trade.controller.admin.order.vo; -import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; +import cn.iocoder.yudao.module.trade.controller.admin.base.member.user.MemberUserRespVO; import cn.iocoder.yudao.module.trade.controller.admin.base.product.property.ProductPropertyValueDetailRespVO; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; @@ -14,24 +14,20 @@ public class TradeOrderPageItemRespVO extends TradeOrderBaseVO { @Schema(description = "收件人地区名字", requiredMode = Schema.RequiredMode.REQUIRED, example = "上海 上海市 普陀区") private String receiverAreaName; - /** - * 订单项列表 - */ + @Schema(description = "订单项列表", requiredMode = Schema.RequiredMode.REQUIRED) private List items; - // TODO @xiaobai:使用 MemberUserRespVO 返回哈;DTO 不直接给前端 - /** - * 用户信息 - */ - private MemberUserRespDTO user; + @Schema(description = "用户信息", requiredMode = Schema.RequiredMode.REQUIRED) + private MemberUserRespVO user; + + @Schema(description = "推广人信息") + private MemberUserRespVO brokerageUser; @Schema(description = "管理后台 - 交易订单的分页项的订单项目") @Data public static class Item extends TradeOrderItemBaseVO { - /** - * 属性数组 - */ + @Schema(description = "属性列表", requiredMode = Schema.RequiredMode.REQUIRED) private List properties; } diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderSummaryRespVO.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderSummaryRespVO.java new file mode 100644 index 000000000..184c8db83 --- /dev/null +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/controller/admin/order/vo/TradeOrderSummaryRespVO.java @@ -0,0 +1,22 @@ +package cn.iocoder.yudao.module.trade.controller.admin.order.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Schema(description = "管理后台 - 交易订单统计 Response VO") +@Data +public class TradeOrderSummaryRespVO { + + @Schema(description = "订单数量", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") + private Long orderCount; + + @Schema(description = "订单金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") + private Long orderPayPrice; + + @Schema(description = "退款单数", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") + private Long afterSaleCount; + + @Schema(description = "退款金额", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") + private Long afterSalePrice; + +} diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java index 40260ae4b..6e59df639 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/convert/order/TradeOrderConvert.java +++ b/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 { TradeOrderPageItemRespVO orderVO = convert(order, xOrderItems); // 处理收货地址 orderVO.setReceiverAreaName(AreaUtils.format(order.getReceiverAreaId())); - // 增加用户昵称 - orderVO.setUser(memberUserMap.get(orderVO.getUserId())); + // 增加用户信息 + orderVO.setUser(convertUser(memberUserMap.get(orderVO.getUserId()))); + // 增加推广人信息 + orderVO.setBrokerageUser(convertUser(memberUserMap.get(orderVO.getBrokerageUserId()))); return orderVO; }); return new PageResult<>(orderVOs, pageResult.getTotal()); } + MemberUserRespVO convertUser(MemberUserRespDTO memberUserRespDTO); + TradeOrderPageItemRespVO convert(TradeOrderDO order, List items); ProductPropertyValueDetailRespVO convert(ProductPropertyValueDetailRespDTO bean); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/order/TradeOrderMapper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/order/TradeOrderMapper.java index fce4e0742..81abbdfc7 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/order/TradeOrderMapper.java +++ b/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; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; +import cn.iocoder.yudao.framework.mybatis.core.query.MPJLambdaWrapperX; import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderPageReqVO; import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderPageReqVO; import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; @@ -11,6 +12,7 @@ import org.apache.ibatis.annotations.Mapper; import java.time.LocalDateTime; import java.util.List; +import java.util.Map; import java.util.Set; @Mapper @@ -42,6 +44,26 @@ public interface TradeOrderMapper extends BaseMapperX { .orderByDesc(TradeOrderDO::getId)); } + default List> selectOrderSummaryGroupByRefundStatus(TradeOrderPageReqVO reqVO, Set userIds) { + return selectMaps(new MPJLambdaWrapperX() + .selectAs(TradeOrderDO::getRefundStatus, TradeOrderDO::getRefundStatus) // 售后状态 + .selectCount(TradeOrderDO::getId, "count") // 售后状态对应的数量 + .selectSum(TradeOrderDO::getPayPrice, "price") // 售后状态对应的支付金额 + .likeIfPresent(TradeOrderDO::getNo, reqVO.getNo()) + .eqIfPresent(TradeOrderDO::getUserId, reqVO.getUserId()) + .eqIfPresent(TradeOrderDO::getDeliveryType, reqVO.getDeliveryType()) + .inIfPresent(TradeOrderDO::getUserId, userIds) + .eqIfPresent(TradeOrderDO::getType, reqVO.getType()) + .eqIfPresent(TradeOrderDO::getStatus, reqVO.getStatus()) + .eqIfPresent(TradeOrderDO::getPayChannelCode, reqVO.getPayChannelCode()) + .eqIfPresent(TradeOrderDO::getTerminal, reqVO.getTerminal()) + .eqIfPresent(TradeOrderDO::getLogisticsId, reqVO.getLogisticsId()) + .inIfPresent(TradeOrderDO::getPickUpStoreId, reqVO.getPickUpStoreIds()) + .likeIfPresent(TradeOrderDO::getPickUpVerifyCode, reqVO.getPickUpVerifyCode()) + .betweenIfPresent(TradeOrderDO::getCreateTime, reqVO.getCreateTime()) + .groupBy(TradeOrderDO::getRefundStatus)); // 按售后状态分组 + } + default PageResult selectPage(AppTradeOrderPageReqVO reqVO, Long userId) { return selectPage(reqVO, new LambdaQueryWrapperX() .eq(TradeOrderDO::getUserId, userId) diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderQueryService.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderQueryService.java index e1c8ca35f..445792232 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderQueryService.java +++ b/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; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderPageReqVO; +import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderSummaryRespVO; import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderPageReqVO; import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; @@ -64,6 +65,14 @@ public interface TradeOrderQueryService { */ PageResult getOrderPage(TradeOrderPageReqVO reqVO); + /** + * 获得订单统计 + * + * @param reqVO 请求参数 + * @return 订单统计 + */ + TradeOrderSummaryRespVO getOrderSummary(TradeOrderPageReqVO reqVO); + /** * 【会员】获得交易订单分页 * diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderQueryServiceImpl.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderQueryServiceImpl.java index 51a558674..de95bde76 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderQueryServiceImpl.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/service/order/TradeOrderQueryServiceImpl.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.trade.service.order; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.map.MapUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.extra.spring.SpringUtil; @@ -8,6 +9,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.member.api.user.MemberUserApi; import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderPageReqVO; +import cn.iocoder.yudao.module.trade.controller.admin.order.vo.TradeOrderSummaryRespVO; import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderPageReqVO; import cn.iocoder.yudao.module.trade.dal.dataobject.delivery.DeliveryExpressDO; import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO; @@ -15,6 +17,7 @@ import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderItemDO; import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderItemMapper; import cn.iocoder.yudao.module.trade.dal.mysql.order.TradeOrderMapper; import cn.iocoder.yudao.module.trade.dal.redis.RedisKeyConstants; +import cn.iocoder.yudao.module.trade.enums.order.TradeOrderRefundStatusEnum; import cn.iocoder.yudao.module.trade.enums.order.TradeOrderStatusEnum; import cn.iocoder.yudao.module.trade.framework.delivery.core.client.ExpressClientFactory; import cn.iocoder.yudao.module.trade.framework.delivery.core.client.dto.ExpressTrackQueryReqDTO; @@ -85,24 +88,57 @@ public class TradeOrderQueryServiceImpl implements TradeOrderQueryService { @Override public PageResult getOrderPage(TradeOrderPageReqVO reqVO) { + // 根据用户查询条件构建用户编号列表 + Set userIds = buildQueryConditionUserIds(reqVO); + if (userIds == null) { // 没查询到用户,说明肯定也没他的订单 + return PageResult.empty(); + } + // 分页查询 + return tradeOrderMapper.selectPage(reqVO, userIds); + } + + private Set buildQueryConditionUserIds(TradeOrderPageReqVO reqVO) { // 获得 userId 相关的查询 Set userIds = new HashSet<>(); if (StrUtil.isNotEmpty(reqVO.getUserMobile())) { MemberUserRespDTO user = memberUserApi.getUserByMobile(reqVO.getUserMobile()); if (user == null) { // 没查询到用户,说明肯定也没他的订单 - return new PageResult<>(); + return null; } userIds.add(user.getId()); } if (StrUtil.isNotEmpty(reqVO.getUserNickname())) { List users = memberUserApi.getUserListByNickname(reqVO.getUserNickname()); if (CollUtil.isEmpty(users)) { // 没查询到用户,说明肯定也没他的订单 - return new PageResult<>(); + return null; } userIds.addAll(convertSet(users, MemberUserRespDTO::getId)); } - // 分页查询 - return tradeOrderMapper.selectPage(reqVO, userIds); + return userIds; + } + + @Override + public TradeOrderSummaryRespVO getOrderSummary(TradeOrderPageReqVO reqVO) { + // 根据用户查询条件构建用户编号列表 + Set userIds = buildQueryConditionUserIds(reqVO); + if (userIds == null) { // 没查询到用户,说明肯定也没他的订单 + return new TradeOrderSummaryRespVO(); + } + // 查询每个售后状态对应的数量、金额 + List> list = tradeOrderMapper.selectOrderSummaryGroupByRefundStatus(reqVO, null); + + TradeOrderSummaryRespVO vo = new TradeOrderSummaryRespVO().setAfterSaleCount(0L).setAfterSalePrice(0L); + for (Map map : list) { + Long count = MapUtil.getLong(map, "count", 0L); + Long price = MapUtil.getLong(map, "price", 0L); + // 未退款的计入订单,部分退款、全部退款计入售后 + if (TradeOrderRefundStatusEnum.NONE.getStatus().equals(MapUtil.getInt(map, "refundStatus"))) { + vo.setOrderCount(count).setOrderPayPrice(price); + } else { + vo.setAfterSaleCount(vo.getAfterSaleCount() + count).setAfterSalePrice(vo.getAfterSalePrice() + price); + } + } + return vo; } @Override From 00e18a480ff4bca6e6be6c7e6119cc684bd32aba Mon Sep 17 00:00:00 2001 From: "zhijiantianya@gmail.com" Date: Wed, 18 Oct 2023 18:39:05 +0800 Subject: [PATCH 2/7] =?UTF-8?q?code=20review=EF=BC=9A=E9=92=B1=E5=8C=85?= =?UTF-8?q?=E3=80=81=E5=85=85=E5=80=BC=E3=80=81=E8=BD=AC=E8=B4=A6=E7=9A=84?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sql/mysql/pay_wallet.sql | 4 +- .../transfer/PayTransferUnifiedReqDTO.java | 4 +- .../impl/alipay/AlipayTransferClient.java | 16 +++-- .../core/client/impl/mock/MockPayClient.java | 1 + .../core/enums/channel/PayChannelEnum.java | 1 + .../transfer/PayTransferStatusRespEnum.java | 2 +- .../enums/transfer/PayTransferTypeEnum.java | 3 + .../pay/api/transfer/PayTransferApi.java | 1 + .../transfer/dto/PayTransferCreateReqDTO.java | 4 ++ .../module/pay/enums/ErrorCodeConstants.java | 3 +- .../enums/transfer/PayTransferStatusEnum.java | 7 +++ .../pay/api/transfer/PayTransferApiImpl.java | 8 ++- .../transfer/PayDemoTransferCreateReqVO.java | 3 + .../admin/transfer/PayTransferController.java | 2 + .../transfer/vo/PayTransferSubmitReqVO.java | 1 + .../transfer/vo/PayTransferSubmitRespVO.java | 1 + .../wallet/PayWalletRechargeController.java | 1 + .../PayWalletTransactionController.java | 2 + .../WalletRechargePackageBaseVO.java | 2 +- .../WalletRechargePackageCreateReqVO.java | 2 +- .../WalletRechargePackagePageReqVO.java | 4 +- .../WalletRechargePackageRespVO.java | 2 +- .../WalletRechargePackageUpdateReqVO.java | 2 +- .../PayWalletTransactionPageReqVO.java | 1 + .../PayWalletTransactionRespVO.java | 3 + .../wallet/vo/wallet/PayWalletPageReqVO.java | 3 + .../wallet/vo/wallet/PayWalletRespVO.java | 2 + .../AppPayWalletRechargeCreateReqVO.java | 4 +- .../pay/convert/wallet/PayWalletConvert.java | 3 +- .../dataobject/demo/PayDemoTransferDO.java | 3 + .../dataobject/transfer/PayTransferDO.java | 63 +++++++++++-------- .../transfer/PayTransferExtensionDO.java | 2 + .../wallet/PayWalletRechargeDO.java | 5 +- .../wallet/PayWalletRechargePackageDO.java | 2 +- .../dal/mysql/demo/PayDemoTransferMapper.java | 6 +- .../transfer/PayTransferExtensionMapper.java | 5 +- .../dal/mysql/transfer/PayTransferMapper.java | 1 + .../pay/dal/mysql/wallet/PayWalletMapper.java | 3 + .../mysql/wallet/PayWalletRechargeMapper.java | 6 +- .../PayWalletRechargePackageMapper.java | 6 +- .../framework/pay/core/WalletPayClient.java | 1 + .../demo/PayDemoTransferServiceImpl.java | 2 + .../service/transfer/PayTransferService.java | 3 + .../transfer/PayTransferServiceImpl.java | 12 +++- .../PayWalletRechargePackageService.java | 20 ++---- .../PayWalletRechargePackageServiceImpl.java | 9 +-- .../wallet/PayWalletRechargeServiceImpl.java | 45 +++++++------ .../pay/service/wallet/PayWalletService.java | 1 + .../service/wallet/PayWalletServiceImpl.java | 3 +- 49 files changed, 178 insertions(+), 112 deletions(-) diff --git a/sql/mysql/pay_wallet.sql b/sql/mysql/pay_wallet.sql index 28b737d3c..0586fdd15 100644 --- a/sql/mysql/pay_wallet.sql +++ b/sql/mysql/pay_wallet.sql @@ -77,7 +77,7 @@ ALTER TABLE `pay_channel` MODIFY COLUMN `config` text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '支付渠道配置' AFTER `app_id`; -- ---------------------------- --- 套餐充值表 +-- 充值套餐表 -- ---------------------------- DROP TABLE IF EXISTS `pay_wallet_recharge_package`; CREATE TABLE `pay_wallet_recharge_package` @@ -94,7 +94,7 @@ CREATE TABLE `pay_wallet_recharge_package` `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', PRIMARY KEY (`id`) USING BTREE -) ENGINE=InnoDB COMMENT='套餐充值表'; +) ENGINE=InnoDB COMMENT='充值套餐表'; -- ---------------------------- -- Table structure for pay_wallet_recharge diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/transfer/PayTransferUnifiedReqDTO.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/transfer/PayTransferUnifiedReqDTO.java index cbaee6975..17e47aa8b 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/dto/transfer/PayTransferUnifiedReqDTO.java +++ b/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 { private String title; /** - * 收款方信息,转账类型不同,收款方信息不同 + * 收款方信息。 + * + * 转账类型 {@link #type} 不同,收款方信息不同 */ @NotEmpty(message = "收款方信息 不能为空") private Map payeeInfo; diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayTransferClient.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayTransferClient.java index b9c7eee73..03aecd61b 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/alipay/AlipayTransferClient.java +++ b/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; import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.BAD_REQUEST; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception0; +// TODO @jason:看看能不能融合到 AbstractAlipayPayClient 中。 /** * 支付宝转账的 PayClient 实现类 * @@ -29,6 +30,7 @@ import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionU */ @Slf4j public class AlipayTransferClient extends AbstractAlipayPayClient { + // TODO @jason:方法之间,要有空格噢 public AlipayTransferClient(Long channelId, AlipayPayClientConfig config) { super(channelId, PayChannelEnum.ALIPAY_TRANSFER.getCode(), config); } @@ -49,16 +51,17 @@ public class AlipayTransferClient extends AbstractAlipayPayClient { model.setOrderTitle(reqDTO.getTitle()); // 转账业务的标题,用于在支付宝用户的账单里显示。 model.setOutBizNo(reqDTO.getOutTransferNo()); model.setProductCode("TRANS_ACCOUNT_NO_PWD"); // 销售产品码。单笔无密转账固定为 TRANS_ACCOUNT_NO_PWD - model.setBizScene("DIRECT_TRANSFER"); // 业务场景 单笔无密转账固定为 DIRECT_TRANSFER。 + model.setBizScene("DIRECT_TRANSFER"); // 业务场景 单笔无密转账固定为 DIRECT_TRANSFER model.setBusinessParams(JsonUtils.toJsonString(reqDTO.getChannelExtras())); PayTransferTypeEnum transferType = PayTransferTypeEnum.ofType(reqDTO.getType()); - switch(transferType){ - case WX_BALANCE : - case WALLET_BALANCE : { + switch(transferType) { + case WX_BALANCE: + case WALLET_BALANCE: { log.error("[doUnifiedTransfer],支付宝转账不支持的转账类型{}", transferType); throw new UnsupportedOperationException(String.format("支付宝转账不支持转账类型: %s",transferType.getName())); } - case ALIPAY_BALANCE : { + // TODO @jason:是不是不用传递 transferType 参数哈?因为应该已经明确是支付宝啦? + case ALIPAY_BALANCE: { // ② 个性化的参数 Participant payeeInfo = new Participant(); payeeInfo.setIdentityType("ALIPAY_LOGON_ID"); @@ -90,7 +93,7 @@ public class AlipayTransferClient extends AbstractAlipayPayClient { return PayTransferRespDTO.successOf(response.getOrderId(), parseTime(response.getTransDate()), response.getOutBizNo(), response); } - case BANK_CARD : { + case BANK_CARD: { Participant payeeInfo = new Participant(); payeeInfo.setIdentityType("BANKCARD_ACCOUNT"); throw new UnsupportedOperationException("待实现"); @@ -100,4 +103,5 @@ public class AlipayTransferClient extends AbstractAlipayPayClient { } } } + } diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/mock/MockPayClient.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/mock/MockPayClient.java index 83a52a800..309813697 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/client/impl/mock/MockPayClient.java +++ b/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 { protected PayTransferRespDTO doUnifiedTransfer(PayTransferUnifiedReqDTO reqDTO) { throw new UnsupportedOperationException("待实现"); } + } diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/channel/PayChannelEnum.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/channel/PayChannelEnum.java index b99f8ef4f..0fa12b405 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/channel/PayChannelEnum.java +++ b/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 { ALIPAY_APP("alipay_app", "支付宝App 支付", AlipayPayClientConfig.class), ALIPAY_QR("alipay_qr", "支付宝扫码支付", AlipayPayClientConfig.class), ALIPAY_BAR("alipay_bar", "支付宝条码支付", AlipayPayClientConfig.class), + // TODO @jason:是不是按照微信聊的,合并回 ALIPAY_PC;因为支付宝、微信都是多种支付方式,选择其中的一种即可; ALIPAY_TRANSFER("alipay_transfer", "支付宝转账", AlipayPayClientConfig.class), MOCK("mock", "模拟支付", NonePayClientConfig.class), diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/transfer/PayTransferStatusRespEnum.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/transfer/PayTransferStatusRespEnum.java index 61d5698b1..145a470cc 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/transfer/PayTransferStatusRespEnum.java +++ b/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 { /** * TODO 转账到银行卡. 会有T+0 T+1 到账的请情况。 还未实现 + * TODO @jason:可以看看其它开源项目,针对这个场景,处理策略是怎么样的?例如说,每天主动轮询?这个状态的单子? */ IN_PROGRESS(10, "转账进行中"), - SUCCESS(20, "转账成功"), /** * 转账关闭 (失败,或者其它情况) diff --git a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/transfer/PayTransferTypeEnum.java b/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/transfer/PayTransferTypeEnum.java index d25ef98b8..89a680a6e 100644 --- a/yudao-framework/yudao-spring-boot-starter-biz-pay/src/main/java/cn/iocoder/yudao/framework/pay/core/enums/transfer/PayTransferTypeEnum.java +++ b/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; @AllArgsConstructor @Getter public enum PayTransferTypeEnum implements IntArrayValuable { + ALIPAY_BALANCE(1, "支付宝余额"), WX_BALANCE(2, "微信余额"), BANK_CARD(3, "银行卡"), @@ -33,7 +34,9 @@ public enum PayTransferTypeEnum implements IntArrayValuable { return ARRAYS; } + // TODO @jason:是不是 typeOf 更符合预期哈? public static PayTransferTypeEnum ofType(Integer type) { return ArrayUtil.firstMatch(item -> item.getType().equals(type), values()); } + } diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/PayTransferApi.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/PayTransferApi.java index 396fe726c..7899068fe 100644 --- a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/PayTransferApi.java +++ b/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 { * @return 转账单编号 */ Long createTransfer(@Valid PayTransferCreateReqDTO reqDTO); + } diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferCreateReqDTO.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferCreateReqDTO.java index f2eacffcc..fec0bd174 100644 --- a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/dto/PayTransferCreateReqDTO.java +++ b/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 { * 类型 */ @NotNull(message = "转账类型不能为空") + // TODO @jason:枚举的校验 private Integer type; /** @@ -34,9 +35,11 @@ public class PayTransferCreateReqDTO { /** * 转账金额,单位:分 */ + // TODO @jason:这个金额是不是非空哈 @Min(value = 1, message = "转账金额必须大于零") private Integer price; + // TODO @jason:这个标题,是不是不允许空呀 /** * 转账标题 */ @@ -44,4 +47,5 @@ public class PayTransferCreateReqDTO { @NotEmpty(message = "收款方信息不能为空") private Map payeeInfo; + } diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/ErrorCodeConstants.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/ErrorCodeConstants.java index bd11e7c47..4b3f1cfad 100644 --- a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/ErrorCodeConstants.java +++ b/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 { ErrorCode PAY_ORDER_IS_EXPIRED = new ErrorCode(1_007_002_003, "支付订单已经过期"); ErrorCode PAY_ORDER_SUBMIT_CHANNEL_ERROR = new ErrorCode(1_007_002_004, "发起支付报错,错误码:{},错误提示:{}"); ErrorCode PAY_ORDER_REFUND_FAIL_STATUS_ERROR = new ErrorCode(1_007_002_005, "支付订单退款失败,原因:状态不是已支付或已退款"); - ErrorCode ORDER_UPDATE_PRICE_FAIL_PAID = new ErrorCode(1_007_002_006, "支付订单调价失败,原因:支付订单已付款,不能调价"); - ErrorCode ORDER_UPDATE_PRICE_FAIL_EQUAL = new ErrorCode(1_007_002_007, "支付订单调价失败,原因:价格没有变化"); // ========== ORDER 模块(拓展单) 1-007-003-000 ========== ErrorCode PAY_ORDER_EXTENSION_NOT_FOUND = new ErrorCode(1_007_003_000, "支付交易拓展单不存在"); @@ -64,6 +62,7 @@ public interface ErrorCodeConstants { ErrorCode WALLET_RECHARGE_PACKAGE_AND_PRICE_IS_EMPTY = new ErrorCode(1_007_008_011, "充值金额和充钱套餐不能同时为空"); ErrorCode WALLET_RECHARGE_PACKAGE_NOT_FOUND = new ErrorCode(1_007_008_012, "钱包充值套餐不存在"); ErrorCode WALLET_RECHARGE_PACKAGE_IS_DISABLE = new ErrorCode(1_007_008_013, "钱包充值套餐已禁用"); + // ========== 转账模块 1-007-009-000 ========== ErrorCode PAY_TRANSFER_SUBMIT_CHANNEL_ERROR = new ErrorCode(1_007_009_000, "发起转账报错,错误码:{},错误提示:{}"); ErrorCode PAY_TRANSFER_ALIPAY_LOGIN_ID_IS_EMPTY = new ErrorCode(1_007_009_001, "支付宝登录 ID 不能为空"); diff --git a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/transfer/PayTransferStatusEnum.java b/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/transfer/PayTransferStatusEnum.java index 9a207fcf3..f3eff1495 100644 --- a/yudao-module-pay/yudao-module-pay-api/src/main/java/cn/iocoder/yudao/module/pay/enums/transfer/PayTransferStatusEnum.java +++ b/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 { */ CLOSED(30, "转账关闭"); + /** + * 状态 + */ private final Integer status; + /** + * 状态名 + */ private final String name; public static boolean isSuccess(Integer status) { @@ -45,4 +51,5 @@ public enum PayTransferStatusEnum { public static boolean isPendingStatus(Integer status) { return Objects.equals(status, WAITING.getStatus()) || Objects.equals(status, IN_PROGRESS.status); } + } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/PayTransferApiImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/PayTransferApiImpl.java index 2ffa4b2cc..d9f5d5663 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/api/transfer/PayTransferApiImpl.java +++ b/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; import org.springframework.validation.annotation.Validated; /** + * 转账单 API 实现类 + * * @author jason */ @Service @Validated public class PayTransferApiImpl implements PayTransferApi { + @Override public Long createTransfer(PayTransferCreateReqDTO reqDTO) { - + // TODO @jason:貌似没实现噢 return null; } -} + +} \ No newline at end of file diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/vo/transfer/PayDemoTransferCreateReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/vo/transfer/PayDemoTransferCreateReqVO.java index 534001eb8..6db343ea3 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/vo/transfer/PayDemoTransferCreateReqVO.java +++ b/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; @Data public class PayDemoTransferCreateReqVO { + // TODO @jason:这个字段,是不是叫 type 就好了。 @Schema(description = "转账类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") @NotNull(message = "转账类型不能为空") @InEnum(PayTransferTypeEnum.class) @@ -26,7 +27,9 @@ public class PayDemoTransferCreateReqVO { @Min(value = 1, message = "转账金额必须大于零") private Integer price; + // TODO @jason:感觉这个动态字段,晚点改;可能要讨论下怎么搞好; @Schema(description = "收款方信息", requiredMode = Schema.RequiredMode.REQUIRED, example = "{'ALIPAY_LOGON_ID':'xxxx'}") @NotEmpty(message = "收款方信息不能为空") private Map payeeInfo; + } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/transfer/PayTransferController.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/transfer/PayTransferController.java index 1c35dc550..5c416b623 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/transfer/PayTransferController.java +++ b/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 { @PostMapping("/submit") @Operation(summary = "提交转账订单") + // TODO @jason:权限的设置 public CommonResult submitPayTransfer(@Valid @RequestBody PayTransferSubmitReqVO reqVO) { PayTransferSubmitRespVO respVO = payTransferService.submitTransfer(reqVO, getClientIP()); return success(respVO); } + } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/transfer/vo/PayTransferSubmitReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/transfer/vo/PayTransferSubmitReqVO.java index d57d538a6..36e67ce01 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/transfer/vo/PayTransferSubmitReqVO.java +++ b/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 { @Schema(description = "转账渠道的额外参数") private Map channelExtras; + } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/transfer/vo/PayTransferSubmitRespVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/transfer/vo/PayTransferSubmitRespVO.java index 4f2d3a90f..fef296f09 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/transfer/vo/PayTransferSubmitRespVO.java +++ b/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 { @Schema(description = "转账状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") // 参见 PayTransferStatusEnum 枚举 private Integer status; + } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/PayWalletRechargeController.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/PayWalletRechargeController.java index 5dea5fb8d..21ba7262b 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/PayWalletRechargeController.java +++ b/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 { Long.valueOf(notifyReqDTO.getMerchantOrderId()), notifyReqDTO.getPayRefundId()); return success(true); } + } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/PayWalletTransactionController.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/PayWalletTransactionController.java index 8354ad1ce..66891ba81 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/PayWalletTransactionController.java +++ b/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 { @GetMapping("/page") @Operation(summary = "获得钱包流水分页") + // TODO @jason:权限校验,缺一个 public CommonResult> getWalletTransactionPage( @Valid PayWalletTransactionPageReqVO pageReqVO) { PageResult result = payWalletTransactionService.getWalletTransactionPage(pageReqVO); return success(PayWalletTransactionConvert.INSTANCE.convertPage2(result)); } + } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/vo/rechargepackage/WalletRechargePackageBaseVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/vo/rechargepackage/WalletRechargePackageBaseVO.java index a950b850f..c3f58e1da 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/vo/rechargepackage/WalletRechargePackageBaseVO.java +++ b/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; import javax.validation.constraints.NotNull; /** - * 套餐充值 Base VO,提供给添加、修改、详细的子 VO 使用 + * 充值套餐 Base VO,提供给添加、修改、详细的子 VO 使用 * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成 */ @Data diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/vo/rechargepackage/WalletRechargePackageCreateReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/vo/rechargepackage/WalletRechargePackageCreateReqVO.java index aea645a6b..4232a9983 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/vo/rechargepackage/WalletRechargePackageCreateReqVO.java +++ b/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; import lombok.EqualsAndHashCode; import lombok.ToString; -@Schema(description = "管理后台 - 套餐充值创建 Request VO") +@Schema(description = "管理后台 - 充值套餐创建 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/vo/rechargepackage/WalletRechargePackagePageReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/vo/rechargepackage/WalletRechargePackagePageReqVO.java index fb87a9693..1914958ae 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/vo/rechargepackage/WalletRechargePackagePageReqVO.java +++ b/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; import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND; -@Schema(description = "管理后台 - 套餐充值分页 Request VO") +@Schema(description = "管理后台 - 充值套餐分页 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) @@ -20,6 +20,8 @@ public class WalletRechargePackagePageReqVO extends PageParam { @Schema(description = "套餐名", example = "李四") private String name; + // TODO @jason:payPrice 和 bonusPrice 可以去掉。。。一般太少检索啦; + @Schema(description = "支付金额", example = "16454") private Integer payPrice; diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/vo/rechargepackage/WalletRechargePackageRespVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/vo/rechargepackage/WalletRechargePackageRespVO.java index 5abc24cd9..84abaf78a 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/vo/rechargepackage/WalletRechargePackageRespVO.java +++ b/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; import lombok.*; import java.time.LocalDateTime; -@Schema(description = "管理后台 - 套餐充值 Response VO") +@Schema(description = "管理后台 - 充值套餐 Response VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/vo/rechargepackage/WalletRechargePackageUpdateReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/vo/rechargepackage/WalletRechargePackageUpdateReqVO.java index 0b4b5785b..37170cb8b 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/vo/rechargepackage/WalletRechargePackageUpdateReqVO.java +++ b/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; import javax.validation.constraints.NotNull; -@Schema(description = "管理后台 - 套餐充值更新 Request VO") +@Schema(description = "管理后台 - 充值套餐更新 Request VO") @Data @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/vo/transaction/PayWalletTransactionPageReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/vo/transaction/PayWalletTransactionPageReqVO.java index 82122f2b3..678649ce0 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/vo/transaction/PayWalletTransactionPageReqVO.java +++ b/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 { @Schema(description = "钱包编号", example = "1") private Long walletId; + } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/vo/transaction/PayWalletTransactionRespVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/vo/transaction/PayWalletTransactionRespVO.java index de6338318..6203b78d5 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/vo/transaction/PayWalletTransactionRespVO.java +++ b/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 { @Schema(description = "交易时间", requiredMode = Schema.RequiredMode.REQUIRED) private LocalDateTime createTime; + + // TODO @jason:merchantOrderId 字段,需要在 PayWalletTransaction 存储下;然后,前端也返回下这个字段,界面也展示下商户名 + } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/vo/wallet/PayWalletPageReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/vo/wallet/PayWalletPageReqVO.java index d511ea409..fcf22f51b 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/vo/wallet/PayWalletPageReqVO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/vo/wallet/PayWalletPageReqVO.java @@ -1,5 +1,7 @@ package cn.iocoder.yudao.module.pay.controller.admin.wallet.vo.wallet; +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; +import cn.iocoder.yudao.framework.common.validation.InEnum; import lombok.*; import io.swagger.v3.oas.annotations.media.Schema; import cn.iocoder.yudao.framework.common.pojo.PageParam; @@ -18,6 +20,7 @@ public class PayWalletPageReqVO extends PageParam { private Long userId; @Schema(description = "用户类型", example = "1") + @InEnum(UserTypeEnum.class) private Integer userType; @Schema(description = "创建时间") diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/vo/wallet/PayWalletRespVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/vo/wallet/PayWalletRespVO.java index 01b35fb3f..2f49b50e0 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/wallet/vo/wallet/PayWalletRespVO.java +++ b/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 { @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED) private LocalDateTime createTime; + // TODO @jason:要不把用户昵称 + avatar 也读取下? + } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/vo/recharge/AppPayWalletRechargeCreateReqVO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/vo/recharge/AppPayWalletRechargeCreateReqVO.java index 6d3f08e9c..007cb91d9 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/wallet/vo/recharge/AppPayWalletRechargeCreateReqVO.java +++ b/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 { @Min(value = 1, message = "支付金额必须大于零") private Integer payPrice; - @Schema(description = "充值套餐编号", example = "1024") private Long packageId; + + // TODO @jaosn:写个 AssertTrue 的校验方法,payPrice 和 packageId 必须二选一 + } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/wallet/PayWalletConvert.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/wallet/PayWalletConvert.java index c64efc517..3617f23a0 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/wallet/PayWalletConvert.java +++ b/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 { AppPayWalletRespVO convert(PayWalletDO bean); - PayWalletRespVO convert02(PayWalletDO wallet); + PayWalletRespVO convert02(PayWalletDO bean); PageResult convertPage(PageResult page); + } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/demo/PayDemoTransferDO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/demo/PayDemoTransferDO.java index e64958dbf..b036c30a2 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/demo/PayDemoTransferDO.java +++ b/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; @KeySequence("pay_demo_transfer_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 @Data public class PayDemoTransferDO extends BaseDO { + /** * 订单编号 */ @@ -41,6 +42,7 @@ public class PayDemoTransferDO extends BaseDO { */ private Integer type; + // TODO @jason:要不字段还是弄成正确的平铺开? /** * 收款人信息,不同类型和渠道不同 */ @@ -66,4 +68,5 @@ public class PayDemoTransferDO extends BaseDO { * 转账支付时间 */ private LocalDateTime transferTime; + } \ No newline at end of file diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/transfer/PayTransferDO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/transfer/PayTransferDO.java index d91d4cd97..84fb470e0 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/transfer/PayTransferDO.java +++ b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/transfer/PayTransferDO.java @@ -1,6 +1,11 @@ package cn.iocoder.yudao.module.pay.dal.dataobject.transfer; import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; +import cn.iocoder.yudao.framework.pay.core.enums.channel.PayChannelEnum; +import cn.iocoder.yudao.framework.pay.core.enums.transfer.PayTransferStatusRespEnum; +import cn.iocoder.yudao.framework.pay.core.enums.transfer.PayTransferTypeEnum; +import cn.iocoder.yudao.module.pay.dal.dataobject.app.PayAppDO; +import cn.iocoder.yudao.module.pay.dal.dataobject.channel.PayChannelDO; import com.baomidou.mybatisplus.annotation.KeySequence; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; @@ -26,70 +31,76 @@ public class PayTransferDO extends BaseDO { */ @TableId private Long id; - + /** + * 应用编号 + * + * 关联 {@link PayAppDO#getId()} + */ + private Long appId; + /** + * 转账渠道编号 + * + * 关联 {@link PayChannelDO#getId()} + */ + private Long channelId; + /** + * 转账渠道编码 + * + * 枚举 {@link PayChannelEnum} + */ + private String channelCode; /** * 类型 + * + * 枚举 {@link PayTransferTypeEnum} */ private Integer type; - /** - * 应用编号 - */ - private Long appId; + // ========== 商户相关字段 ========== /** * 商户订单编号 + * + * 例如说,内部系统 A 的订单号,需要保证每个 PayAppDO 唯一 */ private String merchantOrderId; - - /** - * 转账金额,单位:分 - */ - private Integer price; - + // TODO @jason:这个字段,要不要改成 subject。。。和 payorderdo 保持一致;哈哈哈,我也忘记为啥当时选了这个名字了。。。 /** * 转账标题 */ private String title; + // ========== 转账相关字段 ========== /** - * 收款人信息,不同类型和渠道不同 + * 转账金额,单位:分 */ - @TableField(typeHandler = JacksonTypeHandler.class) - private Map payeeInfo; - + private Integer price; /** * 转账状态 + * + * 枚举 {@link PayTransferStatusRespEnum} */ private Integer status; - /** * 订单转账成功时间 - * */ private LocalDateTime successTime; - /** * 转账成功的转账拓展单编号 * * 关联 {@link PayTransferExtensionDO#getId()} */ private Long extensionId; - /** * 转账成功的转账拓展单号 * * 关联 {@link PayTransferExtensionDO#getNo()} */ private String no; - /** - * 转账渠道编号 + * 收款人信息,不同类型和渠道不同 */ - private Long channelId; + @TableField(typeHandler = JacksonTypeHandler.class) + private Map payeeInfo; - /** - * 转账渠道编码 - */ - private String channelCode; } \ No newline at end of file diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/transfer/PayTransferExtensionDO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/transfer/PayTransferExtensionDO.java index cd3ca5bbf..9a3736b49 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/transfer/PayTransferExtensionDO.java +++ b/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; import java.util.Map; +// TODO @jason:转账是不是类似 refund,不用拓展单呀?支付做拓展单的原因,是因为它存在不确定性,可以切换多种;转账和退款,都是明确方式的; /** * 转账拓展单 DO * @@ -61,4 +62,5 @@ public class PayTransferExtensionDO extends BaseDO { * 支付渠道异步通知的内容 */ private String channelNotifyData; + } \ No newline at end of file diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/wallet/PayWalletRechargeDO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/wallet/PayWalletRechargeDO.java index 3f303f7c7..a842c95e6 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/wallet/PayWalletRechargeDO.java +++ b/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 { * 实际支付金额 */ private Integer payPrice; - /** * 钱包赠送金额 */ @@ -50,8 +49,10 @@ public class PayWalletRechargeDO extends BaseDO { /** * 充值套餐编号 + * + * 关联 {@link PayWalletRechargeDO#getPackageId()} 字段 */ - private Long packageId; + private Long packageId; /** * 是否已支付 diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/wallet/PayWalletRechargePackageDO.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/wallet/PayWalletRechargePackageDO.java index a2f59f80a..72fc43d96 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/wallet/PayWalletRechargePackageDO.java +++ b/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; /** * 会员钱包充值套餐 DO * - * 通过套餐充值时,可以赠送一定金额; + * 通过充值套餐时,可以赠送一定金额; * * @author 芋道源码 */ diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/demo/PayDemoTransferMapper.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/demo/PayDemoTransferMapper.java index 6b087c3e7..5141c0a39 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/demo/PayDemoTransferMapper.java +++ b/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; @Mapper public interface PayDemoTransferMapper extends BaseMapperX { -} - - - - +} \ No newline at end of file diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/transfer/PayTransferExtensionMapper.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/transfer/PayTransferExtensionMapper.java index 189bc2f13..ecd44ec63 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/transfer/PayTransferExtensionMapper.java +++ b/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 status, PayTransferExtensionDO updateObj){ + default int updateByIdAndStatus(Long id, List whereStatuses, PayTransferExtensionDO updateObj) { return update(updateObj, new LambdaQueryWrapper() - .eq(PayTransferExtensionDO::getId, id).in(PayTransferExtensionDO::getStatus, status)); + .eq(PayTransferExtensionDO::getId, id).in(PayTransferExtensionDO::getStatus, whereStatuses)); } + } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/transfer/PayTransferMapper.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/transfer/PayTransferMapper.java index a8bcce4ad..b0bb9ad43 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/transfer/PayTransferMapper.java +++ b/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 { return update(updateObj, new LambdaQueryWrapper() .eq(PayTransferDO::getId, id).in(PayTransferDO::getStatus, status)); } + } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/wallet/PayWalletMapper.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/wallet/PayWalletMapper.java index 0089b286f..e34c76c0c 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/wallet/PayWalletMapper.java +++ b/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 { /** * 冻结钱包部分余额 + * * @param id 钱包 id * @param price 冻结金额 */ @@ -84,6 +85,7 @@ public interface PayWalletMapper extends BaseMapperX { /** * 解冻钱包余额 + * * @param id 钱包 id * @param price 解冻金额 */ @@ -98,6 +100,7 @@ public interface PayWalletMapper extends BaseMapperX { /** * 当充值退款时, 更新钱包 + * * @param id 钱包 id * @param price 退款金额 */ diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/wallet/PayWalletRechargeMapper.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/wallet/PayWalletRechargeMapper.java index 606f61484..4cb77f020 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/wallet/PayWalletRechargeMapper.java +++ b/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 { default PageResult selectPage(WalletRechargePackagePageReqVO reqVO) { + // TODO @jason:排序按照充值金额 return selectPage(reqVO, new LambdaQueryWrapperX() .likeIfPresent(PayWalletRechargePackageDO::getName, reqVO.getName()) .eqIfPresent(PayWalletRechargePackageDO::getPayPrice, reqVO.getPayPrice()) @@ -20,8 +21,5 @@ public interface PayWalletRechargePackageMapper extends BaseMapperX { public PayTransferRespDTO doUnifiedTransfer(PayTransferUnifiedReqDTO reqDTO) { throw new UnsupportedOperationException("待实现"); } + } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoTransferServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoTransferServiceImpl.java index 9aa784c6e..b766788ef 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoTransferServiceImpl.java +++ b/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 { return demoTransfer.getId(); } + // TODO @jason:可以参考 AppBrokerageWithdrawCreateReqVO 搞下字段哈,进行校验 private void validatePayeeInfo(Integer transferType, Map payeeInfo) { PayTransferTypeEnum transferTypeEnum = ofType(transferType); switch (transferTypeEnum) { @@ -83,4 +84,5 @@ public class PayDemoTransferServiceImpl implements PayDemoTransferService { } } } + } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferService.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferService.java index b58c5d401..0da38c640 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferService.java +++ b/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 import javax.validation.Valid; /** + * 转账 Service 接口 + * * @author jason */ public interface PayTransferService { @@ -29,4 +31,5 @@ public interface PayTransferService { * @return 转账单编号 */ Long createTransfer(@Valid PayTransferCreateReqDTO reqDTO); + } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferServiceImpl.java index 4b86e16c8..f8f476afa 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/transfer/PayTransferServiceImpl.java +++ b/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 import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.*; import static cn.iocoder.yudao.module.pay.enums.transfer.PayTransferStatusEnum.*; +// TODO @jason:等彻底实现完,单测写写; /** + * 转账 Service 实现类 + * * @author jason */ @Service @@ -47,10 +50,12 @@ public class PayTransferServiceImpl implements PayTransferService { private PayTransferMapper transferMapper; @Resource private PayTransferExtensionMapper transferExtensionMapper; + @Resource private PayAppService appService; @Resource private PayChannelService channelService; + @Resource private PayNoRedisDAO noRedisDAO; @@ -64,7 +69,7 @@ public class PayTransferServiceImpl implements PayTransferService { PayChannelDO channel = validateChannelCanSubmit(transfer.getAppId(), reqVO.getChannelCode()); PayClient client = channelService.getPayClient(channel.getId()); - // 2 新增转账拓展单 + // 2. 新增转账拓展单 String no = noRedisDAO.generate(TRANSFER_NO_PREFIX); PayTransferExtensionDO transferExtension = new PayTransferExtensionDO().setNo(no) .setTransferId(transfer.getId()).setChannelId(channel.getId()) @@ -112,8 +117,9 @@ public class PayTransferServiceImpl implements PayTransferService { notifyTransferClosed(channel, notify); } // WAITING 状态无需处理 - // TODO IN_PROGRESS 待处理 + // TODO IN_PROGRESS 待处理 } + private void notifyTransferSuccess(PayChannelDO channel, PayTransferRespDTO notify) { // 1. 更新 PayTransferExtensionDO 转账成功 PayTransferExtensionDO transferExtension = updateTransferExtensionSuccess(notify); @@ -121,7 +127,7 @@ public class PayTransferServiceImpl implements PayTransferService { // 2. 更新 PayTransferDO 转账成功 Boolean transferred = updateTransferSuccess(channel,transferExtension, notify); if (transferred) { - return ; + return; } // 3. TODO 插入转账通知记录 } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletRechargePackageService.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletRechargePackageService.java index 0db09c602..d9310e462 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletRechargePackageService.java +++ b/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 { PayWalletRechargePackageDO validWalletRechargePackage(Long packageId); /** - * 创建套餐充值 + * 创建充值套餐 * * @param createReqVO 创建信息 * @return 编号 @@ -39,33 +39,25 @@ public interface PayWalletRechargePackageService { Long createWalletRechargePackage(@Valid WalletRechargePackageCreateReqVO createReqVO); /** - * 更新套餐充值 + * 更新充值套餐 * * @param updateReqVO 更新信息 */ void updateWalletRechargePackage(@Valid WalletRechargePackageUpdateReqVO updateReqVO); - /** - * 删除套餐充值 + * 删除充值套餐 * * @param id 编号 */ void deleteWalletRechargePackage(Long id); /** - * 获得套餐充值列表 - * - * @param ids 编号 - * @return 套餐充值列表 - */ - List getWalletRechargePackageList(Collection ids); - - /** - * 获得套餐充值分页 + * 获得充值套餐分页 * * @param pageReqVO 分页查询 - * @return 套餐充值分页 + * @return 充值套餐分页 */ PageResult getWalletRechargePackagePage(WalletRechargePackagePageReqVO pageReqVO); + } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletRechargePackageServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletRechargePackageServiceImpl.java index 46412db8e..6b73f623b 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletRechargePackageServiceImpl.java +++ b/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 return walletRechargePackage.getId(); } + // TODO @jason:校验下,套餐名唯一 @Override public void updateWalletRechargePackage(WalletRechargePackageUpdateReqVO updateReqVO) { // 校验存在 @@ -80,14 +81,6 @@ public class PayWalletRechargePackageServiceImpl implements PayWalletRechargePac } } - @Override - public List getWalletRechargePackageList(Collection ids) { - if (CollUtil.isEmpty(ids)) { - return ListUtil.empty(); - } - return walletRechargePackageMapper.selectBatchIds(ids); - } - @Override public PageResult getWalletRechargePackagePage(WalletRechargePackagePageReqVO pageReqVO) { return walletRechargePackageMapper.selectPage(pageReqVO); diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletRechargeServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletRechargeServiceImpl.java index 3c29ac645..f09f78960 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletRechargeServiceImpl.java +++ b/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.*; public class PayWalletRechargeServiceImpl implements PayWalletRechargeService { /** - * TODO 放到 配置文件中 + * TODO 芋艿:放到 payconfig */ private static final Long WALLET_PAY_APP_ID = 8L; @@ -65,13 +65,14 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService { @Transactional(rollbackFor = Exception.class) public PayWalletRechargeDO createWalletRecharge(Long userId, Integer userType, AppPayWalletRechargeCreateReqVO reqVO) { - // 1.1 校验参数 + // 1.1 校验参数 TODO @jason:AppPayWalletRechargeCreateReqVO 看下校验; if (Objects.isNull(reqVO.getPayPrice()) && Objects.isNull(reqVO.getPackageId())) { throw exception(WALLET_RECHARGE_PACKAGE_AND_PRICE_IS_EMPTY); } - // 1.2 新增钱包充值记录 - int payPrice ; - int bonusPrice = 0 ; + + // 1.1 计算充值金额 + int payPrice; + int bonusPrice = 0; if (Objects.nonNull(reqVO.getPackageId())) { PayWalletRechargePackageDO rechargePackage = payWalletRechargePackageService.validWalletRechargePackage(reqVO.getPackageId()); payPrice = rechargePackage.getPayPrice(); @@ -79,23 +80,22 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService { } else { payPrice = reqVO.getPayPrice(); } - + // 1.2 插入充值记录 PayWalletDO wallet = payWalletService.getOrCreateWallet(userId, userType); - PayWalletRechargeDO walletRecharge = INSTANCE.convert(wallet.getId(), payPrice, bonusPrice, reqVO.getPackageId()); - walletRechargeMapper.insert(walletRecharge); + PayWalletRechargeDO recharge = INSTANCE.convert(wallet.getId(), payPrice, bonusPrice, reqVO.getPackageId()); + walletRechargeMapper.insert(recharge); // 2.1 创建支付单 Long payOrderId = payOrderService.createOrder(new PayOrderCreateReqDTO() - .setAppId(WALLET_PAY_APP_ID).setUserIp(getClientIP()) - .setMerchantOrderId(walletRecharge.getId().toString()) // 业务的订单编号 - .setSubject(WALLET_RECHARGE_ORDER_SUBJECT).setBody("").setPrice(walletRecharge.getPayPrice()) - .setExpireTime(addTime(Duration.ofHours(2L)))); + .setAppId(WALLET_PAY_APP_ID).setUserIp(getClientIP()) // TODO @jason:clientIp 从 controller 传递进来噢 + .setMerchantOrderId(recharge.getId().toString()) // 业务的订单编号 + .setSubject(WALLET_RECHARGE_ORDER_SUBJECT).setBody("") + .setPrice(recharge.getPayPrice()) + .setExpireTime(addTime(Duration.ofHours(2L)))); // TODO @芋艿:支付超时时间 // 2.2 更新钱包充值记录中支付订单 - walletRechargeMapper.updateById(new PayWalletRechargeDO().setPayOrderId(payOrderId) - .setId(walletRecharge.getId())); - - walletRecharge.setPayOrderId(payOrderId); - return walletRecharge; + walletRechargeMapper.updateById(new PayWalletRechargeDO().setId(recharge.getId()).setPayOrderId(payOrderId)); + recharge.setPayOrderId(payOrderId); + return recharge; } @Override @@ -136,9 +136,11 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService { } // 1.2 校验钱包充值是否可以发起退款 PayWalletDO wallet = validateWalletRechargeCanRefund(walletRecharge); - // 2 冻结退款的余额, 暂时只处理赠送的余额也全部退回 + + // 2. 冻结退款的余额,暂时只处理赠送的余额也全部退回 payWalletService.freezePrice(wallet.getId(), walletRecharge.getTotalPrice()); - // 3 创建退款单 + + // 3. 创建退款单 String walletRechargeId = String.valueOf(id); String refundId = walletRechargeId + "-refund"; Long payRefundId = payRefundService.createPayRefund(new PayRefundCreateReqDTO() @@ -146,7 +148,9 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService { .setMerchantOrderId(walletRechargeId) .setMerchantRefundId(refundId) .setReason("想退钱").setPrice(walletRecharge.getPayPrice())); - // 4 更新充值记录退款单号 + + // 4. 更新充值记录退款单号 + // TODO @jaosn:一般新建这种 update 对象,建议是,第一个 set id 属性,容易知道以它为更新 walletRechargeMapper.updateById(new PayWalletRechargeDO().setPayRefundId(payRefundId) .setRefundStatus(WAITING.getStatus()).setId(walletRecharge.getId())); } @@ -229,6 +233,7 @@ public class PayWalletRechargeServiceImpl implements PayWalletRechargeService { if (wallet.getBalance() < walletRecharge.getTotalPrice()) { throw exception(WALLET_RECHARGE_REFUND_BALANCE_NOT_ENOUGH); } + // TODO @芋艿:需要考虑下,赠送的金额,会不会导致提现超过; return wallet; } diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletService.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletService.java index 3e72099b4..0a6de3ef4 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletService.java +++ b/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 { */ void freezePrice(Long id, Integer price); + // TODO @jason:unfreeze 是单词哈,f 不用大写 /** * 解冻钱包余额 * diff --git a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletServiceImpl.java b/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletServiceImpl.java index 6f52abd67..b76d2028d 100644 --- a/yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/wallet/PayWalletServiceImpl.java +++ b/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 { if (walletTransaction == null) { throw exception(WALLET_TRANSACTION_NOT_FOUND); } + // 2. 校验退款是否存在 PayWalletTransactionDO refundTransaction = walletTransactionService.getWalletTransaction( String.valueOf(refundId), PAYMENT_REFUND); if (refundTransaction != null) { @@ -128,7 +129,7 @@ public class PayWalletServiceImpl implements PayWalletService { } // 2.1 扣除余额 - int updateCounts = 0 ; + int updateCounts; switch (bizType) { case PAYMENT: { updateCounts = walletMapper.updateWhenConsumption(payWallet.getId(), price); From d256275099a57a95ae36cbf883298b637e2fd7be Mon Sep 17 00:00:00 2001 From: YunaiV Date: Wed, 18 Oct 2023 23:48:14 +0800 Subject: [PATCH 3/7] =?UTF-8?q?saas=EF=BC=9A=E6=94=AF=E6=8C=81=E7=A4=BE?= =?UTF-8?q?=E4=BA=A4=E5=BA=94=E7=94=A8=E7=9A=84=E5=A4=9A=E7=A7=9F=E6=88=B7?= =?UTF-8?q?=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sql/mysql/ruoyi-vue-pro.sql | 69 ++++++++---- .../order/core/aop/TradeOrderLogAspect.java | 4 - .../service/auth/MemberAuthServiceImpl.java | 5 +- .../system/api/social/SocialClientApi.java | 22 ++++ .../system/api/social/SocialUserApi.java | 10 -- .../api/social/dto/SocialUserBindReqDTO.java | 2 +- .../social/dto/SocialUserUnbindReqDTO.java | 8 +- .../system/enums/social/SocialTypeEnum.java | 18 ++- .../api/social/SocialClientApiImpl.java | 26 +++++ .../system/api/social/SocialUserApiImpl.java | 7 +- .../controller/admin/auth/AuthController.java | 7 +- .../dal/dataobject/social/SocialClientDO.java | 68 ++++++++++++ .../dal/mysql/social/SocialClientMapper.java | 15 +++ .../service/social/SocialClientService.java | 34 ++++++ .../social/SocialClientServiceImpl.java | 94 ++++++++++++++++ .../service/social/SocialUserService.java | 22 ---- .../service/social/SocialUserServiceImpl.java | 104 +++++++----------- 17 files changed, 375 insertions(+), 140 deletions(-) create mode 100644 yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/social/SocialClientApi.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/social/SocialClientApiImpl.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/social/SocialClientDO.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/social/SocialClientMapper.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialClientService.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialClientServiceImpl.java diff --git a/sql/mysql/ruoyi-vue-pro.sql b/sql/mysql/ruoyi-vue-pro.sql index 0406d9f64..6a409619a 100644 --- a/sql/mysql/ruoyi-vue-pro.sql +++ b/sql/mysql/ruoyi-vue-pro.sql @@ -11,7 +11,7 @@ Target Server Version : 80034 File Encoding : 65001 - Date: 17/10/2023 23:22:59 + Date: 18/10/2023 23:33:15 */ SET NAMES utf8mb4; @@ -384,7 +384,7 @@ CREATE TABLE `infra_api_error_log` ( `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 1735 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '系统异常日志'; +) ENGINE = InnoDB AUTO_INCREMENT = 1739 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '系统异常日志'; -- ---------------------------- -- Records of infra_api_error_log @@ -422,7 +422,7 @@ CREATE TABLE `infra_codegen_column` ( `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 1804 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '代码生成表字段定义'; +) ENGINE = InnoDB AUTO_INCREMENT = 1805 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '代码生成表字段定义'; -- ---------------------------- -- Records of infra_codegen_column @@ -455,7 +455,7 @@ CREATE TABLE `infra_codegen_table` ( `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 136 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '代码生成表定义'; +) ENGINE = InnoDB AUTO_INCREMENT = 137 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '代码生成表定义'; -- ---------------------------- -- Records of infra_codegen_table @@ -615,7 +615,7 @@ CREATE TABLE `infra_job` ( `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 27 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '定时任务表'; +) ENGINE = InnoDB AUTO_INCREMENT = 28 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '定时任务表'; -- ---------------------------- -- Records of infra_job @@ -656,7 +656,7 @@ CREATE TABLE `infra_job_log` ( `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 232 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '定时任务日志表'; +) ENGINE = InnoDB AUTO_INCREMENT = 233 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '定时任务日志表'; -- ---------------------------- -- Records of infra_job_log @@ -709,7 +709,7 @@ CREATE TABLE `member_address` ( `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', PRIMARY KEY (`id`) USING BTREE, INDEX `idx_userId`(`user_id` ASC) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 24 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin COMMENT = '用户收件地址'; +) ENGINE = InnoDB AUTO_INCREMENT = 25 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin COMMENT = '用户收件地址'; -- ---------------------------- -- Records of member_address @@ -768,7 +768,7 @@ CREATE TABLE `member_experience_record` ( PRIMARY KEY (`id`) USING BTREE, INDEX `idx_user_id`(`user_id` ASC) USING BTREE COMMENT '会员经验记录-用户编号', INDEX `idx_user_biz_type`(`user_id` ASC, `biz_type` ASC) USING BTREE COMMENT '会员经验记录-用户业务类型' -) ENGINE = InnoDB AUTO_INCREMENT = 40 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '会员经验记录'; +) ENGINE = InnoDB AUTO_INCREMENT = 41 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '会员经验记录'; -- ---------------------------- -- Records of member_experience_record @@ -883,7 +883,7 @@ CREATE TABLE `member_level_record` ( `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', PRIMARY KEY (`id`) USING BTREE, INDEX `idx_user_id`(`user_id` ASC) USING BTREE COMMENT '会员等级记录-用户编号' -) ENGINE = InnoDB AUTO_INCREMENT = 19 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '会员等级记录'; +) ENGINE = InnoDB AUTO_INCREMENT = 20 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '会员等级记录'; -- ---------------------------- -- Records of member_level_record @@ -913,7 +913,7 @@ CREATE TABLE `member_point_record` ( PRIMARY KEY (`id`) USING BTREE, INDEX `index_userId`(`user_id` ASC) USING BTREE, INDEX `index_title`(`title` ASC) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 59 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '用户积分记录'; +) ENGINE = InnoDB AUTO_INCREMENT = 60 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '用户积分记录'; -- ---------------------------- -- Records of member_point_record @@ -1540,7 +1540,7 @@ CREATE TABLE `system_error_code` ( `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 5932 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '错误码表'; +) ENGINE = InnoDB AUTO_INCREMENT = 5933 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '错误码表'; -- ---------------------------- -- Records of system_error_code @@ -1569,7 +1569,7 @@ CREATE TABLE `system_login_log` ( `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 2582 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '系统访问记录'; +) ENGINE = InnoDB AUTO_INCREMENT = 2599 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '系统访问记录'; -- ---------------------------- -- Records of system_login_log @@ -1634,7 +1634,7 @@ CREATE TABLE `system_mail_log` ( `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 354 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '邮件日志表'; +) ENGINE = InnoDB AUTO_INCREMENT = 355 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '邮件日志表'; -- ---------------------------- -- Records of system_mail_log @@ -2283,7 +2283,7 @@ CREATE TABLE `system_notify_template` ( `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '站内信模板表'; +) ENGINE = InnoDB AUTO_INCREMENT = 6 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '站内信模板表'; -- ---------------------------- -- Records of system_notify_template @@ -2311,7 +2311,7 @@ CREATE TABLE `system_oauth2_access_token` ( `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 3056 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'OAuth2 访问令牌'; +) ENGINE = InnoDB AUTO_INCREMENT = 3063 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'OAuth2 访问令牌'; -- ---------------------------- -- Records of system_oauth2_access_token @@ -2433,7 +2433,7 @@ CREATE TABLE `system_oauth2_refresh_token` ( `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 1063 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'OAuth2 刷新令牌'; +) ENGINE = InnoDB AUTO_INCREMENT = 1070 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = 'OAuth2 刷新令牌'; -- ---------------------------- -- Records of system_oauth2_refresh_token @@ -3481,7 +3481,7 @@ CREATE TABLE `system_sms_code` ( `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', PRIMARY KEY (`id`) USING BTREE, INDEX `idx_mobile`(`mobile` ASC) USING BTREE COMMENT '手机号' -) ENGINE = InnoDB AUTO_INCREMENT = 530 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '手机验证码'; +) ENGINE = InnoDB AUTO_INCREMENT = 531 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '手机验证码'; -- ---------------------------- -- Records of system_sms_code @@ -3574,6 +3574,33 @@ INSERT INTO `system_sms_template` (`id`, `type`, `status`, `code`, `name`, `cont INSERT INTO `system_sms_template` (`id`, `type`, `status`, `code`, `name`, `content`, `params`, `remark`, `api_template_id`, `channel_id`, `channel_code`, `creator`, `create_time`, `updater`, `update_time`, `deleted`) VALUES (16, 1, 0, 'user-reset-password', '会员用户 - 重置密码', '您的验证码{code},该验证码 5 分钟内有效,请勿泄漏于他人!', '[\"code\"]', '', 'null', 4, 'DEBUG_DING_TALK', '1', '2023-08-19 18:58:01', '1', '2023-08-19 11:34:18', b'0'); COMMIT; +-- ---------------------------- +-- Table structure for system_social_client +-- ---------------------------- +DROP TABLE IF EXISTS `system_social_client`; +CREATE TABLE `system_social_client` ( + `id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号', + `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '应用名', + `social_type` tinyint NOT NULL COMMENT '社交平台的类型', + `user_type` tinyint NOT NULL COMMENT '用户类型', + `client_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '客户端编号', + `client_secret` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '客户端密钥', + `status` tinyint NOT NULL COMMENT '状态', + `creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '创建者', + `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '' COMMENT '更新者', + `update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', + `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', + `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB AUTO_INCREMENT = 43 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '社交客户端表'; + +-- ---------------------------- +-- Records of system_social_client +-- ---------------------------- +BEGIN; +COMMIT; + -- ---------------------------- -- Table structure for system_social_user -- ---------------------------- @@ -3596,7 +3623,7 @@ CREATE TABLE `system_social_user` ( `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 21 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '社交用户表'; +) ENGINE = InnoDB AUTO_INCREMENT = 25 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '社交用户表'; -- ---------------------------- -- Records of system_social_user @@ -3621,7 +3648,7 @@ CREATE TABLE `system_social_user_bind` ( `deleted` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否删除', `tenant_id` bigint NOT NULL DEFAULT 0 COMMENT '租户编号', PRIMARY KEY (`id`) USING BTREE -) ENGINE = InnoDB AUTO_INCREMENT = 76 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '社交绑定表'; +) ENGINE = InnoDB AUTO_INCREMENT = 79 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '社交绑定表'; -- ---------------------------- -- Records of system_social_user_bind @@ -3797,7 +3824,7 @@ CREATE TABLE `system_users` ( -- Records of system_users -- ---------------------------- BEGIN; -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); +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); 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); 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); 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`, 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); 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); 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); -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); +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); 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); 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); 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); diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/order/core/aop/TradeOrderLogAspect.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/order/core/aop/TradeOrderLogAspect.java index 6c009ff25..ccdf91c61 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/framework/order/core/aop/TradeOrderLogAspect.java +++ b/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 { */ private static final ThreadLocal> EXTS = new ThreadLocal<>(); - public TradeOrderLogAspect() { - System.out.println(); - } - @Resource private TradeOrderLogService orderLogService; diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/auth/MemberAuthServiceImpl.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/auth/MemberAuthServiceImpl.java index 0b8557e50..ea8f6805b 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/auth/MemberAuthServiceImpl.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/auth/MemberAuthServiceImpl.java @@ -19,6 +19,7 @@ import cn.iocoder.yudao.module.system.api.oauth2.OAuth2TokenApi; import cn.iocoder.yudao.module.system.api.oauth2.dto.OAuth2AccessTokenCreateReqDTO; import cn.iocoder.yudao.module.system.api.oauth2.dto.OAuth2AccessTokenRespDTO; import cn.iocoder.yudao.module.system.api.sms.SmsCodeApi; +import cn.iocoder.yudao.module.system.api.social.SocialClientApi; import cn.iocoder.yudao.module.system.api.social.SocialUserApi; import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO; import cn.iocoder.yudao.module.system.api.social.dto.SocialUserRespDTO; @@ -56,6 +57,8 @@ public class MemberAuthServiceImpl implements MemberAuthService { @Resource private SocialUserApi socialUserApi; @Resource + private SocialClientApi socialClientApi; + @Resource private OAuth2TokenApi oauth2TokenApi; @Resource @@ -154,7 +157,7 @@ public class MemberAuthServiceImpl implements MemberAuthService { @Override public String getSocialAuthorizeUrl(Integer type, String redirectUri) { - return socialUserApi.getAuthorizeUrl(type, redirectUri); + return socialClientApi.getAuthorizeUrl(type, UserTypeEnum.MEMBER.getValue(), redirectUri); } private MemberUserDO login0(String mobile, String password) { diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/social/SocialClientApi.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/social/SocialClientApi.java new file mode 100644 index 000000000..0b12cabf4 --- /dev/null +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/social/SocialClientApi.java @@ -0,0 +1,22 @@ +package cn.iocoder.yudao.module.system.api.social; + +import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum; + +/** + * 社交应用的 API 接口 + * + * @author 芋道源码 + */ +public interface SocialClientApi { + + /** + * 获得社交平台的授权 URL + * + * @param type 社交平台的类型 {@link SocialTypeEnum} + * @param userType 用户类型 + * @param redirectUri 重定向 URL + * @return 社交平台的授权 URL + */ + String getAuthorizeUrl(Integer type, Integer userType, String redirectUri); + +} diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/social/SocialUserApi.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/social/SocialUserApi.java index c7c2fe459..2261a0cf0 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/social/SocialUserApi.java +++ b/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; import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO; import cn.iocoder.yudao.module.system.api.social.dto.SocialUserRespDTO; import cn.iocoder.yudao.module.system.api.social.dto.SocialUserUnbindReqDTO; -import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum; import javax.validation.Valid; @@ -15,15 +14,6 @@ import javax.validation.Valid; */ public interface SocialUserApi { - /** - * 获得社交平台的授权 URL - * - * @param type 社交平台的类型 {@link SocialTypeEnum} - * @param redirectUri 重定向 URL - * @return 社交平台的授权 URL - */ - String getAuthorizeUrl(Integer type, String redirectUri); - /** * 绑定社交用户 * diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/social/dto/SocialUserBindReqDTO.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/social/dto/SocialUserBindReqDTO.java index c591df2c3..f8f7154d7 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/social/dto/SocialUserBindReqDTO.java +++ b/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 { */ @InEnum(SocialTypeEnum.class) @NotNull(message = "社交平台的类型不能为空") - private Integer type; + private Integer socialType; /** * 授权码 */ diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/social/dto/SocialUserUnbindReqDTO.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/social/dto/SocialUserUnbindReqDTO.java index 56398a8ae..acf350866 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/social/dto/SocialUserUnbindReqDTO.java +++ b/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 { */ @InEnum(SocialTypeEnum.class) @NotNull(message = "社交平台的类型不能为空") - private Integer type; + private Integer socialType; /** - * 社交平台的 unionId + * 社交平台的 openid */ - @NotEmpty(message = "社交平台的 unionId 不能为空") - private String unionId; + @NotEmpty(message = "社交平台的 openid 不能为空") + private String openid; } diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/social/SocialTypeEnum.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/social/SocialTypeEnum.java index 197bb2943..602eb1e63 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/social/SocialTypeEnum.java +++ b/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 { /** * Gitee - * 文档链接:https://gitee.com/api/v5/oauth_doc#/ + * + * @see 接入文档 */ GITEE(10, "GITEE"), /** * 钉钉 - * 文档链接:https://developers.dingtalk.com/document/app/obtain-identity-credentials + * + * @see 接入文档 */ DINGTALK(20, "DINGTALK"), /** * 企业微信 - * 文档链接:https://xkcoding.com/2019/08/06/use-justauth-integration-wechat-enterprise.html + * + * @see 接入文档 */ WECHAT_ENTERPRISE(30, "WECHAT_ENTERPRISE"), /** * 微信公众平台 - 移动端 H5 - * 文档链接:https://www.cnblogs.com/juewuzhe/p/11905461.html + * + * @see 接入文档 */ WECHAT_MP(31, "WECHAT_MP"), /** * 微信开放平台 - 网站应用 PC 端扫码授权登录 - * 文档链接:https://justauth.wiki/guide/oauth/wechat_open/#_2-申请开发者资质认证 + * + * @see 接入文档 */ WECHAT_OPEN(32, "WECHAT_OPEN"), /** * 微信小程序 - * 文档链接:https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html + * + * @see 接入文档 */ WECHAT_MINI_APP(34, "WECHAT_MINI_APP"), ; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/social/SocialClientApiImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/social/SocialClientApiImpl.java new file mode 100644 index 000000000..b2e1ec8bb --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/social/SocialClientApiImpl.java @@ -0,0 +1,26 @@ +package cn.iocoder.yudao.module.system.api.social; + +import cn.iocoder.yudao.module.system.service.social.SocialClientService; +import org.springframework.stereotype.Service; +import org.springframework.validation.annotation.Validated; + +import javax.annotation.Resource; + +/** + * 社交应用的 API 实现类 + * + * @author 芋道源码 + */ +@Service +@Validated +public class SocialClientApiImpl implements SocialClientApi { + + @Resource + private SocialClientService socialClientService; + + @Override + public String getAuthorizeUrl(Integer type, Integer userType, String redirectUri) { + return socialClientService.getAuthorizeUrl(type, userType, redirectUri); + } + +} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/social/SocialUserApiImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/social/SocialUserApiImpl.java index d322952af..074382c01 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/social/SocialUserApiImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/social/SocialUserApiImpl.java @@ -21,11 +21,6 @@ public class SocialUserApiImpl implements SocialUserApi { @Resource private SocialUserService socialUserService; - @Override - public String getAuthorizeUrl(Integer type, String redirectUri) { - return socialUserService.getAuthorizeUrl(type, redirectUri); - } - @Override public String bindSocialUser(SocialUserBindReqDTO reqDTO) { return socialUserService.bindSocialUser(reqDTO); @@ -34,7 +29,7 @@ public class SocialUserApiImpl implements SocialUserApi { @Override public void unbindSocialUser(SocialUserUnbindReqDTO reqDTO) { socialUserService.unbindSocialUser(reqDTO.getUserId(), reqDTO.getUserType(), - reqDTO.getType(), reqDTO.getUnionId()); + reqDTO.getSocialType(), reqDTO.getOpenid()); } @Override diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/AuthController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/AuthController.java index e7fad37e1..ec702ea57 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/auth/AuthController.java +++ b/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; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; import cn.iocoder.yudao.framework.security.config.SecurityProperties; @@ -16,7 +17,7 @@ import cn.iocoder.yudao.module.system.service.auth.AdminAuthService; import cn.iocoder.yudao.module.system.service.permission.MenuService; import cn.iocoder.yudao.module.system.service.permission.PermissionService; import cn.iocoder.yudao.module.system.service.permission.RoleService; -import cn.iocoder.yudao.module.system.service.social.SocialUserService; +import cn.iocoder.yudao.module.system.service.social.SocialClientService; import cn.iocoder.yudao.module.system.service.user.AdminUserService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; @@ -57,7 +58,7 @@ public class AuthController { @Resource private PermissionService permissionService; @Resource - private SocialUserService socialUserService; + private SocialClientService socialClientService; @Resource private SecurityProperties securityProperties; @@ -147,7 +148,7 @@ public class AuthController { }) public CommonResult socialLogin(@RequestParam("type") Integer type, @RequestParam("redirectUri") String redirectUri) { - return CommonResult.success(socialUserService.getAuthorizeUrl(type, redirectUri)); + return success(socialClientService.getAuthorizeUrl(type, UserTypeEnum.ADMIN.getValue(), redirectUri)); } @PostMapping("/social-login") diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/social/SocialClientDO.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/social/SocialClientDO.java new file mode 100644 index 000000000..76097898a --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/social/SocialClientDO.java @@ -0,0 +1,68 @@ +package cn.iocoder.yudao.module.system.dal.dataobject.social; + +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; +import cn.iocoder.yudao.framework.tenant.core.db.TenantBaseDO; +import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum; +import com.baomidou.mybatisplus.annotation.KeySequence; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.xingyuv.jushauth.config.AuthConfig; +import lombok.*; + +/** + * 社交客户端 DO + * + * 对应 {@link AuthConfig} 配置,满足不同租户,有自己的客户端配置,实现社交(三方)登录 + * + * @author 芋道源码 + */ +@TableName(value = "system_social_client", autoResultMap = true) +@KeySequence("system_social_client_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。 +@Data +@EqualsAndHashCode(callSuper = true) +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class SocialClientDO extends TenantBaseDO { + + /** + * 编号,自增 + */ + @TableId + private Long id; + /** + * 应用名 + */ + private String name; + /** + * 社交类型 + * + * 枚举 {@link SocialTypeEnum} + */ + private Integer socialType; + /** + * 用户类型 + * + * 目的:不同用户类型,对应不同的小程序,需要自己的配置 + * + * 枚举 {@link UserTypeEnum} + */ + private Integer userType; + /** + * 状态 + * + * 枚举 {@link CommonStatusEnum} + */ + private Integer status; + + /** + * 客户端 id + */ + private String clientId; + /** + * 客户端 Secret + */ + private String clientSecret; + +} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/social/SocialClientMapper.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/social/SocialClientMapper.java new file mode 100644 index 000000000..5d36fafa6 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/social/SocialClientMapper.java @@ -0,0 +1,15 @@ +package cn.iocoder.yudao.module.system.dal.mysql.social; + +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; +import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialClientDO; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface SocialClientMapper extends BaseMapperX { + + default SocialClientDO selectBySocialTypeAndUserType(Integer socialType, Integer userType) { + return selectOne(SocialClientDO::getSocialType, socialType, + SocialClientDO::getUserType, userType); + } + +} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialClientService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialClientService.java new file mode 100644 index 000000000..fbf885ca7 --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialClientService.java @@ -0,0 +1,34 @@ +package cn.iocoder.yudao.module.system.service.social; + +import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum; +import com.xingyuv.jushauth.model.AuthUser; + +/** + * 社交应用 Service 接口 + * + * @author 芋道源码 + */ +public interface SocialClientService { + + /** + * 获得社交平台的授权 URL + * + * @param socialType 社交平台的类型 {@link SocialTypeEnum} + * @param userType 用户类型 + * @param redirectUri 重定向 URL + * @return 社交平台的授权 URL + */ + String getAuthorizeUrl(Integer socialType, Integer userType, String redirectUri); + + /** + * 请求社交平台,获得授权的用户 + * + * @param socialType 社交平台的类型 + * @param userType 用户类型 + * @param code 授权码 + * @param state 授权 state + * @return 授权的用户 + */ + AuthUser getAuthUser(Integer socialType, Integer userType, String code, String state); + +} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialClientServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialClientServiceImpl.java new file mode 100644 index 000000000..071ebd1ba --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialClientServiceImpl.java @@ -0,0 +1,94 @@ +package cn.iocoder.yudao.module.system.service.social; + +import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.lang.Assert; +import cn.hutool.core.util.ReflectUtil; +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.framework.common.util.http.HttpUtils; +import cn.iocoder.yudao.framework.social.core.YudaoAuthRequestFactory; +import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialClientDO; +import cn.iocoder.yudao.module.system.dal.mysql.social.SocialClientMapper; +import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum; +import com.xingyuv.jushauth.config.AuthConfig; +import com.xingyuv.jushauth.model.AuthCallback; +import com.xingyuv.jushauth.model.AuthResponse; +import com.xingyuv.jushauth.model.AuthUser; +import com.xingyuv.jushauth.request.AuthRequest; +import com.xingyuv.jushauth.utils.AuthStateUtils; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.Objects; + +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; +import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString; +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.SOCIAL_USER_AUTH_FAILURE; + +/** + * 社交应用 Service 实现类 + * + * @author 芋道源码 + */ +@Service +@Slf4j +public class SocialClientServiceImpl implements SocialClientService { + + @Resource // 由于自定义了 YudaoAuthRequestFactory 无法覆盖默认的 AuthRequestFactory,所以只能注入它 + private YudaoAuthRequestFactory yudaoAuthRequestFactory; + + @Resource + private SocialClientMapper socialClientMapper; + + @Override + public String getAuthorizeUrl(Integer socialType, Integer userType, String redirectUri) { + // 获得对应的 AuthRequest 实现 + AuthRequest authRequest = buildAuthRequest(socialType, userType); + // 生成跳转地址 + String authorizeUri = authRequest.authorize(AuthStateUtils.createState()); + return HttpUtils.replaceUrlQuery(authorizeUri, "redirect_uri", redirectUri); + } + + @Override + public AuthUser getAuthUser(Integer socialType, Integer userType, String code, String state) { + // 构建请求 + AuthRequest authRequest = buildAuthRequest(socialType, userType); + AuthCallback authCallback = AuthCallback.builder().code(code).state(state).build(); + // 执行请求 + AuthResponse authResponse = authRequest.login(authCallback); + log.info("[getAuthUser][请求社交平台 type({}) request({}) response({})]", socialType, + toJsonString(authCallback), toJsonString(authResponse)); + if (!authResponse.ok()) { + throw exception(SOCIAL_USER_AUTH_FAILURE, authResponse.getMsg()); + } + return (AuthUser) authResponse.getData(); + } + + /** + * 构建 AuthRequest 对象,支持多租户配置 + * + * @param socialType 社交类型 + * @param userType 用户类型 + * @return AuthRequest 对象 + */ + private AuthRequest buildAuthRequest(Integer socialType, Integer userType) { + // 1. 先查找默认的配置项,从 application-*.yaml 中读取 + AuthRequest request = yudaoAuthRequestFactory.get(SocialTypeEnum.valueOfType(socialType).getSource()); + Assert.notNull(request, String.format("社交平台(%d) 不存在", socialType)); + // 2. 查询 DB 的配置项,如果存在则进行覆盖 + SocialClientDO client = socialClientMapper.selectBySocialTypeAndUserType(socialType, userType); + if (client != null && Objects.equals(client.getStatus(), CommonStatusEnum.ENABLE.getStatus())) { + // 2.1 构造新的 AuthConfig 对象 + AuthConfig authConfig = (AuthConfig) ReflectUtil.getFieldValue(request, "config"); + AuthConfig newAuthConfig = ReflectUtil.newInstance(authConfig.getClass()); + BeanUtil.copyProperties(authConfig, newAuthConfig); + // 2.2 修改对应的 clientId + clientSecret 密钥 + newAuthConfig.setClientId(client.getClientId()); + newAuthConfig.setClientSecret(client.getClientSecret()); + // 2.3 设置会 request 里,进行后续使用 + ReflectUtil.setFieldValue(request, "config", newAuthConfig); + } + return request; + } + +} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialUserService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialUserService.java index bc776ec60..4818f9d95 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialUserService.java +++ b/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; import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum; import javax.validation.Valid; -import javax.validation.constraints.NotNull; import java.util.List; /** @@ -17,27 +16,6 @@ import java.util.List; */ public interface SocialUserService { - /** - * 获得社交平台的授权 URL - * - * @param type 社交平台的类型 {@link SocialTypeEnum} - * @param redirectUri 重定向 URL - * @return 社交平台的授权 URL - */ - String getAuthorizeUrl(Integer type, String redirectUri); - - /** - * 授权获得对应的社交用户 - * 如果授权失败,则会抛出 {@link ServiceException} 异常 - * - * @param type 社交平台的类型 {@link SocialTypeEnum} - * @param code 授权码 - * @param state state - * @return 授权用户 - */ - @NotNull - SocialUserDO authSocialUser(Integer type, String code, String state); - /** * 获得指定用户的社交用户列表 * diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialUserServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialUserServiceImpl.java index bd5548af7..70c94d5bc 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialUserServiceImpl.java +++ b/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; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.lang.Assert; -import cn.iocoder.yudao.framework.common.util.http.HttpUtils; -import cn.iocoder.yudao.framework.social.core.YudaoAuthRequestFactory; +import cn.iocoder.yudao.framework.common.exception.ServiceException; import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO; import cn.iocoder.yudao.module.system.api.social.dto.SocialUserRespDTO; import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialUserBindDO; @@ -11,24 +10,22 @@ import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialUserDO; import cn.iocoder.yudao.module.system.dal.mysql.social.SocialUserBindMapper; import cn.iocoder.yudao.module.system.dal.mysql.social.SocialUserMapper; import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum; -import com.xingyuv.jushauth.model.AuthCallback; -import com.xingyuv.jushauth.model.AuthResponse; import com.xingyuv.jushauth.model.AuthUser; -import com.xingyuv.jushauth.request.AuthRequest; -import com.xingyuv.jushauth.utils.AuthStateUtils; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; +import javax.validation.constraints.NotNull; import java.util.Collections; import java.util.List; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString; -import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.AUTH_THIRD_LOGIN_NOT_BIND; +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.SOCIAL_USER_NOT_FOUND; /** * 社交用户 Service 实现类 @@ -40,51 +37,13 @@ import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; @Slf4j public class SocialUserServiceImpl implements SocialUserService { - @Resource// 由于自定义了 YudaoAuthRequestFactory 无法覆盖默认的 AuthRequestFactory,所以只能注入它 - private YudaoAuthRequestFactory yudaoAuthRequestFactory; - @Resource private SocialUserBindMapper socialUserBindMapper; @Resource private SocialUserMapper socialUserMapper; - @Override - public String getAuthorizeUrl(Integer type, String redirectUri) { - // 获得对应的 AuthRequest 实现 - AuthRequest authRequest = yudaoAuthRequestFactory.get(SocialTypeEnum.valueOfType(type).getSource()); - // 生成跳转地址 - String authorizeUri = authRequest.authorize(AuthStateUtils.createState()); - return HttpUtils.replaceUrlQuery(authorizeUri, "redirect_uri", redirectUri); - } - - @Override - public SocialUserDO authSocialUser(Integer type, String code, String state) { - // 优先从 DB 中获取,因为 code 有且可以使用一次。 - // 在社交登录时,当未绑定 User 时,需要绑定登录,此时需要 code 使用两次 - SocialUserDO socialUser = socialUserMapper.selectByTypeAndCodeAnState(type, code, state); - if (socialUser != null) { - return socialUser; - } - - // 请求获取 - AuthUser authUser = getAuthUser(type, code, state); - Assert.notNull(authUser, "三方用户不能为空"); - - // 保存到 DB 中 - socialUser = socialUserMapper.selectByTypeAndOpenid(type, authUser.getUuid()); - if (socialUser == null) { - socialUser = new SocialUserDO(); - } - socialUser.setType(type).setCode(code).setState(state) // 需要保存 code + state 字段,保证后续可查询 - .setOpenid(authUser.getUuid()).setToken(authUser.getToken().getAccessToken()).setRawTokenInfo((toJsonString(authUser.getToken()))) - .setNickname(authUser.getNickname()).setAvatar(authUser.getAvatar()).setRawUserInfo(toJsonString(authUser.getRawUserInfo())); - if (socialUser.getId() == null) { - socialUserMapper.insert(socialUser); - } else { - socialUserMapper.updateById(socialUser); - } - return socialUser; - } + @Resource + private SocialClientService socialClientService; @Override public List getSocialUserList(Long userId, Integer userType) { @@ -101,7 +60,8 @@ public class SocialUserServiceImpl implements SocialUserService { @Transactional public String bindSocialUser(SocialUserBindReqDTO reqDTO) { // 获得社交用户 - SocialUserDO socialUser = authSocialUser(reqDTO.getType(), reqDTO.getCode(), reqDTO.getState()); + SocialUserDO socialUser = authSocialUser(reqDTO.getSocialType(), reqDTO.getUserType(), + reqDTO.getCode(), reqDTO.getState()); Assert.notNull(socialUser, "社交用户不能为空"); // 社交用户可能之前绑定过别的用户,需要进行解绑 @@ -134,7 +94,7 @@ public class SocialUserServiceImpl implements SocialUserService { @Override public SocialUserRespDTO getSocialUser(Integer userType, Integer type, String code, String state) { // 获得社交用户 - SocialUserDO socialUser = authSocialUser(type, code, state); + SocialUserDO socialUser = authSocialUser(type, userType, code, state); Assert.notNull(socialUser, "社交用户不能为空"); // 如果未绑定的社交用户,则无法自动登录,进行报错 @@ -146,24 +106,44 @@ public class SocialUserServiceImpl implements SocialUserService { return new SocialUserRespDTO(socialUser.getOpenid(), socialUserBind.getUserId()); } + // TODO 芋艿:调整下单测 /** - * 请求社交平台,获得授权的用户 + * 授权获得对应的社交用户 + * 如果授权失败,则会抛出 {@link ServiceException} 异常 * - * @param type 社交平台的类型 + * @param type 社交平台的类型 {@link SocialTypeEnum} + * @param userType 用户类型 * @param code 授权码 - * @param state 授权 state - * @return 授权的用户 + * @param state state + * @return 授权用户 */ - private AuthUser getAuthUser(Integer type, String code, String state) { - AuthRequest authRequest = yudaoAuthRequestFactory.get(SocialTypeEnum.valueOfType(type).getSource()); - AuthCallback authCallback = AuthCallback.builder().code(code).state(state).build(); - AuthResponse authResponse = authRequest.login(authCallback); - log.info("[getAuthUser][请求社交平台 type({}) request({}) response({})]", type, - toJsonString(authCallback), toJsonString(authResponse)); - if (!authResponse.ok()) { - throw exception(SOCIAL_USER_AUTH_FAILURE, authResponse.getMsg()); + @NotNull + public SocialUserDO authSocialUser(Integer type, Integer userType, String code, String state) { + // 优先从 DB 中获取,因为 code 有且可以使用一次。 + // 在社交登录时,当未绑定 User 时,需要绑定登录,此时需要 code 使用两次 + SocialUserDO socialUser = socialUserMapper.selectByTypeAndCodeAnState(type, code, state); + if (socialUser != null) { + return socialUser; } - return (AuthUser) authResponse.getData(); + + // 请求获取 + AuthUser authUser = socialClientService.getAuthUser(type, userType, code, state); + Assert.notNull(authUser, "三方用户不能为空"); + + // 保存到 DB 中 + socialUser = socialUserMapper.selectByTypeAndOpenid(type, authUser.getUuid()); + if (socialUser == null) { + socialUser = new SocialUserDO(); + } + socialUser.setType(type).setCode(code).setState(state) // 需要保存 code + state 字段,保证后续可查询 + .setOpenid(authUser.getUuid()).setToken(authUser.getToken().getAccessToken()).setRawTokenInfo((toJsonString(authUser.getToken()))) + .setNickname(authUser.getNickname()).setAvatar(authUser.getAvatar()).setRawUserInfo(toJsonString(authUser.getRawUserInfo())); + if (socialUser.getId() == null) { + socialUserMapper.insert(socialUser); + } else { + socialUserMapper.updateById(socialUser); + } + return socialUser; } } From 6f757e5297d7e77f9906b7265cb3545ddb41a016 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Thu, 19 Oct 2023 12:54:44 +0800 Subject: [PATCH 4/7] =?UTF-8?q?saas=EF=BC=9A=E6=94=AF=E6=8C=81=E7=A4=BE?= =?UTF-8?q?=E4=BA=A4=E5=BA=94=E7=94=A8=E7=9A=84=E5=A4=9A=E7=A7=9F=E6=88=B7?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=EF=BC=88mp=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/auth/AppAuthController.http | 5 ++ .../app/auth/AppAuthController.java | 16 ++++ .../vo/AuthWeixinJsapiSignatureRespVO.java | 31 +++++++ .../member/convert/auth/AuthConvert.java | 3 + .../system/api/social/SocialClientApi.java | 10 +++ .../dto/SocialWxJsapiSignatureRespDTO.java | 34 ++++++++ .../api/social/SocialClientApiImpl.java | 9 ++ .../system/controller/app/package-info.java | 4 - .../app/weixin/AppWxMpController.http | 4 - .../app/weixin/AppWxMpController.java | 38 --------- .../convert/social/SocialClientConvert.java | 15 ++++ .../service/social/SocialClientService.java | 10 +++ .../social/SocialClientServiceImpl.java | 83 +++++++++++++++++++ 13 files changed, 216 insertions(+), 46 deletions(-) create mode 100644 yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AuthWeixinJsapiSignatureRespVO.java create mode 100644 yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/social/dto/SocialWxJsapiSignatureRespDTO.java delete mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/package-info.java delete mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/weixin/AppWxMpController.http delete mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/weixin/AppWxMpController.java create mode 100644 yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/social/SocialClientConvert.java diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/AppAuthController.http b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/AppAuthController.http index 648802b80..998c70c21 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/AppAuthController.http +++ b/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}} POST {{appApi}}/member/auth/refresh-token?refreshToken=bc43d929094849a28b3a69f6e6940d70 Content-Type: application/json tenant-id: {{appTenentId}} + +### 请求 /auth/create-weixin-jsapi-signature 接口 => 成功 +POST {{appApi}}/member/auth/create-weixin-jsapi-signature?url=http://www.iocoder.cn +Authorization: Bearer {{appToken}} +tenant-id: {{appTenentId}} diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/AppAuthController.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/AppAuthController.java index 0765df143..ed3963e90 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/AppAuthController.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/AppAuthController.java @@ -1,12 +1,16 @@ package cn.iocoder.yudao.module.member.controller.app.auth; import cn.hutool.core.util.StrUtil; +import cn.iocoder.yudao.framework.common.enums.UserTypeEnum; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog; import cn.iocoder.yudao.framework.security.config.SecurityProperties; import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils; import cn.iocoder.yudao.module.member.controller.app.auth.vo.*; +import cn.iocoder.yudao.module.member.convert.auth.AuthConvert; import cn.iocoder.yudao.module.member.service.auth.MemberAuthService; +import cn.iocoder.yudao.module.system.api.social.SocialClientApi; +import cn.iocoder.yudao.module.system.api.social.dto.SocialWxJsapiSignatureRespDTO; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Parameters; @@ -33,6 +37,9 @@ public class AppAuthController { @Resource private MemberAuthService authService; + @Resource + private SocialClientApi socialClientApi; + @Resource private SecurityProperties securityProperties; @@ -109,4 +116,13 @@ public class AppAuthController { return success(authService.weixinMiniAppLogin(reqVO)); } + @PostMapping("/create-weixin-jsapi-signature") + @Operation(summary = "创建微信 JS SDK 初始化所需的签名", + description = "参考 https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html 文档") + public CommonResult createWeixinMpJsapiSignature(@RequestParam("url") String url) { + SocialWxJsapiSignatureRespDTO signature = socialClientApi.createWxMpJsapiSignature( + UserTypeEnum.MEMBER.getValue(), url); + return success(AuthConvert.INSTANCE.convert(signature)); + } + } diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AuthWeixinJsapiSignatureRespVO.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AuthWeixinJsapiSignatureRespVO.java new file mode 100644 index 000000000..37e63652b --- /dev/null +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/controller/app/auth/vo/AuthWeixinJsapiSignatureRespVO.java @@ -0,0 +1,31 @@ +package cn.iocoder.yudao.module.member.controller.app.auth.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Schema(description = "用户 APP - 微信公众号 JSAPI 签名 Response VO") +@Data +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class AuthWeixinJsapiSignatureRespVO { + + @Schema(description = "微信公众号的 appId", requiredMode = Schema.RequiredMode.REQUIRED, example = "hello") + private String appId; + + @Schema(description = "匿名串", requiredMode = Schema.RequiredMode.REQUIRED, example = "world") + private String nonceStr; + + @Schema(description = "时间戳", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") + private Long timestamp; + + @Schema(description = "URL", requiredMode = Schema.RequiredMode.REQUIRED, example = "https://www.iocoder.cn") + private String url; + + @Schema(description = "签名", requiredMode = Schema.RequiredMode.REQUIRED, example = "阿巴阿巴") + private String signature; + +} diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/auth/AuthConvert.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/auth/AuthConvert.java index 08c9b59ea..29e8f4fdc 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/convert/auth/AuthConvert.java +++ b/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; import cn.iocoder.yudao.module.system.api.sms.dto.code.SmsCodeValidateReqDTO; import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO; import cn.iocoder.yudao.module.system.api.social.dto.SocialUserUnbindReqDTO; +import cn.iocoder.yudao.module.system.api.social.dto.SocialWxJsapiSignatureRespDTO; import cn.iocoder.yudao.module.system.enums.sms.SmsSceneEnum; import org.mapstruct.Mapper; import org.mapstruct.factory.Mappers; @@ -29,4 +30,6 @@ public interface AuthConvert { SmsCodeValidateReqDTO convert(AppAuthSmsValidateReqVO bean); + SocialWxJsapiSignatureRespDTO convert(SocialWxJsapiSignatureRespDTO bean); + } diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/social/SocialClientApi.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/social/SocialClientApi.java index 0b12cabf4..e308d2b7b 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/social/SocialClientApi.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/social/SocialClientApi.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.system.api.social; +import cn.iocoder.yudao.module.system.api.social.dto.SocialWxJsapiSignatureRespDTO; import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum; /** @@ -19,4 +20,13 @@ public interface SocialClientApi { */ String getAuthorizeUrl(Integer type, Integer userType, String redirectUri); + /** + * 创建微信 JS SDK 初始化所需的签名 + * + * @param userType 用户类型 + * @param url 访问的 URL 地址 + * @return 签名 + */ + SocialWxJsapiSignatureRespDTO createWxMpJsapiSignature(Integer userType, String url); + } diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/social/dto/SocialWxJsapiSignatureRespDTO.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/social/dto/SocialWxJsapiSignatureRespDTO.java new file mode 100644 index 000000000..7d332e926 --- /dev/null +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/social/dto/SocialWxJsapiSignatureRespDTO.java @@ -0,0 +1,34 @@ +package cn.iocoder.yudao.module.system.api.social.dto; + +import lombok.Data; + +/** + * 微信公众号 JSAPI 签名 Response DTO + * + * @author 芋道源码 + */ +@Data +public class SocialWxJsapiSignatureRespDTO { + + /** + * 微信公众号的 appId + */ + private String appId; + /** + * 匿名串 + */ + private String nonceStr; + /** + * 时间戳 + */ + private Long timestamp; + /** + * URL + */ + private String url; + /** + * 签名 + */ + private String signature; + +} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/social/SocialClientApiImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/social/SocialClientApiImpl.java index b2e1ec8bb..d0f2a800e 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/social/SocialClientApiImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/social/SocialClientApiImpl.java @@ -1,6 +1,9 @@ package cn.iocoder.yudao.module.system.api.social; +import cn.iocoder.yudao.module.system.api.social.dto.SocialWxJsapiSignatureRespDTO; +import cn.iocoder.yudao.module.system.convert.social.SocialClientConvert; import cn.iocoder.yudao.module.system.service.social.SocialClientService; +import me.chanjar.weixin.common.bean.WxJsapiSignature; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; @@ -23,4 +26,10 @@ public class SocialClientApiImpl implements SocialClientApi { return socialClientService.getAuthorizeUrl(type, userType, redirectUri); } + @Override + public SocialWxJsapiSignatureRespDTO createWxMpJsapiSignature(Integer userType, String url) { + WxJsapiSignature signature = socialClientService.createWxMpJsapiSignature(userType, url); + return SocialClientConvert.INSTANCE.convert(signature); + } + } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/package-info.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/package-info.java deleted file mode 100644 index 9e4739f4c..000000000 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * 占位,避免 package 无法提交到 Git 仓库 - */ -package cn.iocoder.yudao.module.system.controller.app; diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/weixin/AppWxMpController.http b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/weixin/AppWxMpController.http deleted file mode 100644 index 6af305aef..000000000 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/weixin/AppWxMpController.http +++ /dev/null @@ -1,4 +0,0 @@ -### 请求 /login 接口 => 成功 -POST {{appApi}}/system/wx-mp/create-jsapi-signature?url=http://www.iocoder.cn -Authorization: Bearer {{appToken}} -tenant-id: {{appTenentId}} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/weixin/AppWxMpController.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/weixin/AppWxMpController.java deleted file mode 100644 index e6e91b669..000000000 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/app/weixin/AppWxMpController.java +++ /dev/null @@ -1,38 +0,0 @@ -package cn.iocoder.yudao.module.system.controller.app.weixin; - -import cn.iocoder.yudao.framework.common.pojo.CommonResult; -import io.swagger.v3.oas.annotations.tags.Tag; -import io.swagger.v3.oas.annotations.Operation; -import lombok.extern.slf4j.Slf4j; -import me.chanjar.weixin.common.bean.WxJsapiSignature; -import me.chanjar.weixin.common.error.WxErrorException; -import me.chanjar.weixin.mp.api.WxMpService; -import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -import javax.annotation.Resource; - -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; - -@Tag(name = "微信公众号") -@RestController -@RequestMapping("/system/wx-mp") -@Validated -@Slf4j -public class AppWxMpController { - - @Resource - private WxMpService mpService; - - // TODO @芋艿:需要额外考虑个问题;多租户下,如果每个小程序一个微信公众号,则会存在多个 appid; - @PostMapping("/create-jsapi-signature") - @Operation(summary = "创建微信 JS SDK 初始化所需的签名", - description = "参考 https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html 文档") - public CommonResult createJsapiSignature(@RequestParam("url") String url) throws WxErrorException { - return success(mpService.createJsapiSignature(url)); - } - -} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/social/SocialClientConvert.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/social/SocialClientConvert.java new file mode 100644 index 000000000..12da8a08b --- /dev/null +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/social/SocialClientConvert.java @@ -0,0 +1,15 @@ +package cn.iocoder.yudao.module.system.convert.social; + +import cn.iocoder.yudao.module.system.api.social.dto.SocialWxJsapiSignatureRespDTO; +import me.chanjar.weixin.common.bean.WxJsapiSignature; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +@Mapper +public interface SocialClientConvert { + + SocialClientConvert INSTANCE = Mappers.getMapper(SocialClientConvert.class); + + SocialWxJsapiSignatureRespDTO convert(WxJsapiSignature bean); + +} diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialClientService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialClientService.java index fbf885ca7..0346728c0 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialClientService.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialClientService.java @@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.system.service.social; import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum; import com.xingyuv.jushauth.model.AuthUser; +import me.chanjar.weixin.common.bean.WxJsapiSignature; /** * 社交应用 Service 接口 @@ -31,4 +32,13 @@ public interface SocialClientService { */ AuthUser getAuthUser(Integer socialType, Integer userType, String code, String state); + /** + * 创建微信 JS SDK 初始化所需的签名 + * + * @param userType 用户类型 + * @param url 访问的 URL 地址 + * @return 签名 + */ + WxJsapiSignature createWxMpJsapiSignature(Integer userType, String url); + } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialClientServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialClientServiceImpl.java index 071ebd1ba..61966ecb9 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialClientServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialClientServiceImpl.java @@ -4,21 +4,33 @@ import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.lang.Assert; import cn.hutool.core.util.ReflectUtil; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; +import cn.iocoder.yudao.framework.common.util.cache.CacheUtils; import cn.iocoder.yudao.framework.common.util.http.HttpUtils; import cn.iocoder.yudao.framework.social.core.YudaoAuthRequestFactory; import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialClientDO; import cn.iocoder.yudao.module.system.dal.mysql.social.SocialClientMapper; import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum; +import com.binarywang.spring.starter.wxjava.mp.properties.WxMpProperties; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; import com.xingyuv.jushauth.config.AuthConfig; import com.xingyuv.jushauth.model.AuthCallback; import com.xingyuv.jushauth.model.AuthResponse; import com.xingyuv.jushauth.model.AuthUser; import com.xingyuv.jushauth.request.AuthRequest; import com.xingyuv.jushauth.utils.AuthStateUtils; +import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; +import me.chanjar.weixin.common.bean.WxJsapiSignature; +import me.chanjar.weixin.common.redis.RedisTemplateWxRedisOps; +import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl; +import me.chanjar.weixin.mp.config.impl.WxMpRedisConfigImpl; +import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Service; import javax.annotation.Resource; +import java.time.Duration; import java.util.Objects; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; @@ -37,6 +49,32 @@ public class SocialClientServiceImpl implements SocialClientService { @Resource // 由于自定义了 YudaoAuthRequestFactory 无法覆盖默认的 AuthRequestFactory,所以只能注入它 private YudaoAuthRequestFactory yudaoAuthRequestFactory; + @Resource + private WxMpService mpService; + @Resource + private StringRedisTemplate stringRedisTemplate; // WxMpService 需要使用到,所以在 Service 注入了它 + @Resource + private WxMpProperties mpProperties; + /** + * 缓存 WxMpService 对象 + * + * key:使用微信公众号的 appId + secret 拼接,即 {@link SocialClientDO} 的 clientId 和 clientSecret 属性。 + * 为什么 key 使用这种格式?因为 {@link SocialClientDO} 在管理后台可以变更,通过这个 key 存储它的单例。 + * + * 为什么要做 WxMpService 缓存?因为 WxMpService 构建成本比较大,所以尽量保证它是单例。 + */ + private final LoadingCache mpServiceCache = CacheUtils.buildAsyncReloadingCache( + Duration.ofSeconds(10L), + new CacheLoader() { + + @Override + public WxMpService load(String key) { + String[] keys = key.split(":"); + return buildMpService(keys[0], keys[1]); + } + + }); + @Resource private SocialClientMapper socialClientMapper; @@ -91,4 +129,49 @@ public class SocialClientServiceImpl implements SocialClientService { return request; } + @Override + @SneakyThrows + public WxJsapiSignature createWxMpJsapiSignature(Integer userType, String url) { + WxMpService mpService = buildMpService(userType); + return mpService.createJsapiSignature(url); + } + + /** + * 创建 clientId + clientSecret 对应的 WxMpService 对象 + * + * @param userType 用户类型 + * @return WxMpService 对象 + */ + private WxMpService buildMpService(Integer userType) { + // 第一步,查询 DB 的配置项,获得对应的 WxMpService 对象 + SocialClientDO client = socialClientMapper.selectBySocialTypeAndUserType( + SocialTypeEnum.WECHAT_MP.getType(), userType); + if (client != null && Objects.equals(client.getStatus(), CommonStatusEnum.ENABLE.getStatus())) { + return mpServiceCache.getUnchecked(client.getClientId() + ":" + client.getClientSecret()); + } + // 第二步,不存在 DB 配置项,则使用 application-*.yaml 对应的 WxMpService 对象 + return mpService; + } + + /** + * 创建 clientId + clientSecret 对应的 WxMpService 对象 + * + * @param clientId 微信公众号 appId + * @param clientSecret 微信公众号 secret + * @return WxMpService 对象 + */ + private WxMpService buildMpService(String clientId, String clientSecret) { + // 第一步,创建 WxMpRedisConfigImpl 对象 + WxMpRedisConfigImpl configStorage = new WxMpRedisConfigImpl( + new RedisTemplateWxRedisOps(stringRedisTemplate), + mpProperties.getConfigStorage().getKeyPrefix()); + configStorage.setAppId(clientId); + configStorage.setSecret(clientSecret); + + // 第二步,创建 WxMpService 对象 + WxMpService service = new WxMpServiceImpl(); + service.setWxMpConfigStorage(configStorage); + return service; + } + } From 979b484d7fda952917390988869368f6d0e64e7e Mon Sep 17 00:00:00 2001 From: YunaiV Date: Thu, 19 Oct 2023 21:42:39 +0800 Subject: [PATCH 5/7] =?UTF-8?q?saas=EF=BC=9A=E6=94=AF=E6=8C=81=E7=A4=BE?= =?UTF-8?q?=E4=BA=A4=E5=BA=94=E7=94=A8=E7=9A=84=E5=A4=9A=E7=A7=9F=E6=88=B7?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=EF=BC=88wx=20=E5=B0=8F=E7=A8=8B=E5=BA=8F?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../member/enums/ErrorCodeConstants.java | 1 - .../yudao-module-member-biz/pom.xml | 4 - .../service/auth/MemberAuthServiceImpl.java | 20 ++-- .../system/api/social/SocialClientApi.java | 12 +- .../dto/SocialWxPhoneNumberInfoRespDTO.java | 27 +++++ .../system/enums/ErrorCodeConstants.java | 2 + .../api/social/SocialClientApiImpl.java | 8 ++ .../convert/social/SocialClientConvert.java | 4 + .../service/social/SocialClientService.java | 16 ++- .../social/SocialClientServiceImpl.java | 107 +++++++++++++++--- 10 files changed, 168 insertions(+), 33 deletions(-) create mode 100644 yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/social/dto/SocialWxPhoneNumberInfoRespDTO.java diff --git a/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/ErrorCodeConstants.java b/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/ErrorCodeConstants.java index e499f72f7..c7dc8b749 100644 --- a/yudao-module-member/yudao-module-member-api/src/main/java/cn/iocoder/yudao/module/member/enums/ErrorCodeConstants.java +++ b/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 { ErrorCode AUTH_LOGIN_BAD_CREDENTIALS = new ErrorCode(1_004_003_000, "登录失败,账号密码不正确"); ErrorCode AUTH_LOGIN_USER_DISABLED = new ErrorCode(1_004_003_001, "登录失败,账号被禁用"); ErrorCode AUTH_THIRD_LOGIN_NOT_BIND = new ErrorCode(1_004_003_005, "未绑定账号,需要进行绑定"); - ErrorCode AUTH_WEIXIN_MINI_APP_PHONE_CODE_ERROR = new ErrorCode(1_004_003_006, "获得手机号失败"); ErrorCode AUTH_MOBILE_USED = new ErrorCode(1_004_003_007, "手机号已经被使用"); // ========== 用户收件地址 1-004-004-000 ========== diff --git a/yudao-module-member/yudao-module-member-biz/pom.xml b/yudao-module-member/yudao-module-member-biz/pom.xml index a5eda05b0..249c061ae 100644 --- a/yudao-module-member/yudao-module-member-biz/pom.xml +++ b/yudao-module-member/yudao-module-member-biz/pom.xml @@ -43,10 +43,6 @@ cn.iocoder.boot yudao-spring-boot-starter-biz-tenant - - cn.iocoder.boot - yudao-spring-boot-starter-biz-weixin - diff --git a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/auth/MemberAuthServiceImpl.java b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/auth/MemberAuthServiceImpl.java index ea8f6805b..b6e88fd41 100644 --- a/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/auth/MemberAuthServiceImpl.java +++ b/yudao-module-member/yudao-module-member-biz/src/main/java/cn/iocoder/yudao/module/member/service/auth/MemberAuthServiceImpl.java @@ -1,7 +1,5 @@ package cn.iocoder.yudao.module.member.service.auth; -import cn.binarywang.wx.miniapp.api.WxMaService; -import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo; import cn.hutool.core.lang.Assert; import cn.hutool.core.util.ObjectUtil; import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; @@ -23,6 +21,7 @@ import cn.iocoder.yudao.module.system.api.social.SocialClientApi; import cn.iocoder.yudao.module.system.api.social.SocialUserApi; import cn.iocoder.yudao.module.system.api.social.dto.SocialUserBindReqDTO; import cn.iocoder.yudao.module.system.api.social.dto.SocialUserRespDTO; +import cn.iocoder.yudao.module.system.api.social.dto.SocialWxPhoneNumberInfoRespDTO; import cn.iocoder.yudao.module.system.enums.logger.LoginLogTypeEnum; import cn.iocoder.yudao.module.system.enums.logger.LoginResultEnum; import cn.iocoder.yudao.module.system.enums.oauth2.OAuth2ClientConstants; @@ -61,9 +60,6 @@ public class MemberAuthServiceImpl implements MemberAuthService { @Resource private OAuth2TokenApi oauth2TokenApi; - @Resource - private WxMaService wxMaService; - @Override public AppAuthLoginRespVO login(AppAuthLoginReqVO reqVO) { // 使用手机 + 密码,进行登录。 @@ -124,15 +120,13 @@ public class MemberAuthServiceImpl implements MemberAuthService { @Override public AppAuthLoginRespVO weixinMiniAppLogin(AppAuthWeixinMiniAppLoginReqVO reqVO) { // 获得对应的手机号信息 - // TODO @芋艿:需要弱化微信小程序的依赖,通过 system 获取手机号 - WxMaPhoneNumberInfo phoneNumberInfo; - try { - phoneNumberInfo = wxMaService.getUserService().getPhoneNoInfo(reqVO.getPhoneCode()); - } catch (Exception exception) { - throw exception(AUTH_WEIXIN_MINI_APP_PHONE_CODE_ERROR); - } + SocialWxPhoneNumberInfoRespDTO phoneNumberInfo = socialClientApi.getWxMaPhoneNumberInfo( + UserTypeEnum.MEMBER.getValue(), reqVO.getPhoneCode()); + Assert.notNull(phoneNumberInfo, "获得手机信息失败,结果为空"); + // 获得获得注册用户 - MemberUserDO user = userService.createUserIfAbsent(phoneNumberInfo.getPurePhoneNumber(), getClientIP(), TerminalEnum.WECHAT_MINI_PROGRAM.getTerminal()); + MemberUserDO user = userService.createUserIfAbsent(phoneNumberInfo.getPurePhoneNumber(), + getClientIP(), TerminalEnum.WECHAT_MINI_PROGRAM.getTerminal()); Assert.notNull(user, "获取用户失败,结果为空"); // 绑定社交用户 diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/social/SocialClientApi.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/social/SocialClientApi.java index e308d2b7b..1b32f7721 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/social/SocialClientApi.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/social/SocialClientApi.java @@ -1,6 +1,7 @@ package cn.iocoder.yudao.module.system.api.social; import cn.iocoder.yudao.module.system.api.social.dto.SocialWxJsapiSignatureRespDTO; +import cn.iocoder.yudao.module.system.api.social.dto.SocialWxPhoneNumberInfoRespDTO; import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum; /** @@ -21,7 +22,7 @@ public interface SocialClientApi { String getAuthorizeUrl(Integer type, Integer userType, String redirectUri); /** - * 创建微信 JS SDK 初始化所需的签名 + * 创建微信公众号 JS SDK 初始化所需的签名 * * @param userType 用户类型 * @param url 访问的 URL 地址 @@ -29,4 +30,13 @@ public interface SocialClientApi { */ SocialWxJsapiSignatureRespDTO createWxMpJsapiSignature(Integer userType, String url); + /** + * 获得微信小程序的手机信息 + * + * @param userType 用户类型 + * @param phoneCode 手机授权码 + * @return 手机信息 + */ + SocialWxPhoneNumberInfoRespDTO getWxMaPhoneNumberInfo(Integer userType, String phoneCode); + } diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/social/dto/SocialWxPhoneNumberInfoRespDTO.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/social/dto/SocialWxPhoneNumberInfoRespDTO.java new file mode 100644 index 000000000..9d404b3c1 --- /dev/null +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/api/social/dto/SocialWxPhoneNumberInfoRespDTO.java @@ -0,0 +1,27 @@ +package cn.iocoder.yudao.module.system.api.social.dto; + +import lombok.Data; + +/** + * 微信小程序的手机信息 Response DTO + * + * @author 芋道源码 + */ +@Data +public class SocialWxPhoneNumberInfoRespDTO { + + /** + * 用户绑定的手机号(国外手机号会有区号) + */ + private String phoneNumber; + + /** + * 没有区号的手机号 + */ + private String purePhoneNumber; + /** + * 区号 + */ + private String countryCode; + +} diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java index d13c0288c..f1822465d 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java +++ b/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 { ErrorCode SOCIAL_USER_UNBIND_NOT_SELF = new ErrorCode(1_002_018_001, "社交解绑失败,非当前用户绑定"); ErrorCode SOCIAL_USER_NOT_FOUND = new ErrorCode(1_002_018_002, "社交授权失败,找不到对应的用户"); + ErrorCode SOCIAL_APP_WEIXIN_MINI_APP_PHONE_CODE_ERROR = new ErrorCode(1_002_018_103, "获得手机号失败"); + // ========== 系统敏感词 1-002-019-000 ========= ErrorCode SENSITIVE_WORD_NOT_EXISTS = new ErrorCode(1_002_019_000, "系统敏感词在所有标签中都不存在"); ErrorCode SENSITIVE_WORD_EXISTS = new ErrorCode(1_002_019_001, "系统敏感词已在标签中存在"); diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/social/SocialClientApiImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/social/SocialClientApiImpl.java index d0f2a800e..203110721 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/social/SocialClientApiImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/social/SocialClientApiImpl.java @@ -1,6 +1,8 @@ package cn.iocoder.yudao.module.system.api.social; +import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo; import cn.iocoder.yudao.module.system.api.social.dto.SocialWxJsapiSignatureRespDTO; +import cn.iocoder.yudao.module.system.api.social.dto.SocialWxPhoneNumberInfoRespDTO; import cn.iocoder.yudao.module.system.convert.social.SocialClientConvert; import cn.iocoder.yudao.module.system.service.social.SocialClientService; import me.chanjar.weixin.common.bean.WxJsapiSignature; @@ -32,4 +34,10 @@ public class SocialClientApiImpl implements SocialClientApi { return SocialClientConvert.INSTANCE.convert(signature); } + @Override + public SocialWxPhoneNumberInfoRespDTO getWxMaPhoneNumberInfo(Integer userType, String phoneCode) { + WxMaPhoneNumberInfo info = socialClientService.getWxMaPhoneNumberInfo(userType, phoneCode); + return SocialClientConvert.INSTANCE.convert(info); + } + } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/social/SocialClientConvert.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/social/SocialClientConvert.java index 12da8a08b..169696014 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/social/SocialClientConvert.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/convert/social/SocialClientConvert.java @@ -1,6 +1,8 @@ package cn.iocoder.yudao.module.system.convert.social; +import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo; import cn.iocoder.yudao.module.system.api.social.dto.SocialWxJsapiSignatureRespDTO; +import cn.iocoder.yudao.module.system.api.social.dto.SocialWxPhoneNumberInfoRespDTO; import me.chanjar.weixin.common.bean.WxJsapiSignature; import org.mapstruct.Mapper; import org.mapstruct.factory.Mappers; @@ -12,4 +14,6 @@ public interface SocialClientConvert { SocialWxJsapiSignatureRespDTO convert(WxJsapiSignature bean); + SocialWxPhoneNumberInfoRespDTO convert(WxMaPhoneNumberInfo bean); + } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialClientService.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialClientService.java index 0346728c0..320ebb8be 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialClientService.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialClientService.java @@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.system.service.social; +import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo; import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum; import com.xingyuv.jushauth.model.AuthUser; import me.chanjar.weixin.common.bean.WxJsapiSignature; @@ -32,8 +33,10 @@ public interface SocialClientService { */ AuthUser getAuthUser(Integer socialType, Integer userType, String code, String state); + // =================== 微信公众号独有 =================== + /** - * 创建微信 JS SDK 初始化所需的签名 + * 创建微信公众号的 JS SDK 初始化所需的签名 * * @param userType 用户类型 * @param url 访问的 URL 地址 @@ -41,4 +44,15 @@ public interface SocialClientService { */ WxJsapiSignature createWxMpJsapiSignature(Integer userType, String url); + // =================== 微信小程序独有 =================== + + /** + * 获得微信小程序的手机信息 + * + * @param userType 用户类型 + * @param phoneCode 手机授权码 + * @return 手机信息 + */ + WxMaPhoneNumberInfo getWxMaPhoneNumberInfo(Integer userType, String phoneCode); + } diff --git a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialClientServiceImpl.java b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialClientServiceImpl.java index 61966ecb9..a08f73bd4 100644 --- a/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialClientServiceImpl.java +++ b/yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialClientServiceImpl.java @@ -1,5 +1,9 @@ package cn.iocoder.yudao.module.system.service.social; +import cn.binarywang.wx.miniapp.api.WxMaService; +import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl; +import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo; +import cn.binarywang.wx.miniapp.config.impl.WxMaRedisBetterConfigImpl; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.lang.Assert; import cn.hutool.core.util.ReflectUtil; @@ -10,6 +14,7 @@ import cn.iocoder.yudao.framework.social.core.YudaoAuthRequestFactory; import cn.iocoder.yudao.module.system.dal.dataobject.social.SocialClientDO; import cn.iocoder.yudao.module.system.dal.mysql.social.SocialClientMapper; import cn.iocoder.yudao.module.system.enums.social.SocialTypeEnum; +import com.binarywang.spring.starter.wxjava.miniapp.properties.WxMaProperties; import com.binarywang.spring.starter.wxjava.mp.properties.WxMpProperties; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; @@ -22,6 +27,7 @@ import com.xingyuv.jushauth.utils.AuthStateUtils; import lombok.SneakyThrows; import lombok.extern.slf4j.Slf4j; import me.chanjar.weixin.common.bean.WxJsapiSignature; +import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.common.redis.RedisTemplateWxRedisOps; import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl; @@ -35,6 +41,7 @@ import java.util.Objects; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString; +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.SOCIAL_APP_WEIXIN_MINI_APP_PHONE_CODE_ERROR; import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.SOCIAL_USER_AUTH_FAILURE; /** @@ -50,11 +57,11 @@ public class SocialClientServiceImpl implements SocialClientService { private YudaoAuthRequestFactory yudaoAuthRequestFactory; @Resource - private WxMpService mpService; + private WxMpService wxMpService; + @Resource + private WxMpProperties wxMpProperties; @Resource private StringRedisTemplate stringRedisTemplate; // WxMpService 需要使用到,所以在 Service 注入了它 - @Resource - private WxMpProperties mpProperties; /** * 缓存 WxMpService 对象 * @@ -63,14 +70,35 @@ public class SocialClientServiceImpl implements SocialClientService { * * 为什么要做 WxMpService 缓存?因为 WxMpService 构建成本比较大,所以尽量保证它是单例。 */ - private final LoadingCache mpServiceCache = CacheUtils.buildAsyncReloadingCache( + private final LoadingCache wxMpServiceCache = CacheUtils.buildAsyncReloadingCache( Duration.ofSeconds(10L), new CacheLoader() { @Override public WxMpService load(String key) { String[] keys = key.split(":"); - return buildMpService(keys[0], keys[1]); + return buildWxMpService(keys[0], keys[1]); + } + + }); + + @Resource + private WxMaService wxMaService; + @Resource + private WxMaProperties wxMaProperties; + /** + * 缓存 WxMaService 对象 + * + * 说明同 {@link #wxMpServiceCache} 变量 + */ + private final LoadingCache wxMaServiceCache = CacheUtils.buildAsyncReloadingCache( + Duration.ofSeconds(10L), + new CacheLoader() { + + @Override + public WxMaService load(String key) { + String[] keys = key.split(":"); + return buildWxMaService(keys[0], keys[1]); } }); @@ -129,28 +157,30 @@ public class SocialClientServiceImpl implements SocialClientService { return request; } + // =================== 微信公众号独有 =================== + @Override @SneakyThrows public WxJsapiSignature createWxMpJsapiSignature(Integer userType, String url) { - WxMpService mpService = buildMpService(userType); - return mpService.createJsapiSignature(url); + WxMpService service = getWxMpService(userType); + return service.createJsapiSignature(url); } /** - * 创建 clientId + clientSecret 对应的 WxMpService 对象 + * 获得 clientId + clientSecret 对应的 WxMpService 对象 * * @param userType 用户类型 * @return WxMpService 对象 */ - private WxMpService buildMpService(Integer userType) { + private WxMpService getWxMpService(Integer userType) { // 第一步,查询 DB 的配置项,获得对应的 WxMpService 对象 SocialClientDO client = socialClientMapper.selectBySocialTypeAndUserType( SocialTypeEnum.WECHAT_MP.getType(), userType); if (client != null && Objects.equals(client.getStatus(), CommonStatusEnum.ENABLE.getStatus())) { - return mpServiceCache.getUnchecked(client.getClientId() + ":" + client.getClientSecret()); + return wxMpServiceCache.getUnchecked(client.getClientId() + ":" + client.getClientSecret()); } // 第二步,不存在 DB 配置项,则使用 application-*.yaml 对应的 WxMpService 对象 - return mpService; + return wxMpService; } /** @@ -160,11 +190,11 @@ public class SocialClientServiceImpl implements SocialClientService { * @param clientSecret 微信公众号 secret * @return WxMpService 对象 */ - private WxMpService buildMpService(String clientId, String clientSecret) { + private WxMpService buildWxMpService(String clientId, String clientSecret) { // 第一步,创建 WxMpRedisConfigImpl 对象 WxMpRedisConfigImpl configStorage = new WxMpRedisConfigImpl( new RedisTemplateWxRedisOps(stringRedisTemplate), - mpProperties.getConfigStorage().getKeyPrefix()); + wxMpProperties.getConfigStorage().getKeyPrefix()); configStorage.setAppId(clientId); configStorage.setSecret(clientSecret); @@ -174,4 +204,55 @@ public class SocialClientServiceImpl implements SocialClientService { return service; } + // =================== 微信小程序独有 =================== + + @Override + public WxMaPhoneNumberInfo getWxMaPhoneNumberInfo(Integer userType, String phoneCode) { + WxMaService service = getWxMaService(userType); + try { + return service.getUserService().getPhoneNoInfo(phoneCode); + } catch (WxErrorException e) { + log.error("[getPhoneNoInfo][userType({}) phoneCode({}) 获得手机号失败]", userType, phoneCode, e); + throw exception(SOCIAL_APP_WEIXIN_MINI_APP_PHONE_CODE_ERROR); + } + } + + /** + * 获得 clientId + clientSecret 对应的 WxMpService 对象 + * + * @param userType 用户类型 + * @return WxMpService 对象 + */ + private WxMaService getWxMaService(Integer userType) { + // 第一步,查询 DB 的配置项,获得对应的 WxMaService 对象 + SocialClientDO client = socialClientMapper.selectBySocialTypeAndUserType( + SocialTypeEnum.WECHAT_MINI_APP.getType(), userType); + if (client != null && Objects.equals(client.getStatus(), CommonStatusEnum.ENABLE.getStatus())) { + return wxMaServiceCache.getUnchecked(client.getClientId() + ":" + client.getClientSecret()); + } + // 第二步,不存在 DB 配置项,则使用 application-*.yaml 对应的 WxMaService 对象 + return wxMaService; + } + + /** + * 创建 clientId + clientSecret 对应的 WxMaService 对象 + * + * @param clientId 微信小程序 appId + * @param clientSecret 微信小程序 secret + * @return WxMaService 对象 + */ + private WxMaService buildWxMaService(String clientId, String clientSecret) { + // 第一步,创建 WxMaRedisBetterConfigImpl 对象 + WxMaRedisBetterConfigImpl configStorage = new WxMaRedisBetterConfigImpl( + new RedisTemplateWxRedisOps(stringRedisTemplate), + wxMaProperties.getConfigStorage().getKeyPrefix()); + configStorage.setAppid(clientId); + configStorage.setSecret(clientSecret); + + // 第二步,创建 WxMpService 对象 + WxMaService service = new WxMaServiceImpl(); + service.setWxMaConfig(configStorage); + return service; + } + } From 453f69931fcd33d1144f2658c69f8eb8bd4c6ebc Mon Sep 17 00:00:00 2001 From: YunaiV Date: Thu, 19 Oct 2023 23:41:39 +0800 Subject: [PATCH 6/7] =?UTF-8?q?code=20review=EF=BC=9A=E8=90=A5=E9=94=80?= =?UTF-8?q?=E6=96=87=E7=AB=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../app/activity/AppActivityController.java | 15 +++++++++------ .../app/article/AppArticleCategoryController.java | 2 +- .../app/article/AppArticleController.java | 2 ++ .../combination/CombinationActivityConvert.java | 15 +++++---------- .../dal/mysql/bargain/BargainActivityMapper.java | 1 + .../service/article/ArticleServiceImpl.java | 5 +---- .../combination/CombinationRecordServiceImpl.java | 5 +++-- 7 files changed, 22 insertions(+), 23 deletions(-) diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/activity/AppActivityController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/activity/AppActivityController.java index a8cdfce2b..4cd971a3b 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/activity/AppActivityController.java +++ b/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 { @Parameter(name = "spuId", description = "商品编号", required = true) public CommonResult> getActivityListBySpuId(@RequestParam("spuId") Long spuId) { // 每种活动,只返回一个 - return success(getAppActivityRespVOList(Collections.singletonList(spuId))); + return success(getAppActivityList(Collections.singletonList(spuId))); } @GetMapping("/list-by-spu-ids") @@ -57,16 +57,17 @@ public class AppActivityController { return success(MapUtil.empty()); } // 每种活动,只返回一个;key 为 SPU 编号 - return success(convertMultiMap(getAppActivityRespVOList(spuIds), AppActivityRespVO::getSpuId)); + return success(convertMultiMap(getAppActivityList(spuIds), AppActivityRespVO::getSpuId)); } - private List getAppActivityRespVOList(Collection spuIds) { + private List getAppActivityList(Collection spuIds) { if (CollUtil.isEmpty(spuIds)) { return new ArrayList<>(); } LocalDateTime now = LocalDateTime.now(); List activityList = new ArrayList<>(); - // 拼团活动-获取开启的且开始的且没有结束的活动 + + // 1. 拼团活动 - 获取开启的且开始的且没有结束的活动 List combinationActivities = combinationActivityService.getCombinationActivityBySpuIdsAndStatusAndDateTimeLt( spuIds, CommonStatusEnum.ENABLE.getStatus(), now); if (CollUtil.isNotEmpty(combinationActivities)) { @@ -76,7 +77,8 @@ public class AppActivityController { .setSpuId(item.getSpuId()).setStartTime(item.getStartTime()).setEndTime(item.getEndTime())); }); } - // 秒杀活动-获取开启的且开始的且没有结束的活动 + + // 2. 秒杀活动 - 获取开启的且开始的且没有结束的活动 List seckillActivities = seckillActivityService.getSeckillActivityBySpuIdsAndStatusAndDateTimeLt( spuIds, CommonStatusEnum.ENABLE.getStatus(), now); if (CollUtil.isNotEmpty(seckillActivities)) { @@ -86,7 +88,8 @@ public class AppActivityController { .setSpuId(item.getSpuId()).setStartTime(item.getStartTime()).setEndTime(item.getEndTime())); }); } - // 砍价活动-获取开启的且开始的且没有结束的活动 + + // 3. 砍价活动 - 获取开启的且开始的且没有结束的活动 List bargainActivities = bargainActivityService.getBargainActivityBySpuIdsAndStatusAndDateTimeLt( spuIds, CommonStatusEnum.ENABLE.getStatus(), now); if (CollUtil.isNotEmpty(bargainActivities)) { diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/article/AppArticleCategoryController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/article/AppArticleCategoryController.java index 1c600d816..482b497d9 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/article/AppArticleCategoryController.java +++ b/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 { public CommonResult> getArticleCategoryList() { List categoryList = articleCategoryService.getArticleCategoryListByStatus( CommonStatusEnum.ENABLE.getStatus()); - categoryList.sort(Comparator.comparing(ArticleCategoryDO::getSort).reversed()); // 按 sort 降序排列 + categoryList.sort(Comparator.comparing(ArticleCategoryDO::getSort)); // 按 sort 降序排列 return success(ArticleCategoryConvert.INSTANCE.convertList04(categoryList)); } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/article/AppArticleController.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/article/AppArticleController.java index 2b403c03e..534e82ff3 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/article/AppArticleController.java +++ b/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 { return success(ArticleConvert.INSTANCE.convert01(articleService.getArticle(id))); } + // TODO @puhui999:add-browse-count 噢;前端 uniapp 也要接下;就是打开文章的时候,调用下这个接口; @PutMapping("/add-browseCount") @Operation(summary = "增加文章浏览量") @Parameter(name = "id", description = "文章编号", example = "1024") public CommonResult addBrowseCount(@RequestParam("id") Long id) { + // TODO @puhui999:addArticleBrowseCount articleService.addBrowseCount(id); return success(true); } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/combination/CombinationActivityConvert.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/combination/CombinationActivityConvert.java index 7ccb0d93e..1e4405b0d 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/convert/combination/CombinationActivityConvert.java +++ b/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 { return respVO; } - @Mapping(target = "id", ignore = true) - CombinationRecordDO convert5(CombinationRecordDO headRecord); - /** * 转换生成虚拟成团虚拟记录 * @@ -214,21 +211,19 @@ public interface CombinationActivityConvert { * @return 虚拟记录列表 */ default List convertVirtualRecordList(CombinationRecordDO headRecord) { - List createRecords = new ArrayList<>(); - // 计算需要创建的虚拟成团记录数量 int count = headRecord.getUserSize() - headRecord.getUserCount(); + List createRecords = new ArrayList<>(count); for (int i = 0; i < count; i++) { // 基础信息和团长保持一致 CombinationRecordDO newRecord = convert5(headRecord); // 虚拟信息 - newRecord.setCount(0); - newRecord.setUserId(0L); - newRecord.setNickname(""); - newRecord.setAvatar(""); - newRecord.setOrderId(0L); + newRecord.setCount(0) // 会单独更新下,在后续的 Service 逻辑里 + .setUserId(0L).setNickname("").setAvatar("").setOrderId(0L); createRecords.add(newRecord); } return createRecords; } + @Mapping(target = "id", ignore = true) + CombinationRecordDO convert5(CombinationRecordDO headRecord); } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/bargain/BargainActivityMapper.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/bargain/BargainActivityMapper.java index e03a21b5f..fd5466648 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/dal/mysql/bargain/BargainActivityMapper.java +++ b/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 { .groupBy("spu_id")); } + // TODO @puhui999:是不是只要 endTime 小于就可以啦; /** * 获取指定活动编号的活动列表且 * 开始时间和结束时间小于给定时间 dateTime 的活动列表 diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/article/ArticleServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/article/ArticleServiceImpl.java index 5b95753ff..47e614057 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/article/ArticleServiceImpl.java +++ b/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 import cn.iocoder.yudao.module.promotion.dal.dataobject.article.ArticleDO; import cn.iocoder.yudao.module.promotion.dal.mysql.article.ArticleMapper; import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import javax.annotation.Resource; @@ -112,12 +111,10 @@ public class ArticleServiceImpl implements ArticleService { } @Override - @Transactional(rollbackFor = Exception.class) public void addBrowseCount(Long id) { // 校验文章是否存在 validateArticleExists(id); - - // 增加浏览次数 TODO 先简单做,用户规模不大,只 +1 + // 增加浏览次数 articleMapper.updateBrowseCount(id); } diff --git a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationRecordServiceImpl.java b/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationRecordServiceImpl.java index 43d365701..db4197f52 100644 --- a/yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/service/combination/CombinationRecordServiceImpl.java +++ b/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 { keyValue.setValue(keyValue.getValue() + 1); } } catch (Exception ignored) { // 处理异常继续循环 + // TODO @puhui999:拼团过期 or 虚拟成团 可以改成 expireCombinationRecord;因为找方法更容易一些; log.error("[拼团过期 or 虚拟成团][record({}) 处理异常,请进行处理!record 数据是:{}]", record.getId(), JsonUtils.toJsonString(record)); } @@ -383,10 +384,10 @@ public class CombinationRecordServiceImpl implements CombinationRecordService { */ @Transactional(rollbackFor = Exception.class) public void handleExpireRecord(CombinationRecordDO headRecord) { - // 1.更新拼团记录 + // 1. 更新拼团记录 List headAndRecords = updateBatchCombinationRecords(headRecord, CombinationRecordStatusEnum.FAILED); - // 2.订单取消 + // 2. 订单取消 headAndRecords.forEach(item -> tradeOrderApi.cancelPaidOrder(item.getUserId(), item.getOrderId())); } From 6c8e82ca5a14193fb9d469fcd57e79ecc1aacca5 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Fri, 20 Oct 2023 00:30:27 +0800 Subject: [PATCH 7/7] =?UTF-8?q?code=20review=EF=BC=9A=E8=87=AA=E6=8F=90?= =?UTF-8?q?=E7=BB=9F=E8=AE=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yudao/module/trade/dal/mysql/order/TradeOrderMapper.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/order/TradeOrderMapper.java b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/order/TradeOrderMapper.java index 81abbdfc7..21fc038ba 100644 --- a/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/order/TradeOrderMapper.java +++ b/yudao-module-mall/yudao-module-trade-biz/src/main/java/cn/iocoder/yudao/module/trade/dal/mysql/order/TradeOrderMapper.java @@ -44,6 +44,7 @@ public interface TradeOrderMapper extends BaseMapperX { .orderByDesc(TradeOrderDO::getId)); } + // TODO @疯狂:如果用 map 返回,要不这里直接用 TradeOrderSummaryRespVO 返回?也算合理,就当 sql 查询出这么个玩意~~ default List> selectOrderSummaryGroupByRefundStatus(TradeOrderPageReqVO reqVO, Set userIds) { return selectMaps(new MPJLambdaWrapperX() .selectAs(TradeOrderDO::getRefundStatus, TradeOrderDO::getRefundStatus) // 售后状态 @@ -114,7 +115,7 @@ public interface TradeOrderMapper extends BaseMapperX { default TradeOrderDO selectOneByPickUpVerifyCode(String pickUpVerifyCode) { return selectOne(TradeOrderDO::getPickUpVerifyCode, pickUpVerifyCode); } - + default TradeOrderDO selectByUserIdAndCombinationActivityIdAndStatus(Long userId, Long combinationActivityId, Integer status) { return selectOne(new LambdaQueryWrapperX() .eq(TradeOrderDO::getUserId, userId)