Commit bde11b59 authored by tangtuo's avatar tangtuo

debug

parent c4c9a96b
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
<profile version="1.0"> <profile version="1.0">
<option name="myName" value="Project Default" /> <option name="myName" value="Project Default" />
<inspection_tool class="ArgNamesErrorsInspection" enabled="false" level="ERROR" enabled_by_default="false" /> <inspection_tool class="ArgNamesErrorsInspection" enabled="false" level="ERROR" enabled_by_default="false" />
<inspection_tool class="BigDecimalMethodWithoutRoundingCalled" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="DuplicatedCode" enabled="true" level="WEAK WARNING" enabled_by_default="true"> <inspection_tool class="DuplicatedCode" enabled="true" level="WEAK WARNING" enabled_by_default="true">
<Languages> <Languages>
<language minSize="60" name="Java" /> <language minSize="60" name="Java" />
......
...@@ -12,6 +12,7 @@ import io.swagger.annotations.ApiParam; ...@@ -12,6 +12,7 @@ import io.swagger.annotations.ApiParam;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.io.IOException;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
/** /**
...@@ -50,7 +51,7 @@ public class CopyrightApplyController { ...@@ -50,7 +51,7 @@ public class CopyrightApplyController {
@PostMapping(value = "/reject") @PostMapping(value = "/reject")
@ApiOperation(value = "驳回") @ApiOperation(value = "驳回")
public ResponseModel<Boolean> reject(@RequestParam Integer id, @RequestParam String rejectReason) { public ResponseModel<Boolean> reject(@RequestParam Integer id, @RequestParam String rejectReason) throws IOException, InterruptedException {
boolean result = copyrightApplyService.reject(id, rejectReason); boolean result = copyrightApplyService.reject(id, rejectReason);
return ResponseModel.success(result); return ResponseModel.success(result);
} }
......
package com.fzm.admin.controller;
import com.fzm.common.annotation.Authentication;
import com.fzm.common.entity.vo.PaymentVo;
import com.fzm.common.model.ResponseModel;
import com.fzm.common.service.PaymentService;
import com.github.pagehelper.PageInfo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
/**
* @author tangtuo
* @date 2022/2/8 16:11
*/
@Authentication
@RestController
@RequestMapping("/payment")
@Api(tags = "支付流水管理")
public class PaymentController {
@Resource
private PaymentService paymentService;
@GetMapping("/pages")
@ApiOperation(value = "分页查询")
public ResponseModel<PageInfo<PaymentVo>> pages(@ApiParam(value = "页码", required = true) @RequestParam Integer pageNum,
@ApiParam(value = "每页记录数", required = true) @RequestParam Integer pageSize,
@ApiParam(value = "姓名") @RequestParam(required = false) String name,
@ApiParam(value = "注册手机号") @RequestParam(required = false) String telephone,
@ApiParam(value = "订单名") @RequestParam(required = false) String orderName,
@ApiParam(value = "交易类型") @RequestParam(required = false) String type,
@ApiParam(value = "支付场景 1-nft发行 2-版权申请") @RequestParam(required = false) Integer payScene,
@ApiParam(value = "创建开始日期,yyyy-MM-dd格式") @RequestParam(required = false) String start,
@ApiParam(value = "创建截止日期,yyyy-MM-dd格式") @RequestParam(required = false) String end) {
PageInfo<PaymentVo> pageInfo = paymentService.pages(pageNum, pageSize, name, telephone, orderName, type, payScene, start, end);
return ResponseModel.success(pageInfo);
}
}
...@@ -9,14 +9,18 @@ import cn.hutool.json.JSONUtil; ...@@ -9,14 +9,18 @@ import cn.hutool.json.JSONUtil;
import com.fzm.common.config.RabbitMQConfig; import com.fzm.common.config.RabbitMQConfig;
import com.fzm.common.entity.CopyrightApply; import com.fzm.common.entity.CopyrightApply;
import com.fzm.common.entity.Nft; import com.fzm.common.entity.Nft;
import com.fzm.common.entity.Order;
import com.fzm.common.entity.dto.CopyrightQueryRequest; import com.fzm.common.entity.dto.CopyrightQueryRequest;
import com.fzm.common.entity.dto.CopyrightQueryResponse; import com.fzm.common.entity.dto.CopyrightQueryResponse;
import com.fzm.common.entity.dto.EvidenceHashMessage; import com.fzm.common.entity.dto.EvidenceHashMessage;
import com.fzm.common.entity.vo.NftVo; import com.fzm.common.entity.vo.NftVo;
import com.fzm.common.enums.CopyrightApplyState; import com.fzm.common.enums.CopyrightApplyState;
import com.fzm.common.enums.PayScene;
import com.fzm.common.properties.CopyrightProperties; import com.fzm.common.properties.CopyrightProperties;
import com.fzm.common.service.CopyrightApplyService; import com.fzm.common.service.CopyrightApplyService;
import com.fzm.common.service.NftService; import com.fzm.common.service.NftService;
import com.fzm.common.service.OrderService;
import com.fzm.common.service.WxPayService;
import com.fzm.common.utils.CopyrightSignUtil; import com.fzm.common.utils.CopyrightSignUtil;
import com.fzm.common.utils.JsonUtil; import com.fzm.common.utils.JsonUtil;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
...@@ -67,6 +71,12 @@ public class CopyrightTask { ...@@ -67,6 +71,12 @@ public class CopyrightTask {
@Resource @Resource
private RabbitTemplate rabbitTemplate; private RabbitTemplate rabbitTemplate;
@Resource
private WxPayService wxPayService;
@Resource
private OrderService orderService;
/** /**
* 定时任务更新版权申请状态 * 定时任务更新版权申请状态
*/ */
...@@ -137,8 +147,12 @@ public class CopyrightTask { ...@@ -137,8 +147,12 @@ public class CopyrightTask {
EvidenceHashMessage msg = new EvidenceHashMessage(serial_code, hash); EvidenceHashMessage msg = new EvidenceHashMessage(serial_code, hash);
rabbitTemplate.convertAndSend(RabbitMQConfig.COPYRIGHT_DIRECT, "evidence.hash.query", msg); rabbitTemplate.convertAndSend(RabbitMQConfig.COPYRIGHT_DIRECT, "evidence.hash.query", msg);
} else if (registerState.equals(CopyrightApplyState.FAILED.getCode())) { } else if (registerState.equals(CopyrightApplyState.FAILED.getCode())) {
// 审核失败,更新驳回原因 // 审核失败,更新驳回原因,主动发起退款
copyrightApply.setRejectReason(copyrightResponse.getRemark()); copyrightApply.setRejectReason(copyrightResponse.getRemark());
Order order = orderService.getByPaySceneAndProductId(PayScene.COPYRIGHT.getCode(), copyrightApply.getId());
if (order != null) {
wxPayService.refund(order.getId());
}
} }
copyrightApplyService.updateById(copyrightApply); copyrightApplyService.updateById(copyrightApply);
} catch (Exception e) { } catch (Exception e) {
......
...@@ -98,7 +98,21 @@ huaweiyun: ...@@ -98,7 +98,21 @@ huaweiyun:
wx-pay: wx-pay:
app-id: wxbdddd81913c795e9 app-id: wxbdddd81913c795e9
app-secret: aa201717c46a0e07c4c143b1ee73229a
mch-id: 1604477044 mch-id: 1604477044
api-v3-key: D864DA53FEF8ACD41519064967DC10D2 api-v3-key: D864DA53FEF8ACD41519064967DC10D2
mch-serial-num: 72A62544B0A08A214FAEC780108692EDC6E7D5FA mch-serial-num: 72A62544B0A08A214FAEC780108692EDC6E7D5FA
private-key-path: apiclient_key.pem private-key-path: apiclient_key.pem
sms:
app-key: Yiru
app-secret: mx5oaR^RY8!(ziHn
login-message-codetype: quick
login-email-codetype: quick
login-voice-codetype: quick
send-sms-url: http://118.31.52.32/send/sms2
validate-code-url: http://118.31.52.32/validate/code
transfer-nft-message-codetype: notice_transfer
transfer-nft-email-codetype: notice_transfer
transfer-nft-voice-codetype: notice_transfer
refund-message-codetype: notice_refund
\ No newline at end of file
...@@ -99,7 +99,21 @@ huaweiyun: ...@@ -99,7 +99,21 @@ huaweiyun:
wx-pay: wx-pay:
app-id: wxbdddd81913c795e9 app-id: wxbdddd81913c795e9
app-secret: aa201717c46a0e07c4c143b1ee73229a
mch-id: 1604477044 mch-id: 1604477044
api-v3-key: D864DA53FEF8ACD41519064967DC10D2 api-v3-key: D864DA53FEF8ACD41519064967DC10D2
mch-serial-num: 72A62544B0A08A214FAEC780108692EDC6E7D5FA mch-serial-num: 72A62544B0A08A214FAEC780108692EDC6E7D5FA
private-key-path: apiclient_key.pem private-key-path: apiclient_key.pem
sms:
app-key: Yiru
app-secret: mx5oaR^RY8!(ziHn
login-message-codetype: quick
login-email-codetype: quick
login-voice-codetype: quick
send-sms-url: http://118.31.52.32/send/sms2
validate-code-url: http://118.31.52.32/validate/code
transfer-nft-message-codetype: notice_transfer
transfer-nft-email-codetype: notice_transfer
transfer-nft-voice-codetype: notice_transfer
refund-message-codetype: notice_refund
\ No newline at end of file
...@@ -99,7 +99,21 @@ huaweiyun: ...@@ -99,7 +99,21 @@ huaweiyun:
wx-pay: wx-pay:
app-id: wxbdddd81913c795e9 app-id: wxbdddd81913c795e9
app-secret: aa201717c46a0e07c4c143b1ee73229a
mch-id: 1604477044 mch-id: 1604477044
api-v3-key: D864DA53FEF8ACD41519064967DC10D2 api-v3-key: D864DA53FEF8ACD41519064967DC10D2
mch-serial-num: 72A62544B0A08A214FAEC780108692EDC6E7D5FA mch-serial-num: 72A62544B0A08A214FAEC780108692EDC6E7D5FA
private-key-path: apiclient_key.pem private-key-path: apiclient_key.pem
sms:
app-key: Yiru
app-secret: mx5oaR^RY8!(ziHn
login-message-codetype: quick
login-email-codetype: quick
login-voice-codetype: quick
send-sms-url: http://118.31.52.32/send/sms2
validate-code-url: http://118.31.52.32/validate/code
transfer-nft-message-codetype: notice_transfer
transfer-nft-email-codetype: notice_transfer
transfer-nft-voice-codetype: notice_transfer
refund-message-codetype: notice_refund
\ No newline at end of file
...@@ -99,7 +99,21 @@ huaweiyun: ...@@ -99,7 +99,21 @@ huaweiyun:
wx-pay: wx-pay:
app-id: wxbdddd81913c795e9 app-id: wxbdddd81913c795e9
app-secret: aa201717c46a0e07c4c143b1ee73229a
mch-id: 1604477044 mch-id: 1604477044
api-v3-key: D864DA53FEF8ACD41519064967DC10D2 api-v3-key: D864DA53FEF8ACD41519064967DC10D2
mch-serial-num: 72A62544B0A08A214FAEC780108692EDC6E7D5FA mch-serial-num: 72A62544B0A08A214FAEC780108692EDC6E7D5FA
private-key-path: apiclient_key.pem private-key-path: apiclient_key.pem
sms:
app-key: Yiru
app-secret: mx5oaR^RY8!(ziHn
login-message-codetype: quick
login-email-codetype: quick
login-voice-codetype: quick
send-sms-url: http://118.31.52.32/send/sms2
validate-code-url: http://118.31.52.32/validate/code
transfer-nft-message-codetype: notice_transfer
transfer-nft-email-codetype: notice_transfer
transfer-nft-voice-codetype: notice_transfer
refund-message-codetype: notice_refund
\ No newline at end of file
spring: spring:
profiles: profiles:
active: local active: nj
application: application:
name: ly-admin name: ly-admin
......
...@@ -36,6 +36,9 @@ public class Refund { ...@@ -36,6 +36,9 @@ public class Refund {
@ApiModelProperty("通知参数") @ApiModelProperty("通知参数")
private String content; private String content;
@ApiModelProperty("退款发起渠道 1-用户发起 2-后台运营发起")
private Integer channel;
private Date createDate; private Date createDate;
private Date updateDate; private Date updateDate;
......
package com.fzm.common.entity.vo;
import com.fzm.common.entity.Order;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.Date;
/**
* @author tangtuo
* @date 2022/2/8 17:45
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class PaymentVo extends Order {
@ApiModelProperty("交易类型 1-支付 2-退款")
private String type;
@ApiModelProperty("交易时间")
private Date tradeTime;
@ApiModelProperty("姓名")
private String name;
@ApiModelProperty("手机号")
private String telephone;
}
package com.fzm.common.mapper; package com.fzm.common.mapper;
import cn.hutool.core.date.DateTime;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.fzm.common.entity.Payment; import com.fzm.common.entity.Payment;
import com.fzm.common.entity.vo.PaymentVo;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/** /**
* @author tangtuo * @author tangtuo
...@@ -10,4 +15,7 @@ import org.apache.ibatis.annotations.Mapper; ...@@ -10,4 +15,7 @@ import org.apache.ibatis.annotations.Mapper;
*/ */
@Mapper @Mapper
public interface PaymentMapper extends BaseMapper<Payment> { public interface PaymentMapper extends BaseMapper<Payment> {
List<PaymentVo> list(@Param("name") String name, @Param("telephone") String telephone, @Param("orderName") String orderName, @Param("type") String type, @Param("payScene") Integer payScene, @Param("startDate") DateTime startDate, @Param("endDate") DateTime endDate);
} }
...@@ -44,5 +44,8 @@ public class SmsProperties { ...@@ -44,5 +44,8 @@ public class SmsProperties {
@ApiModelProperty("转让nft语言验证码模板") @ApiModelProperty("转让nft语言验证码模板")
private String transferNftVoiceCodetype; private String transferNftVoiceCodetype;
@ApiModelProperty("退款的短信模板")
private String refundMessageCodetype;
} }
...@@ -8,6 +8,7 @@ import com.fzm.common.entity.vo.CopyrightCertificateVo; ...@@ -8,6 +8,7 @@ import com.fzm.common.entity.vo.CopyrightCertificateVo;
import com.fzm.common.entity.vo.CopyrightVo; import com.fzm.common.entity.vo.CopyrightVo;
import com.github.pagehelper.PageInfo; import com.github.pagehelper.PageInfo;
import java.io.IOException;
import java.util.List; import java.util.List;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
...@@ -40,7 +41,7 @@ public interface CopyrightApplyService extends IService<CopyrightApply> { ...@@ -40,7 +41,7 @@ public interface CopyrightApplyService extends IService<CopyrightApply> {
* @param id * @param id
* @return * @return
*/ */
Boolean withdraw(Integer id); Boolean withdraw(Integer id) throws IOException, InterruptedException;
/** /**
...@@ -87,7 +88,7 @@ public interface CopyrightApplyService extends IService<CopyrightApply> { ...@@ -87,7 +88,7 @@ public interface CopyrightApplyService extends IService<CopyrightApply> {
* @param rejectReason * @param rejectReason
* @return * @return
*/ */
boolean reject(Integer id, String rejectReason); boolean reject(Integer id, String rejectReason) throws IOException, InterruptedException;
/** /**
* 审核通过 * 审核通过
......
...@@ -22,7 +22,7 @@ public interface OrderService extends IService<Order> { ...@@ -22,7 +22,7 @@ public interface OrderService extends IService<Order> {
* @param productId * @param productId
* @return * @return
*/ */
Order getByPaySceneAndProductId(Integer payScene, Integer productId, Integer orderStatus); Order getByPaySceneAndProductId(Integer payScene, Integer productId);
/** /**
* 更新订单状态 * 更新订单状态
...@@ -49,11 +49,11 @@ public interface OrderService extends IService<Order> { ...@@ -49,11 +49,11 @@ public interface OrderService extends IService<Order> {
/** /**
* 取消订单 * 取消订单
* *
* @param orderId
* @param orderStatus * @param orderStatus
* @param orderId
* @return * @return
*/ */
Boolean cancel(Long orderId); Boolean cancel(Long orderId, OrderStatus orderStatus);
/** /**
* 获取我的订单 * 获取我的订单
...@@ -72,4 +72,12 @@ public interface OrderService extends IService<Order> { ...@@ -72,4 +72,12 @@ public interface OrderService extends IService<Order> {
* @return * @return
*/ */
Boolean renewOrderStatus(Long orderId) throws IOException, InterruptedException; Boolean renewOrderStatus(Long orderId) throws IOException, InterruptedException;
/**
* 查询超时的订单
*
* @param hours
* @return
*/
List<Order> getTimeOutOrders(int hours);
} }
...@@ -2,6 +2,8 @@ package com.fzm.common.service; ...@@ -2,6 +2,8 @@ package com.fzm.common.service;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import com.fzm.common.entity.Payment; import com.fzm.common.entity.Payment;
import com.fzm.common.entity.vo.PaymentVo;
import com.github.pagehelper.PageInfo;
/** /**
* @author tangtuo * @author tangtuo
...@@ -10,4 +12,20 @@ import com.fzm.common.entity.Payment; ...@@ -10,4 +12,20 @@ import com.fzm.common.entity.Payment;
public interface PaymentService extends IService<Payment> { public interface PaymentService extends IService<Payment> {
Payment getByOrderId(Long orderId); Payment getByOrderId(Long orderId);
/**
* 分页查询
*
* @param pageNum
* @param pageSize
* @param name
* @param telephone
* @param orderName
* @param type
* @param payScene
* @param start
* @param end
* @return
*/
PageInfo<PaymentVo> pages(Integer pageNum, Integer pageSize, String name, String telephone, String orderName, String type, Integer payScene, String start, String end);
} }
...@@ -8,4 +8,12 @@ import com.fzm.common.entity.Refund; ...@@ -8,4 +8,12 @@ import com.fzm.common.entity.Refund;
* @date 2022/1/24 14:26 * @date 2022/1/24 14:26
*/ */
public interface RefundService extends IService<Refund> { public interface RefundService extends IService<Refund> {
/**
* 根据订单id查询
*
* @param orderId
* @return
*/
Refund getByOrderId(Long orderId);
} }
package com.fzm.common.service;
/**
* @author tangtuo
* @date 2022/2/8 14:12
*/
public interface SmsService {
void sendRefundSms(Long orderId);
}
...@@ -42,7 +42,7 @@ public interface WxPayService { ...@@ -42,7 +42,7 @@ public interface WxPayService {
* *
* @param orderId * @param orderId
*/ */
void refund(Long orderId) throws IOException; void refund(Long orderId) throws IOException, InterruptedException;
/** /**
* 退款回调 * 退款回调
......
...@@ -18,6 +18,7 @@ import com.fzm.common.entity.vo.CopyrightApplyVo; ...@@ -18,6 +18,7 @@ import com.fzm.common.entity.vo.CopyrightApplyVo;
import com.fzm.common.entity.vo.CopyrightCertificateVo; import com.fzm.common.entity.vo.CopyrightCertificateVo;
import com.fzm.common.entity.vo.CopyrightVo; import com.fzm.common.entity.vo.CopyrightVo;
import com.fzm.common.enums.CopyrightApplyState; import com.fzm.common.enums.CopyrightApplyState;
import com.fzm.common.enums.PayScene;
import com.fzm.common.enums.ResultCode; import com.fzm.common.enums.ResultCode;
import com.fzm.common.exception.GlobalException; import com.fzm.common.exception.GlobalException;
import com.fzm.common.mapper.CopyrightApplyMapper; import com.fzm.common.mapper.CopyrightApplyMapper;
...@@ -37,6 +38,7 @@ import org.springframework.stereotype.Service; ...@@ -37,6 +38,7 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
...@@ -99,6 +101,12 @@ public class CopyrightApplyServiceImpl extends ServiceImpl<CopyrightApplyMapper, ...@@ -99,6 +101,12 @@ public class CopyrightApplyServiceImpl extends ServiceImpl<CopyrightApplyMapper,
@Resource @Resource
private DraftService draftService; private DraftService draftService;
@Resource
private OrderService orderService;
@Resource
private WxPayService wxPayService;
@Override @Override
public Integer submit(CopyrightDTO copyrightDTO) { public Integer submit(CopyrightDTO copyrightDTO) {
...@@ -168,7 +176,7 @@ public class CopyrightApplyServiceImpl extends ServiceImpl<CopyrightApplyMapper, ...@@ -168,7 +176,7 @@ public class CopyrightApplyServiceImpl extends ServiceImpl<CopyrightApplyMapper,
} }
@Override @Override
public Boolean withdraw(Integer id) { public Boolean withdraw(Integer id) throws IOException, InterruptedException {
CopyrightApply copyright = getById(id); CopyrightApply copyright = getById(id);
if (copyright == null) { if (copyright == null) {
throw GlobalException.newException(ResultCode.DATA_ERROR, "此版权登记记录不存在,请核对后重试"); throw GlobalException.newException(ResultCode.DATA_ERROR, "此版权登记记录不存在,请核对后重试");
...@@ -177,7 +185,13 @@ public class CopyrightApplyServiceImpl extends ServiceImpl<CopyrightApplyMapper, ...@@ -177,7 +185,13 @@ public class CopyrightApplyServiceImpl extends ServiceImpl<CopyrightApplyMapper,
throw GlobalException.newException(ResultCode.OPERATION_FAILED, "此版权申请记录已提交,无法撤回"); throw GlobalException.newException(ResultCode.OPERATION_FAILED, "此版权申请记录已提交,无法撤回");
} }
copyright.setRegisterState(CopyrightApplyState.WITHDRAW.getCode()); copyright.setRegisterState(CopyrightApplyState.WITHDRAW.getCode());
return updateById(copyright); updateById(copyright);
// 用户撤回后,需要主动退款
Order order = orderService.getByPaySceneAndProductId(PayScene.COPYRIGHT.getCode(), id);
if (order != null) {
wxPayService.refund(order.getId());
}
return true;
} }
...@@ -187,8 +201,9 @@ public class CopyrightApplyServiceImpl extends ServiceImpl<CopyrightApplyMapper, ...@@ -187,8 +201,9 @@ public class CopyrightApplyServiceImpl extends ServiceImpl<CopyrightApplyMapper,
if (copyright == null) { if (copyright == null) {
throw GlobalException.newException(ResultCode.DATA_ERROR, "此版权登记记录不存在,请核对后重试"); throw GlobalException.newException(ResultCode.DATA_ERROR, "此版权登记记录不存在,请核对后重试");
} }
// 只有撤回、驳回和登记失败的才能删除 // 只有待支付、撤回、驳回和登记失败的才能删除
if (CopyrightApplyState.WITHDRAW.getCode() != copyright.getRegisterState() && if (CopyrightApplyState.WITHDRAW.getCode() != copyright.getRegisterState() &&
CopyrightApplyState.TO_BE_PAY.getCode() != copyright.getRegisterState() &&
CopyrightApplyState.REJECTED.getCode() != copyright.getRegisterState() && CopyrightApplyState.REJECTED.getCode() != copyright.getRegisterState() &&
CopyrightApplyState.FAILED.getCode() != copyright.getRegisterState()) { CopyrightApplyState.FAILED.getCode() != copyright.getRegisterState()) {
throw GlobalException.newException(ResultCode.OPERATION_FAILED, "当前版权记录不能被删除"); throw GlobalException.newException(ResultCode.OPERATION_FAILED, "当前版权记录不能被删除");
...@@ -325,7 +340,7 @@ public class CopyrightApplyServiceImpl extends ServiceImpl<CopyrightApplyMapper, ...@@ -325,7 +340,7 @@ public class CopyrightApplyServiceImpl extends ServiceImpl<CopyrightApplyMapper,
} }
@Override @Override
public boolean reject(Integer id, String rejectReason) { public boolean reject(Integer id, String rejectReason) throws IOException, InterruptedException {
CopyrightApply copyright = getById(id); CopyrightApply copyright = getById(id);
if (copyright == null) { if (copyright == null) {
throw GlobalException.newException(ResultCode.DATA_ERROR, "此版权登记记录不存在,请核对后重试"); throw GlobalException.newException(ResultCode.DATA_ERROR, "此版权登记记录不存在,请核对后重试");
...@@ -335,7 +350,13 @@ public class CopyrightApplyServiceImpl extends ServiceImpl<CopyrightApplyMapper, ...@@ -335,7 +350,13 @@ public class CopyrightApplyServiceImpl extends ServiceImpl<CopyrightApplyMapper,
} }
copyright.setRegisterState(CopyrightApplyState.REJECTED.getCode()); copyright.setRegisterState(CopyrightApplyState.REJECTED.getCode());
copyright.setRejectReason(rejectReason); copyright.setRejectReason(rejectReason);
return updateById(copyright); updateById(copyright);
// 管理员驳回后,需要自动发起退款
Order order = orderService.getByPaySceneAndProductId(PayScene.COPYRIGHT.getCode(), id);
if (order != null) {
wxPayService.refund(order.getId());
}
return true;
} }
@Override @Override
......
...@@ -22,7 +22,8 @@ import org.springframework.transaction.annotation.Transactional; ...@@ -22,7 +22,8 @@ import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.time.Duration;
import java.time.Instant;
import java.util.List; import java.util.List;
/** /**
...@@ -55,11 +56,11 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements ...@@ -55,11 +56,11 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
private WxPayService wxPayService; private WxPayService wxPayService;
@Override @Override
public Order getByPaySceneAndProductId(Integer payScene, Integer productId, Integer orderStatus) { public Order getByPaySceneAndProductId(Integer payScene, Integer productId) {
QueryWrapper<Order> queryWrapper = new QueryWrapper<>(); QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("pay_scene", payScene) queryWrapper.eq("pay_scene", payScene)
.eq("product_id", productId) .eq("product_id", productId)
.eq("order_status", orderStatus); .eq("order_status", OrderStatus.PAYED.getStatus());
return this.getOne(queryWrapper); return this.getOne(queryWrapper);
} }
...@@ -112,7 +113,7 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements ...@@ -112,7 +113,7 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
} }
@Override @Override
public Boolean cancel(Long orderId) { public Boolean cancel(Long orderId, OrderStatus orderStatus) {
Order order = this.getById(orderId); Order order = this.getById(orderId);
Integer productId = order.getProductId(); Integer productId = order.getProductId();
// 判断订单的类型 // 判断订单的类型
...@@ -124,7 +125,7 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements ...@@ -124,7 +125,7 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
copyrightApplyService.delete(productId); copyrightApplyService.delete(productId);
} }
// 修改订单状态为取消 // 修改订单状态为取消
this.updateOrderStatus(orderId, OrderStatus.CANCEL); this.updateOrderStatus(orderId, orderStatus);
return true; return true;
} }
...@@ -152,4 +153,13 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements ...@@ -152,4 +153,13 @@ public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements
} }
return true; return true;
} }
@Override
public List<Order> getTimeOutOrders(int hours) {
Instant instant = Instant.now().minus(Duration.ofHours(hours));
QueryWrapper<Order> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("order_status", OrderStatus.PAYING.getStatus());
queryWrapper.le("create_date", instant);
return this.list(queryWrapper);
}
} }
package com.fzm.common.service.impl; package com.fzm.common.service.impl;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fzm.common.entity.Payment; import com.fzm.common.entity.Payment;
import com.fzm.common.entity.vo.PaymentVo;
import com.fzm.common.mapper.PaymentMapper; import com.fzm.common.mapper.PaymentMapper;
import com.fzm.common.service.PaymentService; import com.fzm.common.service.PaymentService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.List;
/** /**
* @author tangtuo * @author tangtuo
* @date 2022/1/20 16:40 * @date 2022/1/20 16:40
...@@ -16,10 +25,30 @@ import org.springframework.transaction.annotation.Transactional; ...@@ -16,10 +25,30 @@ import org.springframework.transaction.annotation.Transactional;
@Transactional(rollbackFor = RuntimeException.class) @Transactional(rollbackFor = RuntimeException.class)
public class PaymentServiceImpl extends ServiceImpl<PaymentMapper, Payment> implements PaymentService { public class PaymentServiceImpl extends ServiceImpl<PaymentMapper, Payment> implements PaymentService {
@Resource
private PaymentMapper paymentMapper;
@Override @Override
public Payment getByOrderId(Long orderId) { public Payment getByOrderId(Long orderId) {
QueryWrapper<Payment> queryWrapper = new QueryWrapper<>(); QueryWrapper<Payment> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("order_id", orderId); queryWrapper.eq("order_id", orderId);
return getOne(queryWrapper); return getOne(queryWrapper);
} }
@Override
public PageInfo<PaymentVo> pages(Integer pageNum, Integer pageSize, String name, String telephone, String orderName, String type, Integer payScene, String start, String end) {
PageHelper.startPage(pageNum, pageSize);
DateTime startDate = null;
DateTime endDate = null;
if (StringUtils.isNotBlank(start)) {
startDate = DateUtil.parse(start + " 00:00:00", "yyyy-MM-dd HH:mm:ss");
}
if (StringUtils.isNotBlank(end)) {
endDate = DateUtil.parse(end + " 23:59:59", "yyyy-MM-dd HH:mm:ss");
}
List<PaymentVo> list = paymentMapper.list(name, telephone, orderName, type, payScene, startDate, endDate);
return new PageInfo<>(list);
}
} }
package com.fzm.common.service.impl; package com.fzm.common.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fzm.common.entity.Refund; import com.fzm.common.entity.Refund;
import com.fzm.common.mapper.RefundMapper; import com.fzm.common.mapper.RefundMapper;
...@@ -14,4 +15,11 @@ import org.springframework.transaction.annotation.Transactional; ...@@ -14,4 +15,11 @@ import org.springframework.transaction.annotation.Transactional;
@Service @Service
@Transactional(rollbackFor = RuntimeException.class) @Transactional(rollbackFor = RuntimeException.class)
public class RefundServiceImpl extends ServiceImpl<RefundMapper, Refund> implements RefundService { public class RefundServiceImpl extends ServiceImpl<RefundMapper, Refund> implements RefundService {
@Override
public Refund getByOrderId(Long orderId) {
QueryWrapper<Refund> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("order_id", orderId);
return getOne(queryWrapper);
}
} }
package com.fzm.common.service.impl;
import com.fzm.common.entity.Order;
import com.fzm.common.entity.User;
import com.fzm.common.service.OrderService;
import com.fzm.common.service.SmsService;
import com.fzm.common.service.UserService;
import com.fzm.common.utils.SmsUtil;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.math.BigDecimal;
/**
* @author tangtuo
* @date 2022/2/8 14:12
*/
@Service
public class SmsServiceImpl implements SmsService {
@Resource
private UserService userService;
@Resource
private SmsUtil smsUtil;
@Resource
private OrderService orderService;
@Override
@Async("threadPoolTaskExecutor")
public void sendRefundSms(Long orderId) {
Order order = orderService.getById(orderId);
User user = userService.getById(order.getUserId());
String fee = BigDecimal.valueOf(order.getFee()).divide(new BigDecimal(100)).toString();
smsUtil.sendRefundSms(user.getTelephone(), fee);
}
}
...@@ -9,12 +9,14 @@ import com.fzm.common.constant.SystemConstant; ...@@ -9,12 +9,14 @@ import com.fzm.common.constant.SystemConstant;
import com.fzm.common.entity.Order; import com.fzm.common.entity.Order;
import com.fzm.common.entity.Payment; import com.fzm.common.entity.Payment;
import com.fzm.common.entity.Refund; import com.fzm.common.entity.Refund;
import com.fzm.common.entity.User;
import com.fzm.common.entity.dto.JsapiPayDto; import com.fzm.common.entity.dto.JsapiPayDto;
import com.fzm.common.entity.dto.OrderProcessMsg; import com.fzm.common.entity.dto.OrderProcessMsg;
import com.fzm.common.enums.*; import com.fzm.common.enums.*;
import com.fzm.common.exception.GlobalException; import com.fzm.common.exception.GlobalException;
import com.fzm.common.properties.WxPayProperties; import com.fzm.common.properties.WxPayProperties;
import com.fzm.common.service.*; import com.fzm.common.service.*;
import com.fzm.common.utils.SmsUtil;
import com.fzm.common.utils.SnowflakeUtil; import com.fzm.common.utils.SnowflakeUtil;
import com.wechat.pay.contrib.apache.httpclient.util.AesUtil; import com.wechat.pay.contrib.apache.httpclient.util.AesUtil;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
...@@ -37,6 +39,7 @@ import javax.servlet.http.HttpServletRequest; ...@@ -37,6 +39,7 @@ import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException; import java.security.GeneralSecurityException;
import java.security.PrivateKey; import java.security.PrivateKey;
...@@ -83,6 +86,9 @@ public class WxPayServiceImpl implements WxPayService { ...@@ -83,6 +86,9 @@ public class WxPayServiceImpl implements WxPayService {
@Resource @Resource
private RefundService refundService; private RefundService refundService;
@Resource
private SmsService smsService;
public Map<String, Object> payJsapi(JsapiPayDto jsapiPayDto) throws Exception { public Map<String, Object> payJsapi(JsapiPayDto jsapiPayDto) throws Exception {
RLock lock = redisson.getLock("pay-" + jsapiPayDto.getOrderId()); RLock lock = redisson.getLock("pay-" + jsapiPayDto.getOrderId());
if (!lock.tryLock(10, TimeUnit.SECONDS)) { if (!lock.tryLock(10, TimeUnit.SECONDS)) {
...@@ -193,10 +199,10 @@ public class WxPayServiceImpl implements WxPayService { ...@@ -193,10 +199,10 @@ public class WxPayServiceImpl implements WxPayService {
if (lock.tryLock(10, TimeUnit.SECONDS)) { if (lock.tryLock(10, TimeUnit.SECONDS)) {
Order order = orderService.getById(out_trade_no); Order order = orderService.getById(out_trade_no);
// 如果订单状态不是待支付,直接返回 // 如果订单状态不是待支付,直接返回
// if (!OrderStatus.PAYING.getStatus().equals(order.getOrderStatus())) { if (!OrderStatus.PAYING.getStatus().equals(order.getOrderStatus())) {
// log.warn("当前订单已处理完成, 订单号:==> {}", out_trade_no); log.warn("当前订单已处理完成, 订单号:==> {}", out_trade_no);
// return; return;
// } }
Integer productId = order.getProductId(); Integer productId = order.getProductId();
// 订单支付成功后,给mq发送一条消息,处理nft发行或版权申请的状态 // 订单支付成功后,给mq发送一条消息,处理nft发行或版权申请的状态
OrderProcessMsg orderProcessMsg = new OrderProcessMsg(out_trade_no, productId, order.getPayScene()); OrderProcessMsg orderProcessMsg = new OrderProcessMsg(out_trade_no, productId, order.getPayScene());
...@@ -237,12 +243,24 @@ public class WxPayServiceImpl implements WxPayService { ...@@ -237,12 +243,24 @@ public class WxPayServiceImpl implements WxPayService {
} }
@Override @Override
public void refund(Long orderId) throws IOException { public void refund(Long orderId) throws IOException, InterruptedException {
RLock lock = redisson.getLock("refund-" + orderId);
if (!lock.tryLock(10, TimeUnit.SECONDS)) {
throw GlobalException.newException(ResultCode.REFUND_FAILED, "当前订单正在退款中,请勿重复点击");
}
try {
Order order = orderService.getById(orderId); Order order = orderService.getById(orderId);
if (order == null || !order.getOrderStatus().equals(OrderStatus.PAYED.getStatus())) { if (order == null || !order.getOrderStatus().equals(OrderStatus.PAYED.getStatus())) {
throw GlobalException.newException(ResultCode.REFUND_FAILED, "当前订单未支付成功"); throw GlobalException.newException(ResultCode.REFUND_FAILED, "当前订单未支付成功");
} }
Long out_refund_no = snowflakeUtil.snowflakeId(); Refund refund = refundService.getByOrderId(orderId);
Long out_refund_no;
if (refund == null) {
refund = new Refund();
out_refund_no = snowflakeUtil.snowflakeId();
} else {
out_refund_no = refund.getId();
}
String url = "https://api.mch.weixin.qq.com/v3/refund/domestic/refunds"; String url = "https://api.mch.weixin.qq.com/v3/refund/domestic/refunds";
HttpPost httpPost = new HttpPost(url); HttpPost httpPost = new HttpPost(url);
httpPost.addHeader("Accept", "application/json"); httpPost.addHeader("Accept", "application/json");
...@@ -264,18 +282,30 @@ public class WxPayServiceImpl implements WxPayService { ...@@ -264,18 +282,30 @@ public class WxPayServiceImpl implements WxPayService {
CloseableHttpResponse response = httpClient.execute(httpPost); CloseableHttpResponse response = httpClient.execute(httpPost);
String bodyAsString = EntityUtils.toString(response.getEntity()); String bodyAsString = EntityUtils.toString(response.getEntity());
log.info("退款接口返回参数: {}", bodyAsString); log.info("退款接口返回参数: {}", bodyAsString);
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == 200 || statusCode == 204) {
// 发起退款成功
JSONObject jsonObject = JSONUtil.parseObj(bodyAsString); JSONObject jsonObject = JSONUtil.parseObj(bodyAsString);
refund.setRefundId(jsonObject.getStr("refund_id"));
refund.setTransactionId(jsonObject.getStr("transaction_id"));
refund.setUserReceivedAccount(jsonObject.getStr("user_received_account"));
refund.setRefundStatus(RefundStatus.REFUNDING.getStatus());
// 修改订单状态为退款中 // 修改订单状态为退款中
orderService.updateOrderStatus(orderId, OrderStatus.REFUNDING); orderService.updateOrderStatus(orderId, OrderStatus.REFUNDING);
} else {
// 发起退款失败
refund.setRefundStatus(RefundStatus.FAINED.getStatus());
}
// 插入退款信息 // 插入退款信息
Refund refund = new Refund();
refund.setId(out_refund_no); refund.setId(out_refund_no);
refund.setFee(order.getFee()); refund.setFee(order.getFee());
refund.setOrderId(orderId); refund.setOrderId(orderId);
refund.setRefundId(jsonObject.getStr("refund_id")); refundService.saveOrUpdate(refund);
refund.setTransactionId(jsonObject.getStr("transaction_id")); // 异步发送退款短信通知
refund.setUserReceivedAccount(jsonObject.getStr("user_received_account")); smsService.sendRefundSms(orderId);
refundService.save(refund); } finally {
lock.unlock();
}
} }
@Override @Override
......
...@@ -56,6 +56,8 @@ public class SmsUtil { ...@@ -56,6 +56,8 @@ public class SmsUtil {
} }
/** /**
* 发送短信验证码
*
* @param codetype 模板类型 * @param codetype 模板类型
* @param mobile 手机号 * @param mobile 手机号
* @return * @return
...@@ -83,6 +85,37 @@ public class SmsUtil { ...@@ -83,6 +85,37 @@ public class SmsUtil {
return true; return true;
} }
/**
* 发送退款发起短信通知
*
* @param mobile
* @param fee
* @return
*/
public Boolean sendRefundSms(String mobile, String fee) {
String timestamp = getTimestamp();
HashMap<String, Object> params = new HashMap<>();
params.put("mobile", mobile);
params.put("codetype", smsProperties.getRefundMessageCodetype());
params.put("param", fee);
String paramStr = getStringToSignOfStr(params);
System.out.println(paramStr);
String sign = getSign(smsProperties.getAppKey(), smsProperties.getAppSecret(), paramStr, timestamp);
HttpResponse response = HttpRequest.post(smsProperties.getSendSmsUrl()).
header("FZM-Ca-Timestamp", timestamp).
header("FZM-Ca-AppKey", smsProperties.getAppKey()).
header("FZM-Ca-Signature", sign).form(params).execute();
if (response == null || StringUtils.isBlank(response.body())) {
return false;
}
JSONObject jsonObject = JSONUtil.parseObj(response.body());
if (jsonObject.get("code", Integer.class) != HttpStatus.HTTP_OK) {
throw GlobalException.newException(ResultCode.CODE_ERROR, jsonObject.getStr("message"));
}
return true;
}
/** /**
* @param codetype 模板类型,和发短信的一样 * @param codetype 模板类型,和发短信的一样
* @param mobile 手机号 * @param mobile 手机号
...@@ -114,37 +147,23 @@ public class SmsUtil { ...@@ -114,37 +147,23 @@ public class SmsUtil {
return true; return true;
} }
/* public static void main(String[] args) { public static void main(String[] args) {
String timestamp = getTimestamp(); String timestamp = getTimestamp();
HashMap<String, Object> params = new HashMap<>();
params.put("mobile", "17620078872");
params.put("codetype", "quick");
params.put("param", "FzmRandom4");
String paramStr = getStringToSignOfStr(params);
System.out.println(paramStr);
String sign = getSign(APP_KEY, APP_SECRET, paramStr, timestamp);
HttpRequest request = HttpRequest.post("http://118.31.52.32/send/sms2").
header("FZM-Ca-Timestamp", timestamp).
header("FZM-Ca-AppKey", APP_KEY).
header("FZM-Ca-OS", "h5").
header("FZM-Ca-Signature", sign).form(params);
System.out.println(request.getUrl());
System.out.println(request.execute().body());
HashMap<String, Object> paramMap = new HashMap<>(); HashMap<String, Object> paramMap = new HashMap<>();
paramMap.put("t", "sms"); paramMap.put("t", "sms");
paramMap.put("codetype", "quick"); paramMap.put("codetype", "notice_refund");
paramMap.put("code", "8102");
paramMap.put("guide", "1"); paramMap.put("guide", "1");
paramMap.put("mobile", "17620078872"); paramMap.put("mobile", "17620078872");
paramMap.put("param", "100");
String str = getStringToSignOfStr(paramMap); String str = getStringToSignOfStr(paramMap);
String sign1 = getSign(APP_KEY, APP_SECRET, str, timestamp); String sign1 = getSign("Yiru", "mx5oaR^RY8!(ziHn", str, timestamp);
HttpResponse h5 = HttpRequest.post("http://118.31.52.32/validate/code"). HttpResponse h5 = HttpRequest.post("http://118.31.52.32/send/sms2").
header("FZM-Ca-Timestamp", timestamp). header("FZM-Ca-Timestamp", timestamp).
header("FZM-Ca-AppKey", APP_KEY). header("FZM-Ca-AppKey", "Yiru").
header("FZM-Ca-OS", "h5"). header("FZM-Ca-OS", "h5").
header("FZM-Ca-Signature", sign1).form(paramMap).execute(); header("FZM-Ca-Signature", sign1).form(paramMap).execute();
System.out.println(h5.body()); System.out.println(h5.body());
}*/ }
} }
<?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.fzm.common.mapper.PaymentMapper">
<select id="list" resultType="com.fzm.common.entity.vo.PaymentVo">
SELECT
t.*,
o.*,
u.telephone,
p.`name`
FROM
(
SELECT
order_id,
update_date as trade_time,
'支付' AS type
FROM
tb_payment UNION ALL
SELECT
order_id,
update_date as trade_time,
'退款' AS type
FROM
tb_refund
WHERE
refund_status = 2
) t
LEFT JOIN tb_order o ON t.order_id = o.id
left join tb_user u on o.user_id = u.id
left join tb_auth_person p on u.id = p.user_id
<where>
<if test="payScene != null">
and o.pay_scene = #{payScene}
</if>
<if test="orderName != null and orderName != ''">
and o.order_name like concat('%',#{orderName},'%')
</if>
<if test="telephone != null and telephone != ''">
and u.telephone = #{telephone}
</if>
<if test="name != null and name != ''">
and p.name = #{name}
</if>
<if test="type != null and type != ''">
and t.type = #{type}
</if>
<if test="startDate != null">
and t.trade_time >= #{startDate}
</if>
<if test="endDate != null">
and t.trade_time &lt;= #{endDate}
</if>
</where>
ORDER BY
t.trade_time DESC
</select>
</mapper>
\ No newline at end of file
...@@ -5,7 +5,9 @@ import org.mybatis.spring.annotation.MapperScan; ...@@ -5,7 +5,9 @@ import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching; import org.springframework.cache.annotation.EnableCaching;
import org.springframework.scheduling.annotation.EnableAsync;
@EnableAsync
@EnableSwagger2Doc @EnableSwagger2Doc
@EnableCaching @EnableCaching
@SpringBootApplication(scanBasePackages = {"com.fzm.portal", "com.fzm.common"}) @SpringBootApplication(scanBasePackages = {"com.fzm.portal", "com.fzm.common"})
......
...@@ -19,6 +19,7 @@ import org.springframework.validation.annotation.Validated; ...@@ -19,6 +19,7 @@ import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.io.IOException;
import java.util.List; import java.util.List;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
...@@ -55,7 +56,7 @@ public class CopyrightApplyController { ...@@ -55,7 +56,7 @@ public class CopyrightApplyController {
@Authentication @Authentication
@PostMapping(value = "/withdraw") @PostMapping(value = "/withdraw")
@ApiOperation(value = "撤回") @ApiOperation(value = "撤回")
public ResponseModel<Boolean> withdraw(@RequestParam Integer id) { public ResponseModel<Boolean> withdraw(@RequestParam Integer id) throws IOException, InterruptedException {
Boolean result = copyrightApplyService.withdraw(id); Boolean result = copyrightApplyService.withdraw(id);
return ResponseModel.success(result); return ResponseModel.success(result);
} }
......
package com.fzm.portal.controller; package com.fzm.portal.controller;
import com.fzm.common.annotation.Authentication; import com.fzm.common.annotation.Authentication;
import com.fzm.common.entity.Order;
import com.fzm.common.entity.dto.OrderDto; import com.fzm.common.entity.dto.OrderDto;
import com.fzm.common.entity.vo.OrderVo; import com.fzm.common.entity.vo.OrderVo;
import com.fzm.common.enums.OrderStatus; import com.fzm.common.enums.OrderStatus;
...@@ -47,7 +46,7 @@ public class OrderController { ...@@ -47,7 +46,7 @@ public class OrderController {
@PostMapping("/cancel") @PostMapping("/cancel")
@ApiOperation("取消订单") @ApiOperation("取消订单")
public ResponseModel<Boolean> cancelOrder(@RequestParam Long orderId) { public ResponseModel<Boolean> cancelOrder(@RequestParam Long orderId) {
Boolean result = orderService.cancel(orderId); Boolean result = orderService.cancel(orderId, OrderStatus.CANCEL);
return ResponseModel.success(result); return ResponseModel.success(result);
} }
......
...@@ -72,7 +72,7 @@ public class WxPayController { ...@@ -72,7 +72,7 @@ public class WxPayController {
@GetMapping("/refund/{orderId}") @GetMapping("/refund/{orderId}")
public ResponseModel<String> refund(@PathVariable Long orderId) throws IOException { public ResponseModel<String> refund(@PathVariable Long orderId) throws IOException, InterruptedException {
wxPayService.refund(orderId); wxPayService.refund(orderId);
return ResponseModel.success("退款成功"); return ResponseModel.success("退款成功");
} }
......
...@@ -59,8 +59,8 @@ public class NftListener { ...@@ -59,8 +59,8 @@ public class NftListener {
* @param msg * @param msg
*/ */
@RabbitListener(queues = "nft.publish.queue") @RabbitListener(queues = "nft.publish.queue")
public void listenNftPublish(NftPublishMsg msg) throws IOException { public void listenNftPublish(NftPublishMsg msg) throws Exception {
log.info("收到处理确认nft发行结果的消息: {}", msg); log.info("收到确认nft发行结果的消息: {}", msg);
Nft nft = nftService.getById(msg.getId()); Nft nft = nftService.getById(msg.getId());
try { try {
User user = userService.getUserByWallet(nft.getPublishAddress()); User user = userService.getUserByWallet(nft.getPublishAddress());
...@@ -90,7 +90,7 @@ public class NftListener { ...@@ -90,7 +90,7 @@ public class NftListener {
// nft发行失败,需要把nft的发行状态改成failed,然后主动发起退款 // nft发行失败,需要把nft的发行状态改成failed,然后主动发起退款
nft.setPublishStatus(PublishStatus.FAILED.getCode()); nft.setPublishStatus(PublishStatus.FAILED.getCode());
nftService.updateById(nft); nftService.updateById(nft);
Order order = orderService.getByPaySceneAndProductId(PayScene.NFT.getCode(), nft.getId(), OrderStatus.PAYED.getStatus()); Order order = orderService.getByPaySceneAndProductId(PayScene.NFT.getCode(), nft.getId());
if (order != null) { if (order != null) {
wxPayService.refund(order.getId()); wxPayService.refund(order.getId());
} }
......
...@@ -31,7 +31,7 @@ public class OrderListener { ...@@ -31,7 +31,7 @@ public class OrderListener {
private WxPayService wxPayService; private WxPayService wxPayService;
@RabbitListener(queues = "order.process.queue") @RabbitListener(queues = "order.process.queue")
public void listenProcessOrder(OrderProcessMsg msg) throws IOException { public void listenProcessOrder(OrderProcessMsg msg) throws Exception {
log.info("收到处理订单的消息: {}", msg); log.info("收到处理订单的消息: {}", msg);
try { try {
if (PayScene.NFT.getCode().equals(msg.getPayScene())) { if (PayScene.NFT.getCode().equals(msg.getPayScene())) {
......
package com.fzm.portal.schedule;
import cn.hutool.core.collection.CollectionUtil;
import com.fzm.common.entity.Order;
import com.fzm.common.enums.OrderStatus;
import com.fzm.common.enums.WxPayStatus;
import com.fzm.common.service.OrderService;
import com.fzm.common.service.RefundService;
import com.fzm.common.service.WxPayService;
import lombok.extern.slf4j.Slf4j;
import org.redisson.Redisson;
import org.redisson.api.RLock;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
* @author tangtuo
* @date 2022/2/8 15:31
*/
@Slf4j
@Component
public class PayTask {
@Resource
private OrderService orderService;
@Resource
private WxPayService wxPayService;
@Resource
private Redisson redisson;
@Resource
private RefundService refundService;
/**
* 定时关单的任务
*/
@Scheduled(cron = "0 */5 * * * ?")
public void closeOrder() throws InterruptedException, IOException {
RLock lock = redisson.getLock("close-order");
// 加锁,避免集群环境下多个节点同事运行此定时任务
if (!lock.tryLock(30, TimeUnit.SECONDS)) {
log.warn("此任务正在运行中");
return;
}
// 查询超时(创建后超过24小时未支付)的订单
List<Order> orderList = orderService.getTimeOutOrders(24);
if (CollectionUtil.isEmpty(orderList)) {
return;
}
for (Order order : orderList) {
// 确认订单状态
String orderStatus = wxPayService.queryOrder(order.getId());
if (WxPayStatus.NOTPAY.getStatus().equals(orderStatus)) {
// 订单未支付,则关闭订单
orderService.cancel(order.getId(), OrderStatus.CLOSED);
}
}
}
}
...@@ -86,6 +86,7 @@ sms: ...@@ -86,6 +86,7 @@ sms:
transfer-nft-message-codetype: notice_transfer transfer-nft-message-codetype: notice_transfer
transfer-nft-email-codetype: notice_transfer transfer-nft-email-codetype: notice_transfer
transfer-nft-voice-codetype: notice_transfer transfer-nft-voice-codetype: notice_transfer
refund-message-codetype: notice_refund
chain: chain:
para: para:
......
...@@ -86,6 +86,7 @@ sms: ...@@ -86,6 +86,7 @@ sms:
transfer-nft-message-codetype: notice_transfer transfer-nft-message-codetype: notice_transfer
transfer-nft-email-codetype: notice_transfer transfer-nft-email-codetype: notice_transfer
transfer-nft-voice-codetype: notice_transfer transfer-nft-voice-codetype: notice_transfer
refund-message-codetype: notice_refund
chain: chain:
para: para:
......
...@@ -87,6 +87,7 @@ sms: ...@@ -87,6 +87,7 @@ sms:
transfer-nft-message-codetype: notice_transfer transfer-nft-message-codetype: notice_transfer
transfer-nft-email-codetype: notice_transfer transfer-nft-email-codetype: notice_transfer
transfer-nft-voice-codetype: notice_transfer transfer-nft-voice-codetype: notice_transfer
refund-message-codetype: notice_refund
#chain: #chain:
# para: # para:
......
...@@ -88,6 +88,7 @@ sms: ...@@ -88,6 +88,7 @@ sms:
transfer-nft-message-codetype: notice_transfer transfer-nft-message-codetype: notice_transfer
transfer-nft-email-codetype: notice_transfer transfer-nft-email-codetype: notice_transfer
transfer-nft-voice-codetype: notice_transfer transfer-nft-voice-codetype: notice_transfer
refund-message-codetype: notice_refund
chain: chain:
para: para:
......
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment