From f75febd2b4f07bd29a9207de800b51fa24b4f96a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A2=A8=E5=A4=A7=E5=8F=94?= <494979559@qq.com> Date: Wed, 10 Jul 2024 16:00:33 +0800 Subject: [PATCH] =?UTF-8?q?=E9=83=A8=E7=BD=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/ruoyi/common/config/WxPayConfig.java | 22 +++ .../common/pay/wx/domain/NotifyEventType.java | 3 +- .../utils/collection/CollectionUtils.java | 8 + .../service/impl/SmDeviceServiceImpl.java | 43 +---- .../com/ruoyi/ss/refund/domain/Refund.java | 51 +++++ .../ruoyi/ss/refund/domain/RefundQuery.java | 11 ++ .../com/ruoyi/ss/refund/domain/RefundVO.java | 47 +++++ .../ss/refund/domain/enums/RefundStatus.java | 21 +++ .../ruoyi/ss/refund/mapper/RefundMapper.java | 71 +++++++ .../ruoyi/ss/refund/mapper/RefundMapper.xml | 117 ++++++++++++ .../ss/refund/service/RefundConverter.java | 17 ++ .../ss/refund/service/RefundService.java | 80 ++++++++ .../service/impl/RefundConverterImpl.java | 51 +++++ .../service/impl/RefundServiceImpl.java | 174 ++++++++++++++++++ .../com/ruoyi/ss/suit/mapper/SuitMapper.xml | 19 +- .../domain/TransactionBill.java | 2 +- .../domain/TransactionBillVo.java | 5 +- .../domain/dto/BillRefundDTO.java | 27 +++ .../domain/enums/TransactionBillStatus.java | 1 + .../mapper/TransactionBillMapper.java | 27 ++- .../mapper/TransactionBillMapper.xml | 168 ++++++++++------- .../service/TransactionBillService.java | 37 +++- .../impl/TransactionBillServiceImpl.java | 128 +++++++++++-- .../user/service/impl/SmUserServiceImpl.java | 23 ++- .../com/ruoyi/ss/wxPay/domain/RefundAble.java | 23 +++ .../ruoyi/ss/wxPay/service/IWxPayService.java | 13 ++ .../ruoyi/ss/wxPay/service/WxPayService.java | 36 +++- .../java/com/ruoyi/task/bill/PayTask.java | 2 +- .../web/controller/app/AppPayController.java | 41 +++++ .../app/AppTransactionBillController.java | 20 ++ .../web/controller/ss/RefundController.java | 107 +++++++++++ .../ss/SmTransactionBillController.java | 16 +- .../web/controller/ss/SmUserController.java | 4 +- .../aspectj/DeviceAdminRequiredAspect.java | 3 +- .../src/main/resources/application-dev.yml | 4 +- .../main/resources/application-druid-test.yml | 2 +- .../src/main/resources/application-prod.yml | 2 + .../src/main/resources/application-test.yml | 2 + 38 files changed, 1256 insertions(+), 172 deletions(-) create mode 100644 smart-switch-service/src/main/java/com/ruoyi/ss/refund/domain/Refund.java create mode 100644 smart-switch-service/src/main/java/com/ruoyi/ss/refund/domain/RefundQuery.java create mode 100644 smart-switch-service/src/main/java/com/ruoyi/ss/refund/domain/RefundVO.java create mode 100644 smart-switch-service/src/main/java/com/ruoyi/ss/refund/domain/enums/RefundStatus.java create mode 100644 smart-switch-service/src/main/java/com/ruoyi/ss/refund/mapper/RefundMapper.java create mode 100644 smart-switch-service/src/main/java/com/ruoyi/ss/refund/mapper/RefundMapper.xml create mode 100644 smart-switch-service/src/main/java/com/ruoyi/ss/refund/service/RefundConverter.java create mode 100644 smart-switch-service/src/main/java/com/ruoyi/ss/refund/service/RefundService.java create mode 100644 smart-switch-service/src/main/java/com/ruoyi/ss/refund/service/impl/RefundConverterImpl.java create mode 100644 smart-switch-service/src/main/java/com/ruoyi/ss/refund/service/impl/RefundServiceImpl.java create mode 100644 smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/domain/dto/BillRefundDTO.java create mode 100644 smart-switch-service/src/main/java/com/ruoyi/ss/wxPay/domain/RefundAble.java create mode 100644 smart-switch-web/src/main/java/com/ruoyi/web/controller/ss/RefundController.java diff --git a/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/config/WxPayConfig.java b/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/config/WxPayConfig.java index 49541401..ae1b748b 100644 --- a/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/config/WxPayConfig.java +++ b/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/config/WxPayConfig.java @@ -7,6 +7,7 @@ import com.wechat.pay.java.core.notification.NotificationParser; import com.wechat.pay.java.service.payments.app.AppService; import com.wechat.pay.java.service.payments.jsapi.JsapiService; import com.wechat.pay.java.service.payments.jsapi.JsapiServiceExtension; +import com.wechat.pay.java.service.refund.RefundService; import com.wechat.pay.java.service.transferbatch.TransferBatchService; import lombok.Getter; import org.springframework.beans.factory.annotation.Autowired; @@ -39,6 +40,10 @@ public class WxPayConfig { @Value("${wx.pay.notifyUrl}") private String notifyUrl; + // 退款通知回调地址 + @Value("${wx.pay.refundNotifyUrl}") + private String refundNotifyUrl; + // 私钥证书路径 @Value("${wx.pay.privateKeyPath}") private String privateKeyPath; @@ -93,6 +98,23 @@ public class WxPayConfig { .build(); } + @Bean + public RefundService refundService() { + // 初始化商户配置 + Config config = new RSAAutoCertificateConfig.Builder() + .merchantId(merchantId) + // 使用 com.wechat.pay.java.core.util 中的函数从本地文件中加载商户私钥,商户私钥会用来生成请求的签名 + .privateKeyFromPath(privateKeyPath) + .merchantSerialNumber(merchantSerialNumber) + .apiV3Key(apiV3Key) + .build(); + // 初始化服务 + return new RefundService + .Builder() + .config(config) + .build(); + } + // 微信通知解析器 @Bean public NotificationParser notificationParser() { diff --git a/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/pay/wx/domain/NotifyEventType.java b/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/pay/wx/domain/NotifyEventType.java index ae4e7547..9cf2bd61 100644 --- a/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/pay/wx/domain/NotifyEventType.java +++ b/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/pay/wx/domain/NotifyEventType.java @@ -13,7 +13,8 @@ import lombok.Getter; public enum NotifyEventType { TRANSACTION_SUCCESS("TRANSACTION.SUCCESS", "支付成功"), - MCHTRANSFER_BATCH_FINISHED("MCHTRANSFER.BATCH.FINISHED", "商户转账批次完成通知"); + MCHTRANSFER_BATCH_FINISHED("MCHTRANSFER.BATCH.FINISHED", "商户转账批次完成通知"), + REFUND_SUCCESS("REFUND.SUCCESS", "退款成功"); private final String value; private final String name; diff --git a/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/utils/collection/CollectionUtils.java b/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/utils/collection/CollectionUtils.java index 207d12f4..6e41c47c 100644 --- a/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/utils/collection/CollectionUtils.java +++ b/smart-switch-ruoyi/smart-switch-common/src/main/java/com/ruoyi/common/utils/collection/CollectionUtils.java @@ -27,6 +27,10 @@ public class CollectionUtils extends org.springframework.util.CollectionUtils { return org.springframework.util.CollectionUtils.isEmpty(collect); } + public static boolean isNotEmptyElement(List list) { + return !isEmptyElement(list); + } + /** * 填充列表中的元素 * @param oldList 旧列表 @@ -90,4 +94,8 @@ public class CollectionUtils extends org.springframework.util.CollectionUtils { .map(date -> dateToObjectMap.getOrDefault(date, customFactory.apply(date))) .collect(Collectors.toList()); } + + public static boolean isNotEmpty(List deviceList) { + return !isEmpty(deviceList); + } } diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/device/service/impl/SmDeviceServiceImpl.java b/smart-switch-service/src/main/java/com/ruoyi/ss/device/service/impl/SmDeviceServiceImpl.java index 1ef8efbe..40026635 100644 --- a/smart-switch-service/src/main/java/com/ruoyi/ss/device/service/impl/SmDeviceServiceImpl.java +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/device/service/impl/SmDeviceServiceImpl.java @@ -252,8 +252,8 @@ public class SmDeviceServiceImpl implements ISmDeviceService public int register(DeviceRegisterDTO dto) { // 添加 SmDevice device = new SmDevice(); - device.setMac(dto.getMac()); device.setDeviceName("未命名"); + device.setMac(dto.getMac()); device.setDeviceNo(dto.getSn()); return this.addInitDevice(device); } @@ -734,44 +734,15 @@ public class SmDeviceServiceImpl implements ISmDeviceService device = selectByDeviceNo(smDevice.getDeviceNo()); ServiceUtil.assertion(device != null, "该设备SN已存在,无需重复录入"); - // 查询设备的型号 - IotDeviceInfo deviceInfo = null; - try { - deviceInfo = iotService.getDeviceInfo(smDevice.getMac()); - if (deviceInfo == null) { - log.info("iot device info is null"); - throw new ServiceException("OneNet设备不存在"); - } - } catch (Exception e) { + Integer result = transactionTemplate.execute(status -> { + int i = this.insertSmDevice(smDevice); // 添加设备 + ServiceUtil.assertion(i != 1, "添加设备失败"); + + // 创建OneNet设备 boolean create = iotService.create(smDevice.getMac()); ServiceUtil.assertion(!create, "创建OneNet设备失败"); - } - log.info("select model in:{}", deviceInfo.getModel()); - SmModelVo model = smModelService.selectByModel(deviceInfo.getModel()); - - IotDeviceInfo finalDeviceInfo = deviceInfo; - Integer result = transactionTemplate.execute(status -> { - SmModelVo finalModel = model; - - // 如果设备型号为空,则添加新的设备型号 - if (finalModel == null) { - log.info("model is null"); - int addModel = smModelService.addInitModel(finalDeviceInfo); - ServiceUtil.assertion(addModel != 1, "添加设备型号失败"); - finalModel = smModelService.selectByModel(finalDeviceInfo.getModel()); - } - - // 添加设备 - SmDeviceVO byMac = selectByMac(smDevice.getMac()); - if (byMac == null) { - smDevice.setModelId(finalModel != null ? finalModel.getModelId() : null); - smDevice.setCreateTime(DateUtils.getNowDate()); - int i = smDeviceMapper.insertSmDevice(smDevice); // 添加设备 - this.pullDeviceInfo(Collections.singletonList(smDevice.getDeviceId())); // 拉取设备信息 - return i; - } - return 0; + return i; }); return result == null ? 0 : result; diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/refund/domain/Refund.java b/smart-switch-service/src/main/java/com/ruoyi/ss/refund/domain/Refund.java new file mode 100644 index 00000000..d4749dcf --- /dev/null +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/refund/domain/Refund.java @@ -0,0 +1,51 @@ +package com.ruoyi.ss.refund.domain; + +import java.math.BigDecimal; + +import com.ruoyi.ss.wxPay.domain.RefundAble; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.ruoyi.common.annotation.Excel; +import com.ruoyi.common.core.domain.BaseEntity; + +/** + * 退款订单对象 ss_refund + * + * @author ruoyi + * @date 2024-07-09 + */ +@Data +public class Refund extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 退款ID */ + private Long refundId; + + /** 退款订单编号 */ + @Excel(name = "退款订单编号") + private String refundNo; + + /** 原订单ID */ + @Excel(name = "原订单ID") + private Long billId; + + /** 退款金额(元) */ + @Excel(name = "退款金额", readConverterExp = "元=") + private BigDecimal amount; + + /** 退款订单状态 */ + @Excel(name = "退款订单状态") + private String status; + + @ApiModelProperty("退款原因") + private String reason; + + @ApiModelProperty("商户退款金额") + private BigDecimal mchAmount; + + @ApiModelProperty("手续费退款金额") + private BigDecimal serviceAmount; +} diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/refund/domain/RefundQuery.java b/smart-switch-service/src/main/java/com/ruoyi/ss/refund/domain/RefundQuery.java new file mode 100644 index 00000000..3bbd3225 --- /dev/null +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/refund/domain/RefundQuery.java @@ -0,0 +1,11 @@ +package com.ruoyi.ss.refund.domain; + +import lombok.Data; + +/** + * @author wjh + * 2024/7/9 + */ +@Data +public class RefundQuery extends Refund { +} diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/refund/domain/RefundVO.java b/smart-switch-service/src/main/java/com/ruoyi/ss/refund/domain/RefundVO.java new file mode 100644 index 00000000..c0523105 --- /dev/null +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/refund/domain/RefundVO.java @@ -0,0 +1,47 @@ +package com.ruoyi.ss.refund.domain; + +import com.ruoyi.ss.wxPay.domain.RefundAble; +import com.wechat.pay.java.service.refund.model.AmountReq; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import java.math.BigDecimal; + +/** + * @author wjh + * 2024/7/9 + */ +@Data +public class RefundVO extends Refund implements RefundAble { + + @ApiModelProperty("原订单编号") + private String billNo; + + @ApiModelProperty("原订单交易总额") + private BigDecimal billAmount; + + @Override + public String refundOutTradeNo() { + return this.billNo; + } + + @Override + public String refundOutRefundNo() { + return this.getRefundNo(); + } + + @Override + public String refundReason() { + return this.getReason(); + } + + @Override + public AmountReq refundAmount() { + BigDecimal decimal100 = new BigDecimal(100); + AmountReq amount = new AmountReq(); + amount.setRefund(this.getAmount().multiply(decimal100).longValue()); + amount.setTotal(this.billAmount.multiply(decimal100).longValue()); + amount.setCurrency("CNY"); + return amount; + } +} diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/refund/domain/enums/RefundStatus.java b/smart-switch-service/src/main/java/com/ruoyi/ss/refund/domain/enums/RefundStatus.java new file mode 100644 index 00000000..8115ef13 --- /dev/null +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/refund/domain/enums/RefundStatus.java @@ -0,0 +1,21 @@ +package com.ruoyi.ss.refund.domain.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * @author wjh + * 2024/7/9 + */ +@Getter +@AllArgsConstructor +public enum RefundStatus { + + REFUNDING("1", "退款中"), + REFUND_SUCCESS("2", "退款成功"), + REFUND_FAIL("3", "退款失败"); + + private final String status; + private final String desc; + +} diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/refund/mapper/RefundMapper.java b/smart-switch-service/src/main/java/com/ruoyi/ss/refund/mapper/RefundMapper.java new file mode 100644 index 00000000..493332c4 --- /dev/null +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/refund/mapper/RefundMapper.java @@ -0,0 +1,71 @@ +package com.ruoyi.ss.refund.mapper; + +import java.util.List; +import com.ruoyi.ss.refund.domain.Refund; +import com.ruoyi.ss.refund.domain.RefundQuery; +import com.ruoyi.ss.refund.domain.RefundVO; +import org.apache.ibatis.annotations.Param; + +/** + * 退款订单Mapper接口 + * + * @author ruoyi + * @date 2024-07-09 + */ +public interface RefundMapper +{ + /** + * 查询退款订单 + * + * @param refundId 退款订单主键 + * @return 退款订单 + */ + public RefundVO selectRefundByRefundId(Long refundId); + + /** + * 查询退款订单列表 + * + * @param refund 退款订单 + * @return 退款订单集合 + */ + public List selectRefundList(@Param("query") RefundQuery refund); + + /** + * 新增退款订单 + * + * @param refund 退款订单 + * @return 结果 + */ + public int insertRefund(Refund refund); + + /** + * 修改退款订单 + * + * @param refund 退款订单 + * @return 结果 + */ + public int updateRefund(@Param("data") Refund refund); + + /** + * 删除退款订单 + * + * @param refundId 退款订单主键 + * @return 结果 + */ + public int deleteRefundByRefundId(Long refundId); + + /** + * 批量删除退款订单 + * + * @param refundIds 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteRefundByRefundIds(Long[] refundIds); + + RefundVO selectOne(@Param("query") RefundQuery query); + + /** + * 条件更新 + */ + int updateByQuery(@Param("data") Refund data, @Param("query") RefundQuery query); +} diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/refund/mapper/RefundMapper.xml b/smart-switch-service/src/main/java/com/ruoyi/ss/refund/mapper/RefundMapper.xml new file mode 100644 index 00000000..9432e578 --- /dev/null +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/refund/mapper/RefundMapper.xml @@ -0,0 +1,117 @@ + + + + + + + + select + sr.refund_id, + sr.refund_no, + sr.bill_id, + sr.amount, + sr.create_time, + sr.status, + sr.reason, + sr.mch_amount, + sr.service_amount, + smb.money as bill_amount, + smb.bill_no as bill_no + from ss_refund sr + left join sm_transaction_bill smb on smb.bill_id = sr.bill_id + + + + and sr.refund_id = #{query.refundId} + and sr.refund_no = #{query.refundNo} + and sr.bill_id = #{query.billId} + and sr.status = #{query.status} + + + + + + + + + + insert into ss_refund + + refund_no, + bill_id, + amount, + create_time, + `status`, + `reason`, + mch_amount, + service_amount, + + + #{refundNo}, + #{billId}, + #{amount}, + #{createTime}, + #{status}, + #{reason}, + #{mchAmount}, + #{serviceAmount}, + + + + + update ss_refund + + + + where refund_id = #{refundId} + + + + refund_no = #{data.refundNo}, + bill_id = #{data.billId}, + amount = #{data.amount}, + mch_amount = #{data.mchAmount}, + service_amount = #{data.serviceAmount}, + create_time = #{data.createTime}, + `status` = #{data.status}, + `reason` = #{data.reason}, + + + + update ss_refund sr + + + + + + + + + + delete from ss_refund where refund_id = #{refundId} + + + + delete from ss_refund where refund_id in + + #{refundId} + + + diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/refund/service/RefundConverter.java b/smart-switch-service/src/main/java/com/ruoyi/ss/refund/service/RefundConverter.java new file mode 100644 index 00000000..a583ea24 --- /dev/null +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/refund/service/RefundConverter.java @@ -0,0 +1,17 @@ +package com.ruoyi.ss.refund.service; + +import com.ruoyi.ss.refund.domain.Refund; +import com.ruoyi.ss.transactionBill.domain.dto.BillRefundDTO; + +/** + * @author wjh + * 2024/7/9 + */ +public interface RefundConverter { + + /** + * 订单退款DTO -> 退款PO + */ + Refund toPo(BillRefundDTO dto); + +} diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/refund/service/RefundService.java b/smart-switch-service/src/main/java/com/ruoyi/ss/refund/service/RefundService.java new file mode 100644 index 00000000..03b66ec5 --- /dev/null +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/refund/service/RefundService.java @@ -0,0 +1,80 @@ +package com.ruoyi.ss.refund.service; + +import java.util.List; +import com.ruoyi.ss.refund.domain.Refund; +import com.ruoyi.ss.refund.domain.RefundQuery; +import com.ruoyi.ss.refund.domain.RefundVO; + +/** + * 退款订单Service接口 + * + * @author ruoyi + * @date 2024-07-09 + */ +public interface RefundService +{ + /** + * 查询退款订单 + * + * @param refundId 退款订单主键 + * @return 退款订单 + */ + public RefundVO selectRefundByRefundId(Long refundId); + + /** + * 查询退款订单列表 + * + * @param refund 退款订单 + * @return 退款订单集合 + */ + public List selectRefundList(RefundQuery refund); + + /** + * 新增退款订单 + * + * @param refund 退款订单 + * @return 结果 + */ + public int insertRefund(Refund refund); + + /** + * 修改退款订单 + * + * @param refund 退款订单 + * @return 结果 + */ + public int updateRefund(Refund refund); + + /** + * 批量删除退款订单 + * + * @param refundIds 需要删除的退款订单主键集合 + * @return 结果 + */ + public int deleteRefundByRefundIds(Long[] refundIds); + + /** + * 删除退款订单信息 + * + * @param refundId 退款订单主键 + * @return 结果 + */ + public int deleteRefundByRefundId(Long refundId); + + /** + * 查询退款订单 + */ + RefundVO selectRefundByRefundNo(String refundNo); + + RefundVO selectOne(RefundQuery query); + + /** + * 退款成功后操作 + */ + void handleRefundSuccess(String refundNo); + + /** + * 条件更新 + */ + int updateByQuery(Refund data, RefundQuery query); +} diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/refund/service/impl/RefundConverterImpl.java b/smart-switch-service/src/main/java/com/ruoyi/ss/refund/service/impl/RefundConverterImpl.java new file mode 100644 index 00000000..ccc8e93c --- /dev/null +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/refund/service/impl/RefundConverterImpl.java @@ -0,0 +1,51 @@ +package com.ruoyi.ss.refund.service.impl; + +import com.ruoyi.common.utils.ServiceUtil; +import com.ruoyi.common.utils.SnowFlakeUtil; +import com.ruoyi.ss.refund.domain.Refund; +import com.ruoyi.ss.refund.domain.enums.RefundStatus; +import com.ruoyi.ss.refund.service.RefundConverter; +import com.ruoyi.ss.transactionBill.domain.TransactionBill; +import com.ruoyi.ss.transactionBill.domain.TransactionBillVo; +import com.ruoyi.ss.transactionBill.domain.dto.BillRefundDTO; +import com.ruoyi.ss.transactionBill.service.TransactionBillService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.math.BigDecimal; +import java.math.RoundingMode; + +/** + * @author wjh + * 2024/7/9 + */ +@Service +public class RefundConverterImpl implements RefundConverter { + + @Autowired + private TransactionBillService transactionBillService; + + @Override + public Refund toPo(BillRefundDTO dto) { + if (dto == null) { + return null; + } + TransactionBillVo bill = transactionBillService.selectSmTransactionBillByBillId(dto.getBillId()); + ServiceUtil.assertion(bill == null, "待退款订单不存在"); + + // 按比例计算退款金额 + BigDecimal refundAmount = dto.getRefundAmount(); + BigDecimal refundRate = refundAmount.divide(bill.getMoney(), 2, RoundingMode.HALF_UP); // 退款金额比例 + BigDecimal refundServiceAmount = bill.getServiceCharge().multiply(refundRate); // 退款的手续费 + BigDecimal refundMchAmount = refundAmount.subtract(refundServiceAmount); // 退款的商户余额 + + Refund refund = new Refund(); + refund.setBillId(dto.getBillId()); + refund.setAmount(dto.getRefundAmount()); + refund.setStatus(RefundStatus.REFUNDING.getStatus()); + refund.setReason(String.format("充值订单%s退款", bill.getBillNo())); + refund.setMchAmount(refundMchAmount); + refund.setServiceAmount(refundServiceAmount); + return refund; + } +} diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/refund/service/impl/RefundServiceImpl.java b/smart-switch-service/src/main/java/com/ruoyi/ss/refund/service/impl/RefundServiceImpl.java new file mode 100644 index 00000000..664828f8 --- /dev/null +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/refund/service/impl/RefundServiceImpl.java @@ -0,0 +1,174 @@ +package com.ruoyi.ss.refund.service.impl; + +import java.math.BigDecimal; +import java.math.RoundingMode; +import java.util.List; +import com.ruoyi.common.utils.DateUtils; +import com.ruoyi.common.utils.ServiceUtil; +import com.ruoyi.common.utils.SnowFlakeUtil; +import com.ruoyi.ss.refund.domain.RefundQuery; +import com.ruoyi.ss.refund.domain.RefundVO; +import com.ruoyi.ss.refund.domain.enums.RefundStatus; +import com.ruoyi.ss.transactionBill.domain.TransactionBill; +import com.ruoyi.ss.transactionBill.domain.TransactionBillQuery; +import com.ruoyi.ss.transactionBill.domain.TransactionBillVo; +import com.ruoyi.ss.transactionBill.domain.enums.TransactionBillStatus; +import com.ruoyi.ss.transactionBill.service.TransactionBillService; +import com.ruoyi.ss.user.service.ISmUserService; +import org.apache.commons.lang.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import com.ruoyi.ss.refund.mapper.RefundMapper; +import com.ruoyi.ss.refund.domain.Refund; +import com.ruoyi.ss.refund.service.RefundService; +import org.springframework.transaction.support.TransactionTemplate; + +/** + * 退款订单Service业务层处理 + * + * @author ruoyi + * @date 2024-07-09 + */ +@Service +public class RefundServiceImpl implements RefundService +{ + @Autowired + private RefundMapper refundMapper; + + @Autowired + private TransactionTemplate transactionTemplate; + + @Autowired + private TransactionBillService transactionBillService; + + @Autowired + private ISmUserService userService; + + /** + * 查询退款订单 + * + * @param refundId 退款订单主键 + * @return 退款订单 + */ + @Override + public RefundVO selectRefundByRefundId(Long refundId) + { + return refundMapper.selectRefundByRefundId(refundId); + } + + /** + * 查询退款订单列表 + * + * @param refund 退款订单 + * @return 退款订单 + */ + @Override + public List selectRefundList(RefundQuery refund) + { + return refundMapper.selectRefundList(refund); + } + + /** + * 新增退款订单 + * + * @param refund 退款订单 + * @return 结果 + */ + @Override + public int insertRefund(Refund refund) + { + refund.setCreateTime(DateUtils.getNowDate()); + refund.setRefundNo(String.valueOf(SnowFlakeUtil.newId())); + return refundMapper.insertRefund(refund); + } + + /** + * 修改退款订单 + * + * @param refund 退款订单 + * @return 结果 + */ + @Override + public int updateRefund(Refund refund) + { + return refundMapper.updateRefund(refund); + } + + /** + * 批量删除退款订单 + * + * @param refundIds 需要删除的退款订单主键 + * @return 结果 + */ + @Override + public int deleteRefundByRefundIds(Long[] refundIds) + { + return refundMapper.deleteRefundByRefundIds(refundIds); + } + + /** + * 删除退款订单信息 + * + * @param refundId 退款订单主键 + * @return 结果 + */ + @Override + public int deleteRefundByRefundId(Long refundId) + { + return refundMapper.deleteRefundByRefundId(refundId); + } + + @Override + public RefundVO selectRefundByRefundNo(String refundNo) { + RefundQuery query = new RefundQuery(); + query.setRefundNo(refundNo); + return this.selectOne(query); + } + + @Override + public RefundVO selectOne(RefundQuery query) { + return refundMapper.selectOne(query); + } + + @Override + public void handleRefundSuccess(String refundNo) { + ServiceUtil.assertion(StringUtils.isBlank(refundNo), "退款订单编号不允许为空"); + + RefundVO refund = this.selectRefundByRefundNo(refundNo); + ServiceUtil.assertion(refund == null, "退款订单不存在"); + + TransactionBillVo bill = transactionBillService.selectSmTransactionBillByBillId(refund.getBillId()); + ServiceUtil.assertion(bill == null, "原订单不存在"); + + transactionTemplate.execute(status -> { + // 退款订单修改状态 + Refund refundData = new Refund(); + refundData.setStatus(RefundStatus.REFUND_SUCCESS.getStatus()); + RefundQuery refundQuery = new RefundQuery(); + refundQuery.setRefundId(refund.getRefundId()); + refundQuery.setStatus(RefundStatus.REFUNDING.getStatus()); + int updateRefund = this.updateByQuery(refundData, refundQuery); + ServiceUtil.assertion(updateRefund != 1, "修改退款订单状态失败"); + + // 修改原订单状态 + TransactionBillQuery billQuery = new TransactionBillQuery(); + billQuery.setBillId(refund.getBillId()); + billQuery.setStatus(TransactionBillStatus.REFUNDING.getStatus()); + TransactionBill billData = new TransactionBill(); + billData.setStatus(TransactionBillStatus.REFUNDED.getStatus()); + int updateBill = transactionBillService.updateByQuery(billData, billQuery); + ServiceUtil.assertion(updateBill != 1, "修改原订单状态失败"); + + return updateRefund; + }); + + } + + @Override + public int updateByQuery(Refund data, RefundQuery query) { + if (query == null) { + return 0; + } + return refundMapper.updateByQuery(data, query); + } +} diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/suit/mapper/SuitMapper.xml b/smart-switch-service/src/main/java/com/ruoyi/ss/suit/mapper/SuitMapper.xml index 4ada5af1..9b13c9ee 100644 --- a/smart-switch-service/src/main/java/com/ruoyi/ss/suit/mapper/SuitMapper.xml +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/suit/mapper/SuitMapper.xml @@ -4,22 +4,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> - - - - - - - - - - - - - - - - + select @@ -40,7 +25,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" from sm_suit ss left join sm_device sd on sd.device_id = ss.device_id left join sm_store store on store.store_id = sd.store_id - left join sm_user su on su.user_id = store.user_id + left join sm_user su on su.user_id = sd.user_id diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/domain/TransactionBill.java b/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/domain/TransactionBill.java index ed105b8e..75041241 100644 --- a/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/domain/TransactionBill.java +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/domain/TransactionBill.java @@ -60,7 +60,7 @@ public class TransactionBill extends BaseEntity /** 商户(到账用户) */ @Excel(name = "商户(到账用户)") @ApiModelProperty("商户(到账用户)id") - @JsonView(JsonViewProfile.AppMch.class) + @JsonView(JsonViewProfile.App.class) private Long mchId; /** 交易金额 */ diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/domain/TransactionBillVo.java b/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/domain/TransactionBillVo.java index d7c4e3ea..14b68713 100644 --- a/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/domain/TransactionBillVo.java +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/domain/TransactionBillVo.java @@ -18,10 +18,13 @@ public class TransactionBillVo extends TransactionBill { private String userName; @ApiModelProperty("商户(到账用户)名称") - @JsonView(JsonViewProfile.AppMch.class) + @JsonView(JsonViewProfile.App.class) private String mchName; @ApiModelProperty("支付渠道名称") @JsonView(JsonViewProfile.App.class) private String channelName; + + @ApiModelProperty("商户手机号") + private String mchMobile; } diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/domain/dto/BillRefundDTO.java b/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/domain/dto/BillRefundDTO.java new file mode 100644 index 00000000..39c12abc --- /dev/null +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/domain/dto/BillRefundDTO.java @@ -0,0 +1,27 @@ +package com.ruoyi.ss.transactionBill.domain.dto; + +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; +import java.math.BigDecimal; + +/** + * 订单退款DTO + * @author wjh + * 2024/7/9 + */ +@Data +public class BillRefundDTO { + + @ApiModelProperty("订单ID") + @NotNull(message = "订单ID不允许为空") + private Long billId; + + @ApiModelProperty("退款金额") + @NotNull(message = "退款金额不允许为空") + @Min(value = 0, message = "退款金额不允许小于0") + private BigDecimal refundAmount; + +} diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/domain/enums/TransactionBillStatus.java b/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/domain/enums/TransactionBillStatus.java index c23acee7..b6a1ca8e 100644 --- a/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/domain/enums/TransactionBillStatus.java +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/domain/enums/TransactionBillStatus.java @@ -22,6 +22,7 @@ public enum TransactionBillStatus { CANCELED("4", "已取消(用户)"), SYS_CANCELED("5", "已取消(系统)"), PAYING("6", "支付中"), + REFUNDING("7", "退款中"), WITHDRAW_APPROVING("11", "提现申请中"), WITHDRAW_PASSED("12", "提现申请通过"), diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/mapper/TransactionBillMapper.java b/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/mapper/TransactionBillMapper.java index f2f15efb..1b1365fb 100644 --- a/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/mapper/TransactionBillMapper.java +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/mapper/TransactionBillMapper.java @@ -6,6 +6,7 @@ import com.ruoyi.ss.transactionBill.domain.TransactionBillQuery; import com.ruoyi.ss.transactionBill.domain.TransactionBillVo; import org.apache.ibatis.annotations.Param; +import java.math.BigDecimal; import java.util.Date; import java.util.List; @@ -31,7 +32,7 @@ public interface TransactionBillMapper * @param smTransactionBill 充值记录 * @return 充值记录集合 */ - public List selectSmTransactionBillList(TransactionBillQuery smTransactionBill); + public List selectSmTransactionBillList(@Param("query") TransactionBillQuery smTransactionBill); /** * 新增充值记录 @@ -47,7 +48,7 @@ public interface TransactionBillMapper * @param transactionBill 充值记录 * @return 结果 */ - public int updateSmTransactionBill(TransactionBill transactionBill); + public int updateSmTransactionBill(@Param("data")TransactionBill transactionBill); /** * 删除充值记录 @@ -69,7 +70,7 @@ public interface TransactionBillMapper * 获取账单统计数据 * @param dto 查询条件 */ - List selectCount(TransactionBillQuery dto); + List selectCount(@Param("query")TransactionBillQuery dto); /** * 充值成功 @@ -82,7 +83,7 @@ public interface TransactionBillMapper * @param billNo 订单编号 * @return */ - TransactionBill selectSmTransactionBillByBillNo(String billNo); + TransactionBillVo selectSmTransactionBillByBillNo(String billNo); /** * 订单取消 @@ -144,4 +145,22 @@ public interface TransactionBillMapper * 蓝牙充值成功 */ int bluetoothRechargeSuccess(String billNo); + + /** + * 根据条件修改 + */ + int updateByQuery(@Param("data") TransactionBill data, @Param("query") TransactionBillQuery query); + + /** + * 添加退款金额 + * @param billId 订单ID + * @param refundAmount 退款金额 + * @param refundMchAmount 商户退款金额 + * @param refundServiceAmount 服务费退款金额 + */ + int addRefundAmount(@Param("billId") Long billId, + @Param("refundAmount") BigDecimal refundAmount, + @Param("refundMchAmount") BigDecimal refundMchAmount, + @Param("refundServiceAmount") BigDecimal refundServiceAmount + ); } diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/mapper/TransactionBillMapper.xml b/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/mapper/TransactionBillMapper.xml index 38b098e6..27c482d2 100644 --- a/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/mapper/TransactionBillMapper.xml +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/mapper/TransactionBillMapper.xml @@ -42,8 +42,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" stb.device_no, stb.suit_name, stb.device_mac, - su.user_name user_name, - su1.user_name mch_name + su.user_name as user_name, + su1.user_name as mch_name, + su1.phonenumber as mch_mobile from sm_transaction_bill stb left join sm_user su on su.user_id = stb.user_id left join sm_user su1 on su1.user_id = stb.mch_id @@ -52,52 +53,53 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" - and stb.user_id = #{userId} - and stb.device_id = #{deviceId} - and stb.type = #{type} - and stb.mch_id = #{mchId} - and su.user_name like concat('%', #{userName}, '%') - and su1.user_name like concat('%', #{mchName}, '%') - and stb.device_name like concat('%', #{deviceName}, '%') - and stb.create_time = #{createTime} - and date(stb.create_time) = date(#{createDate}) - and year(stb.create_time) = #{year} - and month(stb.create_time) = #{month} - and hour(stb.create_time) = #{hour} - and stb.status = #{status} - and NOW() >= stb.expire_time - and date(stb.create_time) >= date(#{startDate}) - and date(stb.create_time) <= date(#{endDate}) - and stb.device_recharge_status = #{deviceRechargeStatus} - and stb.suit_id = #{suitId} - and stb.store_id = #{storeId} - + and stb.user_id = #{query.userId} + and stb.bill_id = #{query.billId} + and stb.device_id = #{query.deviceId} + and stb.type = #{query.type} + and stb.mch_id = #{query.mchId} + and su.user_name like concat('%', #{query.userName}, '%') + and su1.user_name like concat('%', #{query.mchName}, '%') + and stb.device_name like concat('%', #{query.deviceName}, '%') + and stb.create_time = #{query.createTime} + and date(stb.create_time) = date(#{query.createDate}) + and year(stb.create_time) = #{query.year} + and month(stb.create_time) = #{query.month} + and hour(stb.create_time) = #{query.hour} + and stb.status = #{query.status} + and NOW() >= stb.expire_time + and date(stb.create_time) >= date(#{query.startDate}) + and date(stb.create_time) <= date(#{query.endDate}) + and stb.device_recharge_status = #{query.deviceRechargeStatus} + and stb.suit_id = #{query.suitId} + and stb.store_id = #{query.storeId} + and stb.bill_id in - + #{item} - + and stb.device_recharge_status in - + #{item} - + and stb.status in - + #{item} - + and stb.store_id in - + #{item} - + and stb.device_id in - + #{item} @@ -133,28 +135,28 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" @@ -251,43 +253,66 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + + + update sm_transaction_bill + set refund_amount = refund_amount + #{refundAmount}, + refund_mch_amount = refund_mch_amount + #{refundMchAmount}, + refund_service_amount = refund_service_amount + #{refundServiceAmount} + where bill_id = #{billId} + + update sm_transaction_bill - user_id = #{userId}, - `type` = #{type}, - device_id = #{deviceId}, - mch_id = #{mchId}, - money = #{money}, - arrival_amount = #{arrivalAmount}, - service_charge = #{serviceCharge}, - create_time = #{createTime}, - remark = #{remark}, - `status` = #{status}, - channel_id = #{channelId}, - after_balance = #{afterBalance}, - pay_time = #{payTime}, - expire_time = #{expireTime}, - account_no = #{accountNo}, - payed_amount = #{payedAmount}, - transfer_ids = #{transferIds,typeHandler=com.ruoyi.system.mapper.typehandler.StringListTypeHandler}, - channel_cost = #{channelCost}, - suit_id = #{suitId}, - suit_time = #{suitTime}, - suit_start_time = #{suitStartTime}, - suit_end_time = #{suitEndTime}, - suit_expire_time = #{suitExpireTime}, - store_id = #{storeId}, - store_name = #{storeName}, - store_address = #{storeAddress}, - device_name = #{deviceName}, - device_no = #{deviceNo}, - suit_name = #{suitName}, - device_mac = #{deviceMac}, + where bill_id = #{billId} + + user_id = #{data.userId}, + `type` = #{data.type}, + device_id = #{data.deviceId}, + mch_id = #{data.mchId}, + money = #{data.money}, + arrival_amount = #{data.arrivalAmount}, + service_charge = #{data.serviceCharge}, + create_time = #{data.createTime}, + remark = #{data.remark}, + `status` = #{data.status}, + channel_id = #{data.channelId}, + after_balance = #{data.afterBalance}, + pay_time = #{data.payTime}, + expire_time = #{data.expireTime}, + account_no = #{data.accountNo}, + payed_amount = #{data.payedAmount}, + transfer_ids = #{data.transferIds,typeHandler=com.ruoyi.system.mapper.typehandler.StringListTypeHandler}, + channel_cost = #{data.channelCost}, + suit_id = #{data.suitId}, + suit_time = #{data.suitTime}, + suit_start_time = #{data.suitStartTime}, + suit_end_time = #{data.suitEndTime}, + suit_expire_time = #{data.suitExpireTime}, + store_id = #{data.storeId}, + store_name = #{data.storeName}, + store_address = #{data.storeAddress}, + device_name = #{data.deviceName}, + device_no = #{data.deviceNo}, + suit_name = #{data.suitName}, + device_mac = #{data.deviceMac}, + + + + update sm_transaction_bill stb + + + + + + + + update sm_transaction_bill set channel_id = #{channelId}, @@ -383,4 +408,5 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" set device_recharge_status = '1' where bill_no = #{billNo} and type = '1' and device_recharge_status = '3' and status = '2' + diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/service/TransactionBillService.java b/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/service/TransactionBillService.java index 4bd33243..130698ea 100644 --- a/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/service/TransactionBillService.java +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/service/TransactionBillService.java @@ -5,6 +5,7 @@ import com.ruoyi.ss.transactionBill.domain.TransactionBill; import com.ruoyi.ss.transactionBill.domain.TransactionBillQuery; import com.ruoyi.ss.transactionBill.domain.TransactionBillVo; import com.ruoyi.ss.transactionBill.domain.bo.TransactionBillBO; +import com.ruoyi.ss.transactionBill.domain.dto.BillRefundDTO; import com.ruoyi.ss.transactionBill.domain.enums.TransactionBillStatus; import java.math.BigDecimal; @@ -106,9 +107,10 @@ public interface TransactionBillService /** * 根据订单编号查询数据 + * * @param billNo 订单编号 */ - TransactionBill selectSmTransactionBillByBillNo(String billNo); + TransactionBillVo selectSmTransactionBillByBillNo(String billNo); /** * 获取未支付的充值订单 @@ -169,9 +171,9 @@ public interface TransactionBillService /** * 刷新订单支付结果 - * @param billIds + * @param billId */ - void refreshPayResult(List billIds); + int refreshPayResult(Long billId); /** * 支付中 @@ -223,4 +225,33 @@ public interface TransactionBillService * @return */ boolean bluetoothRechargeSuccess(String billNo); + + /** + * 订单退款 + */ + int refund(BillRefundDTO dto); + + /** + * 根据条件更新 + * @param data + * @param query + */ + int updateByQuery(TransactionBill data, TransactionBillQuery query); + + /** + * 刷新支付结果 + */ + int refreshPayResult(String billNo); + + int refreshPayResult(List billList); + + /** + * 增加订单退款金额 + * + * @param billId 订单ID + * @param refundAmount 退款金额 + * @param refundMchAmount 商户退款金额 + * @param refundServiceAmount 退款手续费 + */ + int addRefundAmount(Long billId, BigDecimal refundAmount, BigDecimal refundMchAmount, BigDecimal refundServiceAmount); } diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/service/impl/TransactionBillServiceImpl.java b/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/service/impl/TransactionBillServiceImpl.java index 8c237d04..5bd32a9d 100644 --- a/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/service/impl/TransactionBillServiceImpl.java +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/transactionBill/service/impl/TransactionBillServiceImpl.java @@ -16,6 +16,10 @@ import com.ruoyi.ss.device.domain.vo.SmDeviceVO; import com.ruoyi.ss.device.service.ISmDeviceService; import com.ruoyi.ss.record.time.service.IRecordTimeService; import com.ruoyi.ss.record.time.service.RecordTimeConverter; +import com.ruoyi.ss.refund.domain.Refund; +import com.ruoyi.ss.refund.domain.RefundVO; +import com.ruoyi.ss.refund.service.RefundConverter; +import com.ruoyi.ss.refund.service.RefundService; import com.ruoyi.ss.store.domain.StoreVo; import com.ruoyi.ss.store.service.IStoreService; import com.ruoyi.ss.suit.domain.SuitVo; @@ -24,6 +28,7 @@ import com.ruoyi.ss.transactionBill.domain.TransactionBill; import com.ruoyi.ss.transactionBill.domain.TransactionBillQuery; import com.ruoyi.ss.transactionBill.domain.TransactionBillVo; import com.ruoyi.ss.transactionBill.domain.bo.TransactionBillBO; +import com.ruoyi.ss.transactionBill.domain.dto.BillRefundDTO; import com.ruoyi.ss.transactionBill.domain.enums.*; import com.ruoyi.ss.transactionBill.mapper.TransactionBillMapper; import com.ruoyi.ss.transactionBill.service.TransactionBillService; @@ -117,6 +122,12 @@ public class TransactionBillServiceImpl implements TransactionBillService { @Autowired private RecordTimeConverter recordTimeConverter; + @Autowired + private RefundService refundService; + + @Autowired + private RefundConverter refundConverter; + /** * 查询充值记录 * @@ -510,28 +521,18 @@ public class TransactionBillServiceImpl implements TransactionBillService { /** * 刷新支付结果 - * @param billIds + * + * @param billId + * @return */ - @Override @Transactional - public void refreshPayResult(List billIds) { - TransactionBillQuery dto = new TransactionBillQuery(); - dto.setBillIds(billIds); - List billList = transactionBillMapper.selectSmTransactionBillList(dto); - if (CollectionUtils.isEmpty(billList)) { - return; - } + public int refreshPayResult(Long billId) { + return this.refreshPayResult(this.selectSmTransactionBillByBillId(billId)); + } - // 获取支付结果,并判断是否支付成功,若成功则更新数据 - Date now = new Date(); - for (TransactionBillVo bill : billList) { - if (TransactionBillStatus.PAYING.getStatus().equals(bill.getStatus()) || TransactionBillStatus.UNPAID.getStatus().equals(bill.getStatus()) ) { - boolean payResult = getPayResult(bill.getBillNo()); - if (payResult) { - this.rechargeSuccess(bill.getBillNo(), now); - } - } - } + @Transactional + public int refreshPayResult(TransactionBillVo bill) { + return this.refreshPayResult(Collections.singletonList(bill)); } @Override @@ -677,7 +678,7 @@ public class TransactionBillServiceImpl implements TransactionBillService { } @Override - public TransactionBill selectSmTransactionBillByBillNo(String billNo) { + public TransactionBillVo selectSmTransactionBillByBillNo(String billNo) { return transactionBillMapper.selectSmTransactionBillByBillNo(billNo); } @@ -838,4 +839,91 @@ public class TransactionBillServiceImpl implements TransactionBillService { return execute != null && execute; } + + @Override + public int refund(BillRefundDTO dto) { + // 校验订单 + TransactionBillVo bill = this.selectSmTransactionBillByBillId(dto.getBillId()); + if (bill == null) { + return 0; + } + ServiceUtil.assertion(dto.getRefundAmount().compareTo(bill.getMoney()) > 0, "退款金额不允许大于订单金额"); + ServiceUtil.assertion(!TransactionBillStatus.SUCCESS.getStatus().equals(bill.getStatus()), "当前订单状态不允许退款"); + + Integer result = transactionTemplate.execute(status -> { + // 修改订单状态 + TransactionBill data = new TransactionBill(); + data.setStatus(TransactionBillStatus.REFUNDING.getStatus()); + TransactionBillQuery billQuery = new TransactionBillQuery(); + billQuery.setBillId(dto.getBillId()); + billQuery.setStatus(TransactionBillStatus.SUCCESS.getStatus()); + int updateBill = this.updateByQuery(data, billQuery); + ServiceUtil.assertion(updateBill != 1, "修改订单状态失败"); + + // 创建退款订单 + Refund refund = refundConverter.toPo(dto); + int updateRefund = refundService.insertRefund(refund); + ServiceUtil.assertion(updateRefund != 1, "创建退款订单失败"); + RefundVO refundVO = refundService.selectRefundByRefundNo(refund.getRefundNo()); + + // 商户余额按照比例扣减 + userService.subtractBalance(bill.getMchId(), refund.getMchAmount()); + + // 修改原订单的退款金额和退款手续费 + int updateRefundAmount = this.addRefundAmount(bill.getBillId(), refund.getAmount(), refund.getMchAmount(), refund.getServiceAmount()); + ServiceUtil.assertion(updateRefundAmount != 1, "修改原订单的退款金额和退款手续费失败"); + + // 发起退款 + if (TransactionBillPayType.WECHAT.getType().equals(bill.getChannelId())) { + wxPayService.refund(refundVO); + } else { + throw new ServiceException("当前支付方式不支持退款"); + } + return 1; + }); + + return result == null ? 0 : result; + } + + @Override + public int updateByQuery(TransactionBill data, TransactionBillQuery query) { + if (query == null) { + return 0; + } + return transactionBillMapper.updateByQuery(data, query); + } + + @Override + @Transactional + public int refreshPayResult(String billNo) { + return this.refreshPayResult(this.selectSmTransactionBillByBillNo(billNo)); + } + + @Override + @Transactional + public int refreshPayResult(List billList) { + if (CollectionUtils.isEmptyElement(billList)) { + return 0; + } + + // 获取支付结果,并判断是否支付成功,若成功则更新数据 + Date now = new Date(); + for (TransactionBillVo bill : billList) { + if (TransactionBillStatus.PAYING.getStatus().equals(bill.getStatus()) || TransactionBillStatus.UNPAID.getStatus().equals(bill.getStatus()) ) { + boolean payResult = getPayResult(bill.getBillNo()); + if (payResult) { + this.rechargeSuccess(bill.getBillNo(), now); + } + } + } + return 1; + } + + @Override + public int addRefundAmount(Long billId, BigDecimal refundAmount, BigDecimal refundMchAmount, BigDecimal refundServiceAmount) { + if (billId == null) { + return 0; + } + return transactionBillMapper.addRefundAmount(billId, refundAmount, refundMchAmount, refundServiceAmount); + } } diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/user/service/impl/SmUserServiceImpl.java b/smart-switch-service/src/main/java/com/ruoyi/ss/user/service/impl/SmUserServiceImpl.java index e8532a7f..67c578ac 100644 --- a/smart-switch-service/src/main/java/com/ruoyi/ss/user/service/impl/SmUserServiceImpl.java +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/user/service/impl/SmUserServiceImpl.java @@ -5,7 +5,13 @@ import com.ruoyi.common.enums.UserType; import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.common.utils.ServiceUtil; +import com.ruoyi.common.utils.collection.CollectionUtils; +import com.ruoyi.ss.device.domain.SmDeviceQuery; +import com.ruoyi.ss.device.domain.vo.SmDeviceVO; import com.ruoyi.ss.device.service.ISmDeviceService; +import com.ruoyi.ss.store.domain.StoreQuery; +import com.ruoyi.ss.store.domain.StoreVo; +import com.ruoyi.ss.store.service.IStoreService; import com.ruoyi.ss.user.domain.SmUserQuery; import com.ruoyi.ss.user.domain.SmUserVo; import com.ruoyi.ss.user.domain.bo.UserUpdateServiceRateBO; @@ -15,7 +21,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.support.TransactionTemplate; -import org.springframework.util.CollectionUtils; import java.math.BigDecimal; import java.util.Collections; @@ -42,6 +47,9 @@ public class SmUserServiceImpl implements ISmUserService @Autowired private ISmDeviceService deviceService; + @Autowired + private IStoreService storeService; + /** * 查询普通用户信息 * @@ -244,8 +252,19 @@ public class SmUserServiceImpl implements ISmUserService * @param userIds */ private void validatePreLogicDel(List userIds) { - ServiceUtil.assertion(!CollectionUtils.isEmpty(userIds), "用户id不能为空"); + ServiceUtil.assertion(CollectionUtils.isEmpty(userIds), "用户id不能为空"); ServiceUtil.assertion(!isExistUsers(userIds), "用户不存在"); + + SmDeviceQuery deviceQuery = new SmDeviceQuery(); + deviceQuery.setUserIds(userIds); + List deviceList = deviceService.selectSmDeviceList(deviceQuery); + ServiceUtil.assertion(CollectionUtils.isNotEmpty(deviceList), "用户存在设备,不允许删除"); + + + StoreQuery storeQuery = new StoreQuery(); + storeQuery.setUserIds(userIds); + List storeList = storeService.selectSmStoreList(storeQuery); + ServiceUtil.assertion(CollectionUtils.isNotEmpty(storeList), "用户存在店铺,不允许删除"); } /** diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/wxPay/domain/RefundAble.java b/smart-switch-service/src/main/java/com/ruoyi/ss/wxPay/domain/RefundAble.java new file mode 100644 index 00000000..fea885e8 --- /dev/null +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/wxPay/domain/RefundAble.java @@ -0,0 +1,23 @@ +package com.ruoyi.ss.wxPay.domain; + +import com.wechat.pay.java.service.refund.model.AmountReq; + +/** + * @author wjh + * 2024/7/10 + */ +public interface RefundAble { + + // 原商户订单号 + String refundOutTradeNo(); + + // 退款单号 + String refundOutRefundNo(); + + // 退款原因 + String refundReason(); + + // 退款金额 + AmountReq refundAmount(); + +} diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/wxPay/service/IWxPayService.java b/smart-switch-service/src/main/java/com/ruoyi/ss/wxPay/service/IWxPayService.java index 3dff3a43..b7df968d 100644 --- a/smart-switch-service/src/main/java/com/ruoyi/ss/wxPay/service/IWxPayService.java +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/wxPay/service/IWxPayService.java @@ -1,8 +1,11 @@ package com.ruoyi.ss.wxPay.service; +import com.ruoyi.ss.wxPay.domain.RefundAble; import com.ruoyi.ss.wxPay.domain.enums.TransferScene; import com.wechat.pay.java.service.payments.jsapi.model.PrepayWithRequestPaymentResponse; import com.wechat.pay.java.service.payments.model.Transaction; +import com.wechat.pay.java.service.refund.model.Refund; +import com.wechat.pay.java.service.refund.model.RefundNotification; import com.wechat.pay.java.service.transferbatch.model.InitiateBatchTransferResponse; import com.wechat.pay.java.service.transferbatch.model.TransferDetailInput; @@ -70,4 +73,14 @@ public interface IWxPayService { * @param transferScene 转账场景 */ List buildTransferDetailList(BigDecimal totalAmount, String openId, TransferScene transferScene); + + /** + * 发起退款 + */ + Refund refund(RefundAble refund); + + /** + * 验签并解析 + */ + T checkAndParse(HttpServletRequest request, String body, Class clazz); } diff --git a/smart-switch-service/src/main/java/com/ruoyi/ss/wxPay/service/WxPayService.java b/smart-switch-service/src/main/java/com/ruoyi/ss/wxPay/service/WxPayService.java index 43b33a86..1a197330 100644 --- a/smart-switch-service/src/main/java/com/ruoyi/ss/wxPay/service/WxPayService.java +++ b/smart-switch-service/src/main/java/com/ruoyi/ss/wxPay/service/WxPayService.java @@ -10,7 +10,6 @@ import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.ServiceUtil; import com.ruoyi.common.utils.SnowFlakeUtil; import com.ruoyi.common.utils.http.HttpUtils; -import com.ruoyi.ss.account.service.ISmAccountService; import com.ruoyi.ss.transactionBill.domain.TransactionBill; import com.ruoyi.ss.transactionBill.domain.enums.TransactionBillPayType; import com.ruoyi.ss.transactionBill.domain.enums.TransactionBillStatus; @@ -18,6 +17,7 @@ import com.ruoyi.ss.transactionBill.domain.enums.TransactionBillType; import com.ruoyi.ss.transactionBill.service.TransactionBillService; import com.ruoyi.ss.user.domain.SmUserVo; import com.ruoyi.ss.user.service.ISmUserService; +import com.ruoyi.ss.wxPay.domain.RefundAble; import com.ruoyi.ss.wxPay.domain.enums.TransferScene; import com.ruoyi.ss.wxPayNotify.domain.SmWxPayNotify; import com.ruoyi.ss.wxPayNotify.mapper.SmWxPayNotifyMapper; @@ -28,6 +28,9 @@ import com.wechat.pay.java.service.payments.jsapi.JsapiService; import com.wechat.pay.java.service.payments.jsapi.JsapiServiceExtension; import com.wechat.pay.java.service.payments.jsapi.model.*; import com.wechat.pay.java.service.payments.model.Transaction; +import com.wechat.pay.java.service.refund.RefundService; +import com.wechat.pay.java.service.refund.model.CreateRequest; +import com.wechat.pay.java.service.refund.model.Refund; import com.wechat.pay.java.service.transferbatch.TransferBatchService; import com.wechat.pay.java.service.transferbatch.model.InitiateBatchTransferRequest; import com.wechat.pay.java.service.transferbatch.model.InitiateBatchTransferResponse; @@ -45,6 +48,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; /** @@ -81,7 +85,7 @@ public class WxPayService implements IWxPayService { private RedisLock redisLock; @Autowired - private ISmAccountService accountService; + private RefundService refundService; @Autowired private TransferBatchService transferBatchService; @@ -125,9 +129,9 @@ public class WxPayService implements IWxPayService { transactionBillService.paying(bill.getBillId()); // 每隔20秒查询支付结果,直到过期,首次10秒查询 -// scheduledExecutorService.schedule(() -> { -// transactionBillService.refreshPayResultBeforeExpire(bill.getBillNo(), 20, TimeUnit.SECONDS); -// }, 10, TimeUnit.SECONDS); + scheduledExecutorService.schedule(() -> { + transactionBillService.refreshPayResultBeforeExpire(bill.getBillNo(), 20, TimeUnit.SECONDS); + }, 10, TimeUnit.SECONDS); } catch (Exception e) { this.closeOrder(bill.getBillNo()); @@ -286,6 +290,25 @@ public class WxPayService implements IWxPayService { return transferDetailList; } + /** + * 发起退款 + * + * @param refund + */ + @Override + public Refund refund(RefundAble refund) { + CreateRequest request = new CreateRequest(); + request.setOutTradeNo(refund.refundOutTradeNo()); + request.setOutRefundNo(refund.refundOutRefundNo()); + request.setReason(refund.refundReason()); + request.setAmount(refund.refundAmount()); + request.setNotifyUrl(wxPayConfig.getRefundNotifyUrl()); + log.info("【退款】请求微信参数: {}", JSON.toJSONString(request)); + Refund res = refundService.create(request); + log.info("【退款】微信返回结果:【{}】",JSON.toJSONString(refund)); + return res; + } + private Long getTransferAmount(BigDecimal money) { return money.multiply(new BigDecimal(100)).longValue(); } @@ -322,7 +345,8 @@ public class WxPayService implements IWxPayService { * @param body 请求体 * @param clazz 返回值类型 */ - private T checkAndParse(HttpServletRequest request, String body, Class clazz) { + @Override + public T checkAndParse(HttpServletRequest request, String body, Class clazz) { // 构造 RequestParam RequestParam requestParam = new RequestParam.Builder() .serialNumber(request.getHeader("Wechatpay-Serial")) diff --git a/smart-switch-service/src/main/java/com/ruoyi/task/bill/PayTask.java b/smart-switch-service/src/main/java/com/ruoyi/task/bill/PayTask.java index 635e93da..3f040ce2 100644 --- a/smart-switch-service/src/main/java/com/ruoyi/task/bill/PayTask.java +++ b/smart-switch-service/src/main/java/com/ruoyi/task/bill/PayTask.java @@ -49,7 +49,7 @@ public class PayTask implements ApplicationRunner { return; } - transactionBillService.refreshPayResult(billList.stream().map(TransactionBill::getBillId).collect(Collectors.toList())); + transactionBillService.refreshPayResult(billList); } diff --git a/smart-switch-web/src/main/java/com/ruoyi/web/controller/app/AppPayController.java b/smart-switch-web/src/main/java/com/ruoyi/web/controller/app/AppPayController.java index b5e86716..2464c874 100644 --- a/smart-switch-web/src/main/java/com/ruoyi/web/controller/app/AppPayController.java +++ b/smart-switch-web/src/main/java/com/ruoyi/web/controller/app/AppPayController.java @@ -1,10 +1,19 @@ package com.ruoyi.web.controller.app; +import com.alibaba.fastjson2.JSON; import com.ruoyi.common.annotation.Anonymous; +import com.ruoyi.common.constant.Constants; import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.exception.ServiceException; +import com.ruoyi.common.pay.wx.domain.NotifyEventType; +import com.ruoyi.common.utils.http.HttpUtils; +import com.ruoyi.ss.refund.service.RefundService; import com.ruoyi.ss.transactionBill.service.TransactionBillService; import com.ruoyi.ss.wxPay.service.IWxPayService; import com.wechat.pay.java.core.exception.ValidationException; +import com.wechat.pay.java.core.notification.Notification; +import com.wechat.pay.java.service.refund.model.RefundNotification; +import com.wechat.pay.java.service.refund.model.Status; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; @@ -32,6 +41,9 @@ public class AppPayController { @Autowired private TransactionBillService transactionBillService; + @Autowired + private RefundService refundService; + @ApiOperation("微信支付") @GetMapping("/wx/{billNo}") public AjaxResult wxPay(@PathVariable @ApiParam("订单编号") String billNo) { @@ -54,6 +66,35 @@ public class AppPayController { return ResponseEntity.status(HttpStatus.OK).body(null); } + // 微信退款回调 + @PostMapping("/notify/wx/refund") + @Anonymous + public ResponseEntity wxPayNotifyRefund(HttpServletRequest request) { + try { + String body = HttpUtils.getBody(request); + log.info("【微信退款回调】接收对象 : " + JSON.toJSONString(body)); + // 解析通知数据 + Notification notification = JSON.parseObject(body, Notification.class); + log.info("【微信退款回调】转换成notification: " + JSON.toJSONString(notification)); + // 退款成功通知 + if (NotifyEventType.REFUND_SUCCESS.getValue().equals(notification.getEventType())) { + // 验签、解密并转换成 RefundNotification + RefundNotification refundNotification = wxPayService.checkAndParse(request, body, RefundNotification.class); + log.info("【微信退款回调】转换成RefundNotification: " + JSON.toJSONString(refundNotification)); + if (Status.SUCCESS.equals(refundNotification.getRefundStatus())) { + // 退款成功操作 + String outRefundNo = refundNotification.getOutRefundNo(); + refundService.handleRefundSuccess(outRefundNo); + } + } + } catch (ValidationException e) { + return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(null); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null); + } + return ResponseEntity.status(HttpStatus.OK).body(null); + } + @ApiOperation("查询支付结果") @GetMapping("/result/{billNo}") public AjaxResult payResult(@PathVariable @ApiParam("订单编号") String billNo) { diff --git a/smart-switch-web/src/main/java/com/ruoyi/web/controller/app/AppTransactionBillController.java b/smart-switch-web/src/main/java/com/ruoyi/web/controller/app/AppTransactionBillController.java index 1095006a..c4b30562 100644 --- a/smart-switch-web/src/main/java/com/ruoyi/web/controller/app/AppTransactionBillController.java +++ b/smart-switch-web/src/main/java/com/ruoyi/web/controller/app/AppTransactionBillController.java @@ -14,6 +14,7 @@ import com.ruoyi.ss.transactionBill.domain.TransactionBill; import com.ruoyi.ss.transactionBill.domain.TransactionBillQuery; import com.ruoyi.ss.transactionBill.domain.TransactionBillVo; import com.ruoyi.ss.transactionBill.domain.bo.TransactionBillBO; +import com.ruoyi.ss.transactionBill.domain.dto.BillRefundDTO; import com.ruoyi.ss.transactionBill.domain.enums.TransactionBillGroupBy; import com.ruoyi.ss.transactionBill.domain.enums.TransactionBillStatus; import com.ruoyi.ss.transactionBill.domain.enums.TransactionBillType; @@ -209,4 +210,23 @@ public class AppTransactionBillController extends BaseController return success(smTransactionBillService.bluetoothRechargeSuccess(billNo)); } + @ApiOperation("订单退款") + @PutMapping("/refund") + public AjaxResult refund(@RequestBody @Validated BillRefundDTO dto) { + // 判断用户是否订单收款人 + TransactionBillVo bill = smTransactionBillService.selectSmTransactionBillByBillId(dto.getBillId()); + if (bill == null) { + return error("订单不存在"); + } + if (!Objects.equals(bill.getMchId(), getUserId())) { + return error("您无权操作退款"); + } + return toAjax(smTransactionBillService.refund(dto)); + } + + @ApiOperation("刷新支付结果") + @PutMapping("/{billNo}/refreshPayResult") + public AjaxResult refreshPayResult(@PathVariable String billNo ) { + return toAjax(smTransactionBillService.refreshPayResult(billNo)); + } } diff --git a/smart-switch-web/src/main/java/com/ruoyi/web/controller/ss/RefundController.java b/smart-switch-web/src/main/java/com/ruoyi/web/controller/ss/RefundController.java new file mode 100644 index 00000000..eff39cad --- /dev/null +++ b/smart-switch-web/src/main/java/com/ruoyi/web/controller/ss/RefundController.java @@ -0,0 +1,107 @@ +package com.ruoyi.web.controller.ss; + +import java.util.List; +import javax.servlet.http.HttpServletResponse; + +import com.ruoyi.ss.refund.domain.RefundQuery; +import com.ruoyi.ss.refund.domain.RefundVO; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.ss.refund.domain.Refund; +import com.ruoyi.ss.refund.service.RefundService; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.common.core.page.TableDataInfo; + +/** + * 退款订单Controller + * + * @author ruoyi + * @date 2024-07-09 + */ +@RestController +@RequestMapping("/ss/refund") +public class RefundController extends BaseController +{ + @Autowired + private RefundService refundService; + + /** + * 查询退款订单列表 + */ + @PreAuthorize("@ss.hasPermi('ss:refund:list')") + @GetMapping("/list") + public TableDataInfo list(RefundQuery refund) + { + startPage(); + List list = refundService.selectRefundList(refund); + return getDataTable(list); + } + + /** + * 导出退款订单列表 + */ + @PreAuthorize("@ss.hasPermi('ss:refund:export')") + @Log(title = "退款订单", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, RefundQuery refund) + { + List list = refundService.selectRefundList(refund); + ExcelUtil util = new ExcelUtil(RefundVO.class); + util.exportExcel(response, list, "退款订单数据"); + } + + /** + * 获取退款订单详细信息 + */ + @PreAuthorize("@ss.hasPermi('ss:refund:query')") + @GetMapping(value = "/{refundId}") + public AjaxResult getInfo(@PathVariable("refundId") Long refundId) + { + return success(refundService.selectRefundByRefundId(refundId)); + } + + /** + * 新增退款订单 + */ + @PreAuthorize("@ss.hasPermi('ss:refund:add')") + @Log(title = "退款订单", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody Refund refund) + { + return toAjax(refundService.insertRefund(refund)); + } + + /** + * 修改退款订单 + */ + @PreAuthorize("@ss.hasPermi('ss:refund:edit')") + @Log(title = "退款订单", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody Refund refund) + { + return toAjax(refundService.updateRefund(refund)); + } + + /** + * 删除退款订单 + */ + @PreAuthorize("@ss.hasPermi('ss:refund:remove')") + @Log(title = "退款订单", businessType = BusinessType.DELETE) + @DeleteMapping("/{refundIds}") + public AjaxResult remove(@PathVariable Long[] refundIds) + { + return toAjax(refundService.deleteRefundByRefundIds(refundIds)); + } +} diff --git a/smart-switch-web/src/main/java/com/ruoyi/web/controller/ss/SmTransactionBillController.java b/smart-switch-web/src/main/java/com/ruoyi/web/controller/ss/SmTransactionBillController.java index 2e82a620..75ead02f 100644 --- a/smart-switch-web/src/main/java/com/ruoyi/web/controller/ss/SmTransactionBillController.java +++ b/smart-switch-web/src/main/java/com/ruoyi/web/controller/ss/SmTransactionBillController.java @@ -2,15 +2,18 @@ package com.ruoyi.web.controller.ss; import java.util.Arrays; import java.util.List; +import java.util.Objects; import javax.servlet.http.HttpServletResponse; import com.ruoyi.ss.transactionBill.domain.bo.TransactionBillBO; import com.ruoyi.ss.transactionBill.domain.TransactionBillQuery; import com.ruoyi.ss.transactionBill.domain.TransactionBillVo; +import com.ruoyi.ss.transactionBill.domain.dto.BillRefundDTO; import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiOperation; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; @@ -145,11 +148,11 @@ public class SmTransactionBillController extends BaseController @ApiModelProperty("刷新支付结果") @PreAuthorize("@ss.hasPermi('system:bill:edit')") - @GetMapping("/refreshPayResult/{billIds}") + @GetMapping("/refreshPayResult/{billId}") @Log(title = "刷新支付结果", businessType = BusinessType.UPDATE) - public AjaxResult refreshPayResult(@PathVariable Long[] billIds) + public AjaxResult refreshPayResult(@PathVariable Long billId) { - smTransactionBillService.refreshPayResult(Arrays.asList(billIds)); + smTransactionBillService.refreshPayResult(billId); return success(); } @@ -162,4 +165,11 @@ public class SmTransactionBillController extends BaseController return success(); } + + // 订单退款 + @PutMapping("/refund") + @PreAuthorize("@ss.hasPermi('system:bill:refund')") + public AjaxResult refund(@RequestBody @Validated BillRefundDTO dto) { + return toAjax(smTransactionBillService.refund(dto)); + } } diff --git a/smart-switch-web/src/main/java/com/ruoyi/web/controller/ss/SmUserController.java b/smart-switch-web/src/main/java/com/ruoyi/web/controller/ss/SmUserController.java index d8f4d1ef..6943c755 100644 --- a/smart-switch-web/src/main/java/com/ruoyi/web/controller/ss/SmUserController.java +++ b/smart-switch-web/src/main/java/com/ruoyi/web/controller/ss/SmUserController.java @@ -137,9 +137,9 @@ public class SmUserController extends BaseController @PreAuthorize("@ss.hasPermi('system:smUser:remove')") @Log(title = "普通用户信息", businessType = BusinessType.DELETE) @DeleteMapping("/{userIds}") - public AjaxResult remove(@PathVariable Long[] userIds) + public AjaxResult remove(@PathVariable List userIds) { - return toAjax(smUserService.deleteSmUserByUserIds(userIds)); + return toAjax(smUserService.logicDel(userIds)); } } diff --git a/smart-switch-web/src/main/java/com/ruoyi/web/core/aspectj/DeviceAdminRequiredAspect.java b/smart-switch-web/src/main/java/com/ruoyi/web/core/aspectj/DeviceAdminRequiredAspect.java index 76c96e89..f292e7a0 100644 --- a/smart-switch-web/src/main/java/com/ruoyi/web/core/aspectj/DeviceAdminRequiredAspect.java +++ b/smart-switch-web/src/main/java/com/ruoyi/web/core/aspectj/DeviceAdminRequiredAspect.java @@ -35,8 +35,7 @@ public class DeviceAdminRequiredAspect { // 判断当前用户是否有权限访问 @Before("@annotation(required)") public void doBefore(JoinPoint point, DeviceAdminRequired required) { - LoginUser loginUser = SecurityUtils.getLoginUser(); - SmUser user = loginUser.getSmUser(); + SmUserVo user = smUserService.selectSmUserByUserId(SecurityUtils.getUserId()); ServiceUtil.assertion(user == null || user.getDeviceAdmin() == null || !user.getDeviceAdmin(), "您无权操作" ); } diff --git a/smart-switch-web/src/main/resources/application-dev.yml b/smart-switch-web/src/main/resources/application-dev.yml index 7664458b..21ae0d8e 100644 --- a/smart-switch-web/src/main/resources/application-dev.yml +++ b/smart-switch-web/src/main/resources/application-dev.yml @@ -20,7 +20,9 @@ wx: # apiV3密钥 apiV3Key: 49819e0f0abdb2df3246f7b27f264d75 # 通知回调地址 - notifyUrl: http://124.221.246.124:2290/dev-api/app/pay/notify/wx # 内网穿透 + notifyUrl: http://124.221.246.124:2290/app/pay/notify/wx # 内网穿透 + # 退款通知回调地址 + refundNotifyUrl: http://124.221.246.124:2290/app/pay/notify/wx/refund # 密钥所在位置 privateKeyPath: D:/project/证书/wxpay/apiclient_key.pem # 证书序列号 diff --git a/smart-switch-web/src/main/resources/application-druid-test.yml b/smart-switch-web/src/main/resources/application-druid-test.yml index 8c168b08..17a9fbb4 100644 --- a/smart-switch-web/src/main/resources/application-druid-test.yml +++ b/smart-switch-web/src/main/resources/application-druid-test.yml @@ -6,7 +6,7 @@ spring: druid: # 主库数据源 master: - url: jdbc:mysql://106.75.233.135:3306/smart-switch?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 + url: jdbc:mysql://106.75.233.135:3306/smart-switch-test?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 username: root password: 9671e015b05b3f11 # 从库数据源 diff --git a/smart-switch-web/src/main/resources/application-prod.yml b/smart-switch-web/src/main/resources/application-prod.yml index 04b18bc7..05d5fc51 100644 --- a/smart-switch-web/src/main/resources/application-prod.yml +++ b/smart-switch-web/src/main/resources/application-prod.yml @@ -21,6 +21,8 @@ wx: apiV3Key: 49819e0f0abdb2df3246f7b27f264d75 # 通知回调地址 notifyUrl: https://kg.chuantewulian.cn/prod-api/app/pay/notify/wx # 正式环境 + # 退款通知回调地址 + refundNotifyUrl: https://kg.chuantewulian.cn/prod-api/app/pay/notify/wx/refund # 密钥所在位置 privateKeyPath: /www/wwwroot/smart-switch/wxpay/apiclient_key.pem # 证书序列号 diff --git a/smart-switch-web/src/main/resources/application-test.yml b/smart-switch-web/src/main/resources/application-test.yml index 4bf497d3..545db15c 100644 --- a/smart-switch-web/src/main/resources/application-test.yml +++ b/smart-switch-web/src/main/resources/application-test.yml @@ -21,6 +21,8 @@ wx: apiV3Key: 49819e0f0abdb2df3246f7b27f264d75 # 通知回调地址 notifyUrl: https://kg.chuantewulian.cn/test-api/app/pay/notify/wx # 测试环境 + # 退款通知回调地址 + refundNotifyUrl: https://kg.chuantewulian.cn/test-api/app/pay/notify/wx/refund # 密钥所在位置 privateKeyPath: /home/www/projects/smart-switch/wxpay/apiclient_key.pem # 证书序列号