pull/1/head
wqy 2 years ago
parent bb067689b4
commit 0e059b57df

@ -5,10 +5,12 @@ import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.symmetric.AES;
import com.alibaba.fastjson.JSON;
import com.cyl.h5.domain.dto.PayNotifyMessageDTO;
import com.cyl.h5.service.H5OrderService;
import com.cyl.job.OrderJob;
import com.cyl.manager.act.service.IntegralHistoryService;
import com.cyl.manager.oms.service.AftersaleService;
import com.cyl.manager.ums.service.MemberCartService;
import com.ruoyi.RuoYiApplication;
import com.ruoyi.common.config.properties.SmsProperties;
@ -16,6 +18,7 @@ import com.ruoyi.common.core.sms.AliyunSmsTemplate;
import com.ruoyi.common.core.sms.SmsTemplate;
import com.ruoyi.common.utils.SecurityUtils;
import com.wechat.pay.java.service.partnerpayments.jsapi.model.Transaction;
import com.wechat.pay.java.service.refund.model.RefundNotification;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
@ -37,6 +40,9 @@ import java.util.Map;
@Slf4j
public class ServiceTest {
@Autowired
private AftersaleService aftersaleService;
@Autowired
private MemberCartService memberCartService;
@ -62,6 +68,12 @@ public class ServiceTest {
}
@Test
public void t(){
String a = "{\"amount\":{\"currency\":\"CNY\",\"discountRefund\":0,\"from\":[],\"payerRefund\":2,\"payerTotal\":2,\"refund\":2,\"refundFee\":0,\"settlementRefund\":2,\"settlementTotal\":2,\"total\":2},\"channel\":\"ORIGINAL\",\"createTime\":\"2024-04-26T18:17:56+08:00\",\"fundsAccount\":\"UNAVAILABLE\",\"outRefundNo\":\"5773276988819456\",\"outTradeNo\":\"5773274485622785\",\"promotionDetail\":[],\"refundId\":\"50303909472024042683046217485\",\"refundStatus\":\"SUCCESS\",\"transactionId\":\"4200002186202404266125196354\",\"userReceivedAccount\":\"支付用户零钱通\"}";
RefundNotification params = JSON.parseObject(a,RefundNotification.class);
aftersaleService.refundOrderExc(params);
}
@Test
public void test1() {
memberCartService.mineCartNum();

@ -2,6 +2,7 @@ package com.cyl.config;
import com.cyl.wechat.WechatPayConfig;
import com.wechat.pay.java.service.payments.jsapi.JsapiService;
import com.wechat.pay.java.service.refund.RefundService;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@ -16,4 +17,9 @@ public class WechatConfig {
public JsapiService jsapiService(){
return new JsapiService.Builder().config(WechatPayConfig.getInstance()).build();
}
@Bean
public RefundService refundService(){
return new RefundService.Builder().config(WechatPayConfig.getInstance()).build();
}
}

@ -1,6 +1,7 @@
package com.cyl.h5.controller;
import com.alibaba.fastjson.JSONObject;
import com.cyl.h5.domain.dto.DeliveryReq;
import com.cyl.h5.domain.form.ApplyRefundForm;
import com.cyl.h5.domain.form.OrderCreateForm;
import com.cyl.h5.domain.form.CancelOrderForm;
@ -12,9 +13,18 @@ import com.cyl.h5.domain.vo.H5OrderVO;
import com.cyl.h5.domain.vo.OrderCalcVO;
import com.cyl.h5.domain.form.OrderSubmitForm;
import com.cyl.h5.service.H5OrderService;
import com.cyl.manager.oms.domain.entity.Aftersale;
import com.cyl.manager.oms.domain.entity.Order;
import com.cyl.manager.oms.domain.form.DealWithAftersaleForm;
import com.cyl.manager.oms.service.AftersaleService;
import com.cyl.manager.oms.service.OrderService;
import com.cyl.manager.ums.domain.entity.Member;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.redis.RedisService;
import com.ruoyi.common.enums.AftersaleStatus;
import com.ruoyi.common.enums.OrderStatus;
import com.ruoyi.framework.config.LocalDataUtil;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
@ -24,6 +34,8 @@ import org.springframework.data.domain.Pageable;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
@RestController
@RequestMapping("/h5/order")
@Slf4j
@ -32,6 +44,10 @@ public class H5OrderController {
private RedisService redisService;
@Autowired
private H5OrderService service;
@Autowired
private AftersaleService aftersaleService;
@Autowired
private OrderService orderService;
@ApiOperation("下单")
@PostMapping("/add")
@ -153,12 +169,20 @@ public class H5OrderController {
@ApiOperation("申请售后")
@PostMapping("/applyRefund")
public ResponseEntity<String> applyRefund(@RequestBody ApplyRefundForm applyRefundForm){
public ResponseEntity<Boolean> applyRefund(@RequestBody ApplyRefundForm applyRefundForm){
String redisKey = "h5_oms_order_applyRefund_" + applyRefundForm.getOrderId();
String redisValue = applyRefundForm.getOrderId() + "_" + System.currentTimeMillis();
try{
redisService.lock(redisKey, redisValue, 60);
return ResponseEntity.ok(service.applyRefund(applyRefundForm));
Order order = service.applyRefund(applyRefundForm);
// 如果是未发货,系统自动退款
if (order.getStatus().equals(OrderStatus.NOT_DELIVERED.getType())) {
DealWithAftersaleForm req = new DealWithAftersaleForm();
req.setOrderId(applyRefundForm.getOrderId());
req.setOptType(1);
aftersaleService.dealWith(req, order.getMemberId(), "直接发起退款");
}
return ResponseEntity.ok(true);
}catch (Exception e){
log.error("申请售后发生异常",e);
throw new RuntimeException(e.getMessage());
@ -197,4 +221,43 @@ public class H5OrderController {
public ResponseEntity<AftersaleRefundInfoVO> refundOrderDetail(@RequestParam Long orderId){
return ResponseEntity.ok(service.refundOrderDetail(orderId));
}
@ApiOperation("用户提交退货单号")
@PostMapping("/aftersale/delivery")
public AjaxResult delivery(@RequestBody @Valid DeliveryReq req){
log.info("用户提交退货单号","提交的数据:"+JSONObject.toJSONString(req));
String redisKey = "h5_oms_order_delivery_"+req.getOrderId();
String redisValue = req.getOrderId()+"_"+System.currentTimeMillis();
try {
redisService.lock(redisKey, redisValue, 60);
Order order = service.selectById(req.getOrderId());
Aftersale aftersale = aftersaleService.queryAfterSale(req.getOrderId());
if(order == null || aftersale == null){
return AjaxResult.error("未查询到订单信息");
}
//仅退款不需要退货
if(aftersale.getType() == 1){
return AjaxResult.error("仅退款不需要退货");
}
if(aftersale.getStatus() != AftersaleStatus.WAIT.getType()){
return AjaxResult.error("当前状态不可退货");
}
//更新退款单
aftersale.setRefundWpCode(req.getDeliveryCompanyCode());
aftersale.setRefundWaybillCode(req.getDeliverySn());
aftersaleService.update(aftersale);
return AjaxResult.success();
}catch (Exception e){
log.error("用户提交退货单号异常", e);
return AjaxResult.error("提交发货信息失败");
}finally {
try{
redisService.unLock(redisKey,redisValue);
}catch (Exception e){
log.error("",e);
}
}
}
}

@ -4,13 +4,17 @@ import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.cyl.h5.domain.dto.PayNotifyMessageDTO;
import com.cyl.h5.service.H5OrderService;
import com.cyl.manager.oms.service.AftersaleService;
import com.cyl.wechat.WechatPayConfig;
import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.core.notification.NotificationConfig;
import com.wechat.pay.java.core.notification.NotificationParser;
import com.wechat.pay.java.core.notification.RequestParam;
import com.wechat.pay.java.service.partnerpayments.jsapi.model.Transaction;
import com.wechat.pay.java.service.refund.model.RefundNotification;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@ -19,9 +23,13 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Map;
/**
* Controller
@ -37,6 +45,8 @@ public class PayNotifyController {
@Autowired
private H5OrderService h5OrderService;
@Autowired
private AftersaleService aftersaleService;
private final SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
@ -91,4 +101,43 @@ public class PayNotifyController {
}
@ApiOperation(value = "微信退款回调")
@PostMapping("/weChatRefundNotify")
public void weChatRefundNotify(HttpServletRequest request) throws IOException {
log.info("收到了微信支付退款回调");
// 从请求头中获取信息
String timestamp = request.getHeader("Wechatpay-Timestamp");
String nonce = request.getHeader("Wechatpay-Nonce");
String signature = request.getHeader("Wechatpay-Signature");
String singType = request.getHeader("Wechatpay-Signature-Type");
String wechatPayCertificateSerialNumber = request.getHeader("Wechatpay-Serial");
// 拿到请求体body
StringBuilder requestBody = new StringBuilder();
String line;
BufferedReader reader;
reader = request.getReader();
while (null != (line = reader.readLine())) {
requestBody.append(line);
}
// 构造 RequestParam
RequestParam requestParam = new RequestParam.Builder()
.serialNumber(wechatPayCertificateSerialNumber)
.nonce(nonce)
.signature(signature)
.timestamp(timestamp)
.body(requestBody.toString())
.build();
log.info("【requestParam】" + JSONObject.toJSON(requestParam));
//初始化了 RSAAutoCertificateConfig
Config config = WechatPayConfig.getInstance();
// 初始化解析器 NotificationParser
NotificationParser parser = new NotificationParser((NotificationConfig) config);
//获取退款回调的信息
RefundNotification refundInfo = parser.parse(requestParam, RefundNotification.class);
aftersaleService.refundOrderExc(refundInfo);
}
}

@ -0,0 +1,30 @@
package com.cyl.h5.domain.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
/**
*
* @author Jinxin
*
*/
@Data
@ApiModel(value = "发货记录")
public class DeliveryReq {
@ApiModelProperty(value = "订单id", required = true)
@NotNull(message = "订单id不能为空")
private Long orderId;
@ApiModelProperty(value = "物流单号", required = true)
@NotBlank(message = "物流单号不能为空")
private String deliverySn;
@ApiModelProperty(value = "快递公司Code", required = true)
@NotBlank(message = "快递公司Code不能为空")
private String deliveryCompanyCode;
}

@ -729,7 +729,7 @@ public class H5OrderService {
* @return
*/
@Transactional
public String applyRefund(ApplyRefundForm applyRefundForm) {
public Order applyRefund(ApplyRefundForm applyRefundForm) {
Order order = orderMapper.selectById(applyRefundForm.getOrderId());
//是否符合售后条件
this.checkIfCanApplyRefund(order);
@ -802,7 +802,7 @@ public class H5OrderService {
if (rows < 1) {
throw new RuntimeException("创建订单操作记录失败");
}
return "售后申请成功";
return order;
}
/**
@ -908,4 +908,8 @@ public class H5OrderService {
vo.setOrderItemList(orderItemConvert.dos2vos(orderItemList));
return vo;
}
public Order selectById(Long orderId) {
return orderMapper.selectById(orderId);
}
}

@ -105,13 +105,14 @@ public class AftersaleController extends BaseController {
@ApiOperation("售后订单操作")
@PostMapping("/dealWith")
public ResponseEntity<String> updateStatus(@RequestBody DealWithAftersaleForm request){
public ResponseEntity<Boolean> updateStatus(@RequestBody DealWithAftersaleForm request){
LoginUser user = SecurityUtils.getLoginUser();
String redisKey = "manager_oms_order_updateOrderStatus_" + user.getUserId();
String redisValue = user.getUserId() + "_" + System.currentTimeMillis();
try {
redisService.lock(redisKey, redisValue, 60);
return ResponseEntity.ok(service.dealWith(request, user));
service.dealWith(request, user.getUserId(), user.getUser().getNickName());
return ResponseEntity.ok(true);
} catch (Exception e) {
log.error("售后订单操作发生异常", e);
throw new RuntimeException(e.getMessage());

@ -74,4 +74,12 @@ public class Aftersale extends BaseAudit {
@Excel(name = "处理人员")
private String handleMan;
@ApiModelProperty("退款快递公司")
@Excel(name = "退款快递公司")
private String refundWpCode;
@ApiModelProperty("退货快递号")
@Excel(name = "退货快递号")
private String refundWaybillCode;
}

@ -48,4 +48,5 @@ public class ManagerRefundOrderDetailVO {
private BigDecimal totalAmount;
@ApiModelProperty("应付金额(实际支付金额)")
private BigDecimal payAmount;
}

@ -1,4 +1,5 @@
package com.cyl.manager.oms.domain.vo;
import com.ruoyi.common.annotation.Excel;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@ -77,4 +78,9 @@ import java.util.List;
private String handleMan;
private String mark;
private String refundWpCode;
@ApiModelProperty("退货快递号")
private String refundWaybillCode;
}

@ -43,4 +43,8 @@ public class RefundInfoVO {
private String logistics;
@ApiModelProperty("所有物流信息 JSON格式")
private String allLogistics;
private String refundWpCode;
@ApiModelProperty("退货快递号")
private String refundWaybillCode;
}

@ -1,46 +1,54 @@
package com.cyl.manager.oms.service;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.cyl.manager.act.service.MemberCouponService;
import com.cyl.manager.oms.convert.OrderOperateHistoryConvert;
import com.cyl.manager.oms.domain.entity.Order;
import com.cyl.manager.oms.domain.entity.OrderItem;
import com.cyl.manager.oms.domain.entity.OrderOperateHistory;
import com.cyl.manager.oms.mapper.OrderItemMapper;
import com.cyl.manager.oms.mapper.OrderMapper;
import com.cyl.manager.oms.mapper.OrderOperateHistoryMapper;
import com.cyl.manager.oms.domain.entity.*;
import com.cyl.manager.oms.mapper.*;
import com.cyl.manager.oms.domain.form.DealWithAftersaleForm;
import com.cyl.manager.oms.domain.form.ManagerAftersaleOrderForm;
import com.cyl.manager.oms.domain.vo.*;
import com.cyl.manager.pms.mapper.SkuMapper;
import com.cyl.manager.ums.domain.entity.Member;
import com.cyl.manager.ums.domain.entity.MemberWechat;
import com.cyl.manager.ums.mapper.MemberMapper;
import com.cyl.manager.ums.mapper.MemberWechatMapper;
import com.cyl.wechat.WechatPayService;
import com.github.pagehelper.PageHelper;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.enums.AftersaleStatus;
import com.ruoyi.common.enums.OrderRefundStatus;
import com.wechat.pay.java.service.refund.model.Refund;
import com.wechat.pay.java.service.refund.model.RefundNotification;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import com.cyl.manager.oms.mapper.AftersaleMapper;
import com.cyl.manager.oms.domain.entity.Aftersale;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
/**
* Service
*
*
* @author zcc
*/
@Service
@Slf4j
public class AftersaleService {
@Autowired
private AftersaleMapper aftersaleMapper;
@ -61,6 +69,16 @@ public class AftersaleService {
private OrderOperateHistoryConvert historyConvert;
@Autowired
private SkuMapper skuMapper;
@Autowired
private MemberCouponService memberCouponService;
@Autowired
private WechatPaymentHistoryMapper wechatPaymentHistoryMapper;
@Autowired
private MemberWechatMapper memberWechatMapper;
@Autowired(required = false)
private WechatPayService wechatPayService;
@Autowired
private OrderOperateHistoryMapper operateHistoryMapper;
/**
*
@ -70,7 +88,7 @@ public class AftersaleService {
*/
public ManagerRefundOrderDetailVO selectById(Long id) {
Order order = orderMapper.selectById(id);
if (order == null){
if (order == null) {
throw new RuntimeException("无该订单信息");
}
ManagerRefundOrderDetailVO result = new ManagerRefundOrderDetailVO();
@ -129,6 +147,9 @@ public class AftersaleService {
refundInfo.setDescription(aftersale.getDescription());
refundInfo.setProofPics(aftersale.getProofPics());
refundInfo.setRefundStatus(aftersale.getStatus());
refundInfo.setRefundWpCode(aftersale.getRefundWpCode());
refundInfo.setRefundWaybillCode(aftersale.getRefundWaybillCode());
refundInfo.setRefundStatus(aftersale.getStatus());
refundInfo.setRemark(aftersale.getHandleNote());
refundInfoList.add(refundInfo);
});
@ -140,18 +161,18 @@ public class AftersaleService {
*
*
* @param query
* @param page
* @param page
* @return
*/
public List<ManagerRefundOrderVO> selectList(ManagerAftersaleOrderForm query, Pageable page) {
if (page != null) {
PageHelper.startPage(page.getPageNumber() + 1, page.getPageSize());
}
if (StrUtil.isNotBlank(query.getOrderSn()) && query.getOrderSn().length() > 7){
if (StrUtil.isNotBlank(query.getOrderSn()) && query.getOrderSn().length() > 7) {
query.setOrderSn(query.getOrderSn().substring(7));
}
List<ManagerRefundOrderVO> managerRefundOrderVOS = aftersaleMapper.selectManagerRefundOrder(query);
if (CollectionUtil.isEmpty(managerRefundOrderVOS)){
if (CollectionUtil.isEmpty(managerRefundOrderVOS)) {
return managerRefundOrderVOS;
}
Set<Long> idSet = managerRefundOrderVOS.stream().map(ManagerRefundOrderVO::getOrderId).collect(Collectors.toSet());
@ -216,35 +237,40 @@ public class AftersaleService {
/**
*
*
* @param request
* @param user
* @param user
* @return
*/
@Transactional
public String dealWith(DealWithAftersaleForm request, LoginUser user) {
@Transactional(rollbackFor = Exception.class)
public void dealWith(DealWithAftersaleForm request, Long userId, String optUserName) {
Order order = orderMapper.selectById(request.getOrderId());
if (order == null){
if (order == null) {
throw new RuntimeException("无该订单");
}
//目前售后类型只有退款,没有退货退款
//所以目前只需要查看是否有待处理的售后单
QueryWrapper<Aftersale> aftersaleQw = new QueryWrapper<>();
aftersaleQw.eq("status", AftersaleStatus.APPLY.getType());
aftersaleQw.eq("order_id", request.getOrderId());
if (request.getOptType() == 3) {
aftersaleQw.eq("status", 1);
} else {
aftersaleQw.eq("status", 0);
}
Aftersale aftersale = aftersaleMapper.selectOne(aftersaleQw);
if (aftersale == null){
if (aftersale == null) {
throw new RuntimeException("没有售后单");
}
//售后状态与售后类型是否对应
boolean ifAgree = Constants.OptType.AGREE.equals(request.getOptType());
boolean ifRefuse = Constants.OptType.REFUSE.equals(request.getOptType());
if (ifAgree || ifRefuse){
if (!AftersaleStatus.APPLY.getType().equals(aftersale.getStatus())){
throw new RuntimeException("订单状态有误,请刷新后重试");
if (Constants.OptType.AGREE.equals(request.getOptType()) || Constants.OptType.REFUSE.equals(request.getOptType())) {
if (!AftersaleStatus.APPLY.getType().equals(aftersale.getStatus())) {
throw new RuntimeException("订单状态错误,请刷新页面后重试!");
}
} else {
if (!AftersaleStatus.WAIT.getType().equals(aftersale.getStatus())) {
throw new RuntimeException("订单状态错误,请刷新页面后重试!");
}
}
//拒绝则理由必填
if (ifRefuse && StrUtil.isBlank(request.getRemark())){
if (Constants.OptType.REFUSE.equals(request.getOptType()) && StrUtil.isBlank(request.getRemark())) {
throw new RuntimeException("请填写拒绝理由");
}
LocalDateTime optDate = LocalDateTime.now();
@ -254,55 +280,177 @@ public class AftersaleService {
optHistory.setOrderSn(order.getOrderSn());
optHistory.setOperateMan("后台管理员");
optHistory.setCreateTime(optDate);
optHistory.setCreateBy(user.getUserId());
optHistory.setUpdateBy(user.getUserId());
optHistory.setCreateBy(userId);
optHistory.setUpdateBy(userId);
optHistory.setUpdateTime(optDate);
//封装售后wrapper
UpdateWrapper<Aftersale> aftersaleWrapper = new UpdateWrapper<>();
aftersaleWrapper.eq("order_id", request.getOrderId());
aftersaleWrapper.eq("status", AftersaleStatus.APPLY.getType());
aftersaleWrapper.set("handle_man", user.getUser().getNickName());
aftersaleWrapper.set("handle_man", optUserName);
aftersaleWrapper.set("update_time", optDate);
aftersaleWrapper.set("handle_time", optDate);
aftersaleWrapper.set("update_by", user.getUserId());
aftersaleWrapper.set("update_by", userId);
//封装订单wrapper
UpdateWrapper<Order> orderWrapper = new UpdateWrapper<>();
orderWrapper.eq("id", request.getOrderId());
orderWrapper.set("update_time", optDate);
orderWrapper.set("update_by", user.getUserId());
orderWrapper.set("update_by", userId);
//更新订单、售后单,创建操作记录
if (ifRefuse){
if (request.getOptType().equals(Constants.OptType.REFUSE)) {
aftersaleWrapper.set("status", AftersaleStatus.REJECT.getType());
aftersaleWrapper.set("handle_note", request.getRemark());
orderWrapper.set("aftersale_status", OrderRefundStatus.NO_REFUND.getType());
optHistory.setOrderStatus(14);
}else if (ifAgree){
//如果是未发货的情况下,直接增加库存
if (order.getStatus() == 1) {
OrderItem orderItem = orderItemMapper.selectOne(new QueryWrapper<OrderItem>().eq("order_id", order.getId()));
skuMapper.updateStockById(orderItem.getSkuId(),LocalDateTime.now(),-1*orderItem.getQuantity());
//todo 微信直接退款
aftersaleWrapper.set("status", AftersaleStatus.SUCCESS.getType());
orderWrapper.set("aftersale_status", OrderRefundStatus.SUCCESS.getType());
} else {
aftersaleWrapper.set("status", AftersaleStatus.WAIT.getType());
orderWrapper.set("aftersale_status", OrderRefundStatus.WAIT.getType());
}
} else if (request.getOptType().equals(Constants.OptType.AGREE)) {
aftersaleWrapper.set("status", AftersaleStatus.WAIT.getType());
orderWrapper.set("aftersale_status", Objects.equals(aftersale.getType(), 1) ? 3 : 2);
optHistory.setOrderStatus(12);
} else {
//如果是退货退款 order身上的售后状态应该是保持不变的 仅退款的话就进入退款了
orderWrapper.set("aftersale_status", 3);
int row = orderMapper.update(null, orderWrapper);
if (row != 1) {
throw new RuntimeException("修改订单状态失败");
}
}
int rows = aftersaleMapper.update(null, aftersaleWrapper);
if (rows < 1){
throw new RuntimeException("更新售后单失败");
}
// if (rows < 1) {
// throw new RuntimeException("更新售后单失败");
// }
rows = orderMapper.update(null, orderWrapper);
if (rows < 1){
if (rows < 1) {
throw new RuntimeException("更新订单失败");
}
rows = orderOperateHistoryMapper.insert(optHistory);
if (rows < 1){
if (rows < 1) {
throw new RuntimeException("创建订单操作记录失败");
}
return "操作成功";
// 是否需要发起退款
if ((request.getOptType() == Constants.OptType.GIVING || (request.getOptType() == Constants.OptType.AGREE && aftersale.getType() == 1))) {
tradeRefund(aftersale, order, optDate, userId);
}
}
public void tradeRefund(Aftersale returnApply, Order order, LocalDateTime optDate, Long userId) {
//查一下微信订单
QueryWrapper<WechatPaymentHistory> qw = new QueryWrapper<>();
qw.eq("order_id", order.getPayId()).eq("op_type", 1);
WechatPaymentHistory history = wechatPaymentHistoryMapper.selectOne(qw);
//查用户的微信信息
QueryWrapper<MemberWechat> wechatQw = new QueryWrapper<>();
wechatQw.eq("member_id", order.getMemberId());
MemberWechat memberWechat = memberWechatMapper.selectOne(wechatQw);
//查订单item
QueryWrapper<OrderItem> itemQw = new QueryWrapper<>();
itemQw.eq("order_id", order.getId());
OrderItem orderItem = orderItemMapper.selectOne(itemQw);
//开始退款
Refund wechatResponse = wechatPayService.refundPay(returnApply.getId() + "",
order.getPayId() + "",
"https://mall.younigou.net/api/no-auth/wechat/weChatRefundNotify",
returnApply.getReturnAmount().multiply(new BigDecimal("100")).longValue(),
history.getMoney().multiply(new BigDecimal("100")).longValue(), returnApply.getReason());
log.info("发起微信退款返回信息,tradeRefund:{}", JSONObject.toJSONString(wechatResponse == null ? "" : wechatResponse));
if (wechatResponse != null && Arrays.asList("PROCESSING", "SUCCESS").contains(wechatResponse.getStatus().name())) {
qw = new QueryWrapper<>();
qw.eq("order_id", order.getId()).eq("op_type", 3);
WechatPaymentHistory refundHistory = wechatPaymentHistoryMapper.selectOne(qw);
if (refundHistory == null) {
WechatPaymentHistory wechatPaymentHistory = new WechatPaymentHistory();
wechatPaymentHistory.setPaymentId(wechatResponse.getRefundId());
wechatPaymentHistory.setMemberId(order.getMemberId());
wechatPaymentHistory.setOpenid(memberWechat.getOpenid());
wechatPaymentHistory.setTitle(orderItem.getProductName());
wechatPaymentHistory.setOrderId(order.getId());
wechatPaymentHistory.setMoney(returnApply.getReturnAmount().multiply(new BigDecimal("100")));
wechatPaymentHistory.setOpType(3);
wechatPaymentHistory.setPaymentStatus(0);
wechatPaymentHistory.setResponseBody(JSON.toJSONString(wechatResponse));
wechatPaymentHistory.setCreateTime(optDate);
wechatPaymentHistory.setUpdateTime(optDate);
wechatPaymentHistory.setCreateBy(userId);
wechatPaymentHistory.setUpdateBy(userId);
wechatPaymentHistoryMapper.insert(wechatPaymentHistory);
} else {
UpdateWrapper<WechatPaymentHistory> updateWrapper = new UpdateWrapper<>();
updateWrapper.eq("id", refundHistory.getId())
.set("payment_id", wechatResponse.getRefundId()).set("update_time", optDate);
wechatPaymentHistoryMapper.update(null, updateWrapper);
}
}
}
/**
* 退MQ
*
* @param weChatRefundNotify
*/
@Transactional
public void refundOrderExc(RefundNotification weChatRefundNotify) {
log.info("收到订单回调MQ" + JSONObject.toJSONString(weChatRefundNotify));
if ("PROCESSING".equals(weChatRefundNotify.getRefundStatus().name())) {
return;
}
//查一下微信订单
QueryWrapper<WechatPaymentHistory> qw = new QueryWrapper<>();
qw.eq("payment_id", weChatRefundNotify.getRefundId()).eq("op_type", 3);
WechatPaymentHistory history = wechatPaymentHistoryMapper.selectOne(qw);
if (history == null) {
log.info("未找到退款单");
throw new RuntimeException();
}
LocalDateTime optDate = LocalDateTime.now();
QueryWrapper<Order> orderQw = new QueryWrapper<>();
orderQw.eq("id", history.getOrderId());
Order order = orderMapper.selectOne(orderQw);
if (order.getStatus() == OrderRefundStatus.SUCCESS.getType()) {
log.info("订单已经是退款成功状态");
throw new RuntimeException();
}
QueryWrapper<Aftersale> aftersaleQw = new QueryWrapper<>();
aftersaleQw.eq("order_id", history.getOrderId()).eq("status", AftersaleStatus.WAIT.getType());
if ("SUCCESS".equals(weChatRefundNotify.getRefundStatus().name())) {
//更改订单表
UpdateWrapper<Order> orderUpdateWrapper = new UpdateWrapper<>();
orderUpdateWrapper.eq("id", history.getOrderId())
.set("aftersale_status", OrderRefundStatus.SUCCESS.getType());
orderMapper.update(null, orderUpdateWrapper);
//更改 售后表
UpdateWrapper<Aftersale> aftersaleWrapper = new UpdateWrapper<>();
aftersaleWrapper.eq("order_id", history.getOrderId()).set("status", AftersaleStatus.SUCCESS.getType());
aftersaleMapper.update(null, aftersaleWrapper);
//更改 微信表
UpdateWrapper<WechatPaymentHistory> paymentWrapper = new UpdateWrapper<>();
paymentWrapper.eq("payment_id", weChatRefundNotify.getRefundId()).eq("op_type", 3)
.set("payment_status", 1);
wechatPaymentHistoryMapper.update(null, paymentWrapper);
OrderOperateHistory optHistory = new OrderOperateHistory();
optHistory.setOrderId(order.getId());
optHistory.setOperateMan("系统");
optHistory.setCreateTime(optDate);
optHistory.setCreateBy(order.getMemberId());
optHistory.setUpdateBy(order.getMemberId());
optHistory.setUpdateTime(optDate);
optHistory.setOrderStatus(13);
operateHistoryMapper.insert(optHistory);
// 回滚商品和sku销量
OrderItem orderItem = orderItemMapper.selectOne(new QueryWrapper<OrderItem>().eq("order_id", order.getId()));
skuMapper.updateStockById(orderItem.getSkuId(), LocalDateTime.now(), -1 * orderItem.getQuantity());
//退还优惠券
if (order.getMemberCouponId() != null) {
memberCouponService.backCoupon(Arrays.asList(order.getMemberCouponId()));
}
} else {
//更改订单表
UpdateWrapper<Order> orderUpdateWrapper = new UpdateWrapper<>();
orderUpdateWrapper.eq("id", history.getOrderId())
.set("aftersale_status", OrderRefundStatus.FAIL.getType());
orderMapper.update(null, orderUpdateWrapper);
}
}
public List<OrderOperateHistoryVO> log(Long orderId) {
@ -313,4 +461,11 @@ public class AftersaleService {
List<OrderOperateHistory> historyList = orderOperateHistoryMapper.selectList(wrapper);
return historyConvert.dos2vos(historyList);
}
public Aftersale queryAfterSale(Long orderId) {
QueryWrapper<Aftersale> itemQw = new QueryWrapper<>();
itemQw.eq("order_id",orderId);
itemQw.in("status",Arrays.asList(AftersaleStatus.APPLY.getType(),AftersaleStatus.WAIT.getType()));
return aftersaleMapper.selectOne(itemQw);
}
}

@ -5,6 +5,10 @@ import com.wechat.pay.java.service.payments.jsapi.model.Amount;
import com.wechat.pay.java.service.payments.jsapi.model.Payer;
import com.wechat.pay.java.service.payments.jsapi.model.PrepayRequest;
import com.wechat.pay.java.service.payments.jsapi.model.PrepayResponse;
import com.wechat.pay.java.service.refund.RefundService;
import com.wechat.pay.java.service.refund.model.AmountReq;
import com.wechat.pay.java.service.refund.model.CreateRequest;
import com.wechat.pay.java.service.refund.model.Refund;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@ -20,6 +24,9 @@ public class WechatPayService {
@Autowired
private JsapiService service;
@Autowired
private RefundService refundService;
/**
* jsapi
* @param orderNo
@ -45,4 +52,24 @@ public class WechatPayService {
PrepayResponse response = service.prepay(prepayRequest);
return response.getPrepayId();
}
public Refund refundPay(String refundId,String payId,String notifyUrl,Long refundAmount, Long totalAmount,String reason) {
//请求参数
CreateRequest request = new CreateRequest();
request.setReason(reason);
//设置退款金额 根据自己的实际业务自行填写
AmountReq amountReq = new AmountReq();
amountReq.setRefund(refundAmount);
amountReq.setTotal(totalAmount);
amountReq.setCurrency("CNY");
request.setAmount(amountReq);
//支付成功后回调回来的transactionId 按照实际情况填写
request.setOutTradeNo(payId);
//支付成功后回调回来的transactionId 按照实际情况填写
request.setOutRefundNo(refundId);
//退款成功的回调地址
request.setNotifyUrl(notifyUrl);
//发起请求,申请退款
return refundService.create(request);
}
}

@ -65,7 +65,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
a.handle_man,
c.nickname nickName,
c.phone_hidden phone,
c.mark
c.mark,
a.refund_wp_code refundWpCode,
a.refund_waybill_code refundWaybillCode
FROM oms_aftersale a
left join ums_member c on a.member_id = c.id
<where>

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save