Commit 063d5e3a8a4376645c751e7bc7ea6686411e37fc

Authored by YunaiV
1 parent 1391e20e

增加支付接入的示例 10%

yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/PayDemoOrderController.java 0 → 100644
  1 +package cn.iocoder.yudao.module.pay.controller.admin.demo;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.CommonResult;
  4 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  5 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  6 +import cn.iocoder.yudao.module.pay.controller.admin.demo.vo.PayDemoOrderCreateReqVO;
  7 +import cn.iocoder.yudao.module.pay.controller.admin.demo.vo.PayDemoOrderRespVO;
  8 +import cn.iocoder.yudao.module.pay.convert.demo.PayDemoOrderConvert;
  9 +import cn.iocoder.yudao.module.pay.dal.dataobject.demo.PayDemoOrderDO;
  10 +import cn.iocoder.yudao.module.pay.service.demo.PayDemoOrderService;
  11 +import io.swagger.v3.oas.annotations.Operation;
  12 +import io.swagger.v3.oas.annotations.tags.Tag;
  13 +import org.springframework.validation.annotation.Validated;
  14 +import org.springframework.web.bind.annotation.*;
  15 +
  16 +import javax.annotation.Resource;
  17 +import javax.validation.Valid;
  18 +
  19 +import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
  20 +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
  21 +
  22 +@Tag(name = "管理后台 - 示例订单")
  23 +@RestController
  24 +@RequestMapping("/pay/demo-order")
  25 +@Validated
  26 +public class PayDemoOrderController {
  27 +
  28 + @Resource
  29 + private PayDemoOrderService payDemoOrderService;
  30 +
  31 + @PostMapping("/create")
  32 + @Operation(summary = "创建示例订单")
  33 + public CommonResult<Long> createDemoOrder(@Valid @RequestBody PayDemoOrderCreateReqVO createReqVO) {
  34 + return success(payDemoOrderService.createDemoOrder(getLoginUserId(), createReqVO));
  35 + }
  36 +
  37 + @GetMapping("/page")
  38 + @Operation(summary = "获得示例订单分页")
  39 + public CommonResult<PageResult<PayDemoOrderRespVO>> getDemoOrderPage(@Valid PageParam pageVO) {
  40 + PageResult<PayDemoOrderDO> pageResult = payDemoOrderService.getDemoOrderPage(pageVO);
  41 + return success(PayDemoOrderConvert.INSTANCE.convertPage(pageResult));
  42 + }
  43 +
  44 +}
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/vo/PayDemoOrderCreateReqVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.pay.controller.admin.demo.vo;
  2 +
  3 +import lombok.*;
  4 +import io.swagger.v3.oas.annotations.media.Schema;
  5 +
  6 +import javax.validation.constraints.NotEmpty;
  7 +import javax.validation.constraints.NotNull;
  8 +
  9 +@Schema(description = "管理后台 - 示例订单创建 Request VO")
  10 +@Data
  11 +public class PayDemoOrderCreateReqVO {
  12 +
  13 + @Schema(description = "商品编号", required = true, example = "17682")
  14 + @NotNull(message = "商品编号不能为空")
  15 + private Long spuId;
  16 +
  17 +}
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/admin/demo/vo/PayDemoOrderRespVO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.pay.controller.admin.demo.vo;
  2 +
  3 +import io.swagger.v3.oas.annotations.media.Schema;
  4 +import lombok.*;
  5 +
  6 +import java.time.LocalDateTime;
  7 +
  8 +/**
  9 +* 示例订单 Base VO,提供给添加、修改、详细的子 VO 使用
  10 +* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
  11 +*/
  12 +@Data
  13 +public class PayDemoOrderRespVO {
  14 +
  15 + @Schema(description = "用户编号", required = true, example = "23199")
  16 + private Long userId;
  17 +
  18 + @Schema(description = "商品编号", required = true, example = "17682")
  19 + private Long spuId;
  20 +
  21 + @Schema(description = "商家备注", example = "李四")
  22 + private String spuName;
  23 +
  24 + @Schema(description = "价格,单位:分", required = true, example = "30381")
  25 + private Integer price;
  26 +
  27 + @Schema(description = "是否已支付", required = true)
  28 + private Boolean payed;
  29 +
  30 + @Schema(description = "支付订单编号", example = "16863")
  31 + private Long payOrderId;
  32 +
  33 + @Schema(description = "订单支付时间")
  34 + private LocalDateTime payTime;
  35 +
  36 + @Schema(description = "退款金额,单位:分", required = true, example = "14039")
  37 + private Integer refundPrice;
  38 +
  39 + @Schema(description = "退款时间")
  40 + private LocalDateTime refundTime;
  41 +
  42 +}
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/controller/app/package-info.java deleted
1 -package cn.iocoder.yudao.module.pay.controller.app;  
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/convert/demo/PayDemoOrderConvert.java 0 → 100644
  1 +package cn.iocoder.yudao.module.pay.convert.demo;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  4 +import cn.iocoder.yudao.module.pay.controller.admin.demo.vo.PayDemoOrderCreateReqVO;
  5 +import cn.iocoder.yudao.module.pay.controller.admin.demo.vo.PayDemoOrderRespVO;
  6 +import cn.iocoder.yudao.module.pay.dal.dataobject.demo.PayDemoOrderDO;
  7 +import org.mapstruct.Mapper;
  8 +import org.mapstruct.factory.Mappers;
  9 +
  10 +/**
  11 + * 示例订单 Convert
  12 + *
  13 + * @author 芋道源码
  14 + */
  15 +@Mapper
  16 +public interface PayDemoOrderConvert {
  17 +
  18 + PayDemoOrderConvert INSTANCE = Mappers.getMapper(PayDemoOrderConvert.class);
  19 +
  20 + PayDemoOrderDO convert(PayDemoOrderCreateReqVO bean);
  21 +
  22 + PayDemoOrderRespVO convert(PayDemoOrderDO bean);
  23 +
  24 + PageResult<PayDemoOrderRespVO> convertPage(PageResult<PayDemoOrderDO> page);
  25 +
  26 +}
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/dataobject/demo/PayDemoOrderDO.java 0 → 100644
  1 +package cn.iocoder.yudao.module.pay.dal.dataobject.demo;
  2 +
  3 +import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  4 +import com.baomidou.mybatisplus.annotation.KeySequence;
  5 +import com.baomidou.mybatisplus.annotation.TableId;
  6 +import com.baomidou.mybatisplus.annotation.TableName;
  7 +import lombok.*;
  8 +
  9 +import java.time.LocalDateTime;
  10 +import java.util.Date;
  11 +
  12 +/**
  13 + * 示例订单
  14 + *
  15 + * 演示业务系统的订单,如何接入 pay 系统的支付与退款
  16 + *
  17 + * @author 芋道源码
  18 + */
  19 +@TableName("pay_demo_order")
  20 +@KeySequence("pay_demo_order_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
  21 +@Data
  22 +@EqualsAndHashCode(callSuper = true)
  23 +@ToString(callSuper = true)
  24 +@Builder
  25 +@NoArgsConstructor
  26 +@AllArgsConstructor
  27 +public class PayDemoOrderDO extends BaseDO {
  28 +
  29 + /**
  30 + * 订单编号,自增
  31 + */
  32 + @TableId
  33 + private Long id;
  34 + /**
  35 + * 用户编号
  36 + */
  37 + private Long userId;
  38 + /**
  39 + * 商品编号
  40 + */
  41 + private Long spuId;
  42 + /**
  43 + * 商品名称
  44 + */
  45 + private String spuName;
  46 + /**
  47 + * 价格,单位:分
  48 + */
  49 + private Integer price;
  50 +
  51 + // ========== 支付相关字段 ==========
  52 +
  53 + /**
  54 + * 是否支付
  55 + */
  56 + private Boolean payed;
  57 + /**
  58 + * 支付订单编号
  59 + *
  60 + * 对接 pay-module-biz 支付服务的支付订单编号,即 PayOrderDO 的 id 编号
  61 + */
  62 + private Long payOrderId;
  63 + /**
  64 + * 付款时间
  65 + */
  66 + private LocalDateTime payTime;
  67 + /**
  68 + * 支付渠道
  69 + *
  70 + * 对应 PayChannelEnum 枚举
  71 + */
  72 + private String payChannelCode;
  73 +
  74 + // ========== 退款相关字段 ==========
  75 + /**
  76 + * 退款金额
  77 + */
  78 + private Integer refundPrice;
  79 + /**
  80 + * 退款时间
  81 + *
  82 + * 由于可以多次退款,记录最后一次退款的时间
  83 + */
  84 + private Date refundTime;
  85 +
  86 +}
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/dal/mysql/demo/PayDemoOrderMapper.java 0 → 100644
  1 +package cn.iocoder.yudao.module.pay.dal.mysql.demo;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  4 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  5 +import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
  6 +import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
  7 +import cn.iocoder.yudao.module.pay.dal.dataobject.demo.PayDemoOrderDO;
  8 +import org.apache.ibatis.annotations.Mapper;
  9 +
  10 +/**
  11 + * 示例订单 Mapper
  12 + *
  13 + * @author 芋道源码
  14 + */
  15 +@Mapper
  16 +public interface PayDemoOrderMapper extends BaseMapperX<PayDemoOrderDO> {
  17 +
  18 + default PageResult<PayDemoOrderDO> selectPage(PageParam reqVO) {
  19 + return selectPage(reqVO, new LambdaQueryWrapperX<PayDemoOrderDO>()
  20 + .orderByDesc(PayDemoOrderDO::getId));
  21 + }
  22 +
  23 +}
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoOrderService.java 0 → 100644
  1 +package cn.iocoder.yudao.module.pay.service.demo;
  2 +
  3 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  4 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  5 +import cn.iocoder.yudao.module.pay.controller.admin.demo.vo.PayDemoOrderCreateReqVO;
  6 +import cn.iocoder.yudao.module.pay.dal.dataobject.demo.PayDemoOrderDO;
  7 +
  8 +import javax.validation.Valid;
  9 +
  10 +/**
  11 + * 示例订单 Service 接口
  12 + *
  13 + * @author 芋道源码
  14 + */
  15 +public interface PayDemoOrderService {
  16 +
  17 + /**
  18 + * 创建示例订单
  19 + *
  20 + * @param userId 用户编号
  21 + * @param createReqVO 创建信息
  22 + * @return 编号
  23 + */
  24 + Long createDemoOrder(Long userId, @Valid PayDemoOrderCreateReqVO createReqVO);
  25 +
  26 + /**
  27 + * 获得示例订单
  28 + *
  29 + * @param id 编号
  30 + * @return 示例订单
  31 + */
  32 + PayDemoOrderDO getDemoOrder(Long id);
  33 +
  34 + /**
  35 + * 获得示例订单分页
  36 + *
  37 + * @param pageReqVO 分页查询
  38 + * @return 示例订单分页
  39 + */
  40 + PageResult<PayDemoOrderDO> getDemoOrderPage(PageParam pageReqVO);
  41 +
  42 +}
yudao-module-pay/yudao-module-pay-biz/src/main/java/cn/iocoder/yudao/module/pay/service/demo/PayDemoOrderServiceImpl.java 0 → 100644
  1 +package cn.iocoder.yudao.module.pay.service.demo;
  2 +
  3 +import cn.hutool.core.lang.Assert;
  4 +import cn.iocoder.yudao.framework.common.pojo.PageParam;
  5 +import cn.iocoder.yudao.framework.common.pojo.PageResult;
  6 +import cn.iocoder.yudao.module.pay.api.order.PayOrderApi;
  7 +import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO;
  8 +import cn.iocoder.yudao.module.pay.controller.admin.demo.vo.PayDemoOrderCreateReqVO;
  9 +import cn.iocoder.yudao.module.pay.dal.dataobject.demo.PayDemoOrderDO;
  10 +import cn.iocoder.yudao.module.pay.dal.mysql.demo.PayDemoOrderMapper;
  11 +import org.springframework.stereotype.Service;
  12 +import org.springframework.validation.annotation.Validated;
  13 +
  14 +import javax.annotation.Resource;
  15 +import java.time.Duration;
  16 +import java.util.HashMap;
  17 +import java.util.Map;
  18 +
  19 +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.addTime;
  20 +import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP;
  21 +
  22 +/**
  23 + * 示例订单 Service 实现类
  24 + *
  25 + * @author 芋道源码
  26 + */
  27 +@Service
  28 +@Validated
  29 +public class PayDemoOrderServiceImpl implements PayDemoOrderService {
  30 +
  31 + /**
  32 + * 接入的实力应用编号
  33 + *
  34 + * 从 [支付管理 -> 应用信息] 里添加
  35 + */
  36 + private static final Long PAY_APP_ID = 7L;
  37 +
  38 + /**
  39 + * 商品信息 Map
  40 + *
  41 + * key:商品编号
  42 + * value:[商品名、商品价格]
  43 + */
  44 + private final Map<Long, Object[]> spuNames = new HashMap<>();
  45 +
  46 + @Resource
  47 + private PayOrderApi payOrderApi;
  48 +
  49 + @Resource
  50 + private PayDemoOrderMapper payDemoOrderMapper;
  51 +
  52 + public PayDemoOrderServiceImpl() {
  53 + spuNames.put(1L, new Object[]{"华为手机", 1});
  54 + spuNames.put(2L, new Object[]{"小米电视", 10});
  55 + spuNames.put(3L, new Object[]{"苹果手表", 100});
  56 + spuNames.put(4L, new Object[]{"华硕笔记本", 200});
  57 + spuNames.put(5L, new Object[]{"蔚来汽车", 300});
  58 + }
  59 +
  60 + @Override
  61 + public Long createDemoOrder(Long userId, PayDemoOrderCreateReqVO createReqVO) {
  62 + // 1.1 获得商品
  63 + Object[] spu = spuNames.get(createReqVO.getSpuId());
  64 + Assert.notNull(spu, "商品({}) 不存在", createReqVO.getSpuId());
  65 + String spuName = (String) spu[0];
  66 + Integer price = (Integer) spu[1];
  67 + // 1.2 插入 demo 订单
  68 + PayDemoOrderDO demoOrder = new PayDemoOrderDO().setUserId(userId)
  69 + .setSpuId(createReqVO.getSpuId()).setSpuName(spuName)
  70 + .setPayed(false).setRefundPrice(0);
  71 + payDemoOrderMapper.insert(demoOrder);
  72 +
  73 + // 2.1 创建支付单
  74 + Long payOrderId = payOrderApi.createOrder(new PayOrderCreateReqDTO()
  75 + .setAppId(PAY_APP_ID).setUserIp(getClientIP()) // 支付应用
  76 + .setMerchantOrderId(demoOrder.getId().toString()) // 业务的订单编号
  77 + .setSubject(spuName).setBody("").setAmount(price) // 价格信息
  78 + .setExpireTime(addTime(Duration.ofHours(2L)))); // 支付的过期时间
  79 + // 2.2 更新支付单到 demo 订单
  80 + payDemoOrderMapper.updateById(new PayDemoOrderDO().setId(demoOrder.getId())
  81 + .setPayOrderId(payOrderId));
  82 + // 返回
  83 + return demoOrder.getId();
  84 + }
  85 +
  86 +// private void validateDemoOrderExists(Long id) {
  87 +// if (demoOrderMapper.selectById(id) == null) {
  88 +// throw exception(DEMO_ORDER_NOT_EXISTS);
  89 +// }
  90 +// }
  91 +
  92 + @Override
  93 + public PayDemoOrderDO getDemoOrder(Long id) {
  94 + return payDemoOrderMapper.selectById(id);
  95 + }
  96 +
  97 + @Override
  98 + public PageResult<PayDemoOrderDO> getDemoOrderPage(PageParam pageReqVO) {
  99 + return payDemoOrderMapper.selectPage(pageReqVO);
  100 + }
  101 +
  102 +}