Browse Source

老师提现

liweifan 2 years ago
parent
commit
e50474a288
15 changed files with 419 additions and 274 deletions
  1. 5 6
      cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/controller/UserWithdrawalController.java
  2. 21 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/constant/WithdrawalConstant.java
  3. 0 7
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/UserWithdrawalDao.java
  4. 12 10
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/search/TeacherWithdrawalSearch.java
  5. 91 68
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/UserWithdrawal.java
  6. 1 46
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/UserWithdrawalCallback.java
  7. 79 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/props/WithdrawalProperties.java
  8. 32 61
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/sdk/WithdrawSdk.java
  9. 11 3
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/UserWithdrawalService.java
  10. 81 18
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/UserWithdrawalServiceImpl.java
  11. 6 7
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/vo/UserWithdrawalVo.java
  12. 27 28
      cooleshow-user/user-biz/src/main/resources/config/mybatis/UserWithdrawalMapper.xml
  13. 0 2
      cooleshow-user/user-student/src/main/java/com/yonge/cooleshow/student/controller/PaymentController.java
  14. 48 1
      cooleshow-user/user-teacher/src/main/java/com/yonge/cooleshow/teacher/controller/UserWithdrawalController.java
  15. 5 17
      cooleshow-user/user-teacher/src/main/java/com/yonge/cooleshow/teacher/controller/WithdrawController.java

+ 5 - 6
cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/controller/UserWithdrawalController.java

@@ -66,9 +66,8 @@ public class UserWithdrawalController extends BaseController {
     @ApiOperation(value = "查询导出", notes = "传入TeacherWithdrawalSearch")
     @PreAuthorize("@pcs.hasPermissions('userWithdrawal/exportExcel')")
     public void exportExcel(@RequestBody TeacherWithdrawalSearch query) {
-        query.setStatus(AuthStatusEnum.DOING);
         List<UserWithdrawalVo> withdrawalVoList = userWithdrawalService.selectList(query);
-        List<UserWithdrawalExport> list = new ArrayList<>();
+        /*List<UserWithdrawalExport> list = new ArrayList<>();
         withdrawalVoList.forEach(o -> {
             UserWithdrawalExport export = new UserWithdrawalExport();
             try {
@@ -86,15 +85,15 @@ public class UserWithdrawalController extends BaseController {
             } catch (InvocationTargetException e) {
                 e.printStackTrace();
             }
-        });
-        ExcelUtils.exportExcel(list, "提现列表数据" + System.currentTimeMillis(),
+        });*/
+        ExcelUtils.exportExcel(withdrawalVoList, "提现列表数据" + System.currentTimeMillis(),
                 "列表数据");
     }
 
     /**
      * 导入
      */
-    @PostMapping("/importExcel")
+    /*@PostMapping("/importExcel")
     @ApiOperation(value = "导入", notes = "传入file")
     @PreAuthorize("@pcs.hasPermissions('userWithdrawal/importExcel')")
     public HttpResponseResult<List<ErrMsg>> importExcel(@RequestParam("file") MultipartFile file) {
@@ -112,5 +111,5 @@ public class UserWithdrawalController extends BaseController {
         } catch (ExcelException e) {
             return HttpResponseResult.failed(BizHttpStatus.IMPORT.getCode(), e.getErrMsgList(), BizHttpStatus.IMPORT.getMsg());
         }
-    }
+    }*/
 }

+ 21 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/constant/WithdrawalConstant.java

@@ -0,0 +1,21 @@
+package com.yonge.cooleshow.biz.dal.constant;
+
+public interface WithdrawalConstant {
+    /**
+     * 提现三方类型:lingxinpay 灵薪付
+     */
+    String openType = "lingxinpay";
+    //第三方url
+    String apiUrl = "http://39.107.15.64:8090";
+    //商户号
+    String memberNo = "1491663782974988288";
+    //第三方公钥
+    String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCYT5eCY6r8sGWgbiId/VqSZmS6XkBNGMkzUqTIkpkecOzsFBxFXTQmgDeR991YfgqmyOaHsJ/ons/H+e8l+RmHsOm4eErFU+9qXFq+k195YFV1vAR9O7MIG+FR5vmLDuhgimPsgqscWhUrGinc8RUpi5KwClgx7d+d8ZJ4GmkR0QIDAQAB";
+    //第三方私钥
+    String privateKey = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBANf/X1s2raYQAmY5VY929XqOIRESFlpLzWbltA08EI2i0jnJY3/kcCpo1sCHqkyWpDFGRgM1WYE90ayzEpS6EdZpyJ2/N5JFJzx4wMil5KHLdtQUmVv9si+xuYNOKfJW6Xn6zI/Wh81J1+hMlUY4WigU5Qci7DjdOjg5OD6e5DO3AgMBAAECgYEAor9ENhII3SsK48MneKWFaQZWW+po9ThQV8uT0rUDM/UOuYPIeMDC0vGTfhW6d2K57Haqohg8jGjr51g2E+HvNV+fARaBfCwy00DGcxjI6N8gEInj2AppsGV6a0ZtzGBh3BxGhEFV7x3NmTylDk3WkGnkGDqDNyrBUgK0BzCJEmECQQD+gYckYRevVfrZEHDQHRNzzMUlV9/ljA9x8dt0LoCNbd/wFvs0Ekjhas/2lUBkewEd4Kr0jaFcYzlUO/qihcpNAkEA2UP5W44yLuIo8ttPpdsfkH/8Ax64IywQHrXWq+thH7I91VwY2vomTduw8x0PafZtp8xryF3LixTZwQ7gsYbwEwJAQbb8SB5x2SogPVALcREw5qOm+/92pnTFwCws+BDRzLLkMcAdWNKn0tybmhXrrIY+QZKzUbYIRiywrtlV3AUjuQJBAJbnFnfX4NUdchGT79Mjyd2kdxZ3rK+JOD0MUWkhWFkahMX/bKgTXK1xLIr/ISiY53rHigkl1Gzqc4Aa5EeJkI8CQFlzlBOfoVnq3fPMZCCZcZSm97L12MgHho0AzoNj9sw9YYn9WPM7bw2HT8GUheiU3aiZGCyGGpYuVHMiBGa7l9U=";
+    //MD5加密的key
+    String md5Key = "0fd42370bad6485e46718b97f3dd1536";
+    //回调地址
+    String notifyUrl = "http://47.114.1.200:8000/teacher-server/withdraw/callback";
+
+}

+ 0 - 7
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/UserWithdrawalDao.java

@@ -1,7 +1,6 @@
 package com.yonge.cooleshow.biz.dal.dao;
 
 import java.util.List;
-import java.util.Map;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
@@ -36,10 +35,4 @@ public interface UserWithdrawalDao extends BaseMapper<UserWithdrawal>{
 	 */
 	List<UserWithdrawalVo> selectList(@Param("param") TeacherWithdrawalSearch teacherWithdrawal);
 
-	/**
-	 * @Description: 提现成功回调
-	 * @Author: cy
-	 * @Date: 2022/5/9
-	 */
-    void withdrawSuccess(Map<String, Object> withdrawRecord);
 }

+ 12 - 10
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/search/TeacherWithdrawalSearch.java

@@ -1,7 +1,9 @@
 package com.yonge.cooleshow.biz.dal.dto.search;
 
+import com.baomidou.mybatisplus.annotation.TableField;
 import com.fasterxml.jackson.annotation.JsonFormat;
 import com.yonge.cooleshow.biz.dal.enums.AuthStatusEnum;
+import com.yonge.cooleshow.biz.dal.enums.TradeStatusEnum;
 import com.yonge.toolset.base.page.QueryInfo;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
@@ -15,10 +17,10 @@ import java.time.LocalDateTime;
 @ApiModel(value = "TeacherWithdrawalSearch对象", description = "老师账户提现表查询对象")
 public class TeacherWithdrawalSearch extends QueryInfo{
 	private static final long serialVersionUID = 1L;
-	@ApiModelProperty("银行(交易)流水号 ")
-	private String bankFlowNo;
-	@ApiModelProperty("状态 DOING、审核中 PASS、通过 UNPASS、不通过")
-	private AuthStatusEnum status;
+	@ApiModelProperty("三方交易流水号 ")
+	private String transNo;
+	@ApiModelProperty("交易状态 pending、交易处理中 succeeded、交易成功 failed、交易失败 ")
+	private TradeStatusEnum status;
 	@ApiModelProperty(value = "申请开始时间")
 	@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
 	private LocalDateTime startTime;
@@ -30,19 +32,19 @@ public class TeacherWithdrawalSearch extends QueryInfo{
 
 	private Long userId;
 
-	public String getBankFlowNo() {
-		return bankFlowNo;
+	public String getTransNo() {
+		return transNo;
 	}
 
-	public void setBankFlowNo(String bankFlowNo) {
-		this.bankFlowNo = bankFlowNo;
+	public void setTransNo(String transNo) {
+		this.transNo = transNo;
 	}
 
-	public AuthStatusEnum getStatus() {
+	public TradeStatusEnum getStatus() {
 		return status;
 	}
 
-	public void setStatus(AuthStatusEnum status) {
+	public void setStatus(TradeStatusEnum status) {
 		this.status = status;
 	}
 

+ 91 - 68
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/UserWithdrawal.java

@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.annotation.TableField;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
 import com.yonge.cooleshow.biz.dal.enums.AuthStatusEnum;
+import com.yonge.cooleshow.biz.dal.enums.TradeStatusEnum;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 
@@ -20,154 +21,176 @@ import java.math.BigDecimal;
 @TableName("user_withdrawal")
 @ApiModel(value = "UserWithdrawal对象", description = "用户账户提现表")
 public class UserWithdrawal implements Serializable {
-	private static final long serialVersionUID = 1L;
+    private static final long serialVersionUID = 1L;
     @ApiModelProperty("提现id ")
     @TableId(value = "id_", type = IdType.AUTO)
     private Long id;
     @ApiModelProperty("用户表id ")
-	@TableField(value = "user_id_")
+    @TableField(value = "user_id_")
     private Long userId;
     @ApiModelProperty("提现金额 ")
-	@TableField(value = "amount_")
+    @TableField(value = "amount_")
     private BigDecimal amount;
     @ApiModelProperty("平台服务费 ")
-	@TableField(value = "plantform_fee_")
+    @TableField(value = "plantform_fee_")
     private BigDecimal plantformFee;
+    @ApiModelProperty("银行卡id ")
+    @TableField(value = "bank_card_id_")
+    private Long bankCardId;
+    @ApiModelProperty("第三方类型 ")
+    @TableField(value = "open_type_")
+    private String openType;
+    @ApiModelProperty("三方交易流水号 ")
+    @TableField(value = "trans_no_")
+    private String transNo;
+    @ApiModelProperty("交易状态 pending、交易处理中 succeeded、交易成功 failed、交易失败 ")
+    @TableField(value = "status_")
+    private TradeStatusEnum status;
     @ApiModelProperty("实际到账金额 ")
-	@TableField(value = "actual_amount_")
+    @TableField(value = "actual_amount_")
     private BigDecimal actualAmount;
-    @ApiModelProperty("银行卡 ")
-	@TableField(value = "bank_card_")
-    private String bankCard;
-    @ApiModelProperty("银行流水号 ")
-	@TableField(value = "bank_flow_no_")
-    private String bankFlowNo;
     @ApiModelProperty("转账时间 ")
-	@TableField(value = "transfer_time_")
+    @TableField(value = "transfer_time_")
     @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
     private Date transferTime;
-    @ApiModelProperty("提现状态 DOING、提现中 PASS、成功 UNPASS、失败")
-    @TableField(value = "status_")
-    private AuthStatusEnum status;
-    @ApiModelProperty("审核人")
-    @TableField(value = "verify_user_id_")
-    private Long verifyUserId;
-    @ApiModelProperty("审核原因")
-    @TableField(value = "verify_reason_")
-    private String verifyReason;
+    @ApiModelProperty("支付失败码 ")
+    @TableField(value = "error_code_")
+    private String errorCode;
+    @ApiModelProperty("支付失败时返回 ")
+    @TableField(value = "error_msg_")
+    private String errorMsg;
+    @ApiModelProperty("三方回调json ")
+    @TableField(value = "callback_json_")
+    private String callbackJson;
     @ApiModelProperty("发起时间 ")
-	@TableField(value = "create_time_")
+    @TableField(value = "create_time_")
     @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
     private Date createTime;
     @ApiModelProperty("修改时间 ")
-	@TableField(value = "update_time_")
+    @TableField(value = "update_time_")
     @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
     private Date updateTime;
 
-	public Long getId() {
+    public Long getId() {
         return id;
     }
 
     public void setId(Long id) {
         this.id = id;
     }
-    
-	public Long getUserId() {
+
+    public Long getUserId() {
         return userId;
     }
 
     public void setUserId(Long userId) {
         this.userId = userId;
     }
-    
-	public BigDecimal getAmount() {
+
+    public BigDecimal getAmount() {
         return amount;
     }
 
     public void setAmount(BigDecimal amount) {
         this.amount = amount;
     }
-    
-	public BigDecimal getPlantformFee() {
+
+    public BigDecimal getPlantformFee() {
         return plantformFee;
     }
 
     public void setPlantformFee(BigDecimal plantformFee) {
         this.plantformFee = plantformFee;
     }
-    
-	public BigDecimal getActualAmount() {
-        return actualAmount;
+
+    public Long getBankCardId() {
+        return bankCardId;
     }
 
-    public void setActualAmount(BigDecimal actualAmount) {
-        this.actualAmount = actualAmount;
+    public void setBankCardId(Long bankCardId) {
+        this.bankCardId = bankCardId;
+    }
+
+    public String getOpenType() {
+        return openType;
+    }
+
+    public void setOpenType(String openType) {
+        this.openType = openType;
+    }
+
+    public String getTransNo() {
+        return transNo;
     }
-    
-	public String getBankCard() {
-        return bankCard;
+
+    public void setTransNo(String transNo) {
+        this.transNo = transNo;
     }
 
-    public void setBankCard(String bankCard) {
-        this.bankCard = bankCard;
+    public TradeStatusEnum getStatus() {
+        return status;
+    }
+
+    public void setStatus(TradeStatusEnum status) {
+        this.status = status;
     }
 
-	public String getBankFlowNo() {
-        return bankFlowNo;
+    public BigDecimal getActualAmount() {
+        return actualAmount;
     }
 
-    public void setBankFlowNo(String bankFlowNo) {
-        this.bankFlowNo = bankFlowNo;
+    public void setActualAmount(BigDecimal actualAmount) {
+        this.actualAmount = actualAmount;
     }
-    
-	public Date getTransferTime() {
+
+    public Date getTransferTime() {
         return transferTime;
     }
 
     public void setTransferTime(Date transferTime) {
         this.transferTime = transferTime;
     }
-    
-	public Date getCreateTime() {
-        return createTime;
+
+    public String getErrorCode() {
+        return errorCode;
     }
 
-    public void setCreateTime(Date createTime) {
-        this.createTime = createTime;
+    public void setErrorCode(String errorCode) {
+        this.errorCode = errorCode;
     }
-    
-	public Date getUpdateTime() {
-        return updateTime;
+
+    public String getErrorMsg() {
+        return errorMsg;
     }
 
-    public void setUpdateTime(Date updateTime) {
-        this.updateTime = updateTime;
+    public void setErrorMsg(String errorMsg) {
+        this.errorMsg = errorMsg;
     }
 
-    public AuthStatusEnum getStatus() {
-        return status;
+    public String getCallbackJson() {
+        return callbackJson;
     }
 
-    public void setStatus(AuthStatusEnum status) {
-        this.status = status;
+    public void setCallbackJson(String callbackJson) {
+        this.callbackJson = callbackJson;
     }
 
-    public Long getVerifyUserId() {
-        return verifyUserId;
+    public Date getCreateTime() {
+        return createTime;
     }
 
-    public void setVerifyUserId(Long verifyUserId) {
-        this.verifyUserId = verifyUserId;
+    public void setCreateTime(Date createTime) {
+        this.createTime = createTime;
     }
 
-    public String getVerifyReason() {
-        return verifyReason;
+    public Date getUpdateTime() {
+        return updateTime;
     }
 
-    public void setVerifyReason(String verifyReason) {
-        this.verifyReason = verifyReason;
+    public void setUpdateTime(Date updateTime) {
+        this.updateTime = updateTime;
     }
 }

+ 1 - 46
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/UserWithdrawalCallback.java

@@ -1,8 +1,5 @@
 package com.yonge.cooleshow.biz.dal.entity;
 
-import com.baomidou.mybatisplus.annotation.IdType;
-import com.baomidou.mybatisplus.annotation.TableField;
-import com.baomidou.mybatisplus.annotation.TableId;
 import com.yonge.cooleshow.common.entity.BaseEntity;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
@@ -14,140 +11,98 @@ import java.util.Date;
  * @Author: cy
  * @Date: 2022/5/10
  */
-@ApiModel(value = "user_withdrawal_callback-提现回调")
+@ApiModel(value = "user_withdrawal_callback-提现回调")
 public class UserWithdrawalCallback extends BaseEntity {
-    @TableId(value = "id_", type = IdType.AUTO)
-    @ApiModelProperty(value = "主键id")
-    private Long id;
-
-    @TableField("order_no_")
     @ApiModelProperty(value = "众薪平台唯一订单号")
     private String orderNo;
 
-    @TableField("out_member_no_")
     @ApiModelProperty(value = "商户号")
     private String outMemberNo;
 
-    @TableField("outer_order_no_")
     @ApiModelProperty(value = "商户唯一订单号")
     private String outerOrderNo;
 
-    @TableField("additional_charge_")
     @ApiModelProperty(value = "个人附加费(单位为:分)")
     private Integer additionalCharge;
 
-    @TableField("actual_amount_")
     @ApiModelProperty(value = "实发金额(单位为:分,范围:1~10000000000)")
     private Integer actualAmount;
 
-    @TableField("company_charge_")
     @ApiModelProperty(value = "企业附加费(单位为:分)")
     private Integer companyCharge;
 
-    @TableField("company_service_fee_")
     @ApiModelProperty(value = "公司服务费汇总=企业个税+企业附加费+企业服务费(单位为:分)")
     private Integer companyServiceFee;
 
-    @TableField("company_tax_")
     @ApiModelProperty(value = "企业承担个税(单位为:分)")
     private Integer companyTax;
 
-    @TableField("service_charge_")
     @ApiModelProperty(value = "企业服务费(单位为:分)")
     private Integer serviceCharge;
 
-    @TableField("tax_fee_")
     @ApiModelProperty(value = "个人承担个税(单位为:分)")
     private Integer taxFee;
 
-    @TableField("person_service_fee_")
     @ApiModelProperty(value = "个人服务费汇总=个人个税+个人附加费(单位为:分)")
     private Integer personServiceFee;
 
-    @TableField("predict_amount_")
     @ApiModelProperty(value = "应发金额(单位为:分,范围:1~10000000000)")
     private Integer predictAmount;
 
-    @TableField("salary_type_")
     @ApiModelProperty(value = "发放类型(0:个人经营所得)")
     private String salaryType;
 
-    @TableField("status_")
     @ApiModelProperty(value = "交易状态(0:交易中;1:交易成功;2:交易失败)")
     private String status;
 
-    @TableField("create_time_")
     @ApiModelProperty(value = "创建时间")
     private Date createTime;
 
-    @TableField("end_time_")
     @ApiModelProperty(value = "完成时间")
     private Date endTime;
 
-    @TableField("error_code_")
     @ApiModelProperty(value = "支付失败时返回")
     private String errorCode;
 
-    @TableField("error_msg_")
     @ApiModelProperty(value = "支付失败时返回")
     private String errorMsg;
 
-    @TableField("mobile_")
     @ApiModelProperty(value = "收款方电话")
     private String mobile;
 
-    @TableField("certificate_no_")
     @ApiModelProperty(value = "收款方身份证号")
     private String certificateNo;
 
-    @TableField("name_")
     @ApiModelProperty(value = "收款方姓名(银行预留姓名等)")
     private String name;
 
-    @TableField("card_attribute_")
     @ApiModelProperty(value = "卡属性:(C:对私)")
     private String cardAttribute;
 
-    @TableField("card_type_")
     @ApiModelProperty(value = "卡类型:DC借记卡")
     private String cardType;
 
-    @TableField("pay_account_")
     @ApiModelProperty(value = "收款方账号(银行卡号/支付宝账号/open_id)以实际业务为准")
     private String payAccount;
 
-    @TableField("pay_type_")
     @ApiModelProperty(value = "支付类型(1:银行卡,2:支付宝,4:微信)以实际业务为准")
     private String payType;
 
-    @TableField("project_name_")
     @ApiModelProperty(value = "项目名称")
     private String projectName;
 
-    @TableField("remark_")
     @ApiModelProperty(value = "备注(扩展字段)只针对测试环境:只要参数合规都会返回交易成功,如果想要模拟交易失败,该字段值中含有“失败”二字即会失败。")
     private String remark;
 
-    @TableField("service_")
     @ApiModelProperty(value = "接口名称: bpotop.zx.pay.order")
     private String service;
 
-    @TableField("sign_type_")
     @ApiModelProperty(value = "签名类型:RSA")
     private String signType;
 
-    @TableField("notify_url_")
     @ApiModelProperty(value = "回调地址")
     private String notifyUrl;
 
-    public Long getId() {
-        return id;
-    }
-
-    public void setId(Long id) {
-        this.id = id;
-    }
-
     public String getOrderNo() {
         return orderNo;
     }

+ 79 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/props/WithdrawalProperties.java

@@ -0,0 +1,79 @@
+package com.yonge.cooleshow.biz.dal.props;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.stereotype.Component;
+
+@Component
+@ConfigurationProperties(prefix = "withdrawal")
+public class WithdrawalProperties {
+    //提现服务提供方 lingxinpay 灵薪付
+    private String openType;
+    //第三方url
+    private String apiUrl;
+    //商户号
+    private String memberNo;
+    //第三方公钥
+    private String publicKey;
+    //第三方私钥
+    private String privateKey;
+    //MD5加密的key
+    private String md5Key;
+    //回调地址
+    private String notifyUrl;
+
+    public String getOpenType() {
+        return openType;
+    }
+
+    public void setOpenType(String openType) {
+        this.openType = openType;
+    }
+
+    public String getApiUrl() {
+        return apiUrl;
+    }
+
+    public void setApiUrl(String apiUrl) {
+        this.apiUrl = apiUrl;
+    }
+
+    public String getMemberNo() {
+        return memberNo;
+    }
+
+    public void setMemberNo(String memberNo) {
+        this.memberNo = memberNo;
+    }
+
+    public String getPublicKey() {
+        return publicKey;
+    }
+
+    public void setPublicKey(String publicKey) {
+        this.publicKey = publicKey;
+    }
+
+    public String getPrivateKey() {
+        return privateKey;
+    }
+
+    public void setPrivateKey(String privateKey) {
+        this.privateKey = privateKey;
+    }
+
+    public String getMd5Key() {
+        return md5Key;
+    }
+
+    public void setMd5Key(String md5Key) {
+        this.md5Key = md5Key;
+    }
+
+    public String getNotifyUrl() {
+        return notifyUrl;
+    }
+
+    public void setNotifyUrl(String notifyUrl) {
+        this.notifyUrl = notifyUrl;
+    }
+}

+ 32 - 61
toolset/thirdparty-component/src/main/java/com/yonge/toolset/thirdparty/lingxinpay/Withdraw.java → cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/sdk/WithdrawSdk.java

@@ -1,30 +1,32 @@
-package com.yonge.toolset.thirdparty.lingxinpay;
+package com.yonge.cooleshow.biz.dal.sdk;
 
 import com.alibaba.fastjson.JSONObject;
+import com.yonge.cooleshow.biz.dal.props.WithdrawalProperties;
+import com.yonge.toolset.thirdparty.lingxinpay.Md5EncryptUtils;
+import com.yonge.toolset.thirdparty.lingxinpay.RSA;
+import com.yonge.toolset.utils.date.DateUtil;
 import com.yonge.toolset.utils.http.HttpUtil;
 import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 import java.io.IOException;
+import java.util.Date;
 import java.util.HashMap;
 import java.util.Map;
-import java.util.UUID;
 
 /**
  * @author: cy
  * @date: 2022/5/9 11:24
  */
 @Service
-public class Withdraw {
-    private static final Logger logger = LoggerFactory.getLogger(Withdraw.class);
+public class WithdrawSdk {
+    private static final Logger logger = LoggerFactory.getLogger(WithdrawSdk.class);
 
-    private String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCYT5eCY6r8sGWgbiId/VqSZmS6XkBNGMkzUqTIkpkecOzsFBxFXTQmgDeR991YfgqmyOaHsJ/ons/H+e8l+RmHsOm4eErFU+9qXFq+k195YFV1vAR9O7MIG+FR5vmLDuhgimPsgqscWhUrGinc8RUpi5KwClgx7d+d8ZJ4GmkR0QIDAQAB";
-    private String md5Key = "0fd42370bad6485e46718b97f3dd1536";
-    private String notifyUrl = "http://47.114.1.200:8000/teacher-server/withdraw/callback";//回调地址
-    private String memberNo = "1491663782974988288";//商户号
-    private String apiUrl = "http://39.107.15.64:8090";//第三方url
+    @Autowired
+    private WithdrawalProperties withdrawalProperties;
 
     /**
      * 单笔提现
@@ -35,35 +37,34 @@ public class Withdraw {
      * @param certificateNo 收款方身份证号
      * @param predictAmount 应发金额(单位为:分,范围: 1~10000000000)
      * @param payAccount    收款方账号(银行卡号/支付宝账号 /open_id)以实际业务为准
-     * @param cardType      卡类型:DC 借记卡
-     * @param salaryType    发放类型(0:个人经营所得)
-     * @param projectName   项目名称
-     * @param payType       支付类型(1:银行卡,2:支付宝,4:微信) 以实际业务为准
-     * @param cardAttribute 卡属性:(C:对私)
      * @param remark        备注(扩展字段) 只针对测试环境:只要参数合规都会返回交易成功,如果想要模拟交易失败,该字段值中含有“失败”二字即会失败。
      * @return
      */
-    public String withdraw(String outerOrderNo, String name, String mobile, String certificateNo, String predictAmount,
-                           String payAccount, String cardType, String salaryType, String projectName, String payType, String cardAttribute, String remark) {
+    public String withdraw(String outerOrderNo, String name, String mobile, String certificateNo, Integer predictAmount,
+                           String payAccount, String remark) {
         Map<String, Object> map = new HashMap<>();
-        map.put("outMemberNo", memberNo);
+        map.put("outMemberNo", withdrawalProperties.getMemberNo());
         map.put("outerOrderNo", outerOrderNo);
         map.put("name", name);
         map.put("certificateNo", certificateNo);
         map.put("predictAmount", predictAmount);
-        String signs = Md5EncryptUtils.sign(map, md5Key);
+        String signs = Md5EncryptUtils.sign(map, withdrawalProperties.getMd5Key());
 
         map.put("charset", "UTF-8");
         map.put("mobile", mobile);
         map.put("version", "1.1");
         map.put("service", "bpotop.zx.pay.order");
         map.put("Md5Key", signs);
-        map.put("notifyUrl", notifyUrl);
-        map.put("cardType", cardType);
-        map.put("salaryType", salaryType);
-        map.put("projectName", projectName);
-        map.put("payType", payType);
-        map.put("cardAttribute", cardAttribute);
+        map.put("notifyUrl", withdrawalProperties.getNotifyUrl());
+        //卡类型 DC 借记卡
+        map.put("cardType", "DC");
+        //输入发放类型(0:工资,1:奖金,2:绩效,3:劳务,4:个人经营所得,5:其他)
+        map.put("salaryType", 4);
+        map.put("projectName", name + DateUtil.format(new Date(), DateUtil.DEFAULT_PATTERN) + "提现");
+        //支付类型(1:银行卡,2:支付宝,4:微信) 以实际业务为准
+        map.put("payType", 1);
+        //卡属性:(C:对私)
+        map.put("cardAttribute", "C");
         map.put("payAccount", payAccount);
         if (StringUtils.isNotBlank(remark)) {
             map.put("remark", remark);
@@ -74,8 +75,8 @@ public class Withdraw {
         JSONObject mapParam = new JSONObject();
         try {
             //使用公钥加密
-            String encryptStr = RSA.encryptPub(jsonStr, publicKey);
-            mapParam.put("outMemberNo", memberNo);
+            String encryptStr = RSA.encryptPub(jsonStr, withdrawalProperties.getPublicKey());
+            mapParam.put("outMemberNo", withdrawalProperties.getMemberNo());
             mapParam.put("signType", "RSA");
             mapParam.put("sign", encryptStr);
             logger.info("单笔请求请求参数:{}", JSONObject.toJSONString(mapParam));
@@ -85,7 +86,7 @@ public class Withdraw {
 
         //发送
         try {
-            String resultJsonStr = HttpUtil.postForHttp(apiUrl + "/bpotop_trade/single", JSONObject.toJSONString(mapParam), null);
+            String resultJsonStr = HttpUtil.postForHttp(withdrawalProperties.getApiUrl() + "/bpotop_trade/single", JSONObject.toJSONString(mapParam), null);
             logger.info("单笔请求返回参数:{}", resultJsonStr);
             return resultJsonStr;
         } catch (IOException e) {
@@ -102,51 +103,21 @@ public class Withdraw {
      */
     public void query(String outerOrderNo) throws Exception {
         Map<String, Object> requestMap = new HashMap<>();
-        requestMap.put("outMemberNo", memberNo);
+        requestMap.put("outMemberNo", withdrawalProperties.getMemberNo());
         requestMap.put("outerOrderNo", outerOrderNo);
         requestMap.put("service", "bpotop.zx.pay.order");
         requestMap.put("version", "1.0");
         requestMap.put("signType", "RSA");
         requestMap.put("charset", "UTF-8");
         String jsonStr = JSONObject.toJSONString(requestMap);
-        String encryptStr = RSA.encryptPub(jsonStr, publicKey);
+        String encryptStr = RSA.encryptPub(jsonStr, withdrawalProperties.getPublicKey());
 
         Map<String, Object> requestMap2 = new HashMap<>();
-        requestMap2.put("outMemberNo", memberNo);
+        requestMap2.put("outMemberNo", withdrawalProperties.getMemberNo());
         requestMap2.put("sign", encryptStr);
         logger.info("单笔查询请求参数:{}", JSONObject.toJSONString(requestMap2));
-        String resultJsonStr = HttpUtil.postForHttp(apiUrl + "/bpotop_trade/order_query", JSONObject.toJSONString(requestMap2), null);
+        String resultJsonStr = HttpUtil.postForHttp(withdrawalProperties.getApiUrl() + "/bpotop_trade/order_query", JSONObject.toJSONString(requestMap2), null);
         logger.info("单笔查询响应参数:{}", resultJsonStr);
     }
 
-    public static void main(String[] args) throws Exception {
-        Withdraw withdraw = new Withdraw();
-
-        //输入商户订单号
-        String outerOrderNo = UUID.randomUUID().toString().substring(0, 12);
-        //输入收款人手机号
-        String name = "何亮";
-        //输入收款人姓名
-        String mobile = "17600220933";
-        //输入收款人身份证号
-        String certificateNo = "130423199206192818";
-        //输入转账金额(单位分)
-        String predictAmount = "1";
-        //输入收款人账号
-        String payAccount = "6228480018864836772";
-        //输入卡类型:DC借记卡,CC信用卡(暂不支持)
-        String cardType = "DC";
-        //输入发放类型(0:工资,1:奖金,2:绩效,3:劳务,4:个人经营所得,5:其他)
-        String salaryType = "4";
-        //输入项目名称
-        String projectName = "测试";
-        //输入支付类型(1:银行卡)
-        String payType = "1";
-        //输入卡属性:(C:对私 ,B:对公)暂时不支持对公
-        String cardAttribute = "C";
-
-        String requestParam = withdraw.withdraw(outerOrderNo, name, mobile, certificateNo, predictAmount, payAccount, cardType,
-                salaryType, projectName, payType, cardAttribute,null);
-        logger.info("单笔请求返回参数:{}", requestParam);
-    }
 }

+ 11 - 3
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/UserWithdrawalService.java

@@ -2,8 +2,10 @@ package com.yonge.cooleshow.biz.dal.service;
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
 import com.yonge.cooleshow.biz.dal.dto.excel.UserWithdrawalExport;
 import com.yonge.cooleshow.biz.dal.dto.req.WithdrawalReq;
+import com.yonge.cooleshow.biz.dal.entity.UserWithdrawalCallback;
 import com.yonge.cooleshow.biz.dal.vo.UserWithdrawalVo;
 import com.yonge.cooleshow.biz.dal.dto.search.TeacherWithdrawalSearch;
 import com.yonge.cooleshow.biz.dal.entity.UserWithdrawal;
@@ -53,12 +55,18 @@ public interface UserWithdrawalService extends IService<UserWithdrawal>  {
 	/***
 	 * 用户发起提现申请
 	 * @author liweifan
-	 * @param: userId
+	 * @param: user
 	 * @param: withdrawalReq
 	 * @updateTime 2022/4/7 15:26
 	 * @return: com.yonge.cooleshow.common.entity.HttpResponseResult<java.lang.Boolean>
 	 */
-	HttpResponseResult<Boolean> withdrawal(Long userId, WithdrawalReq withdrawalReq);
+	HttpResponseResult<Boolean> withdrawal(SysUser user, WithdrawalReq withdrawalReq);
+
+	/**
+	 * 提现回调
+	 * @param callback
+	 */
+	void callback(UserWithdrawalCallback callback,String jsonStr);
 
 	/***
 	 * 导入
@@ -67,5 +75,5 @@ public interface UserWithdrawalService extends IService<UserWithdrawal>  {
 	 * @updateTime 2022/4/20 9:45
 	 * @return: com.yonge.cooleshow.common.entity.HttpResponseResult<java.util.List<com.yonge.toolset.utils.easyexcel.ErrMsg>>
 	 */
-    void importExcel(List<ExcelDataReaderProperty<UserWithdrawalExport>> dataList, Long userId);
+    /*void importExcel(List<ExcelDataReaderProperty<UserWithdrawalExport>> dataList, Long userId);*/
 }

+ 81 - 18
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/UserWithdrawalServiceImpl.java

@@ -2,16 +2,19 @@ package com.yonge.cooleshow.biz.dal.service.impl;
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
 import com.yonge.cooleshow.biz.dal.dto.excel.UserWithdrawalExport;
-import com.yonge.cooleshow.biz.dal.enums.FrozenTypeEnum;
+import com.yonge.cooleshow.biz.dal.entity.UserWithdrawalCallback;
+import com.yonge.cooleshow.biz.dal.enums.*;
+import com.yonge.cooleshow.biz.dal.props.WithdrawalProperties;
+import com.yonge.cooleshow.biz.dal.sdk.WithdrawSdk;
+import com.yonge.cooleshow.biz.dal.service.TeacherService;
+import com.yonge.cooleshow.biz.dal.vo.TeacherVo;
 import com.yonge.cooleshow.common.constant.SysConfigConstant;
 import com.yonge.cooleshow.biz.dal.dao.UserBankCardDao;
 import com.yonge.cooleshow.biz.dal.dto.UserAccountRecordDto;
 import com.yonge.cooleshow.biz.dal.dto.req.WithdrawalReq;
 import com.yonge.cooleshow.biz.dal.entity.UserAccountRecord;
-import com.yonge.cooleshow.biz.dal.enums.AccountBizTypeEnum;
-import com.yonge.cooleshow.biz.dal.enums.AuthStatusEnum;
-import com.yonge.cooleshow.biz.dal.enums.InOrOutEnum;
 import com.yonge.cooleshow.biz.dal.service.SysConfigService;
 import com.yonge.cooleshow.biz.dal.service.UserAccountService;
 import com.yonge.cooleshow.biz.dal.vo.UserAccountVo;
@@ -27,6 +30,7 @@ import com.yonge.toolset.utils.string.ValueUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.core.parameters.P;
 import org.springframework.stereotype.Service;
 import com.yonge.cooleshow.biz.dal.entity.UserWithdrawal;
 import com.yonge.cooleshow.biz.dal.vo.UserWithdrawalVo;
@@ -52,7 +56,10 @@ public class UserWithdrawalServiceImpl extends ServiceImpl<UserWithdrawalDao, Us
     private UserAccountService userAccountService;
     @Autowired
     private SysConfigService sysConfigService;
-
+    @Autowired
+    private WithdrawalProperties withdrawalProperties;
+    @Autowired
+    private WithdrawSdk withdrawSdk;
 
     @Override
     public UserWithdrawalVo detail(Long id) {
@@ -91,34 +98,40 @@ public class UserWithdrawalServiceImpl extends ServiceImpl<UserWithdrawalDao, Us
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public HttpResponseResult<Boolean> withdrawal(Long userId, WithdrawalReq withdrawalReq) {
+    public HttpResponseResult<Boolean> withdrawal(SysUser user, WithdrawalReq withdrawalReq) {
         BigDecimal withdrawalServiceFee = getWithdrawalServiceFee();
         //校验金额
         if (withdrawalReq.getAmountWithdrawal().subtract(withdrawalServiceFee).floatValue() < 0) {
             return HttpResponseResult.failed("提现金额过小");
         }
         //获取用户提现金额
-        BigDecimal amountWithdrawal = getAmountUsable(userId);
+        BigDecimal amountWithdrawal = getAmountUsable(user.getId());
         //比较大小
         if (amountWithdrawal.compareTo(withdrawalReq.getAmountWithdrawal()) < 0) {
             return HttpResponseResult.failed("账户余额不足");
         }
         //获取提现银行卡
-        UserBankCardVo bankCardVo = bankCardDao.getBankByUserIdAndCardId(userId, withdrawalReq.getBankCardId());
+        UserBankCardVo bankCardVo = bankCardDao.getBankByUserIdAndCardId(user.getId(), withdrawalReq.getBankCardId());
         if (null == bankCardVo) {
             return HttpResponseResult.failed("未找到用户绑卡信息");
         }
+
         //插入用户提现表
-        UserWithdrawal userWithdrawal = insertUserWithdrawal(userId, withdrawalReq, bankCardVo, withdrawalServiceFee);
+        UserWithdrawal userWithdrawal = insertUserWithdrawal(user.getId(), withdrawalReq, bankCardVo, withdrawalServiceFee);
         //插入账户变更
         UserAccountRecordDto accountRecordDto = new UserAccountRecordDto(
-                userId, withdrawalReq.getAmountWithdrawal(), InOrOutEnum.OUT, AccountBizTypeEnum.WITHDRAWAL,
+                user.getId(), withdrawalReq.getAmountWithdrawal(), InOrOutEnum.OUT, AccountBizTypeEnum.WITHDRAWAL,
                 userWithdrawal.getId(), "老师提现", null
         );
         accountRecordDto.setFrozenType(FrozenTypeEnum.FROZEN);
         accountRecordDto.setSaveRecord(false);
         HttpResponseResult<UserAccountRecord> accountChange = userAccountService.accountChange(accountRecordDto);
         if (accountChange.getStatus()) {
+            //请求三方接口
+            withdrawSdk.withdraw(
+                    userWithdrawal.getId().toString(), bankCardVo.getName(), bankCardVo.getPhone(), user.getIdCardNo(),
+                    amountWithdrawal.multiply(new BigDecimal("100")).intValue(), bankCardVo.getBankCard(), null
+            );
             return HttpResponseResult.succeed(true);
         } else {
             throw new BizException("提现失败");
@@ -127,6 +140,58 @@ public class UserWithdrawalServiceImpl extends ServiceImpl<UserWithdrawalDao, Us
 
     @Override
     @Transactional(rollbackFor = Exception.class)
+    public void callback(UserWithdrawalCallback callback, String jsonStr) {
+        if (StringUtil.isEmpty(callback.getOuterOrderNo()) ||
+                StringUtil.isEmpty(callback.getStatus())) {
+            throw new BizException("参数异常,参数缺失,param is {}", jsonStr);
+        }
+        UserWithdrawalVo detail = detail(Long.parseLong(callback.getOuterOrderNo().trim()));
+        if (null == detail) {
+            throw new BizException("参数异常,未找到交易记录,param is {}", jsonStr);
+        }
+        if(!TradeStatusEnum.pending.equals(detail.getStatus())){
+            return;
+        }
+        if ("1".equals(callback.getStatus())) {
+            //交易成功
+            detail.setStatus(TradeStatusEnum.succeeded);
+            detail.setTransNo(callback.getOrderNo());
+            BigDecimal actualAmount = new BigDecimal(callback.getActualAmount());
+            detail.setActualAmount(actualAmount.divide(new BigDecimal("100")));
+            detail.setTransferTime(callback.getEndTime());
+
+            //审核通过,账户解冻,入账户明细
+            UserAccountRecordDto accountRecordDto = new UserAccountRecordDto(
+                    detail.getUserId(), detail.getAmount(), InOrOutEnum.OUT, AccountBizTypeEnum.WITHDRAWAL,
+                    detail.getId(), "老师提现", null
+            );
+            accountRecordDto.setFrozenType(FrozenTypeEnum.FROZEN_DEDUCT);
+            accountRecordDto.setSaveRecord(true);
+            userAccountService.accountChange(accountRecordDto);
+
+        }else if("2".equals(callback.getStatus())){
+            //交易失败
+            detail.setStatus(TradeStatusEnum.failed);
+            detail.setErrorCode(callback.getErrorCode());
+            detail.setErrorMsg(callback.getErrorMsg());
+
+            //审核不通过,账户解冻
+            UserAccountRecordDto accountRecordDto = new UserAccountRecordDto(
+                    detail.getUserId(), detail.getAmount(), InOrOutEnum.OUT, AccountBizTypeEnum.WITHDRAWAL,
+                    detail.getId(), "老师提现", null
+            );
+            accountRecordDto.setFrozenType(FrozenTypeEnum.FROZEN_BACK);
+            accountRecordDto.setSaveRecord(false);
+            userAccountService.accountChange(accountRecordDto);
+        }else{
+            return;
+        }
+        detail.setCallbackJson(jsonStr);
+        updateById(detail);
+    }
+
+   /* @Override
+    @Transactional(rollbackFor = Exception.class)
     public void importExcel(List<ExcelDataReaderProperty<UserWithdrawalExport>> dataList, Long userId) {
         List<ErrMsg> errMsgList = new ArrayList<>();
         dataList.sort(Comparator.comparingInt(ExcelDataReaderProperty::getRowIndex));
@@ -171,7 +236,7 @@ public class UserWithdrawalServiceImpl extends ServiceImpl<UserWithdrawalDao, Us
             throw new ExcelException("导入异常", errMsgList);
         }
         authWithdrawalBancth(userWithdrawalList, userId);
-    }
+    }*/
 
     /***
      * 审核
@@ -179,7 +244,7 @@ public class UserWithdrawalServiceImpl extends ServiceImpl<UserWithdrawalDao, Us
      * @param: userWithdrawalList
      * @updateTime 2022/4/20 11:18
      */
-    private void authWithdrawalBancth(List<UserWithdrawal> userWithdrawalList, Long userId) {
+    /*private void authWithdrawalBancth(List<UserWithdrawal> userWithdrawalList, Long userId) {
         for (UserWithdrawal userWithdrawal : userWithdrawalList) {
             UserWithdrawal old = baseMapper.selectById(userWithdrawal.getId());
             if (null == old || !AuthStatusEnum.DOING.equals(old.getStatus()) || AuthStatusEnum.DOING.equals(userWithdrawal.getStatus())) {
@@ -212,7 +277,7 @@ public class UserWithdrawalServiceImpl extends ServiceImpl<UserWithdrawalDao, Us
             }
             baseMapper.updateById(userWithdrawal);
         }
-    }
+    }*/
 
     /***
      * 入提现表
@@ -229,13 +294,11 @@ public class UserWithdrawalServiceImpl extends ServiceImpl<UserWithdrawalDao, Us
         userWithdrawal.setUserId(userId);
         userWithdrawal.setAmount(withdrawalReq.getAmountWithdrawal());
         userWithdrawal.setPlantformFee(withdrawalServiceFee);
-
-        BigDecimal actualAmount = withdrawalReq.getAmountWithdrawal().subtract(withdrawalServiceFee);
-        userWithdrawal.setActualAmount(actualAmount);
-        userWithdrawal.setBankCard(bankCardVo.getBankCard());
+        userWithdrawal.setBankCardId(bankCardVo.getId());
+        userWithdrawal.setOpenType(withdrawalProperties.getOpenType());
+        userWithdrawal.setStatus(TradeStatusEnum.pending);
         userWithdrawal.setCreateTime(new Date());
         userWithdrawal.setUpdateTime(new Date());
-        userWithdrawal.setStatus(AuthStatusEnum.DOING);
         baseMapper.insert(userWithdrawal);
         return userWithdrawal;
     }

+ 6 - 7
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/vo/UserWithdrawalVo.java

@@ -10,15 +10,14 @@ import io.swagger.annotations.ApiModelProperty;
  */
 @ApiModel(value = "UserWithdrawalVo对象", description = "账户提现表查询视图对象")
 public class UserWithdrawalVo extends UserWithdrawal {
-
 	private static final long serialVersionUID = 1L;
 
+	@ApiModelProperty("银行卡号 ")
+	private String bankCard;
 	@ApiModelProperty("银行名称 ")
 	private String bankName;
 	@ApiModelProperty("提现人 ")
 	private String	withdrawaUser;
-	@ApiModelProperty("转账人 ")
-	private String verifyUser;
 
 	public String getBankName() {
 		return bankName;
@@ -36,11 +35,11 @@ public class UserWithdrawalVo extends UserWithdrawal {
 		this.withdrawaUser = withdrawaUser;
 	}
 
-	public String getVerifyUser() {
-		return verifyUser;
+	public String getBankCard() {
+		return bankCard;
 	}
 
-	public void setVerifyUser(String verifyUser) {
-		this.verifyUser = verifyUser;
+	public void setBankCard(String bankCard) {
+		this.bankCard = bankCard;
 	}
 }

+ 27 - 28
cooleshow-user/user-biz/src/main/resources/config/mybatis/UserWithdrawalMapper.xml

@@ -1,43 +1,51 @@
 <?xml version="1.0" encoding="UTF-8" ?>
 <!DOCTYPE  mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
 <mapper namespace="com.yonge.cooleshow.biz.dal.dao.UserWithdrawalDao">
+
     <resultMap id="BaseResultMap" type="com.yonge.cooleshow.biz.dal.entity.UserWithdrawal">
         <result column="id_" property="id" />
         <result column="user_id_" property="userId" />
         <result column="amount_" property="amount" />
         <result column="plantform_fee_" property="plantformFee" />
+        <result column="bank_card_id_" property="bankCardId" />
+        <result column="open_type_" property="openType" />
+        <result column="trans_no_" property="transNo" />
+        <result column="status_" property="status" />
         <result column="actual_amount_" property="actualAmount" />
-        <result column="bank_card_" property="bankCard" />
-        <result column="bank_flow_no_" property="bankFlowNo" />
         <result column="transfer_time_" property="transferTime" />
-        <result column="status_" property="status" />
-        <result column="verify_user_id_" property="verifyUserId" />
-        <result column="verify_reason_" property="verifyReason" />
+        <result column="error_code_" property="errorCode" />
+        <result column="error_msg_" property="errorMsg" />
         <result column="create_time_" property="createTime" />
         <result column="update_time_" property="updateTime" />
     </resultMap>
 
     <!-- 表字段 -->
     <sql id="baseColumns">
-         t.id_ as id
+        t.id_ as id
         , t.user_id_ as userId
         , t.amount_ as amount
         , t.plantform_fee_ as plantformFee
+        , t.bank_card_id_ as bankCardId
+        , t.open_type_ as openType
+        , t.trans_no_ as transNo
+        , t.status_ as status
         , t.actual_amount_ as actualAmount
-        , t.bank_card_ as bankCard
-        , t.bank_flow_no_ as bankFlowNo
         , t.transfer_time_ as transferTime
-        , t.status_ as status
-        , t.verify_user_id_ as verifyUserId
-        , t.verify_reason_ as verifyReason
+        , t.error_code_ as errorCode
+        , t.error_msg_ as errorMsg
         , t.create_time_ as createTime
         , t.update_time_ as updateTime
-        </sql>
+    </sql>
 
     <select id="detail" resultType="com.yonge.cooleshow.biz.dal.vo.UserWithdrawalVo">
         SELECT
-        <include refid="baseColumns"/>
+            <include refid="baseColumns"/>,
+            bc.bank_name_ as bankName,
+            bc.bank_card_ as bankCard,
+            u.username_  as withdrawaUser
         FROM user_withdrawal t
+        LEFT JOIN user_bank_card bc on t.bank_card_id_ = bc.id_ and t.user_id_ = bc.user_id_
+        left join sys_user u on t.user_id_ = u.id_
         where t.id_ = #{id}
     </select>
 
@@ -45,13 +53,11 @@
         SELECT
             <include refid="baseColumns" />,
             bc.bank_name_ as bankName,
-            u.username_  as withdrawaUser,
-            (
-                SELECT u.username_ FROM sys_user u WHERE u.id_ = t.verify_user_id_
-            ) as verifyUser
+            bc.bank_card_ as bankCard,
+            u.username_  as withdrawaUser
         FROM user_withdrawal t
-        left join sys_user u on u.id_ = t.user_id_
-        LEFT JOIN user_bank_card bc on t.bank_card_ = bc.bank_card_ and t.user_id_ = bc.user_id_ and bc.del_flag_ = 0
+        LEFT JOIN user_bank_card bc on t.bank_card_id_ = bc.id_ and t.user_id_ = bc.user_id_
+        left join sys_user u on t.user_id_ = u.id_
         <where>
             <if test="null != param.search and '' != param.search">
                 AND (
@@ -60,8 +66,8 @@
                     u.phone_ LIKE CONCAT('%', #{param.search}, '%')
                 )
             </if>
-            <if test="null != param.bankFlowNo and '' != param.bankFlowNo">
-                AND t.bank_flow_no_ LIKE CONCAT('%', #{param.bankFlowNo}, '%')
+            <if test="null != param.transNo and '' != param.transNo">
+                AND t.trans_no_ LIKE CONCAT('%', #{transNo}, '%')
             </if>
             <if test="param.startTime !=null">
                 <![CDATA[AND t.create_time_ >= #{param.startTime} ]]>
@@ -81,11 +87,4 @@
     <select id="selectList" resultType="com.yonge.cooleshow.biz.dal.vo.UserWithdrawalVo">
         <include refid="selectSql"/>
     </select>
-
-    <insert id="withdrawSuccess" parameterType="java.util.Map">
-        INSERT INTO user_withdrawal_history
-        VALUES (#{outMemberNo},#{outerOrderNo},#{orderNo},#{name},#{mobile},#{certificateNo},
-                #{status},#{payType},#{payAccount},#{predictAmount},#{actualAmount},#{endTime})
-    </insert>
-
 </mapper>

+ 0 - 2
cooleshow-user/user-student/src/main/java/com/yonge/cooleshow/student/controller/PaymentController.java

@@ -125,8 +125,6 @@ public class PaymentController extends BaseController {
         String merchantId = configPaymentService.getPaymentConfig(OpenEnum.ORIGINAL, WxpayConstant.WX_MERCHANT_ID).getParamValue();
         String apiV3Key = configPaymentService.getPaymentConfig(OpenEnum.ORIGINAL, WxpayConstant.WX_API_V3_KEY).getParamValue();
 
-
-
         //支付回调
         if ("executePayment".equals(payMethod)) {
 

+ 48 - 1
cooleshow-user/user-teacher/src/main/java/com/yonge/cooleshow/teacher/controller/UserWithdrawalController.java

@@ -1,10 +1,13 @@
 package com.yonge.cooleshow.teacher.controller;
 
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
 import com.yonge.cooleshow.auth.api.entity.SysUser;
 import com.yonge.cooleshow.biz.dal.dto.req.WithdrawalReq;
 import com.yonge.cooleshow.biz.dal.dto.search.TeacherWithdrawalSearch;
+import com.yonge.cooleshow.biz.dal.entity.UserWithdrawalCallback;
+import com.yonge.cooleshow.biz.dal.props.WithdrawalProperties;
 import com.yonge.cooleshow.biz.dal.service.UserWithdrawalService;
 import com.yonge.cooleshow.biz.dal.support.PageUtil;
 import com.yonge.cooleshow.biz.dal.vo.UserWithdrawalVo;
@@ -13,33 +16,46 @@ import com.yonge.cooleshow.common.controller.BaseController;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.toolset.base.exception.BizException;
 import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.thirdparty.lingxinpay.RSA;
 import com.yonge.toolset.utils.date.DateUtil;
+import com.yonge.toolset.utils.json.JsonUtil;
 import com.yonge.toolset.utils.string.StringUtil;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiImplicitParam;
 import io.swagger.annotations.ApiImplicitParams;
 import io.swagger.annotations.ApiOperation;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.http.HttpStatus;
 import org.springframework.web.bind.annotation.*;
 import springfox.documentation.annotations.ApiIgnore;
 
+import javax.servlet.http.HttpServletRequest;
 import javax.validation.Valid;
 import java.time.LocalDate;
 import java.time.LocalDateTime;
 import java.time.LocalTime;
 import java.time.temporal.TemporalAdjusters;
 import java.util.Date;
+import java.util.Map;
 
 @RestController
 @RequestMapping("/userWithdrawal")
 @Api(value = "用户账户提现表", tags = "用户账户提现表")
 public class UserWithdrawalController extends BaseController {
+    private final static Logger log = LoggerFactory.getLogger(UserWithdrawalController.class);
+
     @Autowired
     private UserWithdrawalService userWithdrawalService;
+
     @Autowired
     private SysUserFeignService sysUserFeignService;
 
+    @Autowired
+    private WithdrawalProperties withdrawalProperties;
+
     @PostMapping("/getWithdrawalInfo")
     @ApiOperation(value = "查询提现页面信息")
     public HttpResponseResult<WithdrawalInfoRes> getWithdrawalInfo() {
@@ -57,7 +73,7 @@ public class UserWithdrawalController extends BaseController {
         if (user == null || null == user.getId()) {
             return failed(HttpStatus.FORBIDDEN, "请登录");
         }
-        return userWithdrawalService.withdrawal(user.getId(), withdrawalReq);
+        return userWithdrawalService.withdrawal(user, withdrawalReq);
     }
 
     @PostMapping("/withdrawalPage")
@@ -101,4 +117,35 @@ public class UserWithdrawalController extends BaseController {
         return succeed(PageUtil.pageInfo(pages));
     }
 
+    /**
+     * 异步回调接收
+     * @param content
+     * @param request
+     * @return
+     */
+    @PostMapping("/callback")
+    public String callback(@RequestBody String content, HttpServletRequest request) {
+        log.info("交易回调请求地址:{} 请求参数:{}", request.getRemoteAddr(), content);
+        try {
+            if (StringUtils.isBlank(content)) {
+                throw new Exception();
+            }
+            Map<String, Object> map = JSONObject.parseObject(content);
+            String jsonStr = RSA.decryptPri((String) map.get("sign"), withdrawalProperties.getPrivateKey());
+            log.info("jsonStr:{}", jsonStr);
+
+            Map<String, Object> withdrawRecord = JSONObject.parseObject(jsonStr);
+            UserWithdrawalCallback callback = JsonUtil.toJavaObject(withdrawRecord, UserWithdrawalCallback.class);
+
+            userWithdrawalService.callback(callback, jsonStr);
+        } catch (BizException e) {
+            log.error("解密失败e:{}", e.getMessage());
+            return "failed";
+        } catch (Exception e) {
+            log.error("解密失败e:{}", e);
+            return "failed";
+        }
+        return "success";
+    }
+
 }

+ 5 - 17
cooleshow-user/user-teacher/src/main/java/com/yonge/cooleshow/teacher/controller/WithdrawController.java

@@ -4,9 +4,8 @@ import com.alibaba.fastjson.JSONObject;
 import com.yonge.cooleshow.biz.dal.entity.UserWithdrawalCallback;
 import com.yonge.cooleshow.biz.dal.service.UserWithdrawalCallbackService;
 import com.yonge.cooleshow.common.controller.BaseController;
-import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.toolset.thirdparty.lingxinpay.RSA;
-import com.yonge.toolset.thirdparty.lingxinpay.Withdraw;
+import com.yonge.cooleshow.biz.dal.sdk.WithdrawSdk;
 import com.yonge.toolset.utils.json.JsonUtil;
 import io.swagger.annotations.Api;
 import org.apache.commons.lang3.StringUtils;
@@ -66,8 +65,7 @@ public class WithdrawController extends BaseController {
 
     @GetMapping("/test")
     public String a(String remark) {
-        Withdraw withdraw = new Withdraw();
-
+        WithdrawSdk withdraw = new WithdrawSdk();
         //输入商户订单号
         String outerOrderNo = UUID.randomUUID().toString().substring(0, 12);
         System.out.println("商户订单号:" + outerOrderNo);
@@ -78,22 +76,12 @@ public class WithdrawController extends BaseController {
         //输入收款人身份证号
         String certificateNo = "130423199206192818";
         //输入转账金额(单位分)
-        String predictAmount = "1";
+        Integer predictAmount = 1;
         //输入收款人账号
         String payAccount = "6228480018864836772";
-        //输入卡类型:DC借记卡,CC信用卡(暂不支持)
-        String cardType = "DC";
-        //输入发放类型(0:工资,1:奖金,2:绩效,3:劳务,4:个人经营所得,5:其他)
-        String salaryType = "4";
-        //输入项目名称
-        String projectName = "测试";
-        //输入支付类型(1:银行卡)
-        String payType = "1";
-        //输入卡属性:(C:对私 ,B:对公)暂时不支持对公
-        String cardAttribute = "C";
 
-        String requestParam = withdraw.withdraw(outerOrderNo, name, mobile, certificateNo, predictAmount, payAccount, cardType,
-                salaryType, projectName, payType, cardAttribute, remark);
+        String requestParam = withdraw.withdraw(outerOrderNo, name, mobile, certificateNo, predictAmount,
+                payAccount, remark);
         log.info("单笔请求返回参数:{}", requestParam);
         return requestParam;
     }