@@ -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
/// <summary>
/// 取消订单并退款
/// </summary>
/// <param name="orderId"></param>
/// <returns></returns>
public async Task < WebApiCallBack > CancelOrderAndRefund ( string orderId )
{
var jm = new WebApiCallBack ( ) ;
//获取订单并确认是否属于已支付并未发货的订单
var where = PredicateBuilder . True < CoreCmsOrder > ( ) ;
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 后 端 根 据 订 单 状 态 生 成 不 同 的 操 作 按 钮
/// <summary>
@@ -1669,7 +1819,10 @@ namespace CoreCms.Net.Services
{
html . Append ( "<a class='layui-btn layui-btn-xs edit-order' lay-active='editOrder' data-id='" + orderId + "'>编辑</a><br>" ) ;
html . Append ( "<a class='layui-btn layui-btn-xs ship-order' lay-active='shipOrder' data-id='" + orderId + "'>发货</a><br>" ) ;
if ( shipStatus = = ( int ) GlobalEnumVars . OrderShipStatus . No )
{
html . Append ( "<a class='layui-btn layui-btn-xs layui-btn-danger cancel-order' lay-active='cancelOrderAndRefund' data-id='" + orderId + "'>取消并退款</a><br>" ) ;
}
if ( receiptType = = ( int ) GlobalEnumVars . OrderReceiptType . IntraCityService | | receiptType = = ( int ) GlobalEnumVars . OrderReceiptType . SelfDelivery )
{
html . Append ( "<a class='layui-btn layui-btn-xs layui-btn-normal seconds-ship-order' lay-active='secondsShipOrder' data-id='" + orderId + "'>秒发</a><br>" ) ;