Explorar el Código

Merge branch 'master' of http://git.dayaedu.com/yonge/cooleshow

liujunchi hace 3 años
padre
commit
8362f8e94e
Se han modificado 21 ficheros con 1371 adiciones y 46 borrados
  1. 46 0
      cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/controller/CourseGroupController.java
  2. 32 4
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/CourseGroupDao.java
  3. 105 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/search/CourseGroupDetailSearch.java
  4. 57 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/search/CourseGroupSearch.java
  5. 25 3
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/CourseGroupService.java
  6. 45 22
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/CourseGroupServiceImpl.java
  7. 0 1
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/UserOrderRefundServiceImpl.java
  8. 133 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/vo/CourseGroupLiveVo.java
  9. 181 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/vo/CourseGroupPracticeDetailVo.java
  10. 143 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/vo/CourseGroupPracticeVo.java
  11. 143 0
      cooleshow-user/user-biz/src/main/resources/config/mybatis/CourseGroupMapper.xml
  12. 5 0
      toolset/toolset-payment/pom.xml
  13. 20 0
      toolset/toolset-payment/src/main/java/com/yonge/toolset/payment/adapay/AdapayTemplate.java
  14. 1 0
      toolset/toolset-payment/src/main/java/com/yonge/toolset/payment/base/constant/PaymentConstant.java
  15. 14 0
      toolset/toolset-payment/src/main/java/com/yonge/toolset/payment/base/model/callback/ClosePaymentCallBack.java
  16. 16 0
      toolset/toolset-payment/src/main/java/com/yonge/toolset/payment/base/model/callback/ExecutePaymentCallBack.java
  17. 15 0
      toolset/toolset-payment/src/main/java/com/yonge/toolset/payment/base/model/callback/RefundPaymentCallBack.java
  18. 195 0
      toolset/toolset-payment/src/main/java/com/yonge/toolset/payment/core/util/RequestKitBean.java
  19. 117 10
      toolset/toolset-payment/src/main/java/com/yonge/toolset/payment/original/ali/OriginalAliAppTemplate.java
  20. 14 0
      toolset/toolset-payment/src/main/java/com/yonge/toolset/payment/original/ali/constant/AlipayConstant.java
  21. 64 6
      toolset/toolset-payment/src/main/java/com/yonge/toolset/payment/original/wx/OriginalWxAppTemplate.java

+ 46 - 0
cooleshow-user/user-admin/src/main/java/com/yonge/cooleshow/admin/controller/CourseGroupController.java

@@ -0,0 +1,46 @@
+package com.yonge.cooleshow.admin.controller;
+
+import com.yonge.cooleshow.biz.dal.dto.search.CourseGroupDetailSearch;
+import com.yonge.cooleshow.biz.dal.dto.search.CourseGroupSearch;
+import com.yonge.cooleshow.biz.dal.service.CourseGroupService;
+import com.yonge.cooleshow.biz.dal.support.PageUtil;
+import com.yonge.cooleshow.biz.dal.vo.*;
+import com.yonge.cooleshow.common.controller.BaseController;
+import com.yonge.cooleshow.common.entity.HttpResponseResult;
+import com.yonge.toolset.base.page.PageInfo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+/**
+ * @Author: cy
+ * @Date: 2022/5/19
+ */
+@RestController
+@RequestMapping("/courseGroup")
+@Api(tags = "课程组")
+@Validated
+public class CourseGroupController extends BaseController {
+    @Autowired
+    private CourseGroupService courseGroupService;
+
+    @ApiOperation(value = "课程组管理-陪练课")
+    @PostMapping(value = "/practice")
+    public HttpResponseResult<PageInfo<CourseGroupPracticeVo>> selectPracticeGroup(@RequestBody CourseGroupSearch search) {
+        return succeed(PageUtil.pageInfo(courseGroupService.selectPracticeGroup(PageUtil.getPage(search), search)));
+    }
+
+    @ApiOperation(value = "课程组管理-陪练课-详情")
+    @PostMapping(value = "/practice/detail")
+    public HttpResponseResult<PageInfo<CourseGroupPracticeDetailVo>> selectPracticeGroupDetail(@Validated @RequestBody CourseGroupDetailSearch search) {
+        return succeed(PageUtil.pageInfo(courseGroupService.selectPracticeGroupDetail(PageUtil.getPage(search), search)));
+    }
+
+    @ApiOperation(value = "课程组管理-直播课")
+    @PostMapping(value = "/live")
+    public HttpResponseResult<PageInfo<CourseGroupLiveVo>> selectLiveGroup(@RequestBody CourseGroupSearch search) {
+        return succeed(PageUtil.pageInfo(courseGroupService.selectLiveGroup(PageUtil.getPage(search), search)));
+    }
+}

+ 32 - 4
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dao/CourseGroupDao.java

@@ -3,9 +3,7 @@ package com.yonge.cooleshow.biz.dal.dao;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
-import com.yonge.cooleshow.biz.dal.dto.search.LiveCourseGroupSearch;
-import com.yonge.cooleshow.biz.dal.dto.search.LiveCourseGroupStudentCourseSearch;
-import com.yonge.cooleshow.biz.dal.dto.search.LiveCourseGroupStudentSearch;
+import com.yonge.cooleshow.biz.dal.dto.search.*;
 import com.yonge.cooleshow.biz.dal.entity.CourseGroup;
 import com.yonge.cooleshow.biz.dal.vo.*;
 import org.apache.ibatis.annotations.Param;
@@ -73,7 +71,7 @@ public interface CourseGroupDao extends BaseMapper<CourseGroup> {
      *
      * @param id 课程组id
      */
-    int opsPreStudentNum(@Param("id") Long id,@Param("num") Integer num);
+    int opsPreStudentNum(@Param("id") Long id, @Param("num") Integer num);
 
     /**
      * 查询课程组详情
@@ -92,5 +90,35 @@ public interface CourseGroupDao extends BaseMapper<CourseGroup> {
      */
     IPage<LiveCourseGroupStudentCourseVo> selectAdminLiveStudentCoursePage(@Param("page") IPage<LiveCourseGroupStudentCourseVo> page,
                                                                            @Param("param") LiveCourseGroupStudentCourseSearch query);
+
+    /**
+     * 查询陪练课
+     *
+     * @param page
+     * @param search
+     * @return
+     */
+    IPage<CourseGroupPracticeVo> selectPracticeGroup(@Param("page") IPage<CourseGroupPracticeVo> page,
+                                                     @Param("param") CourseGroupSearch search);
+
+    /**
+     * 查询陪练课-详情
+     *
+     * @param page
+     * @param search
+     * @return
+     */
+    IPage<CourseGroupPracticeDetailVo> selectPracticeGroupDetail(@Param("page") IPage<CourseGroupPracticeDetailVo> page,
+                                                                 @Param("param") CourseGroupDetailSearch search);
+
+    /**
+     * 查询直播课
+     *
+     * @param page
+     * @param search
+     * @return
+     */
+    IPage<CourseGroupLiveVo> selectLiveGroup(@Param("page") IPage<CourseGroupLiveVo> page,
+                                             @Param("param") CourseGroupSearch search);
 }
 

+ 105 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/search/CourseGroupDetailSearch.java

@@ -0,0 +1,105 @@
+package com.yonge.cooleshow.biz.dal.dto.search;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.yonge.toolset.base.page.QueryInfo;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import javax.validation.constraints.NotNull;
+import java.util.Date;
+
+/**
+ * @Author: cy
+ * @Date: 2022/5/19
+ */
+@ApiModel
+public class CourseGroupDetailSearch extends QueryInfo {
+    @ApiModelProperty(value = "课程组id")
+    @NotNull
+    private Long courseGroupId;
+    @ApiModelProperty(value = "课程编号/老师姓名/老师编号/学员姓名/学员编号")
+    private String search;
+    @ApiModelProperty(value = "老师考勤")
+    private Integer teacherSign;
+    @ApiModelProperty(value = "学生考勤")
+    private Integer studentSign;
+    @ApiModelProperty(value = "课程状态")
+    private String status;
+    @ApiModelProperty(value = "结算状态")
+    private String salaryStatus;
+    @ApiModelProperty(value = "开始时间")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date startTime;
+    @ApiModelProperty(value = "结束时间")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date endTime;
+
+    public Long getCourseGroupId() {
+        return courseGroupId;
+    }
+
+    public void setCourseGroupId(Long courseGroupId) {
+        this.courseGroupId = courseGroupId;
+    }
+
+    @Override
+    public String getSearch() {
+        return search;
+    }
+
+    @Override
+    public void setSearch(String search) {
+        this.search = search;
+    }
+
+    public Integer getTeacherSign() {
+        return teacherSign;
+    }
+
+    public void setTeacherSign(Integer teacherSign) {
+        this.teacherSign = teacherSign;
+    }
+
+    public Integer getStudentSign() {
+        return studentSign;
+    }
+
+    public void setStudentSign(Integer studentSign) {
+        this.studentSign = studentSign;
+    }
+
+    public String getStatus() {
+        return status;
+    }
+
+    public void setStatus(String status) {
+        this.status = status;
+    }
+
+    public String getSalaryStatus() {
+        return salaryStatus;
+    }
+
+    public void setSalaryStatus(String salaryStatus) {
+        this.salaryStatus = salaryStatus;
+    }
+
+    public Date getStartTime() {
+        return startTime;
+    }
+
+    public void setStartTime(Date startTime) {
+        this.startTime = startTime;
+    }
+
+    public Date getEndTime() {
+        return endTime;
+    }
+
+    public void setEndTime(Date endTime) {
+        this.endTime = endTime;
+    }
+}

+ 57 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/dto/search/CourseGroupSearch.java

@@ -0,0 +1,57 @@
+package com.yonge.cooleshow.biz.dal.dto.search;
+
+import com.yonge.toolset.base.page.QueryInfo;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * @Author: cy
+ * @Date: 2022/5/19
+ */
+@ApiModel
+public class CourseGroupSearch extends QueryInfo {
+    @ApiModelProperty(value = "课程组、老师、学员编号/名称")
+    private String search;
+
+    @ApiModelProperty("声部id")
+    private Long subjectId;
+
+    @ApiModelProperty(value = "课程状态")
+    private String status;
+
+//    @ApiModelProperty(value = "开始时间")
+//    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+//    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+//    private Date startTime;
+//
+//    @ApiModelProperty(value = "结束时间")
+//    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+//    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+//    private Date endTime;
+
+    @Override
+    public String getSearch() {
+        return search;
+    }
+
+    @Override
+    public void setSearch(String search) {
+        this.search = search;
+    }
+
+    public Long getSubjectId() {
+        return subjectId;
+    }
+
+    public void setSubjectId(Long subjectId) {
+        this.subjectId = subjectId;
+    }
+
+    public String getStatus() {
+        return status;
+    }
+
+    public void setStatus(String status) {
+        this.status = status;
+    }
+}

+ 25 - 3
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/CourseGroupService.java

@@ -7,9 +7,7 @@ import com.yonge.cooleshow.biz.dal.dto.CheckCourseTimeDto;
 import com.yonge.cooleshow.biz.dal.dto.LiveCourseGroupDto;
 import com.yonge.cooleshow.biz.dal.dto.req.OrderRefundReq;
 import com.yonge.cooleshow.biz.dal.dto.req.OrderReq;
-import com.yonge.cooleshow.biz.dal.dto.search.LiveCourseGroupSearch;
-import com.yonge.cooleshow.biz.dal.dto.search.LiveCourseGroupStudentCourseSearch;
-import com.yonge.cooleshow.biz.dal.dto.search.LiveCourseGroupStudentSearch;
+import com.yonge.cooleshow.biz.dal.dto.search.*;
 import com.yonge.cooleshow.biz.dal.entity.CourseGroup;
 import com.yonge.cooleshow.biz.dal.entity.CourseTimeEntity;
 import com.yonge.cooleshow.biz.dal.entity.UserOrderRefund;
@@ -173,5 +171,29 @@ public interface CourseGroupService extends IService<CourseGroup> {
      * @return: com.yonge.cooleshow.common.entity.HttpResponseResult<com.yonge.cooleshow.biz.dal.vo.res.RefundCreateRes>
      */
     void refundCancel(UserOrderDetailVo userOrderDetailVo);
+
+    /**
+     * 课程组管理-陪练课
+     * @param page
+     * @param search
+     * @return
+     */
+    IPage<CourseGroupPracticeVo> selectPracticeGroup(IPage<CourseGroupPracticeVo> page, CourseGroupSearch search);
+
+    /**
+     * 课程组管理-陪练课-详情
+     * @param page
+     * @param search
+     * @return
+     */
+    IPage<CourseGroupPracticeDetailVo> selectPracticeGroupDetail(IPage<CourseGroupPracticeDetailVo> page, CourseGroupDetailSearch search);
+
+    /**
+     * 课程组管理-直播课
+     * @param page
+     * @param search
+     * @return
+     */
+    IPage<CourseGroupLiveVo> selectLiveGroup(IPage<CourseGroupLiveVo> page, CourseGroupSearch search);
 }
 

+ 45 - 22
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/CourseGroupServiceImpl.java

@@ -14,10 +14,7 @@ import com.yonge.cooleshow.biz.dal.dto.LiveCourseGroupDto;
 import com.yonge.cooleshow.biz.dal.dto.LiveCourseGroupDto.CoursePlanDto;
 import com.yonge.cooleshow.biz.dal.dto.req.OrderRefundReq;
 import com.yonge.cooleshow.biz.dal.dto.req.OrderReq;
-import com.yonge.cooleshow.biz.dal.dto.search.LiveCourseGroupSearch;
-import com.yonge.cooleshow.biz.dal.dto.search.LiveCourseGroupStudentCourseSearch;
-import com.yonge.cooleshow.biz.dal.dto.search.LiveCourseGroupStudentSearch;
-import com.yonge.cooleshow.biz.dal.dto.search.OrderSearch;
+import com.yonge.cooleshow.biz.dal.dto.search.*;
 import com.yonge.cooleshow.biz.dal.entity.*;
 import com.yonge.cooleshow.biz.dal.enums.*;
 import com.yonge.cooleshow.biz.dal.service.*;
@@ -780,8 +777,8 @@ public class CourseGroupServiceImpl extends ServiceImpl<CourseGroupDao, CourseGr
             Map<Long, String> teacherReceivers = new HashMap<>();
             teacherReceivers.put(teacherInfo.getId(), teacherInfo.getPhone());
             sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG, studentBuyLive,
-                    teacherReceivers, null, 0, studentBuyLiveUrl +courseGroup.getId() , ClientEnum.TEACHER.getCode(),
-                    studentInfo.getUsername(), courseGroup.getName() );
+                    teacherReceivers, null, 0, studentBuyLiveUrl + courseGroup.getId(), ClientEnum.TEACHER.getCode(),
+                    studentInfo.getUsername(), courseGroup.getName());
             log.info("buyLiveCourseSuccess buyLiveSendMessage STUDENT_BUY_LIVE ok");
 
             //短信-消息推送-老师端-通知老师有学生购买课程-无需跳转到APP
@@ -874,7 +871,7 @@ public class CourseGroupServiceImpl extends ServiceImpl<CourseGroupDao, CourseGr
         }
 
         // 取消老师课酬
-        cancelTeacherSalary(studentPayment.getUserId(),studentPayment.getCourseGroupId());
+        cancelTeacherSalary(studentPayment.getUserId(), studentPayment.getCourseGroupId());
 
         // 删除学生购买记录
         buyLiveCourseCancel(orderParam);
@@ -883,19 +880,19 @@ public class CourseGroupServiceImpl extends ServiceImpl<CourseGroupDao, CourseGr
     /**
      * 取消老师课酬
      *
-     * @param userId 学生id
+     * @param userId        学生id
      * @param courseGroupId 课程组id
      */
     private void cancelTeacherSalary(Long userId, Long courseGroupId) {
         List<CourseScheduleTeacherSalary> list = courseScheduleTeacherSalaryService.lambdaQuery()
-                                    .eq(CourseScheduleTeacherSalary::getStudentId,userId)
-                                    .eq(CourseScheduleTeacherSalary::getCourseGroupId, courseGroupId)
-                                    .list();
+                .eq(CourseScheduleTeacherSalary::getStudentId, userId)
+                .eq(CourseScheduleTeacherSalary::getCourseGroupId, courseGroupId)
+                .list();
         list = list.stream().filter(csts ->
-             TeacherSalaryEnum.NOT_START.getCode().equals(csts.getStatus())
-        ).peek(csts -> csts.setStatus(CourseScheduleEnum.CANCEL.getCode()))
-        .collect(Collectors.toList());
-        if(CollectionUtils.isEmpty(list)) {
+                        TeacherSalaryEnum.NOT_START.getCode().equals(csts.getStatus())
+                ).peek(csts -> csts.setStatus(CourseScheduleEnum.CANCEL.getCode()))
+                .collect(Collectors.toList());
+        if (CollectionUtils.isEmpty(list)) {
             return;
         }
 
@@ -908,6 +905,21 @@ public class CourseGroupServiceImpl extends ServiceImpl<CourseGroupDao, CourseGr
 
     }
 
+    @Override
+    public IPage<CourseGroupPracticeVo> selectPracticeGroup(IPage<CourseGroupPracticeVo> page, CourseGroupSearch search) {
+        return baseMapper.selectPracticeGroup(page, search);
+    }
+
+    @Override
+    public IPage<CourseGroupPracticeDetailVo> selectPracticeGroupDetail(IPage<CourseGroupPracticeDetailVo> page, CourseGroupDetailSearch search) {
+        return baseMapper.selectPracticeGroupDetail(page, search);
+    }
+
+    @Override
+    public IPage<CourseGroupLiveVo> selectLiveGroup(IPage<CourseGroupLiveVo> page, CourseGroupSearch search) {
+        return baseMapper.selectLiveGroup(page,search);
+    }
+
     /**
      * 定时将符合开售日期的未开售的直播课课程组修改为报名中状态
      */
@@ -961,6 +973,18 @@ public class CourseGroupServiceImpl extends ServiceImpl<CourseGroupDao, CourseGr
                             .eq(CourseSchedule::getCourseGroupId, courseGroup.getId())
                             .set(CourseSchedule::getStatus, CourseScheduleEnum.CANCEL.getCode())
                     );
+                    // 直播课成课失败通知
+                    // 发短信
+                    try {
+                        SysUser user = sysUserFeignService.queryUserById(courseGroup.getTeacherId());
+                        Map<Long, String> receivers = new HashMap<>();
+                        receivers.put(user.getId(), user.getPhone());
+                        sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.AWSMS, MessageTypeEnum.SMS_LIVE_COMPLETION_FAIL,
+                                receivers, null, 0, null, null,
+                                courseGroup.getName());
+                    } catch (Exception e) {
+                        log.warn("直播课成课失败短信发送失败,{}", e.getMessage());
+                    }
                     sendMessage(courseGroup);
 
                     refend(courseGroup);
@@ -983,9 +1007,9 @@ public class CourseGroupServiceImpl extends ServiceImpl<CourseGroupDao, CourseGr
 
         for (String orderNo : orderNoList) {
             try {
-                userOrderRefundService.orderRefund(orderNo,"直播课成课失败退款");
+                userOrderRefundService.orderRefund(orderNo, "直播课成课失败退款");
             } catch (Exception e) {
-                log.warn("直播课成课失败退款 退款失败,退款订单号 {}",orderNo);
+                log.warn("直播课成课失败退款 退款失败,退款订单号 {}", orderNo);
             }
         }
     }
@@ -1003,9 +1027,9 @@ public class CourseGroupServiceImpl extends ServiceImpl<CourseGroupDao, CourseGr
             Map<Long, String> receivers = new HashMap<>();
             receivers.put(user.getId(), user.getPhone());
             sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.AWSMS, MessageTypeEnum.SMS_LIVE_COMPLETION_FAIL,
-                               receivers, null, 0, null, null, courseGroup.getName());
+                    receivers, null, 0, null, null, courseGroup.getName());
         } catch (Exception e) {
-            log.warn("直播课成课失败短信发送失败,{}",e.getMessage());
+            log.warn("直播课成课失败短信发送失败,{}", e.getMessage());
         }
 
         // 发推送
@@ -1014,11 +1038,10 @@ public class CourseGroupServiceImpl extends ServiceImpl<CourseGroupDao, CourseGr
             Map<Long, String> receivers = new HashMap<>();
             receivers.put(user.getId(), user.getPhone());
             sysMessageService.batchSendMessage(MessageSenderPluginContext.MessageSender.JIGUANG, MessageTypeEnum.LIVE_COMPLETION_FAIL,
-                               receivers, null, 0, null, ClientEnum.TEACHER.getCode(), courseGroup.getName());
+                    receivers, null, 0, null, ClientEnum.TEACHER.getCode(), courseGroup.getName());
         } catch (Exception e) {
-            log.warn("直播课成课失败推送发送失败,{}",e.getMessage());
+            log.warn("直播课成课失败推送发送失败,{}", e.getMessage());
         }
     }
-
 }
 

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

@@ -272,7 +272,6 @@ public class UserOrderRefundServiceImpl extends ServiceImpl<UserOrderRefundDao,
         }
 
         return doOrderRefund(orderRefunds);
-
     }
 
 

+ 133 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/vo/CourseGroupLiveVo.java

@@ -0,0 +1,133 @@
+package com.yonge.cooleshow.biz.dal.vo;
+
+import com.yonge.cooleshow.common.entity.BaseEntity;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * @Author: cy
+ * @Date: 2022/5/19
+ */
+@ApiModel
+public class CourseGroupLiveVo extends BaseEntity {
+    @ApiModelProperty("直播课组id")
+    private Long courseGroupId;
+    @ApiModelProperty("直播课组名称")
+    private String courseGroupName;
+    @ApiModelProperty("声部id")
+    private Long subjectId;
+    @ApiModelProperty("声部名称")
+    private String subjectName;
+    @ApiModelProperty("预计购课人数")
+    private Integer studentNum;
+    @ApiModelProperty("课时总数")
+    private Integer courseNum;
+    @ApiModelProperty("已完成课时数")
+    private Integer completeCount;
+    @ApiModelProperty("老师id")
+    private Long teacherId;
+    @ApiModelProperty("老师姓名")
+    private String teacherName;
+    @ApiModelProperty("老师真实姓名")
+    private String teacherRealName;
+    @ApiModelProperty("课程组状态 ING进行中 COMPLETE已完成 DISSOLVE-未成课(解散课程) CANCEL已取消-未开始报名前可取消 APPLY报名中 NOT_SALE未开售")
+    private String status;
+    @ApiModelProperty("第一节课开始时间")
+    private String startTime;
+
+    public Long getCourseGroupId() {
+        return courseGroupId;
+    }
+
+    public void setCourseGroupId(Long courseGroupId) {
+        this.courseGroupId = courseGroupId;
+    }
+
+    public String getCourseGroupName() {
+        return courseGroupName;
+    }
+
+    public void setCourseGroupName(String courseGroupName) {
+        this.courseGroupName = courseGroupName;
+    }
+
+    public Long getSubjectId() {
+        return subjectId;
+    }
+
+    public void setSubjectId(Long subjectId) {
+        this.subjectId = subjectId;
+    }
+
+    public String getSubjectName() {
+        return subjectName;
+    }
+
+    public void setSubjectName(String subjectName) {
+        this.subjectName = subjectName;
+    }
+
+    public Integer getStudentNum() {
+        return studentNum;
+    }
+
+    public void setStudentNum(Integer studentNum) {
+        this.studentNum = studentNum;
+    }
+
+    public Integer getCourseNum() {
+        return courseNum;
+    }
+
+    public void setCourseNum(Integer courseNum) {
+        this.courseNum = courseNum;
+    }
+
+    public Integer getCompleteCount() {
+        return completeCount;
+    }
+
+    public void setCompleteCount(Integer completeCount) {
+        this.completeCount = completeCount;
+    }
+
+    public Long getTeacherId() {
+        return teacherId;
+    }
+
+    public void setTeacherId(Long teacherId) {
+        this.teacherId = teacherId;
+    }
+
+    public String getTeacherName() {
+        return teacherName;
+    }
+
+    public void setTeacherName(String teacherName) {
+        this.teacherName = teacherName;
+    }
+
+    public String getTeacherRealName() {
+        return teacherRealName;
+    }
+
+    public void setTeacherRealName(String teacherRealName) {
+        this.teacherRealName = teacherRealName;
+    }
+
+    public String getStatus() {
+        return status;
+    }
+
+    public void setStatus(String status) {
+        this.status = status;
+    }
+
+    public String getStartTime() {
+        return startTime;
+    }
+
+    public void setStartTime(String startTime) {
+        this.startTime = startTime;
+    }
+}

+ 181 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/vo/CourseGroupPracticeDetailVo.java

@@ -0,0 +1,181 @@
+package com.yonge.cooleshow.biz.dal.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.yonge.cooleshow.common.entity.BaseEntity;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.util.Date;
+
+/**
+ * @Author: cy
+ * @Date: 2022/5/19
+ */
+@ApiModel
+public class CourseGroupPracticeDetailVo extends BaseEntity {
+    @ApiModelProperty("陪练课id")
+    private Long courseId;
+    @ApiModelProperty("声部名称")
+    private String subjectName;
+    @ApiModelProperty("老师id")
+    private Long teacherId;
+    @ApiModelProperty("老师姓名")
+    private String teacherName;
+    @ApiModelProperty("老师真实姓名")
+    private String teacherRealName;
+    @ApiModelProperty("学生id")
+    private Long studentId;
+    @ApiModelProperty("学生姓名")
+    private String studentName;
+    @ApiModelProperty("学生真实姓名")
+    private String studentRealName;
+    @ApiModelProperty("课程状态 NOT_START未开始 ING进行中 COMPLETE已完成 CANCEL已取消")
+    private String status;
+    @ApiModelProperty("开始时间")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date startTime;
+    @ApiModelProperty("结束时间")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date endTime;
+    @ApiModelProperty("老师签到状态 0:异常 1:正常")
+    private Integer teacherInSign;
+    @ApiModelProperty("老师签退状态 0:异常 1:正常")
+    private Integer teacherOutSign;
+    @ApiModelProperty("学生签到状态 0:异常 1:正常")
+    private Integer studentInSign;
+    @ApiModelProperty("学生签退状态 0:异常 1:正常")
+    private Integer studentOutSign;
+    @ApiModelProperty("NOT_START未上课、WAIT待结算、COMPLETE已结算、CANCEL已取消")
+    private String salaryStatus;
+
+    public Long getCourseId() {
+        return courseId;
+    }
+
+    public void setCourseId(Long courseId) {
+        this.courseId = courseId;
+    }
+
+    public String getSubjectName() {
+        return subjectName;
+    }
+
+    public void setSubjectName(String subjectName) {
+        this.subjectName = subjectName;
+    }
+
+    public Long getTeacherId() {
+        return teacherId;
+    }
+
+    public void setTeacherId(Long teacherId) {
+        this.teacherId = teacherId;
+    }
+
+    public String getTeacherName() {
+        return teacherName;
+    }
+
+    public void setTeacherName(String teacherName) {
+        this.teacherName = teacherName;
+    }
+
+    public String getTeacherRealName() {
+        return teacherRealName;
+    }
+
+    public void setTeacherRealName(String teacherRealName) {
+        this.teacherRealName = teacherRealName;
+    }
+
+    public Long getStudentId() {
+        return studentId;
+    }
+
+    public void setStudentId(Long studentId) {
+        this.studentId = studentId;
+    }
+
+    public String getStudentName() {
+        return studentName;
+    }
+
+    public void setStudentName(String studentName) {
+        this.studentName = studentName;
+    }
+
+    public String getStudentRealName() {
+        return studentRealName;
+    }
+
+    public void setStudentRealName(String studentRealName) {
+        this.studentRealName = studentRealName;
+    }
+
+    public String getStatus() {
+        return status;
+    }
+
+    public void setStatus(String status) {
+        this.status = status;
+    }
+
+    public Date getStartTime() {
+        return startTime;
+    }
+
+    public void setStartTime(Date startTime) {
+        this.startTime = startTime;
+    }
+
+    public Date getEndTime() {
+        return endTime;
+    }
+
+    public void setEndTime(Date endTime) {
+        this.endTime = endTime;
+    }
+
+    public Integer getTeacherInSign() {
+        return teacherInSign;
+    }
+
+    public void setTeacherInSign(Integer teacherInSign) {
+        this.teacherInSign = teacherInSign;
+    }
+
+    public Integer getTeacherOutSign() {
+        return teacherOutSign;
+    }
+
+    public void setTeacherOutSign(Integer teacherOutSign) {
+        this.teacherOutSign = teacherOutSign;
+    }
+
+    public Integer getStudentInSign() {
+        return studentInSign;
+    }
+
+    public void setStudentInSign(Integer studentInSign) {
+        this.studentInSign = studentInSign;
+    }
+
+    public Integer getStudentOutSign() {
+        return studentOutSign;
+    }
+
+    public void setStudentOutSign(Integer studentOutSign) {
+        this.studentOutSign = studentOutSign;
+    }
+
+    public String getSalaryStatus() {
+        return salaryStatus;
+    }
+
+    public void setSalaryStatus(String salaryStatus) {
+        this.salaryStatus = salaryStatus;
+    }
+}

+ 143 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/vo/CourseGroupPracticeVo.java

@@ -0,0 +1,143 @@
+package com.yonge.cooleshow.biz.dal.vo;
+
+import com.yonge.cooleshow.common.entity.BaseEntity;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+
+/**
+ * @Author: cy
+ * @Date: 2022/5/19
+ */
+@ApiModel
+public class CourseGroupPracticeVo extends BaseEntity {
+    @ApiModelProperty("陪练课组id")
+    private Long groupId;
+    @ApiModelProperty("声部id")
+    private Long subjectId;
+    @ApiModelProperty("声部名称")
+    private String subjectName;
+    @ApiModelProperty("课时总数")
+    private Integer courseNum;
+    @ApiModelProperty("已完成课时数")
+    private Integer completeCount;
+    @ApiModelProperty("老师id")
+    private Long teacherId;
+    @ApiModelProperty("老师姓名")
+    private String teacherName;
+    @ApiModelProperty("老师真实姓名")
+    private String teacherRealName;
+    @ApiModelProperty("学生id")
+    private Long studentId;
+    @ApiModelProperty("学生姓名")
+    private String studentName;
+    @ApiModelProperty("学生真实姓名")
+    private String studentRealName;
+    @ApiModelProperty("课程组状态 ING进行中 COMPLETE已完成 DISSOLVE-未成课(解散课程) CANCEL已取消-未开始报名前可取消 APPLY报名中 NOT_SALE未开售")
+    private String status;
+    @ApiModelProperty("第一节课开始时间")
+    private String startTime;
+
+    public Long getGroupId() {
+        return groupId;
+    }
+
+    public void setGroupId(Long groupId) {
+        this.groupId = groupId;
+    }
+
+    public Long getSubjectId() {
+        return subjectId;
+    }
+
+    public void setSubjectId(Long subjectId) {
+        this.subjectId = subjectId;
+    }
+
+    public String getSubjectName() {
+        return subjectName;
+    }
+
+    public void setSubjectName(String subjectName) {
+        this.subjectName = subjectName;
+    }
+
+    public Integer getCourseNum() {
+        return courseNum;
+    }
+
+    public void setCourseNum(Integer courseNum) {
+        this.courseNum = courseNum;
+    }
+
+    public Integer getCompleteCount() {
+        return completeCount;
+    }
+
+    public void setCompleteCount(Integer completeCount) {
+        this.completeCount = completeCount;
+    }
+
+    public Long getTeacherId() {
+        return teacherId;
+    }
+
+    public void setTeacherId(Long teacherId) {
+        this.teacherId = teacherId;
+    }
+
+    public String getTeacherName() {
+        return teacherName;
+    }
+
+    public void setTeacherName(String teacherName) {
+        this.teacherName = teacherName;
+    }
+
+    public String getTeacherRealName() {
+        return teacherRealName;
+    }
+
+    public void setTeacherRealName(String teacherRealName) {
+        this.teacherRealName = teacherRealName;
+    }
+
+    public Long getStudentId() {
+        return studentId;
+    }
+
+    public void setStudentId(Long studentId) {
+        this.studentId = studentId;
+    }
+
+    public String getStudentName() {
+        return studentName;
+    }
+
+    public void setStudentName(String studentName) {
+        this.studentName = studentName;
+    }
+
+    public String getStudentRealName() {
+        return studentRealName;
+    }
+
+    public void setStudentRealName(String studentRealName) {
+        this.studentRealName = studentRealName;
+    }
+
+    public String getStatus() {
+        return status;
+    }
+
+    public void setStatus(String status) {
+        this.status = status;
+    }
+
+    public String getStartTime() {
+        return startTime;
+    }
+
+    public void setStartTime(String startTime) {
+        this.startTime = startTime;
+    }
+}

+ 143 - 0
cooleshow-user/user-biz/src/main/resources/config/mybatis/CourseGroupMapper.xml

@@ -334,6 +334,149 @@
         </where>
         order by  cs.id_ desc
     </select>
+    <select id="selectPracticeGroup" resultType="com.yonge.cooleshow.biz.dal.vo.CourseGroupPracticeVo">
+        SELECT
+            cg.id_ AS groupId,
+            cg.name_ AS groupName,
+            cg.subject_id_ AS subjectId,
+            sub.name_ AS subjectName,
+            cg.course_num_ AS courseNum,
+            IFNULL(cs.count_ ,0)AS completeCount,
+            cg.teacher_id_ AS teacherId,
+            tu.username_ AS teacherName,
+            tu.real_name_ AS teacherRealName,
+            sp.user_id_ AS studentId,
+            su.username_ AS studentName,
+            su.real_name_ AS studentRealName,
+            cg.status_ AS `status`,
+            cst.start_time_ AS startTime
+        FROM course_group cg
+        LEFT JOIN `subject` sub ON cg.subject_id_=sub.id_
+        LEFT JOIN sys_user tu ON cg.teacher_id_=tu.id_
+        LEFT JOIN (SELECT user_id_,course_group_id_ FROM course_schedule_student_payment WHERE course_type_='PRACTICE' GROUP BY course_group_id_) sp ON cg.id_=sp.course_group_id_
+        LEFT JOIN sys_user su ON sp.user_id_=su.id_
+        LEFT JOIN (SELECT course_group_id_,COUNT(1) AS count_ FROM course_schedule WHERE type_='PRACTICE' AND status_='COMPLETE' GROUP BY course_group_id_) cs ON cg.id_=cs.course_group_id_
+        LEFT JOIN (SELECT course_group_id_,start_time_ FROM course_schedule WHERE type_='PRACTICE' GROUP BY course_group_id_) cst ON cg.id_=cst.course_group_id_
+        WHERE cg.type_='PRACTICE'
+        <if test="param.search != null and param.search != ''">
+            AND (
+            cg.id_ LIKE concat('%',#{param.search},'%') OR
+            cg.teacher_id_ LIKE concat('%',#{param.search},'%') OR
+            sp.user_id_ LIKE concat('%',#{param.search},'%') OR
+            cg.name_ LIKE concat('%',#{param.search},'%') OR
+            tu.username_ LIKE concat('%',#{param.search},'%') OR
+            su.username_ LIKE concat('%',#{param.search},'%')
+            )
+        </if>
+        <if test="param.subjectId != null">
+            AND cg.subject_id_ = #{param.subjectId}
+        </if>
+        <if test="param.status != null and param.status != ''">
+            AND cg.status_ = #{param.status}
+        </if>
+    </select>
+    <select id="selectPracticeGroupDetail"
+            resultType="com.yonge.cooleshow.biz.dal.vo.CourseGroupPracticeDetailVo">
+        SELECT * FROM
+        (SELECT
+        cs.id_ AS courseId,
+        sb.name_ AS subjectName,
+        cs.teacher_id_ AS teacherId,
+        tu.username_ AS teacherName,
+        tu.real_name_ AS teacherRealName,
+        sp.user_id_ AS studentId,
+        su.username_ AS studentName,
+        su.real_name_ AS studentRealName,
+        cs.status_ AS `status`,
+        cs.start_time_ AS startTime,
+        cs.end_time_ AS endTime,
+        (CASE WHEN cs.start_time_ &gt;= ta.sign_in_time_ THEN 1 ELSE 0 END) AS teacherInSign,
+        (CASE WHEN cs.end_time_ &lt;= ta.sign_out_time_ THEN 1 ELSE 0 END) AS teacherOutSign,
+        (CASE WHEN cs.start_time_ &gt;= sa.sign_in_time_ THEN 1 ELSE 0 END) AS studentInSign,
+        (CASE WHEN cs.end_time_ &lt;= sa.sign_out_time_ THEN 1 ELSE 0 END) AS studentOutSign,
+        ts.status_ AS salaryStatus
+        FROM course_schedule cs
+        LEFT JOIN course_group cg ON cs.course_group_id_=cg.id_
+        LEFT JOIN `subject` sb ON cg.subject_id_=sb.id_
+        LEFT JOIN sys_user tu ON cs.teacher_id_=tu.id_
+        LEFT JOIN course_schedule_student_payment sp ON cs.id_=sp.course_id_
+        LEFT JOIN sys_user su ON sp.user_id_=su.id_
+        LEFT JOIN teacher_attendance ta ON cs.id_=ta.course_schedule_id_
+        LEFT JOIN student_attendance sa ON cs.id_=sa.course_schedule_id_
+        LEFT JOIN course_schedule_teacher_salary ts ON cs.id_=ts.course_schedule_id_
+        WHERE cs.type_='PRACTICE'
+        AND cs.course_group_id_=#{param.courseGroupId}) a
+        <where>
+            <if test="param.search != null and param.search != ''">
+                AND (
+                courseId LIKE concat('%',#{param.search},'%') OR
+                teacherName LIKE concat('%',#{param.search},'%') OR
+                teacherId LIKE concat('%',#{param.search},'%') OR
+                studentName LIKE concat('%',#{param.search},'%') OR
+                studentId LIKE concat('%',#{param.search},'%')
+                )
+            </if>
+            <if test="param.teacherSign == 1">
+                AND teacherInSign = #{param.teacherSign}
+            </if>
+            <if test="param.teacherSign == 0">
+                AND teacherOutSign = #{param.teacherSign}
+            </if>
+            <if test="param.studentSign == 1">
+                AND studentInSign = #{param.studentSign}
+            </if>
+            <if test="param.studentSign == 0">
+                AND studentOutSign = #{param.studentSign}
+            </if>
+            <if test="param.status != null and param.status != ''">
+                AND `status` = #{param.status}
+            </if>
+            <if test="param.salaryStatus != null and param.salaryStatus != ''">
+                AND salaryStatus = #{param.salaryStatus}
+            </if>
+            <if test="param.startTime != null">
+                AND startTime &lt;= #{param.startTime}
+            </if>
+            <if test="param.endTime != null">
+                AND endTime &gt;= #{param.endTime}
+            </if>
+        </where>
+    </select>
+    <select id="selectLiveGroup" resultType="com.yonge.cooleshow.biz.dal.vo.CourseGroupLiveVo">
+        SELECT
+            cg.id_ AS courseGroupId,
+            cg.name_ AS courseGroupName,
+            cg.subject_id_ AS subjectId,
+            sb.name_ AS subjectName,
+            cg.teacher_id_ AS teacherId,
+            su.username_ AS teacherName,
+            su.real_name_ AS teacherRealName,
+            cg.course_num_ AS courseNum,
+            cg.pre_student_num_ AS studentNum,
+            cg.status_ AS `status`,
+            IFNULL(cm.count_,0) AS completeCount,
+            st.start_time_ AS startTime
+        FROM course_group cg
+        LEFT JOIN `subject` sb ON cg.subject_id_=sb.id_
+        LEFT JOIN sys_user su ON su.id_=cg.teacher_id_
+        LEFT JOIN (SELECT course_group_id_,COUNT(1) AS count_ FROM course_schedule WHERE type_='LIVE' AND status_='COMPLETE' GROUP BY course_group_id_) cm ON cg.id_=cm.course_group_id_
+        LEFT JOIN (SELECT course_group_id_,start_time_ FROM course_schedule WHERE type_='LIVE' GROUP BY course_group_id_) st ON cg.id_=st.course_group_id_
+        WHERE cg.type_='LIVE'
+        <if test="param.search != null and param.search != ''">
+            AND (
+            cg.id_ LIKE concat('%',#{param.search},'%') OR
+            cg.teacher_id_ LIKE concat('%',#{param.search},'%') OR
+            cg.name_ LIKE concat('%',#{param.search},'%') OR
+            su.username_ LIKE concat('%',#{param.search},'%')
+            )
+        </if>
+        <if test="param.subjectId != null">
+            AND cg.subject_id_ = #{param.subjectId}
+        </if>
+        <if test="param.status != null and param.status != ''">
+            AND cg.status_ = #{param.status}
+        </if>
+    </select>
 
     <update id="opsPreStudentNum">
         update course_group

+ 5 - 0
toolset/toolset-payment/pom.xml

@@ -60,6 +60,11 @@
             <artifactId>weixin-java-pay</artifactId>
             <version>${binarywang.weixin.java.version}</version>
         </dependency>
+        <dependency>
+            <groupId>joda-time</groupId>
+            <artifactId>joda-time</artifactId>
+            <version>2.9.2</version>
+        </dependency>
         <!-- 汇付 -->
         <dependency>
             <groupId>com.huifu.adapay</groupId>

+ 20 - 0
toolset/toolset-payment/src/main/java/com/yonge/toolset/payment/adapay/AdapayTemplate.java

@@ -31,6 +31,7 @@ import org.springframework.stereotype.Component;
 import org.springframework.util.CollectionUtils;
 
 import javax.servlet.http.HttpServletRequest;
+import java.util.Date;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -206,6 +207,10 @@ public class AdapayTemplate implements PaymentTemplate {
                     ExecutePaymentCallBack executePayment = new ExecutePaymentCallBack();
                     executePayment.setPayAmt(hfRes.getString("pay_amt"));
                     executePayment.setFeeAmt(hfRes.getString("fee_amt"));
+
+                    if(!StringUtil.isEmpty(hfRes.getString("created_time"))){
+                        executePayment.setTradeTime(new Date(Long.parseLong(hfRes.getString("created_time"))));
+                    }
                     paymentCallBack.setExecutePaymentCallBack(executePayment);
                 } else if (type.equals("payment.failed")) {//支付失败
                     paymentCallBack.setId(hfRes.getString("id"));
@@ -215,6 +220,9 @@ public class AdapayTemplate implements PaymentTemplate {
 
                     ExecutePaymentCallBack executePayment = new ExecutePaymentCallBack();
                     executePayment.setPayAmt(hfRes.getString("pay_amt"));
+                    if(!StringUtil.isEmpty(hfRes.getString("created_time"))){
+                        executePayment.setTradeTime(new Date(Long.parseLong(hfRes.getString("created_time"))));
+                    }
                     paymentCallBack.setExecutePaymentCallBack(executePayment);
                 } else if (type.equals("payment.close.succeeded")) {//支付关单成功
                     paymentCallBack.setId(hfRes.getString("payment_id"));
@@ -222,6 +230,9 @@ public class AdapayTemplate implements PaymentTemplate {
                     paymentCallBack.setMethodName(MethodNameEnum.closePayment);
 
                     ClosePaymentCallBack closePayment = new ClosePaymentCallBack();
+                    if(!StringUtil.isEmpty(hfRes.getString("created_time"))){
+                        closePayment.setTradeTime(new Date(Long.parseLong(hfRes.getString("created_time"))));
+                    }
                     paymentCallBack.setClosePaymentCallBack(closePayment);
                 } else if (type.equals("payment.close.failed")) {//支付关单失败
                     paymentCallBack.setId(hfRes.getString("payment_id"));
@@ -230,6 +241,9 @@ public class AdapayTemplate implements PaymentTemplate {
                     paymentCallBack.setMethodName(MethodNameEnum.closePayment);
 
                     ClosePaymentCallBack closePayment = new ClosePaymentCallBack();
+                    if(!StringUtil.isEmpty(hfRes.getString("created_time"))){
+                        closePayment.setTradeTime(new Date(Long.parseLong(hfRes.getString("created_time"))));
+                    }
                     paymentCallBack.setClosePaymentCallBack(closePayment);
                 } else if (type.equals("refund.succeeded")) {//退款成功
                     paymentCallBack.setId(hfRes.getString("payment_id"));
@@ -241,6 +255,9 @@ public class AdapayTemplate implements PaymentTemplate {
                     refundPayment.setTransNo(hfRes.getString("id"));
                     refundPayment.setRefundAmt(hfRes.getString("pay_amt"));
                     refundPayment.setFeeAmt(hfRes.getString("fee_amt"));
+                    if(!StringUtil.isEmpty(hfRes.getString("created_time"))){
+                        refundPayment.setTradeTime(new Date(Long.parseLong(hfRes.getString("created_time"))));
+                    }
                     paymentCallBack.setRefundPaymentCallBack(refundPayment);
                 } else if (type.equals("refund.failed")) {//退款失败
                     paymentCallBack.setId(hfRes.getString("payment_id"));
@@ -253,6 +270,9 @@ public class AdapayTemplate implements PaymentTemplate {
                     refundPayment.setTransNo(hfRes.getString("id"));
                     refundPayment.setRefundAmt(hfRes.getString("pay_amt"));
                     refundPayment.setFeeAmt(hfRes.getString("fee_amt"));
+                    if(!StringUtil.isEmpty(hfRes.getString("created_time"))){
+                        refundPayment.setTradeTime(new Date(Long.parseLong(hfRes.getString("created_time"))));
+                    }
                     paymentCallBack.setRefundPaymentCallBack(refundPayment);
                 }
                 return BaseResult.succeed(paymentCallBack);

+ 1 - 0
toolset/toolset-payment/src/main/java/com/yonge/toolset/payment/base/constant/PaymentConstant.java

@@ -5,4 +5,5 @@ package com.yonge.toolset.payment.base.constant;
  * @Data: 2022/5/10 15:00
  */
 public interface PaymentConstant {
+    String CHARSET = "UTF-8";
 }

+ 14 - 0
toolset/toolset-payment/src/main/java/com/yonge/toolset/payment/base/model/callback/ClosePaymentCallBack.java

@@ -1,10 +1,24 @@
 package com.yonge.toolset.payment.base.model.callback;
 
 import java.io.Serializable;
+import java.util.Date;
 
 /**
  * 关闭订单回调对象
  */
 public class ClosePaymentCallBack implements Serializable {
+    /***
+     * 交易时间
+     * @author liweifan
+     * @updateTime 2022/3/31 11:01
+     */
+    private Date tradeTime;
 
+    public Date getTradeTime() {
+        return tradeTime;
+    }
+
+    public void setTradeTime(Date tradeTime) {
+        this.tradeTime = tradeTime;
+    }
 }

+ 16 - 0
toolset/toolset-payment/src/main/java/com/yonge/toolset/payment/base/model/callback/ExecutePaymentCallBack.java

@@ -1,6 +1,7 @@
 package com.yonge.toolset.payment.base.model.callback;
 
 import java.io.Serializable;
+import java.util.Date;
 
 /**
  * 支付方法回调对象
@@ -19,6 +20,13 @@ public class ExecutePaymentCallBack implements Serializable {
      */
     private String feeAmt;
 
+    /***
+     * 交易时间
+     * @author liweifan
+     * @updateTime 2022/3/31 11:01
+     */
+    private Date tradeTime;
+
     public String getPayAmt() {
         return payAmt;
     }
@@ -34,4 +42,12 @@ public class ExecutePaymentCallBack implements Serializable {
     public void setFeeAmt(String feeAmt) {
         this.feeAmt = feeAmt;
     }
+
+    public Date getTradeTime() {
+        return tradeTime;
+    }
+
+    public void setTradeTime(Date tradeTime) {
+        this.tradeTime = tradeTime;
+    }
 }

+ 15 - 0
toolset/toolset-payment/src/main/java/com/yonge/toolset/payment/base/model/callback/RefundPaymentCallBack.java

@@ -1,6 +1,7 @@
 package com.yonge.toolset.payment.base.model.callback;
 
 import java.io.Serializable;
+import java.util.Date;
 
 /**
  * 退款返回对象
@@ -22,6 +23,12 @@ public class RefundPaymentCallBack implements Serializable {
      * 退款手续费(单位:元)
      */
     private String feeAmt;
+    /***
+     * 交易时间
+     * @author liweifan
+     * @updateTime 2022/3/31 11:01
+     */
+    private Date tradeTime;
 
     public String getBillNo() {
         return billNo;
@@ -54,4 +61,12 @@ public class RefundPaymentCallBack implements Serializable {
     public void setFeeAmt(String feeAmt) {
         this.feeAmt = feeAmt;
     }
+
+    public Date getTradeTime() {
+        return tradeTime;
+    }
+
+    public void setTradeTime(Date tradeTime) {
+        this.tradeTime = tradeTime;
+    }
 }

+ 195 - 0
toolset/toolset-payment/src/main/java/com/yonge/toolset/payment/core/util/RequestKitBean.java

@@ -0,0 +1,195 @@
+package com.yonge.toolset.payment.core.util;
+
+import com.alibaba.fastjson.JSONObject;
+import com.yonge.toolset.base.exception.BizException;
+import com.yonge.toolset.payment.original.wx.OriginalWxAppTemplate;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestAttributes;
+import org.springframework.web.context.request.RequestContextHolder;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.Iterator;
+import java.util.Map;
+
+/*
+ * 基于spring的 req 工具类
+ *
+ * @author terrfly
+ * @site https://www.jeequan.com
+ * @date 2021/6/7 12:16
+ */
+@Component
+public class RequestKitBean {
+
+    private final static Logger log = LoggerFactory.getLogger(RequestKitBean.class);
+
+    @Autowired(required = false)
+    protected HttpServletRequest request;   //自动注入request
+
+    /**
+     * reqContext对象中的key: 转换好的json对象
+     */
+    private static final String REQ_CONTEXT_KEY_PARAMJSON = "REQ_CONTEXT_KEY_PARAMJSON";
+
+    /**
+     * JSON 格式通过请求主体(BODY)传输  获取参数
+     **/
+    public String getReqParamFromBody() {
+
+        String body = "";
+
+        if (isConvertJSON()) {
+
+            try {
+                String str;
+                while ((str = request.getReader().readLine()) != null) {
+                    body += str;
+                }
+
+                return body;
+
+            } catch (Exception e) {
+                log.error("请求参数转换异常! params=[{}]", body);
+                throw new BizException("转换异常");
+            }
+        } else {
+            return body;
+        }
+    }
+
+
+    /**
+     * request.getParameter 获取参数 并转换为JSON格式
+     **/
+    public JSONObject reqParam2JSON() {
+
+        JSONObject returnObject = new JSONObject();
+
+        if (isConvertJSON()) {
+
+            String body = "";
+            try {
+                String str;
+                while ((str = request.getReader().readLine()) != null) {
+                    body += str;
+                }
+
+                if (StringUtils.isEmpty(body)) {
+                    return returnObject;
+                }
+                return JSONObject.parseObject(body);
+
+            } catch (Exception e) {
+                log.error("请求参数转换异常! params=[{}]", body);
+                throw new BizException("转换异常");
+            }
+        }
+
+        // 参数Map
+        Map properties = request.getParameterMap();
+
+        // 返回值Map
+        Iterator entries = properties.entrySet().iterator();
+        Map.Entry entry;
+        String name;
+        String value = "";
+        while (entries.hasNext()) {
+            entry = (Map.Entry) entries.next();
+            name = (String) entry.getKey();
+            Object valueObj = entry.getValue();
+            if (null == valueObj) {
+                value = "";
+            } else if (valueObj instanceof String[]) {
+                String[] values = (String[]) valueObj;
+                for (int i = 0; i < values.length; i++) {
+                    value = values[i] + ",";
+                }
+                value = value.substring(0, value.length() - 1);
+            } else {
+                value = valueObj.toString();
+            }
+
+            if (!name.contains("[")) {
+                returnObject.put(name, value);
+                continue;
+            }
+            //添加对json对象解析的支持  example: {ps[abc] : 1}
+            String mainKey = name.substring(0, name.indexOf("["));
+            String subKey = name.substring(name.indexOf("[") + 1, name.indexOf("]"));
+            JSONObject subJson = new JSONObject();
+            if (returnObject.get(mainKey) != null) {
+                subJson = (JSONObject) returnObject.get(mainKey);
+            }
+            subJson.put(subKey, value);
+            returnObject.put(mainKey, subJson);
+        }
+        return returnObject;
+
+    }
+
+
+    /**
+     * 获取json格式的请求参数
+     **/
+    public JSONObject getReqParamJSON() {
+
+        //将转换好的reqParam JSON格式的对象保存在当前请求上下文对象中进行保存;
+        // 注意1: springMVC的CTRL默认单例模式, 不可使用局部变量保存,会出现线程安全问题;
+        // 注意2: springMVC的请求模式为线程池,如果采用ThreadLocal保存对象信息,可能会出现不清空或者被覆盖的问题。
+        Object reqParamObject = RequestContextHolder.getRequestAttributes().getAttribute(REQ_CONTEXT_KEY_PARAMJSON, RequestAttributes.SCOPE_REQUEST);
+        if (reqParamObject == null) {
+            JSONObject reqParam = reqParam2JSON();
+            RequestContextHolder.getRequestAttributes().setAttribute(REQ_CONTEXT_KEY_PARAMJSON, reqParam, RequestAttributes.SCOPE_REQUEST);
+            return reqParam;
+        }
+        return (JSONObject) reqParamObject;
+    }
+
+    /**
+     * 判断请求参数是否转换为json格式
+     */
+    private boolean isConvertJSON() {
+
+        String contentType = request.getContentType();
+
+        //有contentType  && json格式,  get请求不转换
+        if (contentType != null
+                && contentType.toLowerCase().indexOf("application/json") >= 0
+                && !request.getMethod().equalsIgnoreCase("GET")
+        ) { //application/json 需要转换为json格式;
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * 获取客户端ip地址
+     **/
+    public String getClientIp() {
+        String ipAddress = null;
+        ipAddress = request.getHeader("x-forwarded-for");
+        if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
+            ipAddress = request.getHeader("Proxy-Client-IP");
+        }
+        if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
+            ipAddress = request.getHeader("WL-Proxy-Client-IP");
+        }
+        if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
+            ipAddress = request.getRemoteAddr();
+        }
+
+        // 对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
+        if (ipAddress != null && ipAddress.length() > 15) {
+            if (ipAddress.indexOf(",") > 0) {
+                ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
+            }
+        }
+        return ipAddress;
+    }
+
+}

+ 117 - 10
toolset/toolset-payment/src/main/java/com/yonge/toolset/payment/original/ali/OriginalAliAppTemplate.java

@@ -3,6 +3,7 @@ package com.yonge.toolset.payment.original.ali;
 import com.alibaba.fastjson.JSONObject;
 import com.alipay.api.AlipayApiException;
 import com.alipay.api.AlipayClient;
+import com.alipay.api.internal.util.AlipaySignature;
 import com.alipay.api.request.AlipayTradeAppPayRequest;
 import com.alipay.api.request.AlipayTradeCloseRequest;
 import com.alipay.api.request.AlipayTradeQueryRequest;
@@ -13,25 +14,35 @@ import com.alipay.api.response.AlipayTradeQueryResponse;
 import com.alipay.api.response.AlipayTradeRefundResponse;
 import com.yonge.toolset.base.result.BaseResult;
 import com.yonge.toolset.payment.base.PaymentTemplate;
+import com.yonge.toolset.payment.base.constant.PaymentConstant;
 import com.yonge.toolset.payment.base.enums.MethodNameEnum;
 import com.yonge.toolset.payment.base.enums.OpenEnum;
 import com.yonge.toolset.payment.base.enums.PayChannelEnum;
 import com.yonge.toolset.payment.base.enums.TradeStatusEnum;
 import com.yonge.toolset.payment.base.model.*;
+import com.yonge.toolset.payment.base.model.callback.ClosePaymentCallBack;
+import com.yonge.toolset.payment.base.model.callback.ExecutePaymentCallBack;
 import com.yonge.toolset.payment.base.model.callback.PaymentCallBack;
+import com.yonge.toolset.payment.base.model.callback.RefundPaymentCallBack;
 import com.yonge.toolset.payment.core.props.PaymentProperties;
 import com.yonge.toolset.payment.core.service.SysConfigPaymentService;
+import com.yonge.toolset.payment.core.util.RequestKitBean;
+import com.yonge.toolset.payment.original.ali.constant.AlipayConstant;
+import com.yonge.toolset.utils.date.DateUtil;
+import com.yonge.toolset.utils.string.StringUtil;
+import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
 import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestAttributes;
+import org.springframework.web.context.request.RequestContextHolder;
 
 import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.math.BigDecimal;
+import java.util.*;
 
 @Component
 public class OriginalAliAppTemplate implements PaymentTemplate {
@@ -44,6 +55,12 @@ public class OriginalAliAppTemplate implements PaymentTemplate {
     @Autowired
     private AlipayClient alipayClient;
 
+    @Autowired
+    private SysConfigPaymentService configPaymentService;
+
+    @Autowired
+    private RequestKitBean requestKitBean;
+
     @Override
     public BaseResult<Map<String, Object>> getOpenAuthMsg(OpenAuth openAuth) {
         return null;
@@ -108,13 +125,13 @@ public class OriginalAliAppTemplate implements PaymentTemplate {
                 payment.setPayAmt(response.getPayAmount());
                 //获取交易状态
                 String tradeStatus = response.getTradeStatus();
-                if("WAIT_BUYER_PAY".equals(tradeStatus)){
+                if ("WAIT_BUYER_PAY".equals(tradeStatus)) {
                     payment.setStatus(TradeStatusEnum.pending);
-                }else if("TRADE_CLOSED".equals(tradeStatus)){
+                } else if ("TRADE_CLOSED".equals(tradeStatus)) {
                     payment.setStatus(TradeStatusEnum.succeeded);
-                }else if("TRADE_SUCCESS".equals(tradeStatus)){
+                } else if ("TRADE_SUCCESS".equals(tradeStatus)) {
                     payment.setStatus(TradeStatusEnum.succeeded);
-                }else if("TRADE_FINISHED".equals(tradeStatus)){
+                } else if ("TRADE_FINISHED".equals(tradeStatus)) {
                     payment.setStatus(TradeStatusEnum.succeeded);
                 }
                 return BaseResult.succeed(payment);
@@ -132,7 +149,7 @@ public class OriginalAliAppTemplate implements PaymentTemplate {
 
     @Override
     public BaseResult<ClosePayment> closePayment(ClosePayment closePayment) {
-        AlipayTradeCloseRequest request = new AlipayTradeCloseRequest ();
+        AlipayTradeCloseRequest request = new AlipayTradeCloseRequest();
 
         JSONObject bizContent = new JSONObject();
         bizContent.put("trade_no", closePayment.getId());
@@ -186,8 +203,98 @@ public class OriginalAliAppTemplate implements PaymentTemplate {
         }
     }
 
+
     @Override
     public BaseResult<PaymentCallBack> analysisNotice(OpenEnum openType, PayChannelEnum payChannel, MethodNameEnum methodName, HttpServletRequest request) {
-        return null;
+        PaymentCallBack paymentCallBack = new PaymentCallBack();
+        try {
+            JSONObject params = requestKitBean.getReqParamJSON();
+
+            JSONObject jsonParams = (JSONObject) params;
+
+            //获取验签方式 是否使用证书 YES NO
+            String USE_CERT = configPaymentService.getPaymentConfig(OpenEnum.ORIGINAL, AlipayConstant.ALI_USE_CERT).getParamValue();
+            String ALI_SIGN_TYPE = configPaymentService.getPaymentConfig(OpenEnum.ORIGINAL, AlipayConstant.ALI_SIGN_TYPE).getParamValue();
+            String ALI_ALIPAY_PUBLIC_KEY = configPaymentService.getPaymentConfig(OpenEnum.ORIGINAL, AlipayConstant.ALI_ALIPAY_PUBLIC_KEY).getParamValue();
+            String CERT_PATH = configPaymentService.getPaymentConfig(OpenEnum.ORIGINAL, AlipayConstant.ALI_CERT_PATH).getParamValue();
+
+            boolean verifyResult;
+            if ("YES".equals(USE_CERT)) {
+                verifyResult = AlipaySignature.rsaCertCheckV1(jsonParams.toJavaObject(Map.class), CERT_PATH,
+                        PaymentConstant.CHARSET, ALI_SIGN_TYPE);
+            } else {
+                verifyResult = AlipaySignature.rsaCheckV1(jsonParams.toJavaObject(Map.class), ALI_ALIPAY_PUBLIC_KEY, PaymentConstant.CHARSET, ALI_SIGN_TYPE);
+            }
+            //验签失败
+            if (!verifyResult) {
+                return BaseResult.failed(HttpStatus.INTERNAL_SERVER_ERROR, paymentCallBack, "验签失败");
+            }
+
+            paymentCallBack.setId(jsonParams.getString("trade_no"));
+            paymentCallBack.setPaymentNo(params.getString("out_trade_no"));
+
+            //获取订单所处交易状态
+            String trade_status = jsonParams.getString("trade_status");
+            //退款单号
+            String refundNo = jsonParams.getString("out_biz_no");
+
+            paymentCallBack.setStatus(TradeStatusEnum.succeeded);
+            //退款
+            if (!StringUtil.isEmpty(refundNo)
+                    || null != jsonParams.getBigDecimal("refund_fee")) {
+                paymentCallBack.setMethodName(MethodNameEnum.refundPayment);
+                //退款成功
+                RefundPaymentCallBack refundPayment = new RefundPaymentCallBack();
+                refundPayment.setBillNo(refundNo);
+                refundPayment.setTransNo(refundNo);
+
+                refundPayment.setRefundAmt(jsonParams.getString("refund_fee"));
+                refundPayment.setTradeTime(jsonParams.getDate("gmt_refund"));
+            } else {
+
+                if ("TRADE_CLOSED".equals(trade_status)) {
+                    //关单成功
+                    paymentCallBack.setMethodName(MethodNameEnum.closePayment);
+
+                    ClosePaymentCallBack closePayment = new ClosePaymentCallBack();
+                    closePayment.setTradeTime(jsonParams.getDate("gmt_close"));
+                    paymentCallBack.setClosePaymentCallBack(closePayment);
+                } else {
+                    //支付成功
+                    paymentCallBack.setMethodName(MethodNameEnum.executePayment);
+
+                    ExecutePaymentCallBack executePayment = new ExecutePaymentCallBack();
+                    String total_amount = jsonParams.getString("total_amount");
+                    String receipt_amount = jsonParams.getString("receipt_amount");
+
+                    executePayment.setPayAmt(total_amount);
+                    executePayment.setFeeAmt(sub(total_amount, receipt_amount));
+                    executePayment.setTradeTime(jsonParams.getDate("gmt_payment"));
+                    paymentCallBack.setExecutePaymentCallBack(executePayment);
+                }
+            }
+            return BaseResult.succeed(paymentCallBack);
+        } catch (AlipayApiException e) {
+            return BaseResult.failed(HttpStatus.INTERNAL_SERVER_ERROR, paymentCallBack, "微信回调对象转换失败");
+        } catch (Exception e) {
+            return BaseResult.failed(HttpStatus.INTERNAL_SERVER_ERROR, paymentCallBack, "解析异常");
+        }
+    }
+
+    /**
+     * v1-v2
+     *
+     * @param v1
+     * @param v2
+     * @return
+     */
+    private String sub(String v1, String v2) {
+        try {
+            String s = new BigDecimal(v1).subtract(new BigDecimal(v2)).toString();
+            return s;
+        } catch (Exception e) {
+            return null;
+        }
     }
+
 }

+ 14 - 0
toolset/toolset-payment/src/main/java/com/yonge/toolset/payment/original/ali/constant/AlipayConstant.java

@@ -30,6 +30,7 @@ public interface AlipayConstant {
      * @updateTime 2022/5/12 14:12
      */
     String ALI_ALIPAY_PUBLIC_KEY = "ALI_ALIPAY_PUBLIC_KEY";
+
     /***
      * 支付宝-验签方式
      * @author liweifan
@@ -37,6 +38,19 @@ public interface AlipayConstant {
      */
     String ALI_SIGN_TYPE = "ALI_SIGN_TYPE";
     /***
+     * 支付宝-是否使用证书 YES NO
+     * @author liweifan
+     * @updateTime 2022/5/12 14:12
+     */
+    String ALI_USE_CERT = "ALI_USE_CERT";
+    /***
+     * 支付宝-证书地址
+     * @author liweifan
+     * @updateTime 2022/5/12 14:12
+     */
+    String ALI_CERT_PATH = "ALI_CERT_PATH";
+
+    /***
      * 支付宝-接口内容加密密钥
      * @author liweifan
      * @updateTime 2022/5/12 14:12

+ 64 - 6
toolset/toolset-payment/src/main/java/com/yonge/toolset/payment/original/wx/OriginalWxAppTemplate.java

@@ -19,11 +19,14 @@ import com.yonge.toolset.payment.base.model.ClosePayment;
 import com.yonge.toolset.payment.base.model.OpenAuth;
 import com.yonge.toolset.payment.base.model.Payment;
 import com.yonge.toolset.payment.base.model.RefundBill;
+import com.yonge.toolset.payment.base.model.callback.ExecutePaymentCallBack;
 import com.yonge.toolset.payment.base.model.callback.PaymentCallBack;
+import com.yonge.toolset.payment.base.model.callback.RefundPaymentCallBack;
 import com.yonge.toolset.payment.core.props.PaymentProperties;
 import com.yonge.toolset.payment.core.service.SysConfigPaymentService;
 import com.yonge.toolset.payment.original.wx.constant.WxpayConstant;
 import com.yonge.toolset.utils.collection.MapUtil;
+import com.yonge.toolset.utils.date.DateUtil;
 import com.yonge.toolset.utils.obj.ObjectUtil;
 import com.yonge.toolset.utils.string.StringUtil;
 import com.yonge.toolset.utils.web.WebUtil;
@@ -35,6 +38,8 @@ import org.apache.http.client.utils.URIBuilder;
 import org.apache.http.entity.StringEntity;
 import org.apache.http.impl.client.CloseableHttpClient;
 import org.apache.http.util.EntityUtils;
+import org.joda.time.DateTime;
+import org.joda.time.DateTimeZone;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -44,8 +49,10 @@ import org.springframework.stereotype.Component;
 import javax.servlet.http.HttpServletRequest;
 import java.io.ByteArrayOutputStream;
 import java.math.BigDecimal;
+import java.util.Date;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.TimeZone;
 
 @Component
 public class OriginalWxAppTemplate implements PaymentTemplate {
@@ -213,30 +220,81 @@ public class OriginalWxAppTemplate implements PaymentTemplate {
         header.setSignature(request.getHeader("Wechatpay-Signature"));
 
         String params = WebUtil.getBodyData(request);
+
         PaymentCallBack paymentCallBack = new PaymentCallBack();
+        paymentCallBack.setMethodName(methodName);
 
-        Map<String,Object> resMsg = new HashMap<>();
+        Map<String, Object> resMsg = new HashMap<>();
         try {
             if (MethodNameEnum.executePayment.equals(methodName)) {
                 WxPayOrderNotifyV3Result wxPayOrderNotifyV3Result = wxPayService.parseOrderNotifyV3Result(params, header);
                 //封装支付回调对象
+                WxPayOrderNotifyV3Result.DecryptNotifyResult result = wxPayOrderNotifyV3Result.getResult();
+                paymentCallBack.setId(result.getTransactionId());
+                paymentCallBack.setPaymentNo(result.getOutTradeNo());
+
+                String tradeState = result.getTradeState();
+                if ("SUCCESS".equals(tradeState)) {
+                    paymentCallBack.setStatus(TradeStatusEnum.succeeded);
+                } else if ("NOTPAY".equals(tradeState) || "CLOSED".equals(tradeState) || "REFUND".equals(tradeState)) {
+                    paymentCallBack.setStatus(TradeStatusEnum.close);
+                    paymentCallBack.setErrMsg(result.getTradeStateDesc());
+                } else if ("PAYERROR".equals(tradeState)) {
+                    paymentCallBack.setStatus(TradeStatusEnum.failed);
+                    paymentCallBack.setErrMsg(result.getTradeStateDesc());
+                }
+
+                ExecutePaymentCallBack executePayment = new ExecutePaymentCallBack();
+                if(!StringUtil.isEmpty(result.getAmount().getTotal())){
+                    executePayment.setPayAmt(new BigDecimal(result.getAmount().getTotal()).divide(new BigDecimal("100")).toString());
+                }
+                if(!StringUtil.isEmpty(result.getSuccessTime())){
+                    Date date = new DateTime(result.getSuccessTime()).toDate();
+                    executePayment.setTradeTime(date);
+                }
+                paymentCallBack.setExecutePaymentCallBack(executePayment);
             } else if (MethodNameEnum.refundPayment.equals(methodName)) {
                 WxPayRefundNotifyV3Result wxPayRefundNotifyV3Result = wxPayService.parseRefundNotifyV3Result(params, header);
                 //封装退款回调对象
+                WxPayRefundNotifyV3Result.DecryptNotifyResult result = wxPayRefundNotifyV3Result.getResult();
+                paymentCallBack.setId(result.getTransactionId());
+                paymentCallBack.setPaymentNo(result.getOutTradeNo());
+
+                String refundStatus = result.getRefundStatus();
+                if ("SUCCESS".equals(refundStatus)) {
+                    paymentCallBack.setStatus(TradeStatusEnum.succeeded);
+                } else if ("CLOSED".equals(refundStatus)) {
+                    paymentCallBack.setStatus(TradeStatusEnum.close);
+                    paymentCallBack.setErrMsg("退款关闭");
+                } else if ("ABNORMAL".equals(refundStatus)) {
+                    paymentCallBack.setStatus(TradeStatusEnum.failed);
+                    paymentCallBack.setErrMsg("退款失败");
+                }
+
+                RefundPaymentCallBack refundPayment = new RefundPaymentCallBack();
+                refundPayment.setBillNo(result.getOutRefundNo());
+                refundPayment.setTransNo(result.getRefundId());
+                refundPayment.setRefundAmt(result.getAmount().getRefund());
+
+                if(!StringUtil.isEmpty(result.getSuccessTime())){
+                    Date date = new DateTime(result.getSuccessTime()).toDate();
+                    refundPayment.setTradeTime(date);
+                }
+                paymentCallBack.setRefundPaymentCallBack(refundPayment);
             }
-            resMsg.put("code","SUCCESS");
+            resMsg.put("code", "SUCCESS");
             paymentCallBack.setResMsg(resMsg);
             return BaseResult.succeed(paymentCallBack);
         } catch (WxPayException e) {
-            resMsg.put("code","FAIL");
-            resMsg.put("message","失败");
+            resMsg.put("code", "FAIL");
+            resMsg.put("message", "失败");
             paymentCallBack.setResMsg(resMsg);
             log.error("微信回调对象转换失败, param is {} , err is {}", params, e.toString());
             return BaseResult.failed(HttpStatus.INTERNAL_SERVER_ERROR, paymentCallBack, "微信回调对象转换失败");
         } catch (Exception e) {
             e.printStackTrace();
-            resMsg.put("code","FAIL");
-            resMsg.put("message","失败");
+            resMsg.put("code", "FAIL");
+            resMsg.put("message", "失败");
             paymentCallBack.setResMsg(resMsg);
             return BaseResult.failed(HttpStatus.INTERNAL_SERVER_ERROR, paymentCallBack, "解析异常");
         }