diff --git a/CoreCms.Net.IServices/Order/ICoreCmsOrderServices.cs b/CoreCms.Net.IServices/Order/ICoreCmsOrderServices.cs
index 5c7cec56..b4f65f82 100644
--- a/CoreCms.Net.IServices/Order/ICoreCmsOrderServices.cs
+++ b/CoreCms.Net.IServices/Order/ICoreCmsOrderServices.cs
@@ -163,6 +163,13 @@ namespace CoreCms.Net.IServices
///
Task CancelOrder(string[] ids, int userId = 0);
+ ///
+ /// 取消订单并退款
+ ///
+ ///
+ ///
+ Task CancelOrderAndRefund(string orderId);
+
///
/// 后端根据订单状态生成不同的操作按钮
diff --git a/CoreCms.Net.Services/Order/CoreCmsOrderServices.cs b/CoreCms.Net.Services/Order/CoreCmsOrderServices.cs
index 9a63a887..269959a1 100644
--- a/CoreCms.Net.Services/Order/CoreCmsOrderServices.cs
+++ b/CoreCms.Net.Services/Order/CoreCmsOrderServices.cs
@@ -31,13 +31,17 @@ using CoreCms.Net.Model.ViewModels.UI;
using CoreCms.Net.Utility.Extensions;
using CoreCms.Net.Utility.Helper;
using CoreCms.Net.WeChat.Service.HttpClients;
+using EnumsNET;
using Microsoft.AspNetCore.Http;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
+using Org.BouncyCastle.Crypto;
using SKIT.FlurlHttpClient.Wechat.Api;
using SKIT.FlurlHttpClient.Wechat.Api.Models;
using SqlSugar;
using Yitter.IdGenerator;
+using static CoreCms.Net.Configuration.GlobalEnumVars;
+using static SKIT.FlurlHttpClient.Wechat.Api.Models.ChannelsECAftersaleGetAftersaleOrderResponse.Types.AftersaleOrder.Types;
namespace CoreCms.Net.Services
@@ -62,6 +66,7 @@ namespace CoreCms.Net.Services
private readonly ICoreCmsLogisticsServices _logisticsServices;
private readonly ICoreCmsInvoiceServices _invoiceServices;
private readonly ICoreCmsBillAftersalesServices _billAftersalesServices;
+ private readonly ICoreCmsBillAftersalesItemServices _billAftersalesItemServices;
private readonly ICoreCmsOrderItemServices _orderItemServices;
private readonly ICoreCmsInvoiceRecordServices _invoiceRecordServices;
private readonly ICoreCmsOrderLogServices _orderLogServices;
@@ -107,7 +112,7 @@ namespace CoreCms.Net.Services
, ICoreCmsPaymentsServices paymentsServices
, ICoreCmsBillRefundServices billRefundServices
, ICoreCmsBillLadingServices billLadingServices
- , ICoreCmsBillReshipServices billReshipServices, ICoreCmsMessageCenterServices messageCenterServices, ICoreCmsGoodsCommentServices goodsCommentServices, ISysTaskLogServices taskLogServices, ICoreCmsPromotionRecordServices promotionRecordServices, IRedisOperationRepository redisOperationRepository, ICoreCmsUserWeChatInfoServices userWeChatInfoServices, IWeChatApiHttpClientFactory weChatApiHttpClientFactory, IUnitOfWork unitOfWork)
+ , ICoreCmsBillReshipServices billReshipServices, ICoreCmsMessageCenterServices messageCenterServices, ICoreCmsGoodsCommentServices goodsCommentServices, ISysTaskLogServices taskLogServices, ICoreCmsPromotionRecordServices promotionRecordServices, IRedisOperationRepository redisOperationRepository, ICoreCmsUserWeChatInfoServices userWeChatInfoServices, IWeChatApiHttpClientFactory weChatApiHttpClientFactory, IUnitOfWork unitOfWork, ICoreCmsBillAftersalesItemServices billAftersalesItemServices)
{
this._dal = dal;
base.BaseDal = dal;
@@ -144,6 +149,7 @@ namespace CoreCms.Net.Services
_userWeChatInfoServices = userWeChatInfoServices;
_weChatApiHttpClientFactory = weChatApiHttpClientFactory;
_unitOfWork = unitOfWork;
+ _billAftersalesItemServices = billAftersalesItemServices;
}
#region 查询团购秒杀下单数量(获取货品的秒杀团购数据)
@@ -1638,6 +1644,150 @@ namespace CoreCms.Net.Services
}
#endregion
+ ///
+ /// 取消订单并退款
+ ///
+ ///
+ ///
+ public async Task CancelOrderAndRefund(string orderId)
+ {
+ var jm = new WebApiCallBack();
+ //获取订单并确认是否属于已支付并未发货的订单
+ var where = PredicateBuilder.True();
+ where = where.And(p => p.orderId == orderId);
+ where = where.And(p => p.payStatus == (int)GlobalEnumVars.OrderPayStatus.Yes);
+ where = where.And(p => p.status == (int)GlobalEnumVars.OrderStatus.Normal);
+ where = where.And(p => p.shipStatus == (int)GlobalEnumVars.OrderShipStatus.No);
+
+ var orderInfo = await _dal.QueryByClauseAsync(where);
+ if (orderInfo == null)
+ {
+ jm.status = false;
+ jm.msg = "不满足条件,必须是已支付未发货订单。";
+ return jm;
+ }
+
+ //判断是否存在售后单据。
+ var haveAs = await _billAftersalesServices.ExistsAsync(p => p.orderId == orderId && p.userId == orderInfo.userId);
+ if (haveAs)
+ {
+ jm.msg = "存在售后单,暂不支持直接取消。";
+ jm.status = false;
+ return jm;
+ }
+
+ orderInfo.items = await _orderItemServices.QueryListByClauseAsync(p => p.orderId == orderInfo.orderId);
+ AfterSalesVal(orderInfo, 0);
+
+ if (orderInfo.addAftersalesStatus == false)
+ {
+ jm.msg = GlobalErrorCodeVars.Code13200;
+ jm.code = 13200;
+ return jm;
+ }
+
+ //构建售后单
+ //生成售后单号
+ var afterSalesId = CommonHelper.GetSerialNumberType((int)GlobalEnumVars.SerialNumberType.售后单编号);
+
+ var billAftersales = new CoreCmsBillAftersales();
+ billAftersales.aftersalesId = afterSalesId;
+ billAftersales.orderId = orderId;
+ billAftersales.userId = orderInfo.userId;
+ billAftersales.type = 1;
+ billAftersales.refundAmount = orderInfo.payedAmount;
+ billAftersales.reason = "后台主动发起取消订单,并走售后流程生成退款单。";
+ billAftersales.status = (int)GlobalEnumVars.BillAftersalesStatus.Success;
+ billAftersales.createTime = DateTime.Now;
+ //保存主表数据
+ await _billAftersalesServices.InsertAsync(billAftersales);
+ //保存子项目
+ var aftersalesItemData = orderInfo.items.Select(orderItem => new CoreCmsBillAftersalesItem
+ {
+ aftersalesId = afterSalesId,
+ orderItemsId = orderItem.id,
+ goodsId = orderItem.goodsId,
+ productId = orderItem.productId,
+ sn = orderItem.sn,
+ bn = orderItem.bn,
+ name = orderItem.name,
+ imageUrl = orderItem.imageUrl,
+ nums = orderItem.nums,
+ addon = orderItem.addon,
+ createTime = DateTime.Now
+ })
+ .ToList();
+ await _billAftersalesItemServices.InsertAsync(aftersalesItemData);
+ //构建退款单
+ if (billAftersales.refundAmount > 0)
+ {
+ var billRefund = new CoreCmsBillRefund();
+ billRefund.refundId = CommonHelper.GetSerialNumberType((int)GlobalEnumVars.SerialNumberType.退款单编号);
+ billRefund.aftersalesId = afterSalesId;
+ billRefund.money = billAftersales.refundAmount;
+ billRefund.userId = billAftersales.userId;
+ billRefund.sourceId = billAftersales.orderId;
+ billRefund.type = orderInfo.orderType;
+
+ //取支付成功的支付单号
+ var paymentsInfo = await _billPaymentsServices.QueryByClauseAsync(p => p.sourceId == billRefund.sourceId && p.type == orderInfo.orderType && p.status == (int)GlobalEnumVars.BillPaymentsStatus.Payed);
+ if (paymentsInfo != null)
+ {
+ billRefund.paymentCode = paymentsInfo.paymentCode;
+ billRefund.tradeNo = paymentsInfo.tradeNo;
+ }
+ billRefund.status = (int)GlobalEnumVars.BillRefundStatus.STATUS_NOREFUND;
+ billRefund.createTime = DateTime.Now;
+
+ await _billRefundServices.InsertAsync(billRefund);
+ }
+
+ //构建订单记录
+ //订单记录
+ var orderLog = new CoreCmsOrderLog
+ {
+ orderId = orderInfo.orderId,
+ userId = orderInfo.userId,
+ type = (int)GlobalEnumVars.OrderLogTypes.LOG_TYPE_CANCEL,
+ msg = "后端操作取消订单并退款",
+ data = JsonConvert.SerializeObject(orderInfo),
+ createTime = DateTime.Now
+ };
+ await _orderLogServices.InsertAsync(orderLog);
+
+ //如果有积分消费退还
+ if (orderInfo.point > 0)
+ {
+ await _userPointLogServices.SetPoint(orderInfo.userId, orderInfo.point, (int)GlobalEnumVars.UserPointSourceTypes.PointCanCelOrder, "后端取消订单:" + orderInfo.orderId + "返还积分");
+ }
+
+ //优惠券返还
+ if (!string.IsNullOrEmpty(orderInfo.coupon))
+ {
+ await _couponServices.CancelReturnCoupon(orderInfo.coupon);
+ }
+
+ //状态修改
+ await _dal.UpdateAsync(
+ p => new CoreCmsOrder()
+ {
+ payStatus = (int)GlobalEnumVars.OrderPayStatus.Refunded,
+ status = (int)GlobalEnumVars.OrderStatus.Cancel,
+ updateTime = DateTime.Now
+ }, p => p.orderId == orderId);
+
+ var orderItems = await _orderItemServices.QueryListByClauseAsync(p => p.orderId == orderId);
+ //更改库存
+ foreach (var item in orderItems)
+ {
+ _goodsServices.ChangeStock(item.productId, GlobalEnumVars.OrderChangeStockType.cancel.ToString(), item.nums);
+ }
+
+ jm.msg = "订单取消成功请前往退款单退款。";
+ return jm;
+ }
+
+
#region 后端根据订单状态生成不同的操作按钮
///
@@ -1669,7 +1819,10 @@ namespace CoreCms.Net.Services
{
html.Append("编辑
");
html.Append("发货
");
-
+ if (shipStatus == (int)GlobalEnumVars.OrderShipStatus.No)
+ {
+ html.Append("取消并退款
");
+ }
if (receiptType == (int)GlobalEnumVars.OrderReceiptType.IntraCityService || receiptType == (int)GlobalEnumVars.OrderReceiptType.SelfDelivery)
{
html.Append("秒发
");
diff --git a/CoreCms.Net.Services/Pay/BalancePayServices.cs b/CoreCms.Net.Services/Pay/BalancePayServices.cs
index 6f90f556..4477a750 100644
--- a/CoreCms.Net.Services/Pay/BalancePayServices.cs
+++ b/CoreCms.Net.Services/Pay/BalancePayServices.cs
@@ -108,7 +108,12 @@ namespace CoreCms.Net.Services
var res = await _userBalanceServices.Change(paymentInfo.userId,
(int)GlobalEnumVars.UserBalanceSourceTypes.Refund, refundInfo.money, paymentInfo.paymentId);
- if (res.status == false) return jm;
+ if (res.status == false)
+ {
+ jm.msg = res.msg;
+ jm.status = false;
+ return jm;
+ }
jm.status = true;
jm.data = res;
jm.msg = "退款成功";
diff --git a/CoreCms.Net.Web.Admin/wwwroot/views/order/orders/index.html b/CoreCms.Net.Web.Admin/wwwroot/views/order/orders/index.html
index 7a9b8251..df9a7543 100644
--- a/CoreCms.Net.Web.Admin/wwwroot/views/order/orders/index.html
+++ b/CoreCms.Net.Web.Admin/wwwroot/views/order/orders/index.html
@@ -525,6 +525,11 @@
var id = $(this).attr('data-deliveryId');
refreshDelivery(id);
},
+ //取消订单并退款
+ cancelOrderAndRefund: function () {
+ var id = $(this).attr('data-id');
+ doCancelOrderAndRefund(id);
+ },
});
//头工具栏事件
@@ -1212,6 +1217,21 @@
});
}
+ //取消订单并退款
+ function doCancelOrderAndRefund(id) {
+ layer.confirm('确认取消订单号:' + id + ' 的订单吗?', {
+ title: '提示', btn: ['确认', '取消'] //按钮
+ }, function () {
+ coreHelper.Post("Api/CoreCmsOrder/CancelOrderAndRefund", { id: id }, function (e) {
+ layer.msg(e.msg, { time: 1300 }, function () {
+ layui.table.reloadData('LAY-app-CoreCmsOrder-tableBox'); //重载表格
+ doreLoadOrderCount();
+ });
+ });
+ });
+ return false;
+ }
+
//完成订单
function doCompleteOrder(id) {
coreHelper.Post("Api/CoreCmsOrder/GetDoHaveAfterSale", { id: id }, function (e) {