Merge remote-tracking branch 'origin/feature/mall_product' into feature/mall_product
commit
96b1662e4a
@ -0,0 +1,21 @@
|
|||||||
|
package cn.iocoder.yudao.module.pay.api.transfer;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferCreateReqDTO;
|
||||||
|
|
||||||
|
import javax.validation.Valid;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转账单 API 接口
|
||||||
|
*
|
||||||
|
* @author jason
|
||||||
|
*/
|
||||||
|
public interface PayTransferApi {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建转账单
|
||||||
|
*
|
||||||
|
* @param reqDTO 创建请求
|
||||||
|
* @return 转账单编号
|
||||||
|
*/
|
||||||
|
Long createTransfer(@Valid PayTransferCreateReqDTO reqDTO);
|
||||||
|
}
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
package cn.iocoder.yudao.module.pay.api.transfer;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferCreateReqDTO;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author jason
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@Validated
|
||||||
|
public class PayTransferApiImpl implements PayTransferApi {
|
||||||
|
@Override
|
||||||
|
public Long createTransfer(PayTransferCreateReqDTO reqDTO) {
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
package cn.iocoder.yudao.module.pay.controller.admin.demo;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||||
|
import cn.iocoder.yudao.module.pay.controller.admin.demo.vo.transfer.PayDemoTransferCreateReqVO;
|
||||||
|
import cn.iocoder.yudao.module.pay.service.demo.PayDemoTransferService;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.validation.Valid;
|
||||||
|
|
||||||
|
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||||
|
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
||||||
|
|
||||||
|
@Tag(name = "管理后台 - 示例转账单")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/pay/demo-transfer")
|
||||||
|
@Validated
|
||||||
|
public class PayDemoTransferController {
|
||||||
|
@Resource
|
||||||
|
private PayDemoTransferService demoTransferService;
|
||||||
|
|
||||||
|
@PostMapping("/create")
|
||||||
|
@Operation(summary = "创建示例转账订单")
|
||||||
|
public CommonResult<Long> createDemoOrder(@Valid @RequestBody PayDemoTransferCreateReqVO createReqVO) {
|
||||||
|
return success(demoTransferService.createDemoTransfer(getLoginUserId(), createReqVO));
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
package cn.iocoder.yudao.module.pay.controller.admin.demo.vo.transfer;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||||
|
import cn.iocoder.yudao.framework.pay.core.enums.transfer.PayTransferTypeEnum;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.validation.constraints.Min;
|
||||||
|
import javax.validation.constraints.NotEmpty;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author jason
|
||||||
|
*/
|
||||||
|
@Schema(description = "管理后台 - 示例转账单创建 Request VO")
|
||||||
|
@Data
|
||||||
|
public class PayDemoTransferCreateReqVO {
|
||||||
|
|
||||||
|
@Schema(description = "转账类型", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||||
|
@NotNull(message = "转账类型不能为空")
|
||||||
|
@InEnum(PayTransferTypeEnum.class)
|
||||||
|
private Integer transferType;
|
||||||
|
|
||||||
|
@NotNull(message = "转账金额不能为空")
|
||||||
|
@Min(value = 1, message = "转账金额必须大于零")
|
||||||
|
private Integer price;
|
||||||
|
|
||||||
|
@Schema(description = "收款方信息", requiredMode = Schema.RequiredMode.REQUIRED, example = "{'ALIPAY_LOGON_ID':'xxxx'}")
|
||||||
|
@NotEmpty(message = "收款方信息不能为空")
|
||||||
|
private Map<String, String> payeeInfo;
|
||||||
|
}
|
||||||
@ -0,0 +1,36 @@
|
|||||||
|
package cn.iocoder.yudao.module.pay.controller.admin.transfer;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||||
|
import cn.iocoder.yudao.module.pay.controller.admin.transfer.vo.PayTransferSubmitReqVO;
|
||||||
|
import cn.iocoder.yudao.module.pay.controller.admin.transfer.vo.PayTransferSubmitRespVO;
|
||||||
|
import cn.iocoder.yudao.module.pay.service.transfer.PayTransferService;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.validation.Valid;
|
||||||
|
|
||||||
|
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||||
|
import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP;
|
||||||
|
|
||||||
|
@Tag(name = "管理后台 - 转账单")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/pay/transfer")
|
||||||
|
@Validated
|
||||||
|
public class PayTransferController {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private PayTransferService payTransferService;
|
||||||
|
|
||||||
|
@PostMapping("/submit")
|
||||||
|
@Operation(summary = "提交转账订单")
|
||||||
|
public CommonResult<PayTransferSubmitRespVO> submitPayTransfer(@Valid @RequestBody PayTransferSubmitReqVO reqVO) {
|
||||||
|
PayTransferSubmitRespVO respVO = payTransferService.submitTransfer(reqVO, getClientIP());
|
||||||
|
return success(respVO);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,24 @@
|
|||||||
|
package cn.iocoder.yudao.module.pay.controller.admin.transfer.vo;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotEmpty;
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Schema(description = "管理后台 - 转账单提交 Request VO")
|
||||||
|
@Data
|
||||||
|
public class PayTransferSubmitReqVO {
|
||||||
|
|
||||||
|
@Schema(description = "转账单编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||||
|
@NotNull(message = "转账单编号不能为空")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Schema(description = "转账渠道", requiredMode = Schema.RequiredMode.REQUIRED, example = "alipay_transfer")
|
||||||
|
@NotEmpty(message = "转账渠道不能为空")
|
||||||
|
private String channelCode;
|
||||||
|
|
||||||
|
@Schema(description = "转账渠道的额外参数")
|
||||||
|
private Map<String, String> channelExtras;
|
||||||
|
}
|
||||||
@ -0,0 +1,12 @@
|
|||||||
|
package cn.iocoder.yudao.module.pay.controller.admin.transfer.vo;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Schema(description = "管理后台 - 转账单提交 Response VO")
|
||||||
|
@Data
|
||||||
|
public class PayTransferSubmitRespVO {
|
||||||
|
|
||||||
|
@Schema(description = "转账状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1") // 参见 PayTransferStatusEnum 枚举
|
||||||
|
private Integer status;
|
||||||
|
}
|
||||||
@ -0,0 +1,22 @@
|
|||||||
|
package cn.iocoder.yudao.module.pay.convert.transfer;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.module.pay.api.transfer.dto.PayTransferCreateReqDTO;
|
||||||
|
import cn.iocoder.yudao.module.pay.controller.admin.demo.vo.transfer.PayDemoTransferCreateReqVO;
|
||||||
|
import cn.iocoder.yudao.module.pay.dal.dataobject.transfer.PayTransferDO;
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
import org.mapstruct.Mapping;
|
||||||
|
import org.mapstruct.factory.Mappers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author jason
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface PayTransferConvert {
|
||||||
|
|
||||||
|
PayTransferConvert INSTANCE = Mappers.getMapper(PayTransferConvert.class);
|
||||||
|
|
||||||
|
PayTransferDO convert(PayTransferCreateReqDTO dto);
|
||||||
|
@Mapping(source = "transferType", target = "type")
|
||||||
|
PayTransferCreateReqDTO convert(PayDemoTransferCreateReqVO vo);
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,64 @@
|
|||||||
|
package cn.iocoder.yudao.module.pay.dal.dataobject.transfer;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||||
|
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转账拓展单 DO
|
||||||
|
*
|
||||||
|
* @author jason
|
||||||
|
*/
|
||||||
|
@TableName(value ="pay_transfer_extension",autoResultMap = true)
|
||||||
|
@KeySequence("pay_transfer_extension_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||||
|
@Data
|
||||||
|
public class PayTransferExtensionDO extends BaseDO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 编号
|
||||||
|
*/
|
||||||
|
@TableId
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转账单号
|
||||||
|
*/
|
||||||
|
private String no;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转账单编号
|
||||||
|
*/
|
||||||
|
private Long transferId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转账渠道编号
|
||||||
|
*/
|
||||||
|
private Long channelId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转账渠道编码
|
||||||
|
*/
|
||||||
|
private String channelCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 支付渠道的额外参数
|
||||||
|
*/
|
||||||
|
@TableField(typeHandler = JacksonTypeHandler.class)
|
||||||
|
private Map<String, String> channelExtras;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转账状态
|
||||||
|
*/
|
||||||
|
private Integer status;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 支付渠道异步通知的内容
|
||||||
|
*/
|
||||||
|
private String channelNotifyData;
|
||||||
|
}
|
||||||
@ -0,0 +1,14 @@
|
|||||||
|
package cn.iocoder.yudao.module.pay.dal.mysql.demo;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.module.pay.dal.dataobject.demo.PayDemoTransferDO;
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface PayDemoTransferMapper extends BaseMapperX<PayDemoTransferDO> {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
package cn.iocoder.yudao.module.pay.dal.mysql.transfer;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.module.pay.dal.dataobject.transfer.PayTransferExtensionDO;
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface PayTransferExtensionMapper extends BaseMapperX<PayTransferExtensionDO> {
|
||||||
|
|
||||||
|
default PayTransferExtensionDO selectByNo(String no){
|
||||||
|
return selectOne(PayTransferExtensionDO::getNo, no);
|
||||||
|
}
|
||||||
|
|
||||||
|
default int updateByIdAndStatus(Long id, List<Integer> status, PayTransferExtensionDO updateObj){
|
||||||
|
return update(updateObj, new LambdaQueryWrapper<PayTransferExtensionDO>()
|
||||||
|
.eq(PayTransferExtensionDO::getId, id).in(PayTransferExtensionDO::getStatus, status));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
package cn.iocoder.yudao.module.pay.dal.mysql.transfer;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.module.pay.dal.dataobject.transfer.PayTransferDO;
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface PayTransferMapper extends BaseMapperX<PayTransferDO> {
|
||||||
|
|
||||||
|
default int updateByIdAndStatus(Long id, List<Integer> status, PayTransferDO updateObj) {
|
||||||
|
return update(updateObj, new LambdaQueryWrapper<PayTransferDO>()
|
||||||
|
.eq(PayTransferDO::getId, id).in(PayTransferDO::getStatus, status));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -0,0 +1,22 @@
|
|||||||
|
package cn.iocoder.yudao.module.pay.service.demo;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.module.pay.controller.admin.demo.vo.transfer.PayDemoTransferCreateReqVO;
|
||||||
|
|
||||||
|
import javax.validation.Valid;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 示例转账业务 Service 接口
|
||||||
|
*
|
||||||
|
* @author jason
|
||||||
|
*/
|
||||||
|
public interface PayDemoTransferService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建转账单
|
||||||
|
*
|
||||||
|
* @param userId 用户编号
|
||||||
|
* @param createReqVO 创建信息
|
||||||
|
* @return 编号
|
||||||
|
*/
|
||||||
|
Long createDemoTransfer(Long userId, @Valid PayDemoTransferCreateReqVO createReqVO);
|
||||||
|
}
|
||||||
@ -0,0 +1,86 @@
|
|||||||
|
package cn.iocoder.yudao.module.pay.service.demo;
|
||||||
|
|
||||||
|
import cn.hutool.core.map.MapUtil;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import cn.iocoder.yudao.framework.pay.core.enums.transfer.PayTransferTypeEnum;
|
||||||
|
import cn.iocoder.yudao.module.pay.controller.admin.demo.vo.transfer.PayDemoTransferCreateReqVO;
|
||||||
|
import cn.iocoder.yudao.module.pay.convert.transfer.PayTransferConvert;
|
||||||
|
import cn.iocoder.yudao.module.pay.dal.dataobject.demo.PayDemoTransferDO;
|
||||||
|
import cn.iocoder.yudao.module.pay.dal.mysql.demo.PayDemoTransferMapper;
|
||||||
|
import cn.iocoder.yudao.module.pay.service.transfer.PayTransferService;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.validation.Valid;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||||
|
import static cn.iocoder.yudao.framework.pay.core.enums.transfer.PayTransferTypeEnum.*;
|
||||||
|
import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.PAY_TRANSFER_ALIPAY_ACCOUNT_NAME_IS_EMPTY;
|
||||||
|
import static cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants.PAY_TRANSFER_ALIPAY_LOGIN_ID_IS_EMPTY;
|
||||||
|
import static cn.iocoder.yudao.module.pay.enums.transfer.PayTransferStatusEnum.WAITING;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 示例转账业务 Service 实现类
|
||||||
|
*
|
||||||
|
* @author jason
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@Validated
|
||||||
|
public class PayDemoTransferServiceImpl implements PayDemoTransferService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 接入的实力应用编号
|
||||||
|
|
||||||
|
* 从 [支付管理 -> 应用信息] 里添加
|
||||||
|
*/
|
||||||
|
private static final Long TRANSFER_APP_ID = 8L;
|
||||||
|
@Resource
|
||||||
|
private PayDemoTransferMapper demoTransferMapper;
|
||||||
|
@Resource
|
||||||
|
private PayTransferService transferService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public Long createDemoTransfer(Long userId, @Valid PayDemoTransferCreateReqVO vo) {
|
||||||
|
// 1 校验收款账号
|
||||||
|
validatePayeeInfo(vo.getTransferType(), vo.getPayeeInfo());
|
||||||
|
|
||||||
|
// 2 保存示例转账业务表
|
||||||
|
PayDemoTransferDO demoTransfer = new PayDemoTransferDO().setUserId(userId).setType(vo.getTransferType())
|
||||||
|
.setPrice(vo.getPrice()).setPayeeInfo(vo.getPayeeInfo())
|
||||||
|
.setTransferStatus(WAITING.getStatus());
|
||||||
|
demoTransferMapper.insert(demoTransfer);
|
||||||
|
|
||||||
|
// 3.1 创建转账单
|
||||||
|
Long transferId = transferService.createTransfer(PayTransferConvert.INSTANCE.convert(vo)
|
||||||
|
.setAppId(TRANSFER_APP_ID).setTitle("示例转账")
|
||||||
|
.setMerchantOrderId(String.valueOf(demoTransfer.getId())));
|
||||||
|
// 3.2 更新转账单编号
|
||||||
|
demoTransferMapper.updateById(new PayDemoTransferDO().setId(demoTransfer.getId())
|
||||||
|
.setPayTransferId(transferId));
|
||||||
|
return demoTransfer.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validatePayeeInfo(Integer transferType, Map<String, String> payeeInfo) {
|
||||||
|
PayTransferTypeEnum transferTypeEnum = ofType(transferType);
|
||||||
|
switch (transferTypeEnum) {
|
||||||
|
case ALIPAY_BALANCE: {
|
||||||
|
if (StrUtil.isEmpty(MapUtil.getStr(payeeInfo, ALIPAY_LOGON_ID))) {
|
||||||
|
throw exception(PAY_TRANSFER_ALIPAY_LOGIN_ID_IS_EMPTY);
|
||||||
|
}
|
||||||
|
if (StrUtil.isEmpty(MapUtil.getStr(payeeInfo, ALIPAY_ACCOUNT_NAME))) {
|
||||||
|
throw exception(PAY_TRANSFER_ALIPAY_ACCOUNT_NAME_IS_EMPTY);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WX_BALANCE:
|
||||||
|
case BANK_CARD:
|
||||||
|
case WALLET_BALANCE: {
|
||||||
|
throw new UnsupportedOperationException("待实现");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue