Prechádzať zdrojové kódy

Merge remote-tracking branch 'origin/master'

weifanli 2 rokov pred
rodič
commit
6fdc977648
54 zmenil súbory, kde vykonal 2370 pridanie a 60 odobranie
  1. 2 3
      cooleshow-auth/auth-api/src/main/java/com/yonge/cooleshow/auth/api/client/SysUserFeignService.java
  2. 1 1
      cooleshow-auth/auth-api/src/main/java/com/yonge/cooleshow/auth/api/client/fallback/SysUserFeignServiceFallback.java
  3. 0 16
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/web/controller/TokenController.java
  4. 3 1
      cooleshow-mall/mall-admin/src/main/java/com/yonge/cooleshow/admin/controller/UmsAdminController.java
  5. 5 0
      cooleshow-mall/mall-common/pom.xml
  6. 15 0
      cooleshow-mall/mall-mbg/src/main/java/com/yonge/cooleshow/mbg/mapper/UserOrderPaymentMapper.java
  7. 11 0
      cooleshow-mall/mall-mbg/src/main/java/com/yonge/cooleshow/mbg/model/OmsOrderSetting.java
  8. 145 0
      cooleshow-mall/mall-mbg/src/main/java/com/yonge/cooleshow/mbg/model/UserOrderPayment.java
  9. 2 1
      cooleshow-mall/mall-mbg/src/main/resources/config/mybatis/OmsOrderSettingMapper.xml
  10. 184 0
      cooleshow-mall/mall-mbg/src/main/resources/config/mybatis/UserOrderPaymentMapper.xml
  11. 30 0
      cooleshow-mall/mall-pay/pom.xml
  12. 36 0
      cooleshow-mall/mall-pay/src/main/java/com/yonge/cooleshow/config/HuifuConfiguration.java
  13. 68 0
      cooleshow-mall/mall-pay/src/main/java/com/yonge/cooleshow/enums/OrdeerCacherEnmu.java
  14. 40 0
      cooleshow-mall/mall-pay/src/main/java/com/yonge/cooleshow/enums/OrderStatusEnum.java
  15. 36 0
      cooleshow-mall/mall-pay/src/main/java/com/yonge/cooleshow/enums/PayChannelEnum.java
  16. 37 0
      cooleshow-mall/mall-pay/src/main/java/com/yonge/cooleshow/enums/PayStatusEnum.java
  17. 110 0
      cooleshow-mall/mall-pay/src/main/java/com/yonge/cooleshow/props/HuifuProperties.java
  18. 221 0
      cooleshow-mall/mall-pay/src/main/java/com/yonge/cooleshow/sdk/PaymentSdk.java
  19. 27 0
      cooleshow-mall/mall-pay/src/main/java/com/yonge/cooleshow/sdk/req/DeviceInfo.java
  20. 55 0
      cooleshow-mall/mall-pay/src/main/java/com/yonge/cooleshow/sdk/req/DivMember.java
  21. 147 0
      cooleshow-mall/mall-pay/src/main/java/com/yonge/cooleshow/sdk/req/OrderPayReq.java
  22. 73 0
      cooleshow-mall/mall-pay/src/main/java/com/yonge/cooleshow/sdk/req/PaymentConfirmParam.java
  23. 168 0
      cooleshow-mall/mall-pay/src/main/java/com/yonge/cooleshow/sdk/req/PaymentReq.java
  24. 100 0
      cooleshow-mall/mall-pay/src/main/java/com/yonge/cooleshow/sdk/res/OrderPayRes.java
  25. 27 0
      cooleshow-mall/mall-pay/src/main/java/com/yonge/cooleshow/service/PaymentService.java
  26. 109 0
      cooleshow-mall/mall-pay/src/main/java/com/yonge/cooleshow/service/impl/AdapayPaymentServiceImpl.java
  27. 15 1
      cooleshow-mall/mall-portal/pom.xml
  28. 1 1
      cooleshow-mall/mall-portal/src/main/java/com/yonge/cooleshow/portal/MallPortalApplication.java
  29. 1 1
      cooleshow-mall/mall-portal/src/main/java/com/yonge/cooleshow/portal/controller/OmsPortalOrderController.java
  30. 129 0
      cooleshow-mall/mall-portal/src/main/java/com/yonge/cooleshow/portal/controller/PaymentController.java
  31. 1 1
      cooleshow-mall/mall-portal/src/main/java/com/yonge/cooleshow/portal/dao/PortalOrderDao.java
  32. 21 0
      cooleshow-mall/mall-portal/src/main/java/com/yonge/cooleshow/portal/service/OmsPortalOrderService.java
  33. 29 0
      cooleshow-mall/mall-portal/src/main/java/com/yonge/cooleshow/portal/service/UserOrderPaymentService.java
  34. 193 3
      cooleshow-mall/mall-portal/src/main/java/com/yonge/cooleshow/portal/service/impl/OmsPortalOrderServiceImpl.java
  35. 39 0
      cooleshow-mall/mall-portal/src/main/java/com/yonge/cooleshow/portal/service/impl/UserOrderPaymentServiceImpl.java
  36. 11 8
      cooleshow-mall/mall-portal/src/main/java/com/yonge/cooleshow/portal/task/OrderTimeOutCancelTask.java
  37. 116 0
      cooleshow-mall/mall-portal/src/main/java/com/yonge/cooleshow/portal/util/DistributedLock.java
  38. 3 2
      cooleshow-mall/mall-portal/src/main/resources/config/mybatis/PortalOrderDao.xml
  39. 1 0
      cooleshow-mall/pom.xml
  40. 17 0
      cooleshow-task/src/main/java/com/yonge/cooleshow/task/feign/MallPortalFeignService.java
  41. 16 0
      cooleshow-task/src/main/java/com/yonge/cooleshow/task/feign/fallback/MallPortalFeignServiceFallback.java
  42. 25 0
      cooleshow-task/src/main/java/com/yonge/cooleshow/task/jobs/CancelTimeOutOrderTask.java
  43. 5 4
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/MusicSheetPurchaseRecord.java
  44. 1 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/TeacherFreeTime.java
  45. 1 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/MusicSheetPurchaseRecordService.java
  46. 14 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/MusicSheetService.java
  47. 14 7
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/MusicSheetPurchaseRecordServiceImpl.java
  48. 38 6
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/MusicSheetServiceImpl.java
  49. 0 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/TeacherFreeTimeServiceImpl.java
  50. 7 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/UserOrderServiceImpl.java
  51. 1 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/VideoLessonGroupDetailServiceImpl.java
  52. 12 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/vo/MusicSheetDetailVo.java
  53. 2 1
      cooleshow-user/user-biz/src/main/resources/config/mybatis/MusicSheetMapper.xml
  54. 5 0
      pom.xml

+ 2 - 3
cooleshow-auth/auth-api/src/main/java/com/yonge/cooleshow/auth/api/client/SysUserFeignService.java

@@ -55,10 +55,9 @@ public interface SysUserFeignService {
 										   @RequestParam("clientId")String clientId,
 										   @RequestParam("clientSecret")String clientSecret);
 
-	@GetMapping(value = "/remote/exit")
+	@PostMapping(value = "exit",consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
 	@ApiOperation(value = "退出登录")
-	public HttpResponseResult<String> remoteExit();
-
+	HttpResponseResult<String> logout();
 
 	@PostMapping(value = "user/list")
 	HttpResponseResult<List<SysUser>> page(@RequestBody SysUserQueryInfo queryInfo);

+ 1 - 1
cooleshow-auth/auth-api/src/main/java/com/yonge/cooleshow/auth/api/client/fallback/SysUserFeignServiceFallback.java

@@ -72,7 +72,7 @@ public class SysUserFeignServiceFallback implements SysUserFeignService {
 	}
 
 	@Override
-	public HttpResponseResult<String> remoteExit() {
+	public HttpResponseResult<String> logout() {
 		return HttpResponseResult.failed("请求失败");
 	}
 

+ 0 - 16
cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/web/controller/TokenController.java

@@ -141,22 +141,6 @@ public class TokenController extends BaseController {
 		return succeed("退出成功");
 	}
 
-	@GetMapping(value = "/remote/exit")
-	@ApiOperation(value = "退出登录")
-	public HttpResponseResult<String> remoteExit(HttpServletRequest request) {
-
-		String authHeader = request.getHeader(HttpHeaders.AUTHORIZATION);
-		if (StringUtils.isBlank(authHeader)) {
-			return failed("退出失败,token 为空");
-		}
-
-		String tokenValue = authHeader.toLowerCase().replace(OAuth2AccessToken.BEARER_TYPE.toLowerCase(), StringUtils.EMPTY).trim();
-
-		tokenService.revokeToken(tokenValue);
-
-		return succeed("退出成功");
-	}
-
 	@PostMapping(value = "exit/{clientId}/{phone}", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
 	@ApiOperation(value = "指定用户退出登录")
 	public HttpResponseResult<String> exitByPhone(@PathVariable("clientId") String clientId, @PathVariable("phone") String phone) {

+ 3 - 1
cooleshow-mall/mall-admin/src/main/java/com/yonge/cooleshow/admin/controller/UmsAdminController.java

@@ -101,7 +101,9 @@ public class UmsAdminController {
     @RequestMapping(value = "/logout", method = RequestMethod.POST)
     @ResponseBody
     public CommonResult logout(HttpServletRequest request) {
-        HttpResponseResult<String> logout = sysUserFeignService.remoteExit();
+        // HttpResponseResult<String> logout = sysUserFeignService.remoteExit();
+
+        HttpResponseResult<String> logout = sysUserFeignService.logout();
         if (logout.getStatus()) {
             return CommonResult.success(logout.getData());
         } else {

+ 5 - 0
cooleshow-mall/mall-common/pom.xml

@@ -19,6 +19,10 @@
 
     <dependencies>
 
+        <dependency>
+            <groupId>com.yonge.cooleshow</groupId>
+            <artifactId>cooleshow-common</artifactId>
+        </dependency>
 
         <dependency>
             <groupId>com.alibaba</groupId>
@@ -60,6 +64,7 @@
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-validation</artifactId>
         </dependency>
+
     </dependencies>
 
 </project>

+ 15 - 0
cooleshow-mall/mall-mbg/src/main/java/com/yonge/cooleshow/mbg/mapper/UserOrderPaymentMapper.java

@@ -0,0 +1,15 @@
+package com.yonge.cooleshow.mbg.mapper;
+
+import com.yonge.cooleshow.mbg.model.UmsRole;
+import com.yonge.cooleshow.mbg.model.UserOrderPayment;
+
+public interface UserOrderPaymentMapper {
+
+
+    int insert(UserOrderPayment record);
+
+
+    UserOrderPayment selectByOrderNo(String orderNo);
+
+    int updateByPrimaryKeySelective(UserOrderPayment userOrderPayment);
+}

+ 11 - 0
cooleshow-mall/mall-mbg/src/main/java/com/yonge/cooleshow/mbg/model/OmsOrderSetting.java

@@ -21,6 +21,9 @@ public class OmsOrderSetting implements Serializable {
     @ApiModelProperty(value = "订单完成后自动好评时间(天)")
     private Integer commentOvertime;
 
+    @ApiModelProperty("付款超时时间")
+    private Integer payOrderOvertime;
+
     private static final long serialVersionUID = 1L;
 
     public Long getId() {
@@ -87,4 +90,12 @@ public class OmsOrderSetting implements Serializable {
         sb.append("]");
         return sb.toString();
     }
+
+    public Integer getPayOrderOvertime() {
+        return payOrderOvertime;
+    }
+
+    public void setPayOrderOvertime(Integer payOrderOvertime) {
+        this.payOrderOvertime = payOrderOvertime;
+    }
 }

+ 145 - 0
cooleshow-mall/mall-mbg/src/main/java/com/yonge/cooleshow/mbg/model/UserOrderPayment.java

@@ -0,0 +1,145 @@
+package com.yonge.cooleshow.mbg.model;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.Date;
+
+/**
+ * 平台订单支付表
+ */
+
+@ApiModel(value = "UserOrderPayment对象", description = "平台订单支付表")
+public class UserOrderPayment implements Serializable {
+	private static final long serialVersionUID = 1L;
+
+    private Long id;
+    @ApiModelProperty("订单号 ")
+    private String orderNo;
+    @ApiModelProperty("交易流水号 ")
+    private String transNo;
+    @ApiModelProperty("支付渠道:  alipay 支付宝  wx_lite 微信 ")
+    private String payChannel;
+    @ApiModelProperty("交易金额,必须大于0,保留两位小数点,如0.10、100.05等 ")
+    private BigDecimal payAmt;
+    @ApiModelProperty("汇付收取的服务费 ")
+    private BigDecimal feeAmt;
+    @ApiModelProperty("支付详情信息(用于拉起支付) ")
+    private String payInfo;
+    @ApiModelProperty("交易状态 pending 交易处理中 succeeded 交易成功 failed 交易失败")
+    private String status;
+    @ApiModelProperty("失败信息 ")
+    private String payFailMsg;
+    @ApiModelProperty("到账时间 ")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
+    private Date arrivalTime;
+    @ApiModelProperty("创建时间 ")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
+    private Date createTime;
+    @ApiModelProperty("更新时间 ")
+    @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() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+    
+	public String getOrderNo() {
+        return orderNo;
+    }
+
+    public void setOrderNo(String orderNo) {
+        this.orderNo = orderNo;
+    }
+    
+	public String getTransNo() {
+        return transNo;
+    }
+
+    public void setTransNo(String transNo) {
+        this.transNo = transNo;
+    }
+
+    public String getPayChannel() {
+        return payChannel;
+    }
+
+    public void setPayChannel(String payChannel) {
+        this.payChannel = payChannel;
+    }
+
+    public BigDecimal getPayAmt() {
+        return payAmt;
+    }
+
+    public void setPayAmt(BigDecimal payAmt) {
+        this.payAmt = payAmt;
+    }
+    
+	public String getPayInfo() {
+        return payInfo;
+    }
+
+    public void setPayInfo(String payInfo) {
+        this.payInfo = payInfo;
+    }
+
+    public String getStatus() {
+        return status;
+    }
+
+    public void setStatus(String status) {
+        this.status = status;
+    }
+
+    public Date getArrivalTime() {
+        return arrivalTime;
+    }
+
+    public void setArrivalTime(Date arrivalTime) {
+        this.arrivalTime = arrivalTime;
+    }
+
+    public Date getCreateTime() {
+        return createTime;
+    }
+
+    public void setCreateTime(Date createTime) {
+        this.createTime = createTime;
+    }
+
+    public Date getUpdateTime() {
+        return updateTime;
+    }
+
+    public void setUpdateTime(Date updateTime) {
+        this.updateTime = updateTime;
+    }
+
+    public BigDecimal getFeeAmt() {
+        return feeAmt;
+    }
+
+    public void setFeeAmt(BigDecimal feeAmt) {
+        this.feeAmt = feeAmt;
+    }
+
+    public String getPayFailMsg() {
+        return payFailMsg;
+    }
+
+    public void setPayFailMsg(String payFailMsg) {
+        this.payFailMsg = payFailMsg;
+    }
+}

+ 2 - 1
cooleshow-mall/mall-mbg/src/main/resources/config/mybatis/OmsOrderSettingMapper.xml

@@ -8,6 +8,7 @@
     <result column="confirm_overtime" jdbcType="INTEGER" property="confirmOvertime" />
     <result column="finish_overtime" jdbcType="INTEGER" property="finishOvertime" />
     <result column="comment_overtime" jdbcType="INTEGER" property="commentOvertime" />
+    <result column="pay_order_overtime" jdbcType="INTEGER" property="payOrderOvertime" />
   </resultMap>
   <sql id="Example_Where_Clause">
     <where>
@@ -69,7 +70,7 @@
   </sql>
   <sql id="Base_Column_List">
     id, flash_order_overtime, normal_order_overtime, confirm_overtime, finish_overtime, 
-    comment_overtime
+    comment_overtime,pay_order_overtime
   </sql>
   <select id="selectByExample" parameterType="com.yonge.cooleshow.mbg.model.OmsOrderSettingExample" resultMap="BaseResultMap">
     select

+ 184 - 0
cooleshow-mall/mall-mbg/src/main/resources/config/mybatis/UserOrderPaymentMapper.xml

@@ -0,0 +1,184 @@
+<?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.mbg.mapper.UserOrderPaymentMapper">
+    <resultMap id="BaseResultMap" type="com.yonge.cooleshow.mbg.model.UserOrderPayment">
+        <!--@mbg.generated-->
+        <!--@Table user_order_payment-->
+        <id column="id_" jdbcType="BIGINT" property="id" />
+        <result column="order_no_" jdbcType="VARCHAR" property="orderNo" />
+        <result column="trans_no_" jdbcType="VARCHAR" property="transNo" />
+        <result column="pay_channel_" jdbcType="VARCHAR" property="payChannel" />
+        <result column="pay_amt_" jdbcType="DECIMAL" property="payAmt" />
+        <result column="fee_amt_" jdbcType="DECIMAL" property="feeAmt" />
+        <result column="pay_info_" jdbcType="VARCHAR" property="payInfo" />
+        <result column="status_" jdbcType="VARCHAR" property="status" />
+        <result column="pay_fail_msg_" jdbcType="VARCHAR" property="payFailMsg" />
+        <result column="arrival_time_" jdbcType="TIMESTAMP" property="arrivalTime" />
+        <result column="create_time_" jdbcType="TIMESTAMP" property="createTime" />
+        <result column="update_time_" jdbcType="TIMESTAMP" property="updateTime" />
+    </resultMap>
+    <sql id="Base_Column_List">
+        <!--@mbg.generated-->
+        id_, order_no_, trans_no_, pay_channel_, pay_amt_, fee_amt_, pay_info_, status_,
+        pay_fail_msg_, arrival_time_, create_time_, update_time_
+    </sql>
+    <select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap">
+        <!--@mbg.generated-->
+        select
+        <include refid="Base_Column_List" />
+        from user_order_payment
+        where id_ = #{id,jdbcType=BIGINT}
+    </select>
+    <delete id="deleteByPrimaryKey" parameterType="java.lang.Long">
+        <!--@mbg.generated-->
+        delete from user_order_payment
+        where id_ = #{id,jdbcType=BIGINT}
+    </delete>
+    <insert id="insert" keyColumn="id_" keyProperty="id" parameterType="com.yonge.cooleshow.mbg.model.UserOrderPayment" useGeneratedKeys="true">
+        <!--@mbg.generated-->
+        insert into user_order_payment (order_no_, trans_no_, pay_channel_,
+        pay_amt_, fee_amt_, pay_info_,
+        status_, pay_fail_msg_, arrival_time_,
+        create_time_, update_time_)
+        values (#{orderNo,jdbcType=VARCHAR}, #{transNo,jdbcType=VARCHAR}, #{payChannel,jdbcType=VARCHAR},
+        #{payAmt,jdbcType=DECIMAL}, #{feeAmt,jdbcType=DECIMAL}, #{payInfo,jdbcType=VARCHAR},
+        #{status,jdbcType=VARCHAR}, #{payFailMsg,jdbcType=VARCHAR}, #{arrivalTime,jdbcType=TIMESTAMP},
+        #{createTime,jdbcType=TIMESTAMP}, #{updateTime,jdbcType=TIMESTAMP})
+    </insert>
+    <insert id="insertSelective" keyColumn="id_" keyProperty="id" parameterType="com.yonge.cooleshow.mbg.model.UserOrderPayment" useGeneratedKeys="true">
+        <!--@mbg.generated-->
+        insert into user_order_payment
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="orderNo != null">
+                order_no_,
+            </if>
+            <if test="transNo != null">
+                trans_no_,
+            </if>
+            <if test="payChannel != null">
+                pay_channel_,
+            </if>
+            <if test="payAmt != null">
+                pay_amt_,
+            </if>
+            <if test="feeAmt != null">
+                fee_amt_,
+            </if>
+            <if test="payInfo != null">
+                pay_info_,
+            </if>
+            <if test="status != null">
+                status_,
+            </if>
+            <if test="payFailMsg != null">
+                pay_fail_msg_,
+            </if>
+            <if test="arrivalTime != null">
+                arrival_time_,
+            </if>
+            <if test="createTime != null">
+                create_time_,
+            </if>
+            <if test="updateTime != null">
+                update_time_,
+            </if>
+        </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="orderNo != null">
+                #{orderNo,jdbcType=VARCHAR},
+            </if>
+            <if test="transNo != null">
+                #{transNo,jdbcType=VARCHAR},
+            </if>
+            <if test="payChannel != null">
+                #{payChannel,jdbcType=VARCHAR},
+            </if>
+            <if test="payAmt != null">
+                #{payAmt,jdbcType=DECIMAL},
+            </if>
+            <if test="feeAmt != null">
+                #{feeAmt,jdbcType=DECIMAL},
+            </if>
+            <if test="payInfo != null">
+                #{payInfo,jdbcType=VARCHAR},
+            </if>
+            <if test="status != null">
+                #{status,jdbcType=VARCHAR},
+            </if>
+            <if test="payFailMsg != null">
+                #{payFailMsg,jdbcType=VARCHAR},
+            </if>
+            <if test="arrivalTime != null">
+                #{arrivalTime,jdbcType=TIMESTAMP},
+            </if>
+            <if test="createTime != null">
+                #{createTime,jdbcType=TIMESTAMP},
+            </if>
+            <if test="updateTime != null">
+                #{updateTime,jdbcType=TIMESTAMP},
+            </if>
+        </trim>
+    </insert>
+    <update id="updateByPrimaryKeySelective" parameterType="com.yonge.cooleshow.mbg.model.UserOrderPayment">
+        <!--@mbg.generated-->
+        update user_order_payment
+        <set>
+            <if test="orderNo != null">
+                order_no_ = #{orderNo,jdbcType=VARCHAR},
+            </if>
+            <if test="transNo != null">
+                trans_no_ = #{transNo,jdbcType=VARCHAR},
+            </if>
+            <if test="payChannel != null">
+                pay_channel_ = #{payChannel,jdbcType=VARCHAR},
+            </if>
+            <if test="payAmt != null">
+                pay_amt_ = #{payAmt,jdbcType=DECIMAL},
+            </if>
+            <if test="feeAmt != null">
+                fee_amt_ = #{feeAmt,jdbcType=DECIMAL},
+            </if>
+            <if test="payInfo != null">
+                pay_info_ = #{payInfo,jdbcType=VARCHAR},
+            </if>
+            <if test="status != null">
+                status_ = #{status,jdbcType=VARCHAR},
+            </if>
+            <if test="payFailMsg != null">
+                pay_fail_msg_ = #{payFailMsg,jdbcType=VARCHAR},
+            </if>
+            <if test="arrivalTime != null">
+                arrival_time_ = #{arrivalTime,jdbcType=TIMESTAMP},
+            </if>
+            <if test="createTime != null">
+                create_time_ = #{createTime,jdbcType=TIMESTAMP},
+            </if>
+            <if test="updateTime != null">
+                update_time_ = #{updateTime,jdbcType=TIMESTAMP},
+            </if>
+        </set>
+        where id_ = #{id,jdbcType=BIGINT}
+    </update>
+    <update id="updateByPrimaryKey" parameterType="com.yonge.cooleshow.mbg.model.UserOrderPayment">
+        <!--@mbg.generated-->
+        update user_order_payment
+        set order_no_ = #{orderNo,jdbcType=VARCHAR},
+        trans_no_ = #{transNo,jdbcType=VARCHAR},
+        pay_channel_ = #{payChannel,jdbcType=VARCHAR},
+        pay_amt_ = #{payAmt,jdbcType=DECIMAL},
+        fee_amt_ = #{feeAmt,jdbcType=DECIMAL},
+        pay_info_ = #{payInfo,jdbcType=VARCHAR},
+        status_ = #{status,jdbcType=VARCHAR},
+        pay_fail_msg_ = #{payFailMsg,jdbcType=VARCHAR},
+        arrival_time_ = #{arrivalTime,jdbcType=TIMESTAMP},
+        create_time_ = #{createTime,jdbcType=TIMESTAMP},
+        update_time_ = #{updateTime,jdbcType=TIMESTAMP}
+        where id_ = #{id,jdbcType=BIGINT}
+    </update>
+
+    <select id="selectByOrderNo" resultMap="BaseResultMap">
+        select
+        <include refid="Base_Column_List" />
+      from user_order_payment where order_no_ = #{orderNo} limit 1
+    </select>
+</mapper>

+ 30 - 0
cooleshow-mall/mall-pay/pom.xml

@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>com.yonge.cooleshow</groupId>
+        <artifactId>cooleshow-mall</artifactId>
+        <version>1.0</version>
+    </parent>
+
+    <artifactId>mall-pay</artifactId>
+    <version>1.0</version>
+    <name>mall-pay</name>
+    <description>mall-pay</description>
+    <properties>
+        <java.version>1.8</java.version>
+    </properties>
+    <dependencies>
+        <dependency>
+            <groupId>com.huifu.adapay</groupId>
+            <artifactId>adapay-java-sdk</artifactId>
+            <version>1.2.10</version>
+        </dependency>
+        <dependency>
+            <groupId>com.yonge.cooleshow</groupId>
+            <artifactId>mall-common</artifactId>
+        </dependency>
+    </dependencies>
+
+</project>

+ 36 - 0
cooleshow-mall/mall-pay/src/main/java/com/yonge/cooleshow/config/HuifuConfiguration.java

@@ -0,0 +1,36 @@
+package com.yonge.cooleshow.config;
+
+import com.huifu.adapay.Adapay;
+import com.huifu.adapay.model.MerConfig;
+import com.yonge.cooleshow.props.HuifuProperties;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * 路由配置信息
+ */
+@Configuration
+@EnableConfigurationProperties({HuifuProperties.class})
+public class HuifuConfiguration {
+	private static HuifuProperties huifuProperties;
+	@Bean
+	public MerConfig merConfig(HuifuProperties authProperties) {
+		this.huifuProperties = authProperties;
+
+		MerConfig merConfig = new MerConfig();
+		merConfig.setApiKey(authProperties.getApiKey());
+		merConfig.setApiMockKey(authProperties.getMockApiKey());
+		merConfig.setRSAPrivateKey(authProperties.getRsaPrivateKey());
+		try {
+			Adapay.initWithMerConfig(merConfig);
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+		return merConfig;
+	}
+
+	public static HuifuProperties getHuifuProperties(){
+		return huifuProperties;
+	}
+}

+ 68 - 0
cooleshow-mall/mall-pay/src/main/java/com/yonge/cooleshow/enums/OrdeerCacherEnmu.java

@@ -0,0 +1,68 @@
+package com.yonge.cooleshow.enums;
+
+import com.yonge.cooleshow.common.constant.CommonConstants;
+import org.apache.commons.lang3.StringUtils;
+
+import java.time.Duration;
+
+/**
+ * Description
+ *
+ * @author liujunchi
+ * @date 2022-04-24
+ */
+public enum OrdeerCacherEnmu {
+    LOCK_EXECUTE_ORDER("用户下单锁"),
+    LOCK_PAY_ORDER("用户付款锁"),
+    LOCK_CHANGE_ACCOUNT("账户变更锁");
+
+    ;
+    /***
+     * 缓存描述
+     * @author liweifan
+     * @updateTime 2022/3/28 16:31
+     */
+    private String msg;
+    /***
+     * 缓存时长
+     * @author liweifan
+     * @updateTime 2022/3/28 16:31
+     */
+    private Duration duration;
+
+    OrdeerCacherEnmu(String msg) {
+        this.msg = msg;
+    }
+
+    OrdeerCacherEnmu(String msg, Duration duration) {
+        this.msg = msg;
+        this.duration = duration;
+    }
+
+    public String getCode() {
+        return this.name();
+    }
+
+    public String getMsg() {
+        return msg;
+    }
+
+    public String getRedisKey(Object... detils) {
+        String key = this.getCode();
+        for (Object detil : detils) {
+            try {
+                if (!CommonConstants.REDIS_SPLIT.equals(key.substring(key.length() - 1))) {
+                    key += CommonConstants.REDIS_SPLIT;
+                }
+                if (null != detil && StringUtils.isNotBlank(detil.toString())) {
+                    key += detil.toString();
+                }
+            } catch (Exception e) {
+            }
+        }
+        if (CommonConstants.REDIS_SPLIT.equals(key.substring(key.length() - 1))) {
+            key = key.substring(0, key.length() - 1);
+        }
+        return key;
+    }
+}

+ 40 - 0
cooleshow-mall/mall-pay/src/main/java/com/yonge/cooleshow/enums/OrderStatusEnum.java

@@ -0,0 +1,40 @@
+package com.yonge.cooleshow.enums;
+
+import com.yonge.cooleshow.common.enums.BaseEnum;
+
+/**
+ * 订单状态 WAIT_PAY 待支付 PAYING 支付中  PAID 已付款 CLOSE 已关闭
+ * @Author: liweifan
+ * @Data: 2022/3/31 14:59
+ */
+public enum OrderStatusEnum implements BaseEnum<String, OrderStatusEnum> {
+    WAIT_PAY("WAIT_PAY","待支付"),
+    PAYING("PAYING","支付中"),
+    PAID("PAID","已付款"),
+    CLOSE("CLOSE","已关闭"),
+    FAIL("FAIL","支付失败"),
+    ;
+    private String code;
+    private String msg;
+
+    OrderStatusEnum(String code, String msg) {
+        this.code = code;
+        this.msg = msg;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public String getMsg() {
+        return msg;
+    }
+
+    public void setMsg(String msg) {
+        this.msg = msg;
+    }
+
+    public String getCode() {
+        return this.code;
+    }
+}

+ 36 - 0
cooleshow-mall/mall-pay/src/main/java/com/yonge/cooleshow/enums/PayChannelEnum.java

@@ -0,0 +1,36 @@
+package com.yonge.cooleshow.enums;
+
+
+/**
+ * 支付渠道
+ * @author liweifan
+ * @updateTime 2022/3/31 11:30
+ */
+public enum PayChannelEnum {
+    alipay("alipay","支付宝APP支付"),
+    wx_lite("wx_lite","微信APP支付")
+    ;
+    private String code;
+    private String msg;
+
+    PayChannelEnum(String code, String msg) {
+        this.code = code;
+        this.msg = msg;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public String getMsg() {
+        return msg;
+    }
+
+    public void setMsg(String msg) {
+        this.msg = msg;
+    }
+
+    public String getCode() {
+        return this.code;
+    }
+}

+ 37 - 0
cooleshow-mall/mall-pay/src/main/java/com/yonge/cooleshow/enums/PayStatusEnum.java

@@ -0,0 +1,37 @@
+package com.yonge.cooleshow.enums;
+
+
+/**
+ * 交易状态 pending 交易处理中 succeeded 交易成功 failed 交易失败
+ * @Author: liweifan
+ * @Data: 2022/3/31 14:59
+ */
+public enum PayStatusEnum{
+    pending("pending","交易处理中"),
+    succeeded("succeeded","交易成功"),
+    failed("failed","交易失败")
+    ;
+    private String code;
+    private String msg;
+
+    PayStatusEnum(String code, String msg) {
+        this.code = code;
+        this.msg = msg;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public String getMsg() {
+        return msg;
+    }
+
+    public void setMsg(String msg) {
+        this.msg = msg;
+    }
+
+    public String getCode() {
+        return this.code;
+    }
+}

+ 110 - 0
cooleshow-mall/mall-pay/src/main/java/com/yonge/cooleshow/props/HuifuProperties.java

@@ -0,0 +1,110 @@
+package com.yonge.cooleshow.props;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.cloud.context.config.annotation.RefreshScope;
+
+/**
+ * 权限过滤
+ */
+@RefreshScope
+@ConfigurationProperties("huifu")
+public class HuifuProperties {
+    /***
+     * 汇付 控制台 主页面应用的app_id
+     * @author liweifan
+     * @updateTime 2022/3/31 11:19
+     */
+    private String appId;
+    /***
+     * 汇付 控制台->商户信息管理->证书管理中的API Key(prod模式的API KEY)
+     * @author liweifan
+     * @updateTime 2022/3/31 11:19
+     */
+    private String apiKey;
+    /***
+     * 汇付 控制台->商户信息管理->证书管理中的API Key(mock模式的API KEY)
+     * @author liweifan
+     * @updateTime 2022/3/31 11:19
+     */
+    private String mockApiKey;
+    /***
+     * 商户发起请求时,用于请求参数加签所需要的RSA私钥
+     * @author liweifan
+     * @updateTime 2022/3/31 11:24
+     */
+    private String rsaPrivateKey;
+    /***
+     * 付款成功回调地址
+     * @author liweifan
+     * @updateTime 2022/3/31 11:24
+     */
+    private String notifyUrl;
+    /***
+     * 微信appid
+     * @author liweifan
+     * @updateTime 2022/3/31 11:24
+     */
+    private String wxAppid;
+    /***
+     * 微信secret
+     * @author liweifan
+     * @updateTime 2022/3/31 11:24
+     */
+    private String wxSecret;
+
+    public String getApiKey() {
+        return apiKey;
+    }
+
+    public void setApiKey(String apiKey) {
+        this.apiKey = apiKey;
+    }
+
+    public String getMockApiKey() {
+        return mockApiKey;
+    }
+
+    public void setMockApiKey(String mockApiKey) {
+        this.mockApiKey = mockApiKey;
+    }
+
+    public String getRsaPrivateKey() {
+        return rsaPrivateKey;
+    }
+
+    public void setRsaPrivateKey(String rsaPrivateKey) {
+        this.rsaPrivateKey = rsaPrivateKey;
+    }
+
+    public String getAppId() {
+        return appId;
+    }
+
+    public void setAppId(String appId) {
+        this.appId = appId;
+    }
+
+    public String getWxAppid() {
+        return wxAppid;
+    }
+
+    public void setWxAppid(String wxAppid) {
+        this.wxAppid = wxAppid;
+    }
+
+    public String getWxSecret() {
+        return wxSecret;
+    }
+
+    public void setWxSecret(String wxSecret) {
+        this.wxSecret = wxSecret;
+    }
+
+    public String getNotifyUrl() {
+        return notifyUrl;
+    }
+
+    public void setNotifyUrl(String notifyUrl) {
+        this.notifyUrl = notifyUrl;
+    }
+}

+ 221 - 0
cooleshow-mall/mall-pay/src/main/java/com/yonge/cooleshow/sdk/PaymentSdk.java

@@ -0,0 +1,221 @@
+package com.yonge.cooleshow.sdk;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONObject;
+import com.huifu.adapay.core.exception.BaseAdaPayException;
+import com.huifu.adapay.model.Payment;
+import com.huifu.adapay.model.PaymentConfirm;
+import com.yonge.cooleshow.common.constant.CommonConstants;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.config.HuifuConfiguration;
+import com.yonge.cooleshow.sdk.req.PaymentReq;
+import com.yonge.toolset.thirdparty.exception.ThirdpartyException;
+import com.yonge.toolset.utils.collection.MapUtil;
+import com.yonge.toolset.utils.http.HttpUtil;
+import com.yonge.toolset.utils.string.StringUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Component
+public class PaymentSdk {
+    private final static Logger log = LoggerFactory.getLogger(PaymentSdk.class);
+
+    /**
+     * 执行一个支付交易
+     *
+     * @return 创建的支付对象
+     * @throws Exception 异常
+     */
+    public HttpResponseResult<Map<String, Object>> executePayment(PaymentReq paymentReq) {
+        paymentReq.setApp_id(HuifuConfiguration.getHuifuProperties().getAppId());
+        //创建分账对象
+        Map<String, String> div_member = new HashMap<>();
+        div_member.put("member_id", "0");
+        div_member.put("amount", paymentReq.getPay_amt());
+        div_member.put("fee_flag", "Y");
+        List<Map<String, String>> div_members = Arrays.asList(div_member);
+        paymentReq.setDiv_members(JSONObject.toJSONString(div_members));
+
+        log.info("汇付[创建支付对象] Req:{}", JSONObject.toJSONString(paymentReq));
+        //调用sdk方法,创建支付,得到支付对象
+        Map<String, Object> paymentParams = MapUtil.populateMap(new HashMap<>(), paymentReq);
+        Map<String, Object> res;
+        try {
+            res = Payment.create(paymentParams);
+        } catch (BaseAdaPayException e) {
+            return HttpResponseResult.failed(e.getMessage());
+        }
+        if (null == res) {
+            return HttpResponseResult.failed("请求失败");
+        }
+        log.info("汇付[创建支付对象] Resp:{}", res);
+        String errorCode = (String) res.get("error_code");
+        if (null != errorCode) {
+            String errorMsg = (String) res.get("error_msg");
+            return HttpResponseResult.failed(errorMsg);
+        }
+        return HttpResponseResult.succeed(res);
+    }
+
+    /**
+     * 创建确认对象
+     * 创建支付确认对象适用于延时分账的场景
+     *
+     * @return 查询的支付对象
+     * @throws Exception 异常
+     */
+    public Map<String, Object> createConfirm(Map<String, Object> confirm) throws Exception {
+        confirm = PaymentConfirm.create(confirm);
+
+        String error_code = (String) confirm.get("error_code");
+        if (null != error_code) {
+            String errorMsg = (String) confirm.get("error_msg");
+            throw new ThirdpartyException(errorMsg);
+        }
+        return confirm;
+    }
+
+    /**
+     * 关闭一个支付交易
+     *
+     * @param paymentId 要关闭的支付id
+     * @return 关闭的支付对象
+     * @throws Exception 异常
+     */
+    public Map<String, Object> closePayment(String paymentId) throws Exception {
+        Map<String, Object> payment = new HashMap<>();
+        Map<String, Object> paymentParams = new HashMap<>(10);
+        paymentParams.put("payment_id", paymentId);
+        paymentParams.put("reason", "reason");
+        paymentParams.put("expend", "expend");
+        paymentParams.put("notify_url", "notify_url");
+        payment = com.huifu.adapay.model.Payment.close(paymentParams);
+
+        String error_code = (String) payment.get("error_code");
+        if (null != error_code) {
+            String errorMsg = (String) payment.get("error_msg");
+            throw new ThirdpartyException(errorMsg);
+        }
+        return payment;
+    }
+
+    /**
+     * 查询一个支付交易
+     *
+     * @param paymentId 要查询的支付id
+     * @return 查询的支付对象
+     * @throws Exception 异常
+     */
+    public Map<String, Object> queryPayment(String paymentId) throws Exception {
+        System.out.println("=======query payment begin=======");
+        //查询支付对象的参数,全部参数请参考 https://docs.adapay.tech/api/04-trade.html#id7
+        //调用sdk方法,查询支付交易,得到支付对象
+        Map<String, Object> payment = new HashMap<>();
+        try {
+            System.out.println("支付查询请求参数:" + JSON.toJSONString(paymentId));
+            payment = com.huifu.adapay.model.Payment.query(paymentId);
+        } catch (ThirdpartyException e) {
+            e.printStackTrace();
+        }
+
+        System.out.println("支付查询返回参数:" + JSON.toJSONString(payment));
+
+        String error_code = (String) payment.get("error_code");
+        if (null != error_code) {
+            String error_msg = (String) payment.get("error_msg");
+            System.out.println("error_code:" + error_code + "............." + error_msg);
+        }
+        System.out.println("=======query payment end=======");
+        return payment;
+    }
+    /***
+     * 获取openId
+     * @author liweifan
+     * @param: js_code
+     * @updateTime 2022/4/8 15:49
+     * @return: java.lang.Object
+     */
+    public HttpResponseResult<Map<String, String>> getOpenId(String js_code) {
+        log.info("微信[获取用户openId] Req:{}", js_code);
+        Map<String, Object> param = new HashMap<>();
+        param.put("appid", HuifuConfiguration.getHuifuProperties().getWxAppid());
+        param.put("secret", HuifuConfiguration.getHuifuProperties().getWxSecret());
+        param.put("js_code", js_code);
+        param.put("grant_type", CommonConstants.WECHAT_GRANT_TYPE);
+
+        try {
+            String res = HttpUtil.get("https://api.weixin.qq.com/sns/jscode2session", param);
+            JSONObject jsonObject = JSONObject.parseObject(res);
+            log.info("微信[获取用户openId] Res:{}", jsonObject.toJSONString());
+            String errcode = jsonObject.getString("errcode");
+            if(StringUtil.isEmpty(errcode) || "0".equals(errcode)){
+                Map<String, String> resMap = new HashMap<>();
+                resMap.put("openid", jsonObject.getString("openid"));
+                resMap.put("session_key", jsonObject.getString("session_key"));
+                return HttpResponseResult.succeed(resMap);
+            }else{
+                return HttpResponseResult.failed(jsonObject.getString("errmsg"));
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            return HttpResponseResult.failed("请求失败");
+        }
+    }
+
+/*
+    public static Map<String, Object> queryList(Integer pageIndex, Long createdGte, Long createdLte) throws Exception {
+        Map<String, Object> paymentParams = new HashMap<>();
+        paymentParams.put("app_id", ConfigInit.appId);
+        paymentParams.put("page_index", pageIndex);
+        paymentParams.put("page_size", "20");
+        paymentParams.put("created_gte", createdGte);
+        paymentParams.put("created_lte", createdLte);
+        Map<String, Object> payment = com.huifu.adapay.model.Payment.queryList(paymentParams);
+        String error_code = (String) payment.get("error_code");
+        if (null != error_code) {
+            String errorMsg = (String) payment.get("error_msg");
+            throw new ThirdpartyException(errorMsg);
+        }
+        return payment;
+    }
+
+    public static Map<String, Object> queryConfirmList(String paymentId) throws Exception {
+        Map<String, Object> paymentParams = new HashMap<>();
+        paymentParams.put("app_id", ConfigInit.appId);
+        paymentParams.put("payment_id", paymentId);
+
+        Map<String, Object> payment = com.huifu.adapay.model.Payment.queryConfirmList(paymentParams);
+        String error_code = (String) payment.get("error_code");
+        if (null != error_code) {
+            String errorMsg = (String) payment.get("error_msg");
+            throw new ThirdpartyException(errorMsg);
+        }
+        return payment;
+    }
+
+
+    public static Map<String, Object> getPayMap(BigDecimal amount, String orderNo, String notifyUrl, String returnUrl, String orderSubject, String orderBody) throws Exception {
+        Map<String, Object> paymentParams = new LinkedHashMap<>();
+        paymentParams.put("appId", ConfigInit.appId);
+        paymentParams.put("amount", amount.setScale(2, BigDecimal.ROUND_HALF_UP));
+        paymentParams.put("orderNo", orderNo);
+//        paymentParams.put("notifyUrl", notifyUrl);
+//        paymentParams.put("returnUrl", returnUrl);
+        paymentParams.put("orderSubject", orderSubject);
+        paymentParams.put("orderBody", orderBody);
+        paymentParams.put("wxAppId", ConfigInit.wxAppId);
+
+        String originalStr = JSONObject.toJSONString(paymentParams);
+        String sign = DigestUtils.md5DigestAsHex(originalStr.getBytes());
+
+        paymentParams.put("sign", sign);
+        paymentParams.remove("appId");
+        return paymentParams;
+    }*/
+}

+ 27 - 0
cooleshow-mall/mall-pay/src/main/java/com/yonge/cooleshow/sdk/req/DeviceInfo.java

@@ -0,0 +1,27 @@
+package com.yonge.cooleshow.sdk.req;
+
+import java.io.Serializable;
+
+/**
+ * 交易设备信息
+ * @Author: liweifan
+ * @Data: 2022/3/31 11:36
+ */
+public class DeviceInfo implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    /***
+     * 交易设备所在的公网 IP
+     * @author liweifan
+     * @updateTime 2022/3/31 11:07
+     */
+    private String device_ip;
+
+    public String getDevice_ip() {
+        return device_ip;
+    }
+
+    public void setDevice_ip(String device_ip) {
+        this.device_ip = device_ip;
+    }
+}

+ 55 - 0
cooleshow-mall/mall-pay/src/main/java/com/yonge/cooleshow/sdk/req/DivMember.java

@@ -0,0 +1,55 @@
+package com.yonge.cooleshow.sdk.req;
+
+import java.io.Serializable;
+
+/**
+ * 分账对象
+ * @Author: liweifan
+ * @Data: 2022/3/31 11:26
+ */
+public class DivMember implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 分账用户 Member对象 的 id;若是商户本身时,传入0
+     * @author liweifan
+     * @updateTime 2022/3/31 11:27
+     */
+    private String member_id;
+    /**
+     * 分账金额,精确到分,如0.50,1.00等,分账总金额必须等于主交易金额,金额不能为0.00
+     * @author liweifan
+     * @updateTime 2022/3/31 11:28
+     */
+    private String amount;
+    /**
+     * 是否手续费承担方,N-否,Y-是,手续费承担方有且只能有一个
+     * @author liweifan
+     * @updateTime 2022/3/31 11:28
+     */
+    private String fee_flag;
+
+    public String getMember_id() {
+        return member_id;
+    }
+
+    public void setMember_id(String member_id) {
+        this.member_id = member_id;
+    }
+
+    public String getAmount() {
+        return amount;
+    }
+
+    public void setAmount(String amount) {
+        this.amount = amount;
+    }
+
+    public String getFee_flag() {
+        return fee_flag;
+    }
+
+    public void setFee_flag(String fee_flag) {
+        this.fee_flag = fee_flag;
+    }
+}

+ 147 - 0
cooleshow-mall/mall-pay/src/main/java/com/yonge/cooleshow/sdk/req/OrderPayReq.java

@@ -0,0 +1,147 @@
+package com.yonge.cooleshow.sdk.req;
+
+import com.yonge.cooleshow.enums.OrderStatusEnum;
+import com.yonge.cooleshow.enums.PayChannelEnum;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import java.math.BigDecimal;
+
+/**
+ * 下单支付请求
+ *
+ * @Author: liweifan
+ * @Data: 2022/3/31 14:55
+ */
+@ApiModel(value = "OrderPayReq对象", description = "下单支付请求")
+public class OrderPayReq {
+    @NotBlank(message = "订单号不能为空")
+    @ApiModelProperty(value = "订单号 ", required = true)
+    private String orderNo;
+    @NotNull(message = "支付渠道不能为空")
+    @ApiModelProperty(value = "支付渠道:  alipay 支付宝  wx_lite 微信 ", required = true)
+    private PayChannelEnum payChannel;
+    @ApiModelProperty(value = "用户id ")
+    private Long userId;
+    @ApiModelProperty(value = "用户端公网ip ")
+    private String ipAddress;
+    @ApiModelProperty(value = "微信用户openId(微信支付必传)")
+    private String openId;
+
+    @ApiModelProperty(value = "订单状态",hidden = true)
+    private OrderStatusEnum orderStatus;
+
+    @ApiModelProperty(value = "订单金额",hidden = true)
+    private BigDecimal orderPrice;
+
+    @ApiModelProperty(value = "商品标题",hidden = true)
+    private String goodTitle;
+
+    @ApiModelProperty(value = "商品描述",hidden = true)
+    private String goodDesc;
+
+    @ApiModelProperty("拉起支付信息")
+    private String payInfo;
+
+    public void orderStatus(Integer orderStatus) {
+        if (orderStatus == 0) {
+            this.orderStatus = OrderStatusEnum.WAIT_PAY;
+        } else if (orderStatus == 1) {
+            this.orderStatus = OrderStatusEnum.PAID;
+        }else if (orderStatus == 2) {
+            this.orderStatus = OrderStatusEnum.CLOSE;
+        }else if (orderStatus == 3) {
+            this.orderStatus = OrderStatusEnum.CLOSE;
+        }else if (orderStatus == 4) {
+            this.orderStatus = OrderStatusEnum.CLOSE;
+        }else if (orderStatus == 5) {
+            this.orderStatus = OrderStatusEnum.CLOSE;
+        }else if (orderStatus == 6) {
+            this.orderStatus = OrderStatusEnum.PAYING;
+        }else if (orderStatus == 7) {
+            this.orderStatus = OrderStatusEnum.FAIL;
+        }
+    }
+
+    public OrderStatusEnum getOrderStatus() {
+        return orderStatus;
+    }
+
+    public void setOrderStatus(OrderStatusEnum orderStatus) {
+        this.orderStatus = orderStatus;
+    }
+
+    public BigDecimal getOrderPrice() {
+        return orderPrice;
+    }
+
+    public void setOrderPrice(BigDecimal orderPrice) {
+        this.orderPrice = orderPrice;
+    }
+
+    public String getGoodTitle() {
+        return goodTitle;
+    }
+
+    public void setGoodTitle(String goodTitle) {
+        this.goodTitle = goodTitle;
+    }
+
+    public String getGoodDesc() {
+        return goodDesc;
+    }
+
+    public void setGoodDesc(String goodDesc) {
+        this.goodDesc = goodDesc;
+    }
+
+    public String getOrderNo() {
+        return orderNo;
+    }
+
+    public void setOrderNo(String orderNo) {
+        this.orderNo = orderNo;
+    }
+
+    public PayChannelEnum getPayChannel() {
+        return payChannel;
+    }
+
+    public void setPayChannel(PayChannelEnum payChannel) {
+        this.payChannel = payChannel;
+    }
+
+    public Long getUserId() {
+        return userId;
+    }
+
+    public void setUserId(Long userId) {
+        this.userId = userId;
+    }
+
+    public String getIpAddress() {
+        return ipAddress;
+    }
+
+    public void setIpAddress(String ipAddress) {
+        this.ipAddress = ipAddress;
+    }
+
+    public String getOpenId() {
+        return openId;
+    }
+
+    public void setOpenId(String openId) {
+        this.openId = openId;
+    }
+
+    public String getPayInfo() {
+        return payInfo;
+    }
+
+    public void setPayInfo(String payInfo) {
+        this.payInfo = payInfo;
+    }
+}

+ 73 - 0
cooleshow-mall/mall-pay/src/main/java/com/yonge/cooleshow/sdk/req/PaymentConfirmParam.java

@@ -0,0 +1,73 @@
+package com.yonge.cooleshow.sdk.req;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * @Author: liweifan
+ * @Data: 2022/3/11 17:44
+ */
+public class PaymentConfirmParam implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    //Adapay生成的支付对象id
+    private String payment_id;
+    //请求订单号,只能为英文、数字或者下划线的一种或多种组合,保证在app_id下唯一
+    private String order_no;
+    //确认金额,必须大于0,保留两位小数点,如0.10、100.05等。必须小于等于原支付金额-已确认金额-已撤销金额。
+    private String confirm_amt;
+    //附加说明
+    private String description;
+    //分账对象信息列表,一次请求最多仅支持7个分账方
+    private List<DivMember> div_members;
+    //手续费收取模式:O-商户手续费账户扣取手续费,I-交易金额中扣取手续费;值为空时,默认值为I;若为O时,分账对象列表中不支持传入手续费承担方
+    private String fee_mode;
+
+    public String getPayment_id() {
+        return payment_id;
+    }
+
+    public void setPayment_id(String payment_id) {
+        this.payment_id = payment_id;
+    }
+
+    public String getOrder_no() {
+        return order_no;
+    }
+
+    public void setOrder_no(String order_no) {
+        this.order_no = order_no;
+    }
+
+    public String getConfirm_amt() {
+        return confirm_amt;
+    }
+
+    public void setConfirm_amt(String confirm_amt) {
+        this.confirm_amt = confirm_amt;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public List<DivMember> getDiv_members() {
+        return div_members;
+    }
+
+    public void setDiv_members(List<DivMember> div_members) {
+        this.div_members = div_members;
+    }
+
+    public String getFee_mode() {
+        return fee_mode;
+    }
+
+    public void setFee_mode(String fee_mode) {
+        this.fee_mode = fee_mode;
+    }
+}

+ 168 - 0
cooleshow-mall/mall-pay/src/main/java/com/yonge/cooleshow/sdk/req/PaymentReq.java

@@ -0,0 +1,168 @@
+package com.yonge.cooleshow.sdk.req;
+
+import java.io.Serializable;
+import java.util.Map;
+
+/**
+ * 创建支付对象请求参数
+ * @Author: liweifan
+ * @Data: 2022/3/31 10:58
+ */
+public class PaymentReq implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    /***
+     * 请求订单号,只能为英文、数字或者下划线的一种或多种组合,保证在app_id下唯一
+     * @author liweifan
+     * @updateTime 2022/3/31 11:00
+     */
+    private String order_no;
+    /***
+     * 控制台 主页面应用的app_id
+     * @author liweifan
+     * @updateTime 2022/3/31 11:00
+     */
+    private String app_id;
+    /***
+     * 支付渠道,参见 支付渠道
+     * @author liweifan
+     * @updateTime 2022/3/31 11:01
+     */
+    private String pay_channel;
+    /***
+     * 交易金额,必须大于0,保留两位小数点,如0.10、100.05等
+     * @author liweifan
+     * @updateTime 2022/3/31 11:01
+     */
+    private String pay_amt;
+    /***
+     * 商品标题
+     * @author liweifan
+     * @updateTime 2022/3/31 11:01
+     */
+    private String goods_title;
+    /***
+     * 商品描述信息,微信小程序和微信公众号该字段最大长度42个字符
+     * @author liweifan
+     * @updateTime 2022/3/31 11:01
+     */
+    private String goods_desc;
+    /***
+     * 分账对象信息列表,最多仅支持7个分账方,json 数组形式,详见 分账对象信息列表
+     * @author liweifan
+     * @updateTime 2022/3/31 11:01
+     */
+    private String div_members;
+    /***
+     * 订单附加说明
+     * @author liweifan
+     * @updateTime 2022/3/31 11:01
+     */
+    private String description;
+    /***
+     * 前端设备信息,详见 设备信息
+     * @author liweifan
+     * @updateTime 2022/3/31 11:01
+     */
+    private DeviceInfo device_info;
+    /***
+     * 支付渠道额外参数,JSON格式,条件可输入,详见 支付渠道 expend参数
+     * @author liweifan
+     * @updateTime 2022/3/31 11:01
+     */
+    private Map<String,Object> expend;
+    /***
+     * 异步通知地址,url为http/https路径,服务器POST回调,URL 上请勿附带参数
+     * @author liweifan
+     * @updateTime 2022/3/31 11:01
+     */
+    private String notify_url;
+
+    public String getOrder_no() {
+        return order_no;
+    }
+
+    public void setOrder_no(String order_no) {
+        this.order_no = order_no;
+    }
+
+    public String getApp_id() {
+        return app_id;
+    }
+
+    public void setApp_id(String app_id) {
+        this.app_id = app_id;
+    }
+
+    public String getPay_amt() {
+        return pay_amt;
+    }
+
+    public void setPay_amt(String pay_amt) {
+        this.pay_amt = pay_amt;
+    }
+
+    public String getGoods_title() {
+        return goods_title;
+    }
+
+    public void setGoods_title(String goods_title) {
+        this.goods_title = goods_title;
+    }
+
+    public String getGoods_desc() {
+        return goods_desc;
+    }
+
+    public void setGoods_desc(String goods_desc) {
+        this.goods_desc = goods_desc;
+    }
+
+    public String getDiv_members() {
+        return div_members;
+    }
+
+    public void setDiv_members(String div_members) {
+        this.div_members = div_members;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public DeviceInfo getDevice_info() {
+        return device_info;
+    }
+
+    public void setDevice_info(DeviceInfo device_info) {
+        this.device_info = device_info;
+    }
+
+    public Map<String, Object> getExpend() {
+        return expend;
+    }
+
+    public void setExpend(Map<String, Object> expend) {
+        this.expend = expend;
+    }
+
+    public String getNotify_url() {
+        return notify_url;
+    }
+
+    public void setNotify_url(String notify_url) {
+        this.notify_url = notify_url;
+    }
+
+    public String getPay_channel() {
+        return pay_channel;
+    }
+
+    public void setPay_channel(String pay_channel) {
+        this.pay_channel = pay_channel;
+    }
+}

+ 100 - 0
cooleshow-mall/mall-pay/src/main/java/com/yonge/cooleshow/sdk/res/OrderPayRes.java

@@ -0,0 +1,100 @@
+package com.yonge.cooleshow.sdk.res;
+
+import com.yonge.cooleshow.enums.OrderStatusEnum;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * @Author: liweifan
+ * @Data: 2022/4/1 15:35
+ */
+@ApiModel(value = "OrderPayRes", description = "订单支付请求返回对象")
+public class OrderPayRes {
+    @ApiModelProperty("支付金额")
+    private String pay_amt;
+    @ApiModelProperty("pay_info")
+    private String pay_info;
+
+    @ApiModelProperty("执行状态")
+    private boolean status = true;
+
+    @ApiModelProperty("订单状态")
+    private OrderStatusEnum orderStatus;
+
+    @ApiModelProperty("出错信息")
+    private String message;
+
+    @ApiModelProperty("订单编号")
+    private String orderNo;
+
+    @ApiModelProperty("支付方式")
+    private String payChannel;
+
+    @ApiModelProperty("交易流水号")
+    private String transNo;
+
+
+    public String getTransNo() {
+        return transNo;
+    }
+
+    public void setTransNo(String transNo) {
+        this.transNo = transNo;
+    }
+
+    public String getOrderNo() {
+        return orderNo;
+    }
+
+    public void setOrderNo(String orderNo) {
+        this.orderNo = orderNo;
+    }
+
+    public String getPayChannel() {
+        return payChannel;
+    }
+
+    public void setPayChannel(String payChannel) {
+        this.payChannel = payChannel;
+    }
+
+    public OrderStatusEnum getOrderStatus() {
+        return orderStatus;
+    }
+
+    public void setOrderStatus(OrderStatusEnum orderStatus) {
+        this.orderStatus = orderStatus;
+    }
+
+    public boolean isStatus() {
+        return status;
+    }
+
+    public void setStatus(boolean status) {
+        this.status = status;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+    public String getPay_amt() {
+        return pay_amt;
+    }
+
+    public void setPay_amt(String pay_amt) {
+        this.pay_amt = pay_amt;
+    }
+
+    public String getPay_info() {
+        return pay_info;
+    }
+
+    public void setPay_info(String pay_info) {
+        this.pay_info = pay_info;
+    }
+}

+ 27 - 0
cooleshow-mall/mall-pay/src/main/java/com/yonge/cooleshow/service/PaymentService.java

@@ -0,0 +1,27 @@
+package com.yonge.cooleshow.service;
+
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.sdk.req.OrderPayReq;
+import com.yonge.cooleshow.sdk.res.OrderPayRes;
+
+/**
+ * Description 支付服务
+ *
+ * @author liujunchi
+ * @date 2022-04-21
+ */
+public interface PaymentService {
+
+    /**
+     * 调用支付
+     *
+     * @param payReq
+     * @return
+     */
+    OrderPayRes orderPay(OrderPayReq payReq);
+
+    OrderPayRes orderPayWaitPay(OrderPayReq payReq);
+
+
+    OrderPayRes orderPayPaying(OrderPayReq payReq);
+}

+ 109 - 0
cooleshow-mall/mall-pay/src/main/java/com/yonge/cooleshow/service/impl/AdapayPaymentServiceImpl.java

@@ -0,0 +1,109 @@
+package com.yonge.cooleshow.service.impl;
+
+import com.alibaba.fastjson.JSONObject;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.config.HuifuConfiguration;
+import com.yonge.cooleshow.enums.OrderStatusEnum;
+import com.yonge.cooleshow.enums.PayChannelEnum;
+import com.yonge.cooleshow.enums.PayStatusEnum;
+import com.yonge.cooleshow.sdk.PaymentSdk;
+import com.yonge.cooleshow.sdk.req.DeviceInfo;
+import com.yonge.cooleshow.sdk.req.OrderPayReq;
+import com.yonge.cooleshow.sdk.req.PaymentReq;
+import com.yonge.cooleshow.sdk.res.OrderPayRes;
+import com.yonge.cooleshow.service.PaymentService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.math.BigDecimal;
+import java.math.RoundingMode;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Description
+ *
+ * @author liujunchi
+ * @date 2022-04-21
+ */
+@Service("adapayPaymentService")
+public class AdapayPaymentServiceImpl implements PaymentService {
+
+    @Autowired
+    private PaymentSdk paymentSdk;
+
+    @Override
+    public OrderPayRes orderPay(OrderPayReq payReq) {
+        if (OrderStatusEnum.WAIT_PAY.equals(payReq.getOrderStatus())) {
+            //处于待支付状态,需要调用汇付发起付款请求接口
+            return orderPayWaitPay(payReq);
+        } else if (OrderStatusEnum.PAYING.equals(payReq.getOrderStatus())) {
+            //处于付款中状态,需要拉起付款接口返回信息,并且去到汇付
+            return orderPayPaying(payReq);
+        }
+        OrderPayRes orderPayRes = new OrderPayRes();
+        orderPayRes.setStatus(false);
+        orderPayRes.setMessage("订单状态异常");
+        return orderPayRes;
+    }
+
+    @Override
+    public OrderPayRes orderPayWaitPay(OrderPayReq payReq) {
+        PaymentReq paymentReq = new PaymentReq();
+        paymentReq.setOrder_no(payReq.getOrderNo());
+        paymentReq.setPay_channel(payReq.getPayChannel().getCode());
+        paymentReq.setPay_amt(payReq.getOrderPrice().setScale(2, RoundingMode.HALF_UP).toString());
+        paymentReq.setGoods_title(payReq.getGoodTitle());
+        paymentReq.setGoods_desc(payReq.getGoodDesc());
+
+        DeviceInfo deviceInfo = new DeviceInfo();
+        deviceInfo.setDevice_ip(payReq.getIpAddress());
+
+        paymentReq.setDevice_info(deviceInfo);
+        //异步通知地址
+        paymentReq.setNotify_url(HuifuConfiguration.getHuifuProperties().getNotifyUrl());
+
+        if (PayChannelEnum.wx_lite.equals(payReq.getPayChannel())) {
+            Map<String, Object> expend = new HashMap<>();
+            expend.put("open_id", payReq.getOpenId());
+            paymentReq.setExpend(expend);
+        }
+        //付款请求
+        HttpResponseResult<Map<String, Object>> responseResult = paymentSdk.executePayment(paymentReq);
+        OrderPayRes orderPayRes = new OrderPayRes();
+        orderPayRes.setOrderNo(payReq.getOrderNo());
+        orderPayRes.setPayChannel(payReq.getPayChannel().getCode());
+
+        if (responseResult.getStatus()) {
+            Map<String, Object> res = responseResult.getData();
+            orderPayRes.setTransNo(res.get("id").toString());
+            orderPayRes.setPay_amt(
+                    new BigDecimal(res.get("pay_amt").toString()).setScale(2, RoundingMode.HALF_UP).toString()
+            );
+            String pay_info = ((JSONObject) res.get("expend")).getString("pay_info");
+            orderPayRes.setPay_info(pay_info);
+            orderPayRes.setOrderStatus(OrderStatusEnum.PAYING);
+            orderPayRes.setPay_amt(payReq.getOrderPrice().setScale(2, RoundingMode.HALF_UP).toString());
+            return orderPayRes;
+        } else {
+            //入订单付款表,同时修改订单状态
+            orderPayRes.setOrderStatus(OrderStatusEnum.FAIL);
+            orderPayRes.setStatus(false);
+            orderPayRes.setMessage(responseResult.getMsg());
+            return orderPayRes;
+        }
+    }
+
+    @Override
+    public OrderPayRes orderPayPaying(OrderPayReq payReq) {
+        OrderPayRes orderPayRes = new OrderPayRes();
+        if (OrderStatusEnum.PAYING.getCode().equals(payReq.getOrderStatus().getCode())) {
+            orderPayRes.setPay_info(payReq.getPayInfo());
+            orderPayRes.setPay_amt(payReq.getOrderPrice().toString());
+        } else {
+            orderPayRes.setStatus(false);
+            orderPayRes.setMessage("订单不处于支付状态中");
+        }
+        return orderPayRes;
+    }
+}

+ 15 - 1
cooleshow-mall/mall-portal/pom.xml

@@ -33,7 +33,7 @@
         </dependency>
         <dependency>
             <groupId>com.yonge.cooleshow</groupId>
-            <artifactId>mall-common</artifactId>
+            <artifactId>mall-pay</artifactId>
         </dependency>
         <dependency>
             <groupId>com.yonge.toolset</groupId>
@@ -69,6 +69,20 @@
             <version>20.0</version>
             <scope>compile</scope>
         </dependency>
+        <dependency>
+            <groupId>org.redisson</groupId>
+            <artifactId>redisson</artifactId>
+            <version>3.16.4</version>
+            <scope>compile</scope>
+        </dependency>
+
+        <!-- redisson -->
+        <dependency>
+            <groupId>org.redisson</groupId>
+            <artifactId>redisson-spring-boot-starter</artifactId>
+            <version>3.16.4</version>
+        </dependency>
+
     </dependencies>
 
     <build>

+ 1 - 1
cooleshow-mall/mall-portal/src/main/java/com/yonge/cooleshow/portal/MallPortalApplication.java

@@ -10,7 +10,7 @@ import org.springframework.context.annotation.ComponentScan;
 
 @SpringBootApplication
 @MapperScan({"com.yonge.cooleshow.mbg.mapper", "com.yonge.cooleshow.portal.dao"})
-@ComponentScan(basePackages = {"com.yonge.cooleshow.portal","com.yonge.cooleshow.mbg", "com.yonge.cooleshow.mall.common", "com.yonge.cooleshow.common","com.yonge.toolset"})
+@ComponentScan(basePackages = {"com.yonge.cooleshow.portal","com.yonge.cooleshow.mbg", "com.yonge.cooleshow.mall.common", "com.yonge.cooleshow.common","com.yonge.toolset","com.yonge.cooleshow"})
 @EnableSwagger2Doc
 @EnableDiscoveryClient
 @EnableFeignClients("com.yonge.cooleshow")

+ 1 - 1
cooleshow-mall/mall-portal/src/main/java/com/yonge/cooleshow/portal/controller/OmsPortalOrderController.java

@@ -44,7 +44,7 @@ public class OmsPortalOrderController {
     }
 
     @ApiOperation("用户支付成功的回调")
-    @RequestMapping(value = "/paySuccess", method = RequestMethod.POST)
+    // @RequestMapping(value = "/paySuccess", method = RequestMethod.POST)
     @ResponseBody
     public CommonResult paySuccess(@RequestParam Long orderId,@RequestParam Integer payType) {
         Integer count = portalOrderService.paySuccess(orderId,payType);

+ 129 - 0
cooleshow-mall/mall-portal/src/main/java/com/yonge/cooleshow/portal/controller/PaymentController.java

@@ -0,0 +1,129 @@
+package com.yonge.cooleshow.portal.controller;
+
+import com.alibaba.fastjson.JSONObject;
+import com.huifu.adapay.core.AdapayCore;
+import com.huifu.adapay.core.util.AdapaySign;
+import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
+import com.yonge.cooleshow.auth.api.entity.SysUser;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.cooleshow.enums.OrdeerCacherEnmu;
+import com.yonge.cooleshow.portal.service.OmsPortalOrderService;
+import com.yonge.cooleshow.portal.util.DistributedLock;
+import com.yonge.cooleshow.sdk.PaymentSdk;
+import com.yonge.cooleshow.sdk.req.OrderPayReq;
+import com.yonge.cooleshow.sdk.res.OrderPayRes;
+import com.yonge.toolset.utils.web.WebUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.redisson.api.RedissonClient;
+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 javax.servlet.http.HttpServletRequest;
+import javax.validation.Valid;
+import java.util.Map;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * @Author: liweifan
+ * @Data: 2022/3/11 18:16
+ */
+@RestController
+@RequestMapping("/payment")
+@Api(value = "付款接口", tags = "付款接口")
+public class PaymentController extends BaseController {
+    private final static Logger log = LoggerFactory.getLogger(PaymentController.class);
+    @Autowired
+    private PaymentSdk paymentSdk;
+    @Autowired
+    private OmsPortalOrderService portalOrderService;
+    @Autowired
+    private SysUserFeignService sysUserFeignService;
+    @Autowired
+    private RedissonClient redissonClient;
+
+    @ApiOperation(value = "查询付款单")
+    @GetMapping("/queryPayment")
+    public HttpResponseResult<Map<String, Object>> queryPayment(String paymentId) throws Exception {
+        return HttpResponseResult.succeed(paymentSdk.queryPayment(paymentId));
+    }
+
+    @ApiOperation(value = "微信支付获取openid")
+    @GetMapping("/getOpenId")
+    public HttpResponseResult<Map<String, String>> getOpenId(String js_code) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        HttpResponseResult<Map<String, String>> responseResult = paymentSdk.getOpenId(js_code);
+        if (responseResult.getStatus()) {
+            Map<String, String> data = responseResult.getData();
+            //绑定到用户表
+            user.setWxOpenid(data.get("openid"));
+            log.info("绑定用户openid,param is {}", JSONObject.toJSONString(user));
+            sysUserFeignService.bindOpenId(user);
+        }
+        return responseResult;
+    }
+
+    /***
+     * 汇付回调
+     * 问题:1、成功失败需要回执什么信息 2、回调url地址是否需要加入白名单
+     * @author liweifan
+     * @param: request
+     * @updateTime 2022/3/11 18:35
+     */
+    @PostMapping("/callback")
+    public void callback(HttpServletRequest request) {
+        try {
+            //验签传参data
+            String data = request.getParameter("data");
+            //验签传参sign
+            String sign = request.getParameter("sign");
+            //验签传参publicKey
+            String publicKey = AdapayCore.PUBLIC_KEY;
+            //验签
+            boolean checkSign = AdapaySign.verifySign(data, sign, publicKey);
+            log.info("汇付回调,res is {}", data);
+            if (checkSign) {
+                //验签成功逻辑
+                log.info("验签成功");
+                portalOrderService.orderCallback(data);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    @ApiOperation(value = "订单付款")
+    @PostMapping("/orderPay")
+    public HttpResponseResult<OrderPayRes> orderPay(@Valid @RequestBody OrderPayReq payReq, HttpServletRequest request) {
+        SysUser user = sysUserFeignService.queryUserInfo();
+        if (user == null || null == user.getId()) {
+            return failed(HttpStatus.FORBIDDEN, "请登录");
+        }
+        payReq.setUserId(user.getId());
+        payReq.setIpAddress(WebUtil.getRemoteIp(request));
+
+        Future<OrderPayRes> orderPayResFuture = DistributedLock.of(redissonClient)
+              .callIfLockCanGet(OrdeerCacherEnmu.LOCK_PAY_ORDER.getRedisKey(user.getId()),
+                                () -> portalOrderService.orderPay(payReq), 60L, TimeUnit.SECONDS);
+
+        try {
+            OrderPayRes orderPayRes = orderPayResFuture.get();
+            if (orderPayRes.isStatus()) {
+                return succeed(orderPayRes);
+            }  else {
+                return failed(orderPayRes.getMessage());
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            return HttpResponseResult.failed("付款失败");
+        }
+    }
+}

+ 1 - 1
cooleshow-mall/mall-portal/src/main/java/com/yonge/cooleshow/portal/dao/PortalOrderDao.java

@@ -25,7 +25,7 @@ public interface PortalOrderDao {
      * 获取超时订单
      * @param minute 超时时间(分)
      */
-    List<OmsOrderDetail> getTimeOutOrders(@Param("minute") Integer minute);
+    List<OmsOrderDetail> getTimeOutOrders(@Param("orderMinute") Integer orderMinute,@Param("payMinute") Integer payMinute);
 
     /**
      * 批量修改订单状态

+ 21 - 0
cooleshow-mall/mall-portal/src/main/java/com/yonge/cooleshow/portal/service/OmsPortalOrderService.java

@@ -4,10 +4,13 @@ import com.yonge.cooleshow.mall.common.api.CommonPage;
 import com.yonge.cooleshow.portal.domain.ConfirmOrderResult;
 import com.yonge.cooleshow.portal.domain.OmsOrderDetail;
 import com.yonge.cooleshow.portal.domain.OrderParam;
+import com.yonge.cooleshow.sdk.req.OrderPayReq;
+import com.yonge.cooleshow.sdk.res.OrderPayRes;
 import org.springframework.transaction.annotation.Transactional;
 
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.Future;
 
 /**
  * 前台订单管理Service
@@ -47,11 +50,13 @@ public interface OmsPortalOrderService {
     /**
      * 发送延迟消息取消订单
      */
+    @Transactional
     void sendDelayMessageCancelOrder(Long orderId);
 
     /**
      * 确认收货
      */
+    @Transactional
     void confirmReceiveOrder(Long orderId);
 
     /**
@@ -67,5 +72,21 @@ public interface OmsPortalOrderService {
     /**
      * 用户根据订单ID删除订单
      */
+    @Transactional
     void deleteOrder(Long orderId);
+
+    /**
+     *
+     * @param data
+     */
+    void orderCallback(String data);
+
+    /**
+     * 订单拉起支付
+     *
+     * @param payReq 支付信息
+     * @return
+     */
+    @Transactional
+    OrderPayRes orderPay(OrderPayReq payReq);
 }

+ 29 - 0
cooleshow-mall/mall-portal/src/main/java/com/yonge/cooleshow/portal/service/UserOrderPaymentService.java

@@ -0,0 +1,29 @@
+package com.yonge.cooleshow.portal.service;
+
+import com.yonge.cooleshow.mbg.model.UserOrderPayment;
+
+/**
+ * Description
+ *
+ * @author liujunchi
+ * @date 2022-04-24
+ */
+public interface UserOrderPaymentService {
+
+    /**
+     *  根据订单查询
+     *
+     * @param orderNo 订单id
+     * @return
+     */
+    UserOrderPayment getByOrderNo(String orderNo);
+
+    /**
+     * 保存订单记录
+     *
+     * @param userOrderPayment
+     */
+    void save(UserOrderPayment userOrderPayment);
+
+    void saveOrUpdate(UserOrderPayment userOrderPayment);
+}

+ 193 - 3
cooleshow-mall/mall-portal/src/main/java/com/yonge/cooleshow/portal/service/impl/OmsPortalOrderServiceImpl.java

@@ -2,7 +2,11 @@ package com.yonge.cooleshow.portal.service.impl;
 
 import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.collection.CollUtil;
+import com.alibaba.fastjson.JSONObject;
 import com.github.pagehelper.PageHelper;
+import com.yonge.cooleshow.common.exception.BizException;
+import com.yonge.cooleshow.enums.OrderStatusEnum;
+import com.yonge.cooleshow.enums.PayStatusEnum;
 import com.yonge.cooleshow.mall.common.api.CommonPage;
 import com.yonge.cooleshow.mall.common.exception.Asserts;
 import com.yonge.cooleshow.mall.common.service.RedisService;
@@ -14,15 +18,23 @@ import com.yonge.cooleshow.portal.dao.PortalOrderItemDao;
 import com.yonge.cooleshow.portal.dao.SmsCouponHistoryDao;
 import com.yonge.cooleshow.portal.domain.*;
 import com.yonge.cooleshow.portal.service.*;
+import com.yonge.cooleshow.sdk.PaymentSdk;
+import com.yonge.cooleshow.sdk.req.OrderPayReq;
+import com.yonge.cooleshow.sdk.res.OrderPayRes;
+import com.yonge.cooleshow.service.PaymentService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.CollectionUtils;
 
 import java.math.BigDecimal;
 import java.math.RoundingMode;
 import java.text.SimpleDateFormat;
 import java.util.*;
+import java.util.function.Consumer;
 import java.util.stream.Collectors;
 
 /**
@@ -31,6 +43,8 @@ import java.util.stream.Collectors;
  */
 @Service
 public class OmsPortalOrderServiceImpl implements OmsPortalOrderService {
+
+    private static final Logger log = LoggerFactory.getLogger(OmsPortalOrderService.class);
     @Autowired
     private UmsMemberService memberService;
     @Autowired
@@ -64,6 +78,15 @@ public class OmsPortalOrderServiceImpl implements OmsPortalOrderService {
     @Autowired
     private CancelOrderSender cancelOrderSender;
 
+    @Autowired
+    private UserOrderPaymentService userOrderPaymentService;
+
+    @Autowired
+    private PaymentService adapayPaymentService;
+
+    @Autowired
+    private PaymentSdk paymentSdk;
+
     @Override
     public ConfirmOrderResult generateConfirmOrder(List<Long> cartIds) {
         ConfirmOrderResult result = new ConfirmOrderResult();
@@ -260,7 +283,8 @@ public class OmsPortalOrderServiceImpl implements OmsPortalOrderService {
         Integer count=0;
         OmsOrderSetting orderSetting = orderSettingMapper.selectByPrimaryKey(1L);
         //查询超时、未支付的订单及订单详情
-        List<OmsOrderDetail> timeOutOrders = portalOrderDao.getTimeOutOrders(orderSetting.getNormalOrderOvertime());
+        List<OmsOrderDetail> timeOutOrders = portalOrderDao.getTimeOutOrders(orderSetting.getNormalOrderOvertime()
+                ,orderSetting.getPayOrderOvertime());
         if (CollectionUtils.isEmpty(timeOutOrders)) {
             return count;
         }
@@ -280,6 +304,14 @@ public class OmsPortalOrderServiceImpl implements OmsPortalOrderService {
                 UmsMember member = memberService.getById(timeOutOrder.getMemberId());
                 memberService.updateIntegration(timeOutOrder.getMemberId(), member.getIntegration() + timeOutOrder.getUseIntegration());
             }
+
+            UserOrderPayment orderPayment = userOrderPaymentService.getByOrderNo(timeOutOrder.getOrderSn());
+            if (null != orderPayment) {
+                //更新付款单
+                orderPayment.setStatus(OrderStatusEnum.FAIL.getCode());
+                orderPayment.setPayFailMsg("交易取消");
+                userOrderPaymentService.saveOrUpdate(orderPayment);
+            }
         }
         return timeOutOrders.size();
     }
@@ -288,13 +320,13 @@ public class OmsPortalOrderServiceImpl implements OmsPortalOrderService {
     public void cancelOrder(Long orderId) {
         //查询未付款的取消订单
         OmsOrderExample example = new OmsOrderExample();
-        example.createCriteria().andIdEqualTo(orderId).andStatusEqualTo(0).andDeleteStatusEqualTo(0);
+        example.createCriteria().andIdEqualTo(orderId).andDeleteStatusEqualTo(0);
         List<OmsOrder> cancelOrderList = orderMapper.selectByExample(example);
         if (CollectionUtils.isEmpty(cancelOrderList)) {
             return;
         }
         OmsOrder cancelOrder = cancelOrderList.get(0);
-        if (cancelOrder != null) {
+        if (cancelOrder != null && (cancelOrder.getStatus() == 0 || cancelOrder.getStatus() == 6) ) {
             //修改订单状态为取消
             cancelOrder.setStatus(4);
             orderMapper.updateByPrimaryKeySelective(cancelOrder);
@@ -312,6 +344,13 @@ public class OmsPortalOrderServiceImpl implements OmsPortalOrderService {
                 UmsMember member = memberService.getById(cancelOrder.getMemberId());
                 memberService.updateIntegration(cancelOrder.getMemberId(), member.getIntegration() + cancelOrder.getUseIntegration());
             }
+            UserOrderPayment orderPayment = userOrderPaymentService.getByOrderNo(cancelOrder.getOrderSn());
+            if (null != orderPayment) {
+                //更新付款单
+                orderPayment.setStatus(OrderStatusEnum.FAIL.getCode());
+                orderPayment.setPayFailMsg("交易取消");
+                userOrderPaymentService.saveOrUpdate(orderPayment);
+            }
         }
     }
 
@@ -395,6 +434,25 @@ public class OmsPortalOrderServiceImpl implements OmsPortalOrderService {
         return orderDetail;
     }
 
+    public OmsOrderDetail detail(String orderSn) {
+        OmsOrderExample orderExample = new OmsOrderExample();
+        orderExample.createCriteria().andOrderSnEqualTo(orderSn);
+        List<OmsOrder> omsOrders = orderMapper.selectByExample(orderExample);
+        if (CollUtil.isEmpty(omsOrders)) {
+            throw new BizException("订单信息错误");
+        } else if (omsOrders.size() != 1) {
+            throw new BizException("订单号重复");
+        }
+        OmsOrder omsOrder = omsOrders.get(0);
+        OmsOrderItemExample example = new OmsOrderItemExample();
+        example.createCriteria().andOrderIdEqualTo(omsOrder.getId());
+        List<OmsOrderItem> orderItemList = orderItemMapper.selectByExample(example);
+        OmsOrderDetail orderDetail = new OmsOrderDetail();
+        BeanUtil.copyProperties(omsOrder,orderDetail);
+        orderDetail.setOrderItemList(orderItemList);
+        return orderDetail;
+    }
+
     @Override
     public void deleteOrder(Long orderId) {
         UmsMember member = memberService.getCurrentMember();
@@ -410,6 +468,138 @@ public class OmsPortalOrderServiceImpl implements OmsPortalOrderService {
         }
     }
 
+    @Override
+    @Transactional
+    public OrderPayRes orderPay(OrderPayReq payReq) {
+        OrderPayRes orderPayRes = new OrderPayRes();
+        OmsOrderDetail detail = detail(payReq.getOrderNo());
+        if (detail == null) {
+            orderPayRes.setStatus(false);
+            orderPayRes.setMessage("订单不存在");
+            return orderPayRes;
+        }
+        UserOrderPayment userOrderPayment = userOrderPaymentService.getByOrderNo(detail.getOrderSn());
+        payReq.orderStatus(detail.getStatus());
+        payReq.setOrderNo(detail.getOrderSn());
+        payReq.setOrderPrice(detail.getPayAmount());
+        payReq.setGoodTitle("");
+        payReq.setGoodDesc("");
+        if (userOrderPayment != null) {
+            payReq.setPayInfo(userOrderPayment.getPayInfo());
+        }
+        // 支付中的返回拉起信息
+        orderPayRes = adapayPaymentService.orderPay(payReq);
+        // 订单状态没变直接返回
+        if (payReq.getOrderStatus().getCode().equals(orderPayRes.getOrderStatus().getCode())) {
+            return orderPayRes;
+        }
+        // 订单状态变了, 改支付状态 和订单支付表
+        OmsOrder omsOrder = new OmsOrder();
+        omsOrder.setId(detail.getId());
+        if (orderPayRes.getOrderStatus().getCode().equals(OrderStatusEnum.PAYING.getCode())) {
+            omsOrder.setStatus(6);
+            orderMapper.updateByPrimaryKeySelective(omsOrder);
+            // 保存订单支付表
+            if (userOrderPayment == null) {
+                userOrderPayment = new UserOrderPayment();
+            }
+            userOrderPayment.setOrderNo(orderPayRes.getOrderNo());
+            userOrderPayment.setPayChannel(orderPayRes.getPayChannel());
+            userOrderPayment.setTransNo(orderPayRes.getTransNo());
+            userOrderPayment.setPayAmt(new BigDecimal(orderPayRes.getPay_amt()));
+            userOrderPayment.setPayInfo(orderPayRes.getPay_info());
+            userOrderPayment.setStatus(orderPayRes.getOrderStatus().getCode());
+            userOrderPayment.setPayFailMsg(orderPayRes.getMessage());
+            userOrderPayment.setCreateTime(new Date());
+            userOrderPayment.setUpdateTime(new Date());
+            userOrderPaymentService.saveOrUpdate(userOrderPayment);
+        }else {
+            // 异常将取消订单
+            cancelOrder(detail.getId());
+        }
+
+        return orderPayRes;
+    }
+
+    @Override
+    public void orderCallback(String data) {
+        JSONObject hfRes = JSONObject.parseObject(data);
+        if (PayStatusEnum.succeeded.getCode().equals(hfRes.getString("status"))) {
+            //订单完成
+            OmsOrderDetail orderDetail = detail(hfRes.getString("order_no"));
+            if (null == orderDetail) {
+                log.error("汇付支付回调,订单未找到。 req is {}", data);
+                return;
+            }
+            if (orderDetail.getStatus() == 0
+                    && orderDetail.getStatus() == 6
+                    && orderDetail.getStatus() == 7) {
+                orderSuccess(orderDetail, hfRes);
+            } else {
+                log.error("汇付支付回调,订单状态异常。 req is {}", data);
+            }
+        }
+    }
+    /***
+     * 处理支付中订单
+     * @author liweifan
+     * @param: userOrder
+     * @updateTime 2022/4/13 16:51
+     */
+    @Transactional(rollbackFor = Exception.class)
+    void payingOrderHandle(OmsOrder userOrder) {
+        //判断汇付订单状态
+        UserOrderPayment orderPayment = userOrderPaymentService.getByOrderNo(userOrder.getOrderSn());
+        if (null == orderPayment) {
+            return;
+        }
+        try {
+            Map<String, Object> resMap = paymentSdk.queryPayment(orderPayment.getTransNo());
+            //支付失败
+            if (PayStatusEnum.failed.getCode().equals(resMap.get("status").toString())) {
+                cancelOrder(userOrder.getId());
+            }
+            //支付成功
+            if (PayStatusEnum.succeeded.getCode().equals(resMap.get("status").toString())) {
+                orderSuccess(userOrder,null);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            log.error("轮询处理支付中订单异常,异常参数: {}", JSONObject.toJSONString(userOrder));
+        }
+    }
+
+    /**
+     * 订单完成
+     *
+     * @author liweifan
+     * @param: detail
+     * @updateTime 2022/4/13 17:17
+     */
+    @Transactional(rollbackFor = Exception.class)
+    void orderSuccess(OmsOrder detail, JSONObject hfRes) {
+        //更新订单
+        UserOrderPayment orderPayment = userOrderPaymentService.getByOrderNo(detail.getOrderSn());
+        if (orderPayment.getPayChannel().equals("alipay")) {
+            paySuccess(detail.getId(),1);
+        } else if (orderPayment.getPayChannel().equals("wx_lite")) {
+            paySuccess(detail.getId(),2);
+        }
+        orderPayment.setStatus(OrderStatusEnum.PAID.getCode());
+        orderPayment.setArrivalTime(new Date());
+        if (null != hfRes) {
+            try {
+                orderPayment.setPayAmt(new BigDecimal(hfRes.getString("pay_amt")));
+                orderPayment.setFeeAmt(new BigDecimal(hfRes.getString("fee_amt")));
+            } catch (Exception e) {
+                e.printStackTrace();
+                log.error("完成订单,付款单金额格式化失败,参数{}", hfRes.toJSONString());
+            }
+        }
+        userOrderPaymentService.saveOrUpdate(orderPayment);
+    }
+
+
     /**
      * 生成18位订单编号:8位日期+2位平台号码+2位支付方式+6位以上自增id
      */

+ 39 - 0
cooleshow-mall/mall-portal/src/main/java/com/yonge/cooleshow/portal/service/impl/UserOrderPaymentServiceImpl.java

@@ -0,0 +1,39 @@
+package com.yonge.cooleshow.portal.service.impl;
+
+import com.yonge.cooleshow.mbg.mapper.UserOrderPaymentMapper;
+import com.yonge.cooleshow.mbg.model.UserOrderPayment;
+import com.yonge.cooleshow.portal.service.UserOrderPaymentService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+/**
+ * Description
+ *
+ * @author liujunchi
+ * @date 2022-04-24
+ */
+@Service
+public class UserOrderPaymentServiceImpl implements UserOrderPaymentService {
+
+    @Autowired
+    private UserOrderPaymentMapper userOrderPaymentMapper;
+
+    @Override
+    public UserOrderPayment getByOrderNo(String orderNo) {
+        return userOrderPaymentMapper.selectByOrderNo(orderNo);
+    }
+
+    @Override
+    public void save(UserOrderPayment userOrderPayment) {
+        userOrderPaymentMapper.insert(userOrderPayment);
+    }
+
+    @Override
+    public void saveOrUpdate(UserOrderPayment userOrderPayment) {
+        if (userOrderPayment.getId() == null) {
+            userOrderPaymentMapper.insert(userOrderPayment);
+        } else {
+            userOrderPaymentMapper.updateByPrimaryKeySelective(userOrderPayment);
+        }
+    }
+}

+ 11 - 8
cooleshow-mall/mall-portal/src/main/java/com/yonge/cooleshow/portal/component/OrderTimeOutCancelTask.java → cooleshow-mall/mall-portal/src/main/java/com/yonge/cooleshow/portal/task/OrderTimeOutCancelTask.java

@@ -1,29 +1,32 @@
-package com.yonge.cooleshow.portal.component;
+package com.yonge.cooleshow.portal.task;
 
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.cooleshow.portal.service.OmsPortalOrderService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.scheduling.annotation.Scheduled;
-import org.springframework.stereotype.Component;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
 
 /**
  * 取消超时订单并解锁库存的定时器
  * Created by macro on 2018/8/24.
  */
-@Component
+@RestController
+@RequestMapping("/task")
 public class OrderTimeOutCancelTask {
     private Logger LOGGER =LoggerFactory.getLogger(OrderTimeOutCancelTask.class);
     @Autowired
     private OmsPortalOrderService portalOrderService;
 
     /**
-     * cron表达式:Seconds Minutes Hours DayofMonth Month DayofWeek [Year]
-     * 每10分钟扫描一次,扫描超时未支付订单,进行取消操作
+     * 订单轮询
      */
-    @Scheduled(cron = "0 0/10 * ? * ?")
-    private void cancelTimeOutOrder(){
+    @GetMapping("/pollingOrder")
+    public HttpResponseResult cancelTimeOutOrder(){
         Integer count = portalOrderService.cancelTimeOutOrder();
         LOGGER.info("取消订单,并根据sku编号释放锁定库存,取消订单数量:{}",count);
+        return HttpResponseResult.succeed();
     }
 }

+ 116 - 0
cooleshow-mall/mall-portal/src/main/java/com/yonge/cooleshow/portal/util/DistributedLock.java

@@ -0,0 +1,116 @@
+package com.yonge.cooleshow.portal.util;
+
+import org.redisson.api.RLock;
+import org.redisson.api.RedissonClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Objects;
+import java.util.concurrent.*;
+
+/**
+ * 分布式竞争锁
+ *
+ * @author hgw
+ */
+public class DistributedLock {
+    private final static Logger log = LoggerFactory.getLogger(DistributedLock.class);
+
+    private final RedissonClient redissonClient;
+
+    private static final long DEFAULT_TIMEOUT = 60L;// key过期时间默认1分钟后
+
+    private static final TimeUnit DEFAULT_TIME_UNIT = TimeUnit.SECONDS;//默认过期时间单位-秒钟
+
+    private DistributedLock(RedissonClient redissonClient) {
+        this.redissonClient = redissonClient;
+    }
+
+    public static DistributedLock of(RedissonClient redissonClient) {
+        return new DistributedLock(redissonClient);
+    }
+
+    /**
+     * 分布式锁-默认锁60秒
+     *
+     * @param lockName lockKey
+     * @param runnable 任务
+     * @return true 锁成功  false 锁失败
+     */
+    public boolean runIfLockCanGet(final String lockName, Runnable runnable) {
+        return runIfLockCanGet(lockName, runnable, DEFAULT_TIMEOUT, DEFAULT_TIME_UNIT);
+    }
+
+    /**
+     * 分布式锁
+     *
+     * @param lockName lockKey
+     * @param runnable 任务
+     * @param timeout  超时时间
+     * @param unit     超时时间单位
+     * @return true 锁成功  false 锁失败
+     */
+    public boolean runIfLockCanGet(final String lockName, Runnable runnable, final long timeout, TimeUnit unit) {
+        RLock lock = redissonClient.getLock(lockName);
+        if (Objects.isNull(lock)) {
+            log.info("runIfLockCanGet lock is null lockName : {}", lockName);
+            return false;
+        }
+        try {
+            if (lock.tryLock(0, timeout, unit)) {
+                if (Objects.nonNull(runnable)) {
+                    runnable.run();
+                }
+                return true;
+            } else {
+                return false;
+            }
+        } catch (Exception e) {
+            log.error("runIfLockCanGet error lockName : {}", lockName, e);
+            throw new RuntimeException("runIfLockCanGet error lockName :" + lockName, e);
+        } finally {
+            unlock(lock);
+        }
+    }
+
+    /**
+     * 分布式锁-异步
+     *
+     * @param lockName lockKey
+     * @param callable 任务
+     * @param timeout  超时时间
+     * @param unit     超时时间单位
+     * @return Future 异步任务
+     */
+    public <T> Future<T> callIfLockCanGet(final String lockName, Callable<T> callable, final long timeout, TimeUnit unit) {
+        RLock lock = redissonClient.getLock(lockName);
+        if (Objects.isNull(lock)) {
+            log.info("callIfLockCanGet lock is null lockName : {}", lockName);
+            return null;
+        }
+        ExecutorService executor = Executors.newCachedThreadPool();
+        try {
+            if (lock.tryLock(0, timeout, unit)) {
+                return executor.submit(callable);
+            } else {
+                return null;
+            }
+        } catch (Exception e) {
+            log.error("callIfLockCanGet error lockKey {}", lockName);
+            throw new RuntimeException("任务执行异常");
+        } finally {
+            executor.shutdown();
+            unlock(lock);
+        }
+    }
+
+    /**
+     * 解锁
+     */
+    public void unlock(RLock lock) {
+        if (lock.getHoldCount() != 0) {
+            lock.unlock();
+        }
+    }
+
+}

+ 3 - 2
cooleshow-mall/mall-portal/src/main/resources/config/mybatis/PortalOrderDao.xml

@@ -42,9 +42,10 @@
         FROM
             oms_order o
             LEFT JOIN oms_order_item ot ON o.id = ot.order_id
+        left join user_order_payment uop on uop.order_no_ = o.order_sn
         WHERE
-            o.status = 0
-            AND o.create_time &lt; date_add(NOW(), INTERVAL -#{minute} MINUTE);
+            (o.status = 0 AND o.create_time &lt; date_add(NOW(), INTERVAL -#{orderMinute} MINUTE))
+            or (o.status = 6 and uop.create_time_ &lt; date_add(NOW(), INTERVAL -#{payMinute} MINUTE));
     </select>
 
     <update id="updateSkuStock">

+ 1 - 0
cooleshow-mall/pom.xml

@@ -90,5 +90,6 @@
         <module>mall-admin</module>
         <module>mall-common</module>
         <module>mall-portal</module>
+        <module>mall-pay</module>
     </modules>
 </project>

+ 17 - 0
cooleshow-task/src/main/java/com/yonge/cooleshow/task/feign/MallPortalFeignService.java

@@ -0,0 +1,17 @@
+package com.yonge.cooleshow.task.feign;
+
+import com.yonge.cooleshow.common.config.FeignConfiguration;
+import com.yonge.cooleshow.task.feign.fallback.MallPortalFeignServiceFallback;
+import com.yonge.cooleshow.task.feign.fallback.StudentFeignServiceFallback;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.GetMapping;
+
+@FeignClient(name = "mall-portal-server", configuration = FeignConfiguration.class, fallback = MallPortalFeignServiceFallback.class)
+public interface MallPortalFeignService {
+
+    /**
+     * 订单轮询
+     */
+    @GetMapping("/task/pollingOrder")
+    Object cancelTimeOutOrder();
+}

+ 16 - 0
cooleshow-task/src/main/java/com/yonge/cooleshow/task/feign/fallback/MallPortalFeignServiceFallback.java

@@ -0,0 +1,16 @@
+package com.yonge.cooleshow.task.feign.fallback;
+
+import com.yonge.cooleshow.task.feign.MallPortalFeignService;
+
+/**
+ * Description
+ *
+ * @author liujunchi
+ * @date 2022-04-26
+ */
+public class MallPortalFeignServiceFallback implements MallPortalFeignService {
+    @Override
+    public Object cancelTimeOutOrder() {
+        return null;
+    }
+}

+ 25 - 0
cooleshow-task/src/main/java/com/yonge/cooleshow/task/jobs/CancelTimeOutOrderTask.java

@@ -0,0 +1,25 @@
+package com.yonge.cooleshow.task.jobs;
+
+import com.yonge.cooleshow.task.core.BaseTask;
+import com.yonge.cooleshow.task.core.TaskException;
+import com.yonge.cooleshow.task.feign.MallPortalFeignService;
+import com.yonge.cooleshow.task.feign.StudentFeignService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+/**
+ * 订单轮询
+ * @Author: liweifan
+ * @Data: 2022/4/13 17:36
+ */
+@Service
+public class CancelTimeOutOrderTask extends BaseTask {
+
+    @Autowired
+    private MallPortalFeignService mallPortalFeignService;
+
+    @Override
+    public void execute() throws TaskException {
+        Object o = mallPortalFeignService.cancelTimeOutOrder();
+    }
+}

+ 5 - 4
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/entity/MusicSheetPurchaseRecord.java

@@ -1,5 +1,6 @@
 package com.yonge.cooleshow.biz.dal.entity;
 
+import com.yonge.cooleshow.biz.dal.enums.OrderStatusEnum;
 import com.yonge.cooleshow.biz.dal.enums.YesOrNoEnum;
 import com.yonge.cooleshow.common.entity.BaseEntity;
 import com.baomidou.mybatisplus.annotation.IdType;
@@ -60,8 +61,8 @@ public class MusicSheetPurchaseRecord extends BaseEntity {
 	private BigDecimal musicSheetServiceFee;
 
     @TableField("order_status_")
-    @ApiModelProperty(value = "订单状态(1:已完成;0:取消)")
-    private YesOrNoEnum orderStatus;  //订单状态(1:已完成;0:取消)
+    @ApiModelProperty(value = "订单状态(WAIT_PAY:待支付;PAYING:支付中,PAID:已付款)")
+    private OrderStatusEnum orderStatus;  //订单状态(1:已完成;0:取消)
 
 	public BigDecimal getOriginalPrice() {
 		return originalPrice;
@@ -142,12 +143,12 @@ public class MusicSheetPurchaseRecord extends BaseEntity {
 	    return this.purchasePrice;
 	}
 
-	public MusicSheetPurchaseRecord setOrderStatus(YesOrNoEnum orderStatus) {
+	public MusicSheetPurchaseRecord setOrderStatus(OrderStatusEnum orderStatus) {
 	    this.orderStatus = orderStatus;
 	    return this;
 	}
 
-	public YesOrNoEnum getOrderStatus() {
+	public OrderStatusEnum getOrderStatus() {
 	    return this.orderStatus;
 	}
 

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

@@ -44,7 +44,7 @@ public class TeacherFreeTime implements Serializable {
 
     @NotBlank(message = "声部单课时金额不可为空")
     @TableField("subject_price_")
-    @ApiModelProperty(value = "声部单课时金额:[{'id':1,'price':100.1}]")
+    @ApiModelProperty(value = "声部单课时金额:[{'subjectId':1,'subjectPrice':100.88,'subjectName':'西洋管乐'},{'subjectId':2,'subjectPrice':200.88,'subjectName':'长笛'}]")
     private String subjectPrice;
 
     @TableField("monday_")

+ 1 - 1
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/MusicSheetPurchaseRecordService.java

@@ -18,5 +18,5 @@ public interface MusicSheetPurchaseRecordService extends IService<MusicSheetPurc
      * @param musicSheetId 曲目id
      * @return boolean
      */
-    boolean checkPurchase(Long userId, Long musicSheetId);
+    MusicSheetPurchaseRecord checkPurchase(Long userId, Long musicSheetId);
 }

+ 14 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/MusicSheetService.java

@@ -184,4 +184,18 @@ public interface MusicSheetService extends IService<MusicSheet> {
      * @param userOrderDetailVo
      */
     void buyMusicSheetSuccess(UserOrderDetailVo userOrderDetailVo);
+
+    /**
+     * 订单生产后,创建记录
+     *
+     * @param userOrderDetailVo
+     */
+    void orderAfterSheet(UserOrderDetailVo userOrderDetailVo);
+
+    /**
+     *  订单取消
+     *
+     * @param userOrderDetailVo
+     */
+    void buyMusicSheetCancel(UserOrderDetailVo userOrderDetailVo);
 }

+ 14 - 7
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/MusicSheetPurchaseRecordServiceImpl.java

@@ -9,6 +9,9 @@ import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Service;
 import org.springframework.beans.factory.annotation.Autowired;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.util.CollectionUtils;
+
+import java.util.List;
 
 /**
  * MusicSheetPurchaseRecordService服务实现类
@@ -29,12 +32,16 @@ public class MusicSheetPurchaseRecordServiceImpl extends ServiceImpl<MusicSheetP
     }
 
     @Override
-    public boolean checkPurchase(Long userId, Long musicSheetId) {
-        Integer count = this.lambdaQuery()
-                            .eq(MusicSheetPurchaseRecord::getMusicSheetId, musicSheetId)
-                            .eq(MusicSheetPurchaseRecord::getStudentId, userId)
-                            .eq(MusicSheetPurchaseRecord::getOrderStatus, YesOrNoEnum.YES.getCode())
-                            .count();
-        return count > 0 ;
+    public MusicSheetPurchaseRecord checkPurchase(Long userId, Long musicSheetId) {
+        List<MusicSheetPurchaseRecord> list = this.lambdaQuery()
+                                                  .eq(MusicSheetPurchaseRecord::getMusicSheetId, musicSheetId)
+                                                  .eq(MusicSheetPurchaseRecord::getStudentId, userId)
+                                                  .eq(MusicSheetPurchaseRecord::getOrderStatus,
+                                                      YesOrNoEnum.YES.getCode())
+                                                  .list();
+        if (CollectionUtils.isEmpty(list)) {
+            return null;
+        }
+        return list.get(0);
     }
 }

+ 38 - 6
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/MusicSheetServiceImpl.java

@@ -160,9 +160,13 @@ public class MusicSheetServiceImpl extends ServiceImpl<MusicSheetDao,MusicSheet>
             // 单曲购买 判断购买记录,有记录课播放
             if (ChargeTypeEnum.CHARGE.getCode().equals(detail.getChargeType().getCode())) {
                 // 学生须判断是否能播放曲目
-                boolean b = musicSheetPurchaseRecordService.checkPurchase(sysUser.getId(),detail.getId());
-                if (b) {
-                    detail.setPlay(YesOrNoEnum.YES);
+                MusicSheetPurchaseRecord musicSheetPurchaseRecord = musicSheetPurchaseRecordService.checkPurchase(
+                        sysUser.getId(), detail.getId());
+                if (musicSheetPurchaseRecord != null) {
+                    detail.setOrderStatus(musicSheetPurchaseRecord.getOrderStatus());
+                    if (OrderStatusEnum.PAID.getCode().equals(musicSheetPurchaseRecord.getOrderStatus().getCode())) {
+                        detail.setPlay(YesOrNoEnum.YES);
+                    }
                 }
             } else if  (ChargeTypeEnum.VIP.getCode().equals(detail.getChargeType().getCode())) {
                 // 会员 判断是否为会员, 会员可播放
@@ -376,7 +380,11 @@ public class MusicSheetServiceImpl extends ServiceImpl<MusicSheetDao,MusicSheet>
         BigDecimal serviceFeeAmount = actualPrice.multiply(serviceFee).setScale(2, RoundingMode.HALF_UP);
 
         // 保存购买记录
-        MusicSheetPurchaseRecord musicSheetPurchaseRecord = new MusicSheetPurchaseRecord();
+        MusicSheetPurchaseRecord musicSheetPurchaseRecord = musicSheetPurchaseRecordService
+                .checkPurchase(userOrderDetailVo.getUserId(),userOrderDetailVo.getBizId());
+        if (musicSheetPurchaseRecord == null) {
+            musicSheetPurchaseRecord = new MusicSheetPurchaseRecord();
+        }
         musicSheetPurchaseRecord.setMusicSheetId(userOrderDetailVo.getBizId());
         musicSheetPurchaseRecord.setOrderNo(userOrderDetailVo.getOrderNo());
         musicSheetPurchaseRecord.setPurchasePrice(actualPrice);
@@ -384,7 +392,7 @@ public class MusicSheetServiceImpl extends ServiceImpl<MusicSheetDao,MusicSheet>
         musicSheetPurchaseRecord.setTeacherId(userOrderDetailVo.getMerchId());
         musicSheetPurchaseRecord.setOriginalPrice(userOrderDetailVo.getOriginalPrice());
         musicSheetPurchaseRecord.setMusicSheetServiceFee(serviceFeeAmount);
-        musicSheetPurchaseRecord.setOrderStatus(YesOrNoEnum.YES);
+        musicSheetPurchaseRecord.setOrderStatus(OrderStatusEnum.PAID);
         musicSheetPurchaseRecord.setStudentId(userOrderDetailVo.getUserId());
         musicSheetPurchaseRecordService.save(musicSheetPurchaseRecord);
 
@@ -393,7 +401,6 @@ public class MusicSheetServiceImpl extends ServiceImpl<MusicSheetDao,MusicSheet>
         userAccountRecordDto.setUserId(userOrderDetailVo.getMerchId());
         userAccountRecordDto.setFrozenType(FrozenTypeEnum.NONE);
 
-        //
         userAccountRecordDto.setTransAmount(actualPrice.subtract(serviceFeeAmount).setScale(2, RoundingMode.HALF_UP));
         userAccountRecordDto.setInOrOut(InOrOutEnum.IN);
         userAccountRecordDto.setBizType(AccountBizTypeEnum.MUSIC);
@@ -403,6 +410,31 @@ public class MusicSheetServiceImpl extends ServiceImpl<MusicSheetDao,MusicSheet>
         userAccountService.accountChange(userAccountRecordDto);
     }
 
+    @Override
+    public void orderAfterSheet(UserOrderDetailVo userOrderDetailVo) {
+        // 保存购买记录
+        MusicSheetPurchaseRecord musicSheetPurchaseRecord = musicSheetPurchaseRecordService
+                .checkPurchase(userOrderDetailVo.getUserId(),userOrderDetailVo.getBizId());
+        if (musicSheetPurchaseRecord == null) {
+            musicSheetPurchaseRecord = new MusicSheetPurchaseRecord();
+        }
+        musicSheetPurchaseRecord.setMusicSheetId(userOrderDetailVo.getBizId());
+        musicSheetPurchaseRecord.setOrderNo(userOrderDetailVo.getOrderNo());
+        musicSheetPurchaseRecord.setTeacherId(userOrderDetailVo.getMerchId());
+        musicSheetPurchaseRecord.setOriginalPrice(userOrderDetailVo.getOriginalPrice());
+        musicSheetPurchaseRecord.setOrderStatus(OrderStatusEnum.WAIT_PAY);
+        musicSheetPurchaseRecord.setStudentId(userOrderDetailVo.getUserId());
+        musicSheetPurchaseRecordService.save(musicSheetPurchaseRecord);
+    }
+
+    @Override
+    public void buyMusicSheetCancel(UserOrderDetailVo userOrderDetailVo) {
+        MusicSheetPurchaseRecord musicSheetPurchaseRecord = musicSheetPurchaseRecordService
+                .checkPurchase(userOrderDetailVo.getUserId(),userOrderDetailVo.getBizId());
+        if (musicSheetPurchaseRecord == null) return;
+        musicSheetPurchaseRecordService.removeById(musicSheetPurchaseRecord.getId());
+    }
+
     private SysUser getSysUser(Long userId) {
         return Optional.ofNullable(userId)
                        .map(sysUserFeignService::queryUserById)

+ 0 - 1
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/TeacherFreeTimeServiceImpl.java

@@ -20,7 +20,6 @@ import java.util.Objects;
 
 /**
  * 老师可排课时间表(TeacherFreeTime)表服务实现类
- *
  * @author zx
  * @since 2022-03-25 10:04:27
  */

+ 7 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/UserOrderServiceImpl.java

@@ -91,6 +91,10 @@ public class UserOrderServiceImpl extends ServiceImpl<UserOrderDao, UserOrder> i
 
         /**********订单生成后******************/
 
+
+        //曲目购买
+        orderAfter.put(GoodTypeEnum.MUSIC,musicSheetService::orderAfterSheet);
+
         /**********订单完成后******************/
         //vip开通缴费
         orderSuccess.put(GoodTypeEnum.VIP, memberPriceSettingsService::orderSuccess);
@@ -113,6 +117,9 @@ public class UserOrderServiceImpl extends ServiceImpl<UserOrderDao, UserOrder> i
         orderCancel.put(GoodTypeEnum.VIDEO, recordService::buyVideoCourseFailed);
         //直播课购买
         orderCancel.put(GoodTypeEnum.LIVE, courseGroupService::buyLiveCourseCancel);
+
+        // 曲目购买
+        orderCancel.put(GoodTypeEnum.MUSIC,musicSheetService::buyMusicSheetCancel);
     }
 
     @Override

+ 1 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/VideoLessonGroupDetailServiceImpl.java

@@ -10,6 +10,7 @@ import com.yonge.cooleshow.biz.dal.dto.search.VideoLessonSearch;
 import com.yonge.cooleshow.biz.dal.entity.VideoLessonGroup;
 import com.yonge.cooleshow.biz.dal.entity.VideoLessonGroupDetail;
 import com.yonge.cooleshow.biz.dal.dao.VideoLessonGroupDetailDao;
+
 import com.yonge.cooleshow.biz.dal.entity.VideoLessonPurchaseRecord;
 import com.yonge.cooleshow.biz.dal.enums.AuthStatusEnum;
 import com.yonge.cooleshow.biz.dal.service.VideoLessonGroupDetailService;

+ 12 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/vo/MusicSheetDetailVo.java

@@ -2,6 +2,7 @@ package com.yonge.cooleshow.biz.dal.vo;
 
 import com.yonge.cooleshow.biz.dal.entity.MusicSheet;
 import com.yonge.cooleshow.biz.dal.entity.MusicSheetAccompaniment;
+import com.yonge.cooleshow.biz.dal.enums.OrderStatusEnum;
 import com.yonge.cooleshow.biz.dal.enums.YesOrNoEnum;
 import io.swagger.annotations.ApiModelProperty;
 
@@ -21,6 +22,9 @@ public class MusicSheetDetailVo extends MusicSheet {
     @ApiModelProperty("是否能播放(0:否,1:是) 学生端进入云教练判断 试用/完整 播放")
     private YesOrNoEnum play;
 
+    @ApiModelProperty("订单状态(WAIT_PAY:待支付;PAYING:支付中,PAID:已付款)")
+    private OrderStatusEnum orderStatus;
+
     @ApiModelProperty("上传老师名称")
     private String userName;
 
@@ -80,5 +84,13 @@ public class MusicSheetDetailVo extends MusicSheet {
     public void setPlay(YesOrNoEnum play) {
         this.play = play;
     }
+
+    public OrderStatusEnum getOrderStatus() {
+        return orderStatus;
+    }
+
+    public void setOrderStatus(OrderStatusEnum orderStatus) {
+        this.orderStatus = orderStatus;
+    }
 }
 

+ 2 - 1
cooleshow-user/user-biz/src/main/resources/config/mybatis/MusicSheetMapper.xml

@@ -196,6 +196,7 @@
         <result column="showFingering" jdbcType="TINYINT" property="showFingering"/>
         <result column="chargeType" jdbcType="TINYINT" property="chargeType"/>
         <result column="auditStatus" jdbcType="TINYINT" property="auditStatus"/>
+        <result column="state" jdbcType="TINYINT" property="state"/>
         <result column="sortNumber" jdbcType="INTEGER" property="sortNumber"/>
         <result column="topFlag" jdbcType="TINYINT" property="topFlag"/>
         <result column="hotFlag" jdbcType="TINYINT" property="hotFlag"/>
@@ -213,7 +214,7 @@
         <result column="url" jdbcType="BOOLEAN" property="url"/>
         <result column="metronomeUrl" jdbcType="BOOLEAN" property="metronomeUrl"/>
         <result column="midiUrl" jdbcType="BOOLEAN" property="midiUrl"/>
-        <result column="mp3Type" jdbcType="BOOLEAN" property="mp3Type"/>
+        <result column="mp3Type" jdbcType="VARCHAR" property="mp3Type"/>
         <result column="remark" jdbcType="VARCHAR" property="remark"/>
         <result column="userName" jdbcType="VARCHAR" property="userName"/>
         <collection property="background" ofType="com.yonge.cooleshow.biz.dal.entity.MusicSheetAccompaniment">

+ 5 - 0
pom.xml

@@ -106,6 +106,11 @@
 				<artifactId>mall-common</artifactId>
 				<version>1.0</version>
 			</dependency>
+			<dependency>
+				<groupId>com.yonge.cooleshow</groupId>
+				<artifactId>mall-pay</artifactId>
+				<version>1.0</version>
+			</dependency>
 			<!--mall中MBG生成模块-->
 			<dependency>
 				<groupId>com.yonge.cooleshow</groupId>