添加项目文件。

This commit is contained in:
JianWeie
2021-12-20 21:27:32 +08:00
parent 747486f5cb
commit 82d825b7a5
3514 changed files with 887941 additions and 0 deletions

View File

@@ -0,0 +1,35 @@
/***********************************************************************
* Project: CoreCms
* ProjectName: 核心内容管理系统
* Web: https://www.corecms.net
* Author: 大灰灰
* Email: jianweie@163.com
* CreateTime: 2021/1/31 21:45:10
* Description: 暂无
***********************************************************************/
using CoreCms.Net.IRepository;
using CoreCms.Net.IRepository.UnitOfWork;
using CoreCms.Net.IServices;
using CoreCms.Net.Model.Entities;
namespace CoreCms.Net.Services
{
/// <summary>
/// 商品图片关联表 接口实现
/// </summary>
public class CoreCmsBillAftersalesImagesServices : BaseServices<CoreCmsBillAftersalesImages>,
ICoreCmsBillAftersalesImagesServices
{
private readonly ICoreCmsBillAftersalesImagesRepository _dal;
private readonly IUnitOfWork _unitOfWork;
public CoreCmsBillAftersalesImagesServices(IUnitOfWork unitOfWork, ICoreCmsBillAftersalesImagesRepository dal)
{
_dal = dal;
BaseDal = dal;
_unitOfWork = unitOfWork;
}
}
}

View File

@@ -0,0 +1,34 @@
/***********************************************************************
* Project: CoreCms
* ProjectName: 核心内容管理系统
* Web: https://www.corecms.net
* Author: 大灰灰
* Email: jianweie@163.com
* CreateTime: 2021/1/31 21:45:10
* Description: 暂无
***********************************************************************/
using CoreCms.Net.IRepository;
using CoreCms.Net.IRepository.UnitOfWork;
using CoreCms.Net.IServices;
using CoreCms.Net.Model.Entities;
namespace CoreCms.Net.Services
{
/// <summary>
/// 售后单明细表 接口实现
/// </summary>
public class CoreCmsBillAftersalesItemServices : BaseServices<CoreCmsBillAftersalesItem>,
ICoreCmsBillAftersalesItemServices
{
private readonly ICoreCmsBillAftersalesItemRepository _dal;
private readonly IUnitOfWork _unitOfWork;
public CoreCmsBillAftersalesItemServices(IUnitOfWork unitOfWork, ICoreCmsBillAftersalesItemRepository dal)
{
_dal = dal;
BaseDal = dal;
_unitOfWork = unitOfWork;
}
}
}

View File

@@ -0,0 +1,787 @@
/***********************************************************************
* Project: CoreCms
* ProjectName: 核心内容管理系统
* Web: https://www.corecms.net
* Author: 大灰灰
* Email: jianweie@163.com
* CreateTime: 2021/1/31 21:45:10
* Description: 暂无
***********************************************************************/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
using CoreCms.Net.Caching.AutoMate.RedisCache;
using CoreCms.Net.Configuration;
using CoreCms.Net.IRepository;
using CoreCms.Net.IRepository.UnitOfWork;
using CoreCms.Net.IServices;
using CoreCms.Net.Loging;
using CoreCms.Net.Model.Entities;
using CoreCms.Net.Model.Entities.Expression;
using CoreCms.Net.Model.ViewModels.Basics;
using CoreCms.Net.Model.ViewModels.QueryMuch;
using CoreCms.Net.Model.ViewModels.UI;
using CoreCms.Net.Model.ViewModels.DTO;
using CoreCms.Net.Utility.Extensions;
using CoreCms.Net.Utility.Helper;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Newtonsoft.Json.Linq;
using SqlSugar;
namespace CoreCms.Net.Services
{
/// <summary>
/// 退货单表 接口实现
/// </summary>
public class CoreCmsBillAftersalesServices : BaseServices<CoreCmsBillAftersales>, ICoreCmsBillAftersalesServices
{
private readonly ICoreCmsBillAftersalesRepository _dal;
private readonly IUnitOfWork _unitOfWork;
private readonly IServiceProvider _serviceProvider;
private readonly ICoreCmsMessageCenterServices _messageCenterServices;
private readonly ICoreCmsUserPointLogServices _userPointLogServices;
private readonly IRedisOperationRepository _redisOperationRepository;
public CoreCmsBillAftersalesServices(IUnitOfWork unitOfWork, ICoreCmsBillAftersalesRepository dal, IServiceProvider serviceProvider, ICoreCmsMessageCenterServices messageCenterServices, ICoreCmsUserPointLogServices userPointLogServices, IRedisOperationRepository redisOperationRepository)
{
this._dal = dal;
base.BaseDal = dal;
_unitOfWork = unitOfWork;
_serviceProvider = serviceProvider;
_messageCenterServices = messageCenterServices;
_userPointLogServices = userPointLogServices;
_redisOperationRepository = redisOperationRepository;
}
#region ======================
/// <summary>
/// 根据订单号查询已经售后的内容
/// </summary>
/// <param name="orderId">订单编号</param>
/// <param name="aftersaleLevel">取售后单的时候售后单的等级0待审核的和审核通过的售后单1未审核的2审核通过的</param>
/// <returns></returns>
public WebApiCallBack OrderToAftersales(string orderId, int aftersaleLevel = 0)
{
var jm = new WebApiCallBack();
List<int> statusInts = new List<int>();
switch (aftersaleLevel)
{
case 0:
statusInts.Add((int)GlobalEnumVars.BillAftersalesStatus.Success);
statusInts.Add((int)GlobalEnumVars.BillAftersalesStatus.WaitAudit);
break;
case 1:
statusInts.Add((int)GlobalEnumVars.BillAftersalesStatus.WaitAudit);
break;
case 2:
statusInts.Add((int)GlobalEnumVars.BillAftersalesStatus.Success);
break;
default:
jm.msg = "aftersale_level值类型不对";
return jm;
}
//算已经退过款的金额,取已经完成的售后单的金额汇总
var where = PredicateBuilder.True<CoreCmsBillAftersales>();
where = where.And(p => p.orderId == orderId && statusInts.Contains(p.status)); //加上待审核状态,这样申请过售后的商品和金额不会再重复申请了
//已经退过款的金额
var refundMoney = base.GetSum(where, p => p.refundAmount);
//算退货商品明细
var list = base.QueryMuch<CoreCmsBillAftersalesItem, CoreCmsBillAftersales, QMAftersalesItems>(
(child, parent) => new object[]
{
JoinType.Inner, child.aftersalesId == parent.aftersalesId
},
(child, parent) => new QMAftersalesItems
{
orderItemsId = child.orderItemsId,
nums = child.nums,
status = parent.status,
type = parent.type
}, (child, parent) => parent.orderId == orderId && statusInts.Contains(parent.status));
var reshipGoods = new Dictionary<int, reshipGoods>();
if (list != null && list.Count > 0)
{
foreach (var item in list)
{
var reshipGoodsItem = new reshipGoods()
{
reshipNums = 0,
reshipedNums = 0
};
reshipGoodsItem.reshipNums += item.nums;
if (item.type == (int)GlobalEnumVars.BillAftersalesIsReceive.Reship)
{
reshipGoodsItem.reshipedNums += item.nums;
}
reshipGoods.Add(item.orderItemsId, reshipGoodsItem);
}
}
var billAftersales = base.QueryListByClause(where);
jm.data = new OrderToAftersalesDto
{
refundMoney = refundMoney,
reshipGoods = reshipGoods,
billAftersales = billAftersales
};
jm.status = true;
jm.msg = jm.status ? GlobalConstVars.GetDataSuccess : GlobalConstVars.GetDataFailure;
return jm;
}
#endregion
#region ============================================
/// <summary>
/// 统计用户的售后数量
/// </summary>
/// <param name="userId"></param>
/// <param name="status"></param>
/// <returns></returns>
public async Task<int> GetUserAfterSalesNum(int userId, int status)
{
var count = await base.GetCountAsync(p => p.userId == userId && p.status == status);
return count;
}
#endregion
#region
/// <summary>
/// 创建售后单
/// </summary>
/// <param name="userId"></param>
/// <param name="orderId">发起售后的订单</param>
/// <param name="type">是否收到退货1未收到退货不会创建退货单2收到退货会创建退货单,只有未发货的商品才能选择未收到货,只有已发货的才能选择已收到货</param>
/// <param name="items">如果是退款退货,退货的明细 以 [[order_item_id=>nums]]的二维数组形式传值</param>
/// <param name="images"></param>
/// <param name="reason">售后理由</param>
/// <param name="refund">退款金额,只在退款退货的时候用,如果是退款,直接就是订单金额</param>
/// <returns></returns>
public async Task<WebApiCallBack> ToAdd(int userId, string orderId, int type, JArray items, string[] images, string reason, decimal refund)
{
var jm = new WebApiCallBack();
//做个简单校验,防止乱传值
if (type != (int)GlobalEnumVars.BillAftersalesIsReceive.Refund && type != (int)GlobalEnumVars.BillAftersalesIsReceive.Reship)
{
jm.msg = GlobalErrorCodeVars.Code10000;
jm.code = 10000;
return jm;
}
using var container = _serviceProvider.CreateScope();
var orderServices = container.ServiceProvider.GetService<ICoreCmsOrderServices>();
var settingServices = container.ServiceProvider.GetService<ICoreCmsSettingServices>();
var imagesServices = container.ServiceProvider.GetService<ICoreCmsBillAftersalesImagesServices>();
var itemServices = container.ServiceProvider.GetService<ICoreCmsBillAftersalesItemServices>();
var result = await orderServices.GetOrderInfoByOrderId(orderId, userId);
if (result.status == false)
{
jm.msg = GlobalErrorCodeVars.Code13101;
jm.code = 13101;
return jm;
}
var orderInfo = new CoreCmsOrder();
orderInfo = result.data as CoreCmsOrder;
if (orderInfo.addAftersalesStatus == false)
{
jm.msg = GlobalErrorCodeVars.Code13200;
jm.code = 13200;
return jm;
}
//生成售后单号
var aftersalesId = CommonHelper.GetSerialNumberType((int)GlobalEnumVars.SerialNumberType.);
//校验订单是否可以进行此售后,并且校验订单价格是否合理
var verifyResult = Verify(type, orderInfo, refund, items);
if (verifyResult.status == false)
{
return verifyResult;
}
jm.otherData = new
{
orderInfo,
items,
verifyResult
};
//判断图片是否大于系统限定
//var allConfigs = await settingServices.GetConfigDictionaries();
if (images.Length > 5)
{
jm.msg = GlobalErrorCodeVars.Code10006;
jm.code = 10006;
return jm;
}
var billAftersales = new CoreCmsBillAftersales();
billAftersales.aftersalesId = aftersalesId;
billAftersales.orderId = orderId;
billAftersales.userId = userId;
billAftersales.type = type;
billAftersales.refundAmount = refund;
billAftersales.reason = reason;
billAftersales.status = (int)GlobalEnumVars.BillAftersalesStatus.WaitAudit;
billAftersales.createTime = DateTime.Now;
//保存主表数据
await _dal.InsertAsync(billAftersales);
if (items != null && items.Any())
{
//如果是退货,判断退货明细,数量是否超出可退的数量
var aftersalesItems = formatAftersalesItems(orderInfo, items, aftersalesId);
if (!aftersalesItems.status)
{
return aftersalesItems;
}
//保存售后明细
if (aftersalesItems.data != null)
{
var list = aftersalesItems.data as List<CoreCmsBillAftersalesItem>;
await itemServices.InsertAsync(list);
}
}
//保存图片
if (images.Length > 0)
{
var imagesList = new List<CoreCmsBillAftersalesImages>();
for (int i = 0; i < images.Length; i++)
{
imagesList.Add(new CoreCmsBillAftersalesImages()
{
aftersalesId = aftersalesId,
imageUrl = images[i],
sortId = i
});
}
await imagesServices.InsertAsync(imagesList);
}
//消息模板推送给客户
SmsHelper.SendMessage();
jm.status = true;
jm.data = billAftersales;
return jm;
}
#endregion
#region
/// <summary>
/// 校验是否可以进行售后
/// </summary>
/// <param name="type"></param>
/// <param name="orderInfo"></param>
/// <param name="refund"></param>
/// <param name="items"></param>
/// <returns></returns>
private WebApiCallBack Verify(int type, CoreCmsOrder orderInfo, decimal refund, JArray items)
{
var jm = new WebApiCallBack();
//判断订单是否是可以售后
//只有活动订单才能售后
if (orderInfo.status != (int)GlobalEnumVars.OrderStatus.Normal)
{
jm.msg = GlobalErrorCodeVars.Code13200;
jm.code = 13200;
return jm;
}
//未付款订单和已退款订单不能售后
if (orderInfo.payStatus == (int)GlobalEnumVars.OrderPayStatus.No || orderInfo.payStatus == (int)GlobalEnumVars.OrderPayStatus.Refunded)
{
jm.msg = GlobalErrorCodeVars.Code13203;
jm.code = 13203;
return jm;
}
//如果订单未发货,那么用户不能选择已收到货
if (type == (int)GlobalEnumVars.BillAftersalesIsReceive.Reship && orderInfo.shipStatus == (int)GlobalEnumVars.OrderShipStatus.No)
{
jm.msg = GlobalErrorCodeVars.Code13227;
jm.code = 13227;
return jm;
}
//判断退款金额不能超
if (refund + orderInfo.refunded > orderInfo.payedAmount)
{
jm.msg = GlobalErrorCodeVars.Code13206;
jm.code = 13206;
return jm;
}
//根据是否已收到货和未收到货来判断实际可以退的数量,不能超过最大数量,已收到货的和未收到货的不能一起退,在这里做判断
return verifyNums(type, orderInfo, items);
}
#endregion
#region 退
/// <summary>
/// 判断退货数量是否超标
/// </summary>
/// <param name="type"></param>
/// <param name="orderInfo"></param>
/// <param name="items"></param>
/// <returns></returns>
private WebApiCallBack verifyNums(int type, CoreCmsOrder orderInfo, JArray items)
{
var jm = new WebApiCallBack();
foreach (var item in items)
{
var id = ((JObject)item)["id"].ObjectToInt();
var nums = ((JObject)item)["nums"].ObjectToInt();
foreach (var orderItem in orderInfo.items)
{
if (orderItem.id == id)
{
if (type == (int)GlobalEnumVars.BillAftersalesIsReceive.Refund)
{
var n = orderItem.nums - orderItem.sendNums - (orderItem.reshipNums - orderItem.reshipedNums);
if (n < nums)
{
jm.msg = orderItem.name + orderItem.addon + ",未发货商品,最多能退" + n + "个";
return jm;
}
}
else
{
var n = orderItem.sendNums - orderItem.reshipedNums;
if (n < nums)
{
jm.msg = orderItem.name + orderItem.addon + "已发货商品,最多能退" + n + "个";
return jm;
}
}
}
}
}
jm.status = true;
return jm;
}
#endregion
#region 退
/// <summary>
/// 根据退货的明细,生成售后单明细表的数据
/// </summary>
/// <param name="orderInfo">订单的详细数据</param>
/// <param name="items">前台选择的退货商品信息</param>
/// <param name="aftersalesId">将要保存的售后单的单号</param>
/// <returns></returns>
private WebApiCallBack formatAftersalesItems(CoreCmsOrder orderInfo, JArray items, string aftersalesId)
{
var jm = new WebApiCallBack();
var data = new List<CoreCmsBillAftersalesItem>();
foreach (var item in items)
{
var id = ((JObject)item)["id"].ObjectToInt();
var nums = ((JObject)item)["nums"].ObjectToInt();
if (nums <= 0)
{
continue;
}
foreach (var orderItem in orderInfo.items)
{
if (orderItem.id == id)
{
//判断已经退过的加上本次退的,是否超过了购买的数量,具体取nums购买数量还是取sendnums(已发货数量),以后再说吧。要取购买数量,因为未发货的,也可以退的
if (nums + orderItem.reshipNums > orderItem.nums)
{
jm.msg = GlobalErrorCodeVars.Code13201;
jm.code = 13201;
return jm;
}
var billAftersalesItem = 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 = nums,
addon = orderItem.addon,
createTime = DateTime.Now
};
data.Add(billAftersalesItem);
}
}
}
//判断生成的总记录条数,是否和前端传过来的记录条数对应上,如果没有对应上,就说明退货明细不正确
if (data.Count != items.Count)
{
jm.msg = GlobalErrorCodeVars.Code13202;
jm.data = jm.code = 13202;
return jm;
}
jm.status = true;
jm.data = data;
return jm;
}
#endregion
#region
/// <summary>
/// 根据条件查询分页数据
/// </summary>
/// <param name="predicate">判断集合</param>
/// <param name="orderByType">排序方式</param>
/// <param name="pageIndex">当前页面索引</param>
/// <param name="pageSize">分布大小</param>
/// <param name="orderByExpression"></param>
/// <returns></returns>
public async Task<IPageList<CoreCmsBillAftersales>> QueryPageAsync(Expression<Func<CoreCmsBillAftersales, bool>> predicate,
Expression<Func<CoreCmsBillAftersales, object>> orderByExpression, OrderByType orderByType, int pageIndex = 1,
int pageSize = 20)
{
return await _dal.QueryPageAsync(predicate, orderByExpression, orderByType, pageIndex, pageSize);
}
#endregion
#region
/// <summary>
/// 获取单个数据
/// </summary>
/// <param name="aftersalesId"></param>
/// <param name="userId"></param>
/// <returns></returns>
public async Task<CoreCmsBillAftersales> GetInfo(string aftersalesId, int userId)
{
return await _dal.GetInfo(aftersalesId, userId);
}
#endregion
#region Audit平台审核通过或者审核不通过
/// <summary>
/// 平台审核通过或者审核不通过
/// 如果审核通过了,是退款单的话,自动生成退款单,并做订单完成状态,如果是退货的话,自动生成退款单和退货单,如果
/// </summary>
/// <param name="aftersalesId"></param>
/// <param name="status"></param>
/// <param name="type"></param>
/// <param name="refund"></param>
/// <param name="mark"></param>
/// <param name="items"></param>
/// <returns></returns>
public async Task<WebApiCallBack> Audit(string aftersalesId, int status, int type, decimal refund, string mark,
JArray items)
{
var jm = new WebApiCallBack();
var res = await PreAudit(aftersalesId);
if (!res.status)
{
return jm;
}
var info = res.data as CoreCmsBillAftersales;
var orderInfo = info.order;
//校验订单是否可以进行此售后,并且校验订单价格是否合理
var verifyData = Verify(info.type, orderInfo, refund, items);
if (!verifyData.status && status == (int)GlobalEnumVars.BillAftersalesStatus.Success)
{
return verifyData;
}
//如果订单未发货,那么用户不能选择已收到货
if (type == (int)GlobalEnumVars.BillAftersalesIsReceive.Reship &&
orderInfo.shipStatus == (int)GlobalEnumVars.OrderShipStatus.No)
{
jm.msg = GlobalErrorCodeVars.Code13227;
jm.code = 13227;
return jm;
}
//如果是退货单,必须选择退货明细
if (info.type == (int)GlobalEnumVars.BillAftersalesIsReceive.Reship && items.Count <= 0)
{
jm.msg = GlobalErrorCodeVars.Code13205;
jm.code = 13205;
return jm;
}
//如果是退货,判断退货明细,数量是否超出可退的数量
var billAftersalesItems = new List<CoreCmsBillAftersalesItem>();
if (items.Count > 0)
{
var aftersalesItems = formatAftersalesItems(orderInfo, items, aftersalesId);
if (!aftersalesItems.status)
{
return aftersalesItems;
}
billAftersalesItems = aftersalesItems.data as List<CoreCmsBillAftersalesItem>;
}
//判断退款金额不能超了
if (refund + orderInfo.refunded > orderInfo.payedAmount)
{
jm.msg = GlobalErrorCodeVars.Code13206;
jm.code = 13206;
return jm;
}
using (var container = _serviceProvider.CreateScope())
{
var itemServices = container.ServiceProvider.GetService<ICoreCmsBillAftersalesItemServices>();
var orderServices = container.ServiceProvider.GetService<ICoreCmsOrderServices>();
var refundServices = container.ServiceProvider.GetService<ICoreCmsBillRefundServices>();
var reshipServices = container.ServiceProvider.GetService<ICoreCmsBillReshipServices>();
var goodsServices = container.ServiceProvider.GetService<ICoreCmsGoodsServices>();
var couponServices = container.ServiceProvider.GetService<ICoreCmsCouponServices>();
//更新售后单
await _dal.UpdateAsync(p => new CoreCmsBillAftersales() { status = status, mark = mark, refundAmount = refund, type = type },
p => p.aftersalesId == aftersalesId && p.status == (int)GlobalEnumVars.BillAftersalesStatus.WaitAudit);
//更新售后单明细表,先删除,然后全新插入
await itemServices.DeleteAsync(p => p.aftersalesId == aftersalesId);
if (billAftersalesItems != null && billAftersalesItems.Any())
{
await itemServices.InsertAsync(billAftersalesItems);
}
//审核通过的话有退款的生成退款单根据最新的items生成退货单,并做订单的状态更改
if (status == (int)GlobalEnumVars.BillAftersalesStatus.Success)
{
//如果有退款,生成退款单
if (refund > 0)
{
var refundRes = await refundServices.ToAdd(info.userId, info.orderId,
(int)GlobalEnumVars.BillRefundType.Order, refund, info.aftersalesId);
if (!refundRes.status)
{
return refundRes;
}
}
//如果已经发货了,要退货,生成退货单,让用户吧商品邮回来。
if (info.type == (int)GlobalEnumVars.BillAftersalesIsReceive.Reship && billAftersalesItems != null && billAftersalesItems.Any())
{
var reshipRes = await reshipServices.ToAdd(info.userId, info.orderId, info.aftersalesId,
billAftersalesItems);
if (!reshipRes.status)
{
return reshipRes;
}
}
//更新订单状态
//如果是退款,退完了就变成已退款并且订单类型变成已完成,如果未退完,就是部分退款
if (refund > 0)
{
if (refund + orderInfo.refunded == orderInfo.payedAmount)
{
orderInfo.payStatus = (int)GlobalEnumVars.OrderPayStatus.Refunded;
orderInfo.status = (int)GlobalEnumVars.OrderStatus.Complete;
//返还积分
if (orderInfo.point > 0)
{
await _userPointLogServices.SetPoint(orderInfo.userId, orderInfo.point, (int)GlobalEnumVars.UserPointSourceTypes.PointRefundReturn, "售后退款:" + orderInfo.orderId + "返还积分");
}
//返还优惠券
if (!string.IsNullOrEmpty(orderInfo.coupon))
{
await couponServices.CancelReturnCoupon(orderInfo.coupon);
}
}
else
{
orderInfo.payStatus = (int)GlobalEnumVars.OrderPayStatus.PartialNo;
}
}
//判断货物发完没,如果货已发完了,订单发货就变成已发货,为了判断在有退款的情况下,当
var allDeliveryed = true; //商品该发货状态,默认发货了,为了判断部分发货的情况下,的订单发货状态
var noDeliveryed = true; //是否都没发货,默认都没发货
var allSened = true; //商品退货状态(所有退货,包含已发的退货和未发的退货),默认都退货了,为了判断都退了的话,订单状态变成已完成
foreach (var item in orderInfo.items)
{
if (item.id > 0)
{
foreach (var jToken in items)
{
var tt = (JObject)jToken;
if (tt["id"].ToString() == item.id.ToString())
{
item.reshipNums += tt["nums"].ObjectToInt(0);
}
if (type == (int)GlobalEnumVars.BillAftersalesIsReceive.Reship)
{
item.reshipedNums += tt["nums"].ObjectToInt(0);
}
}
}
//有任何商品发货,都不是未发货状态
if (noDeliveryed && item.sendNums > 0)
{
noDeliveryed = false;
}
if (allDeliveryed && (item.nums - item.sendNums - (item.reshipNums - item.reshipedNums) > 0))
{
//说明该发货的商品没发完
allDeliveryed = false;
}
if (allSened && (item.reshipNums < item.nums))
{
//说明未退完商品
allSened = false;
}
}
if (allDeliveryed && !noDeliveryed)
{
orderInfo.shipStatus = (int)GlobalEnumVars.OrderShipStatus.Yes;
}
if (allSened)
{
orderInfo.status = (int)GlobalEnumVars.OrderStatus.Complete;
}
//未发货的商品库存调整,如果订单未发货或者部分发货,并且用户未收到商品的情况下,需要解冻冻结库存
if ((orderInfo.shipStatus == (int)GlobalEnumVars.OrderShipStatus.No ||
orderInfo.shipStatus == (int)GlobalEnumVars.OrderShipStatus.PartialYes) &&
type == (int)GlobalEnumVars.BillAftersalesIsReceive.Refund &&
(billAftersalesItems != null && billAftersalesItems.Count > 0))
{
//未发货商品解冻库存
foreach (var item in billAftersalesItems)
{
goodsServices.ChangeStock(item.productId, GlobalEnumVars.OrderChangeStockType.refund.ToString(), item.nums);
}
}
//如果订单是已完成,但是订单的未发货商品还有的话,需要解冻库存
if (orderInfo.status == (int)GlobalEnumVars.OrderStatus.Complete)
{
foreach (var item in orderInfo.items)
{
var nums = item.nums - item.sendNums - (item.reshipNums - item.reshipedNums);//还未发货的数量
if (nums > 0)
{
goodsServices.ChangeStock(item.productId, GlobalEnumVars.OrderChangeStockType.refund.ToString(), nums);
}
}
}
//更新状态
await orderServices.UpdateAsync(
p => new CoreCmsOrder() { status = orderInfo.status, payStatus = orderInfo.payStatus },
p => p.orderId == orderInfo.orderId && p.status == (int)GlobalEnumVars.OrderStatus.Normal);
}
//售后单审核过后的事件处理
if (status == (int)GlobalEnumVars.BillAftersalesStatus.Success)
{
//售后审核通过后处理
await _redisOperationRepository.ListLeftPushAsync(RedisMessageQueueKey.AfterSalesReview, aftersalesId);
}
}
orderInfo.addAftersalesStatus = true;
orderInfo.billAftersalesId = aftersalesId;
orderInfo.mark = mark;
//发送售后审核消息
await _messageCenterServices.SendMessage(info.userId, GlobalEnumVars.PlatformMessageTypes.AfterSalesPass.ToString(), JObject.FromObject(orderInfo));
jm.status = true;
return jm;
}
#endregion
#region 12
/// <summary>
/// 后端进行审核的时候前置操作1取出页面的数据2在提交过来的表单的时候进行校验
/// </summary>
/// <param name="aftersalesId"></param>
/// <returns></return>
public async Task<WebApiCallBack> PreAudit(string aftersalesId)
{
var jm = new WebApiCallBack();
using var container = _serviceProvider.CreateScope();
var userServices = container.ServiceProvider.GetService<ICoreCmsUserServices>();
var imagesServices = container.ServiceProvider.GetService<ICoreCmsBillAftersalesImagesServices>();
var itemServices = container.ServiceProvider.GetService<ICoreCmsBillAftersalesItemServices>();
var orderServices = container.ServiceProvider.GetService<ICoreCmsOrderServices>();
var model = await _dal.QueryByIdAsync(aftersalesId);
var userModel = await userServices.QueryByClauseAsync(p => p.id == model.userId);
model.userNickName = userModel != null ? userModel.nickName : "";
model.statusName = EnumHelper.GetEnumDescriptionByValue<GlobalEnumVars.BillAftersalesStatus>(model.status);
model.images = await imagesServices.QueryListByClauseAsync(p => p.aftersalesId == model.aftersalesId);
model.items = await itemServices.QueryListByClauseAsync(p => p.aftersalesId == model.aftersalesId);
//获取订单信息
var orderResult = await orderServices.GetOrderInfoByOrderId(model.orderId, model.userId, 2);
if (orderResult.status)
{
model.order = orderResult.data as CoreCmsOrder;
//订单上的退款金额和数量只包含已经售后的,这里要把当次售后单的商品信息保存到订单
foreach (var orderItem in model.order.items)
{
orderItem.promotionList = string.Empty;
orderItem.atPresentReshipNums = 0;
foreach (var it in model.items)
{
if (orderItem.id == it.orderItemsId)
{
orderItem.atPresentReshipNums = it.nums;
}
}
}
}
jm.status = true;
jm.data = model;
return jm;
}
#endregion
}
}

View File

@@ -0,0 +1,34 @@
/***********************************************************************
* Project: CoreCms
* ProjectName: 核心内容管理系统
* Web: https://www.corecms.net
* Author: 大灰灰
* Email: jianweie@163.com
* CreateTime: 2021/1/31 21:45:10
* Description: 暂无
***********************************************************************/
using CoreCms.Net.IRepository;
using CoreCms.Net.IRepository.UnitOfWork;
using CoreCms.Net.IServices;
using CoreCms.Net.Model.Entities;
namespace CoreCms.Net.Services
{
/// <summary>
/// 发货单详情表 接口实现
/// </summary>
public class CoreCmsBillDeliveryItemServices : BaseServices<CoreCmsBillDeliveryItem>,
ICoreCmsBillDeliveryItemServices
{
private readonly ICoreCmsBillDeliveryItemRepository _dal;
private readonly IUnitOfWork _unitOfWork;
public CoreCmsBillDeliveryItemServices(IUnitOfWork unitOfWork, ICoreCmsBillDeliveryItemRepository dal)
{
_dal = dal;
BaseDal = dal;
_unitOfWork = unitOfWork;
}
}
}

View File

@@ -0,0 +1,540 @@
/***********************************************************************
* Project: CoreCms
* ProjectName: 核心内容管理系统
* Web: https://www.corecms.net
* Author: 大灰灰
* Email: jianweie@163.com
* CreateTime: 2021/1/31 21:45:10
* Description: 暂无
***********************************************************************/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using CoreCms.Net.Caching.AutoMate.RedisCache;
using CoreCms.Net.Configuration;
using CoreCms.Net.IRepository;
using CoreCms.Net.IRepository.UnitOfWork;
using CoreCms.Net.IServices;
using CoreCms.Net.Loging;
using CoreCms.Net.Model.Entities;
using CoreCms.Net.Model.ViewModels.Api;
using CoreCms.Net.Model.ViewModels.UI;
using CoreCms.Net.Model.ViewModels.DTO;
using CoreCms.Net.Utility.Helper;
using Flurl.Http;
using Google.Protobuf.WellKnownTypes;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace CoreCms.Net.Services
{
/// <summary>
/// 发货单表 接口实现
/// </summary>
public class CoreCmsBillDeliveryServices : BaseServices<CoreCmsBillDelivery>, ICoreCmsBillDeliveryServices
{
private readonly ICoreCmsBillDeliveryRepository _dal;
private readonly ICoreCmsStoreServices _storeServices;
private readonly ICoreCmsBillDeliveryItemServices _billDeliveryItemServices;
private readonly ICoreCmsOrderLogServices _orderLogServices;
private readonly ICoreCmsSettingServices _settingServices;
private readonly IUnitOfWork _unitOfWork;
private readonly IServiceProvider _serviceProvider;
private readonly IRedisOperationRepository _redisOperationRepository;
public CoreCmsBillDeliveryServices(
IUnitOfWork unitOfWork,
IServiceProvider serviceProvider
, ICoreCmsBillDeliveryRepository dal
, ICoreCmsStoreServices storeServices
, ICoreCmsBillDeliveryItemServices billDeliveryItemServices
, ICoreCmsOrderLogServices orderLogServices
, ICoreCmsSettingServices settingServices, IRedisOperationRepository redisOperationRepository)
{
this._dal = dal;
base.BaseDal = dal;
_unitOfWork = unitOfWork;
_serviceProvider = serviceProvider;
_storeServices = storeServices;
_billDeliveryItemServices = billDeliveryItemServices;
_orderLogServices = orderLogServices;
_settingServices = settingServices;
_redisOperationRepository = redisOperationRepository;
}
/// <summary>
/// 批量发货,可以支持多个订单合并发货,单个订单拆分发货等。
/// </summary>
/// <param name="orderId">英文逗号分隔的订单号</param>
/// <param name="logiCode">物流公司编码</param>
/// <param name="logiNo">物流单号</param>
/// <param name="items">发货明细</param>
/// <param name="storeId">店铺收货地址</param>
/// <param name="shipName">收货人姓名</param>
/// <param name="shipMobile">收货人电话</param>
/// <param name="shipAreaId">省市区id</param>
/// <param name="shipAddress">收货地址</param>
/// <param name="memo">发货描述</param>
/// <returns></returns>
public async Task<WebApiCallBack> BatchShip(string[] orderId, string logiCode, string logiNo, Dictionary<int, int> items, int storeId = 0, string shipName = "", string shipMobile = "", int shipAreaId = 0, string shipAddress = "", string memo = "")
{
using var container = _serviceProvider.CreateScope();
var jm = new WebApiCallBack();
var orderService = container.ServiceProvider.GetService<ICoreCmsOrderServices>();
var stockServices = container.ServiceProvider.GetService<ICoreCmsStockServices>();
//获取订单详情
var dInfoResult = await orderService.GetOrderShipInfo(orderId);
if (!dInfoResult.status)
{
return dInfoResult;
}
var dInfo = dInfoResult.data as AdminOrderShipResult;
var orders = dInfo.orders;
//校验门店自提和普通订单收货地址是否填写
if (storeId != 0)
{
var storeModel = await _storeServices.QueryByIdAsync(storeId);
if (storeModel == null)
{
jm.msg = GlobalErrorCodeVars.Code10000;
jm.data = 1000;
jm.code = 1000;
return jm;
}
shipName = storeModel.storeName;
shipMobile = storeModel.mobile;
shipAreaId = storeModel.areaId;
shipAddress = storeModel.address;
}
if (string.IsNullOrEmpty(shipName) || string.IsNullOrEmpty(shipMobile) || string.IsNullOrEmpty(shipAddress) || shipAreaId == 0)
{
jm.msg = "收货地址信息不全";
jm.otherData = new
{
shipName,
shipMobile,
shipAddress,
shipAreaId
};
return jm;
}
var billDelivery = new CoreCmsBillDelivery();
billDelivery.orderId = string.Join(",", orderId);
billDelivery.deliveryId = CommonHelper.GetSerialNumberType((int)GlobalEnumVars.SerialNumberType.);
billDelivery.logiCode = logiCode;
billDelivery.logiNo = logiNo;
billDelivery.shipAreaId = shipAreaId;
billDelivery.shipAddress = shipAddress;
billDelivery.shipName = shipName;
billDelivery.shipMobile = shipMobile;
billDelivery.status = (int)GlobalEnumVars.BillDeliveryStatus.Already;
billDelivery.memo = memo;
billDelivery.createTime = DateTime.Now;
//设置发货明细
var bdRel = new List<CoreCmsBillDeliveryItem>();
//校验发货内容
var tNum = 0;
foreach (var item in items)
{
var orderItem = dInfo.items.Find(p => p.productId == item.Key);
if (orderItem == null)
{
//发货的商品不在发货明细里,肯定有问题
jm.msg = GlobalErrorCodeVars.Code10000;
return jm;
}
//判断总发货数量
tNum = tNum + item.Value;
if ((orderItem.nums - orderItem.sendNums - (orderItem.reshipNums - orderItem.reshipedNums)) < item.Value)
{
jm.msg = orderItem.name + "发超了";
return jm;
}
//构建发货单明细
var bdItem = new CoreCmsBillDeliveryItem();
bdItem.deliveryId = billDelivery.deliveryId;
bdItem.productId = orderItem.productId;
bdItem.goodsId = orderItem.goodsId;
bdItem.bn = orderItem.bn;
bdItem.sn = orderItem.sn;
bdItem.weight = orderItem.weight;
bdItem.name = orderItem.name;
bdItem.addon = !string.IsNullOrEmpty(orderItem.addon) ? orderItem.addon : "";
bdItem.nums = item.Value;
bdRel.Add(bdItem);
}
if (tNum < 1)
{
jm.msg = "请至少发生一件商品!";
return jm;
}
//事务处理开始
//插入发货单主体表
await _dal.InsertAsync(billDelivery);
//插入发货单明细表
await _billDeliveryItemServices.InsertAsync(bdRel);
//订单更新发货状态,发送各种消息
foreach (var order in orders)
{
await OrderShip(order, items, billDelivery, storeId);
}
var stock = new CoreCmsStock
{
manager = 0,
id = billDelivery.deliveryId,
createTime = DateTime.Now,
type = (int)GlobalEnumVars.StockType.DeliverGoods,
memo = "订单发货操作,发货单号:" + billDelivery.deliveryId
};
await stockServices.InsertAsync(stock);
jm.status = true;
jm.msg = "发货成功";
return jm;
}
/// <summary>
/// 发货,单个订单发货
/// </summary>
/// <param name="orderId">英文逗号分隔的订单号</param>
/// <param name="logiCode">物流公司编码</param>
/// <param name="logiNo">物流单号</param>
/// <param name="items">发货明细</param>
/// <param name="storeId">店铺收货地址</param>
/// <param name="shipName">收货人姓名</param>
/// <param name="shipMobile">收货人电话</param>
/// <param name="shipAreaId">省市区id</param>
/// <param name="shipAddress">收货地址</param>
/// <param name="memo">发货描述</param>
/// <returns></returns>
public async Task<WebApiCallBack> Ship(string orderId, string logiCode, string logiNo, Dictionary<int, int> items, int storeId = 0, string shipName = "", string shipMobile = "", int shipAreaId = 0, string shipAddress = "", string memo = "")
{
using var container = _serviceProvider.CreateScope();
var jm = new WebApiCallBack();
var orderService = container.ServiceProvider.GetService<ICoreCmsOrderServices>();
var stockServices = container.ServiceProvider.GetService<ICoreCmsStockServices>();
//获取订单详情
var dInfoResult = await orderService.GetOrderShipInfo(orderId);
if (!dInfoResult.status)
{
return dInfoResult;
}
var dInfo = dInfoResult.data as AdminOrderShipOneResult;
var orderInfo = dInfo.orderInfo;
//校验门店自提和普通订单收货地址是否填写
if (storeId != 0)
{
var storeModel = await _storeServices.QueryByIdAsync(storeId);
if (storeModel == null)
{
jm.msg = GlobalErrorCodeVars.Code10000;
jm.data = 1000;
jm.code = 1000;
return jm;
}
shipName = storeModel.storeName;
shipMobile = storeModel.mobile;
shipAreaId = storeModel.areaId;
shipAddress = storeModel.address;
}
if (string.IsNullOrEmpty(shipName) || string.IsNullOrEmpty(shipMobile) || string.IsNullOrEmpty(shipAddress) || shipAreaId == 0)
{
jm.msg = "收货地址信息不全";
jm.otherData = new
{
shipName,
shipMobile,
shipAddress,
shipAreaId
};
return jm;
}
var billDelivery = new CoreCmsBillDelivery();
billDelivery.orderId = string.Join(",", orderId);
billDelivery.deliveryId = CommonHelper.GetSerialNumberType((int)GlobalEnumVars.SerialNumberType.);
billDelivery.logiCode = logiCode;
billDelivery.logiNo = logiNo;
billDelivery.shipAreaId = shipAreaId;
billDelivery.shipAddress = shipAddress;
billDelivery.shipName = shipName;
billDelivery.shipMobile = shipMobile;
billDelivery.status = (int)GlobalEnumVars.BillDeliveryStatus.Already;
billDelivery.memo = memo;
billDelivery.createTime = DateTime.Now;
//设置发货明细
var bdRel = new List<CoreCmsBillDeliveryItem>();
//校验发货内容
var tNum = 0;
foreach (var item in items)
{
var orderItem = dInfo.items.Find(p => p.productId == item.Key);
if (orderItem == null)
{
//发货的商品不在发货明细里,肯定有问题
jm.msg = GlobalErrorCodeVars.Code10000;
return jm;
}
//判断总发货数量
tNum = tNum + item.Value;
if ((orderItem.nums - orderItem.sendNums - (orderItem.reshipNums - orderItem.reshipedNums)) < item.Value)
{
jm.msg = orderItem.name + "发超了";
return jm;
}
//构建发货单明细
var bdItem = new CoreCmsBillDeliveryItem();
bdItem.deliveryId = billDelivery.deliveryId;
bdItem.productId = orderItem.productId;
bdItem.goodsId = orderItem.goodsId;
bdItem.bn = orderItem.bn;
bdItem.sn = orderItem.sn;
bdItem.weight = orderItem.weight;
bdItem.name = orderItem.name;
bdItem.addon = !string.IsNullOrEmpty(orderItem.addon) ? orderItem.addon : "";
bdItem.nums = item.Value;
bdRel.Add(bdItem);
}
if (tNum < 1)
{
jm.msg = "请至少发生一件商品!";
return jm;
}
//事务处理开始
//插入发货单主体表
await _dal.InsertAsync(billDelivery);
//插入发货单明细表
await _billDeliveryItemServices.InsertAsync(bdRel);
//订单更新发货状态,发送各种消息
await OrderShip(orderInfo, items, billDelivery, storeId);
var stock = new CoreCmsStock
{
manager = 0,
id = billDelivery.deliveryId,
createTime = DateTime.Now,
type = (int)GlobalEnumVars.StockType.DeliverGoods,
memo = "订单发货操作,发货单号:" + billDelivery.deliveryId
};
await stockServices.InsertAsync(stock);
jm.status = true;
jm.msg = "发货成功";
return jm;
}
/// <summary>
/// 给订单发货
/// </summary>
/// <param name="orderInfo">订单信息</param>
/// <param name="items">总的发货包裹内容</param>
/// <param name="deliveryInfo">发货单信息</param>
/// <param name="storeId">门店自提还是普通订单0是普通订单其他是门店自提</param>
private async Task<bool> OrderShip(CoreCmsOrder orderInfo, Dictionary<int, int> items, CoreCmsBillDelivery deliveryInfo, int storeId = 0)
{
using var container = _serviceProvider.CreateScope();
var orderService = container.ServiceProvider.GetService<ICoreCmsOrderServices>();
var billLadingService = container.ServiceProvider.GetService<ICoreCmsBillLadingServices>();
var messageCenterServices = container.ServiceProvider.GetService<ICoreCmsMessageCenterServices>();
var logisticsServices = container.ServiceProvider.GetService<ICoreCmsLogisticsServices>();
var stockLogServices = container.ServiceProvider.GetService<ICoreCmsStockLogServices>();
var stockServices = container.ServiceProvider.GetService<ICoreCmsStockServices>();
var stockLogs = new List<CoreCmsStockLog>();
var itemList = new Dictionary<int, int>();
foreach (var item in orderInfo.items)
{
if (items.ContainsKey(item.productId))
{
var maxNum = item.nums - item.reshipNums - item.sendNums;
if (maxNum > 0) //如果此条订单明细需要发货的话
{
var sendNum = maxNum;
if (items[item.productId] > maxNum)
{
//足够发此条记录的话
itemList.Add(item.productId, maxNum);
items[item.productId] = items[item.productId] - maxNum;
}
else
{
//此条订单都发不满的情况下
itemList.Add(item.productId, items[item.productId]);
sendNum = items[item.productId];
}
var sLog = new CoreCmsStockLog
{
stockId = deliveryInfo.deliveryId,
productId = item.id,
goodsId = item.goodsId,
nums = -sendNum,
sn = item.sn,
bn = item.bn,
goodsName = item.name,
spesDesc = item.addon
};
stockLogs.Add(sLog);
}
}
}
//如果有发货信息,就去给订单更新发货状态
if (itemList.Keys.Count <= 0)
{
return false;
}
var res = await orderService.EditShipStatus(orderInfo.orderId, itemList);
//如果是门店自提,生成提货单
if (storeId != 0)
{
await billLadingService.AddData(orderInfo.orderId, storeId, orderInfo.shipName, orderInfo.shipMobile);
}
if (res.status == true)
{
//添加操作日志
var log = new CoreCmsOrderLog();
log.orderId = orderInfo.orderId;
log.userId = orderInfo.userId;
log.type = (int)GlobalEnumVars.OrderLogTypes.LOG_TYPE_SHIP;
log.msg = "订单发货操作,发货单号:" + deliveryInfo.deliveryId;
log.data = JsonConvert.SerializeObject(deliveryInfo);
log.createTime = DateTime.Now;
await _orderLogServices.InsertAsync(log);
var logistics = await logisticsServices.QueryByClauseAsync(p => p.logiCode == deliveryInfo.logiCode);
deliveryInfo.logiName = logistics != null ? logistics.logiName : deliveryInfo.logiCode;
//添加库存出库日志
if (stockLogs.Any())
{
//var stock = new CoreCmsStock
//{
// manager = 0,
// id = deliveryInfo.deliveryId,
// createTime = DateTime.Now,
// type = (int)GlobalEnumVars.StockType.DeliverGoods,
// memo = log.msg
//};
//await stockServices.InsertAsync(stock);
await stockLogServices.InsertAsync(stockLogs);
}
//发送消息
await messageCenterServices.SendMessage(orderInfo.userId, GlobalEnumVars.PlatformMessageTypes.DeliveryNotice.ToString(), JObject.FromObject(deliveryInfo));
}
return true;
}
/// <summary>
/// 物流信息查询根据快递编码和单号查询(快递100)未使用
/// </summary>
/// <param name="code">查询的快递公司的编码, 一律用小写字母yuantong</param>
/// <param name="no">查询的快递单号, 单号的最大长度是32个字符</param>
/// <returns></returns>
public async Task<WebApiCallBack> GetLogistic(string code, string no)
{
var jm = new WebApiCallBack();
//快递100分配给贵司的的公司编号, 请在企业管理后台查看
var allConfigs = await _settingServices.GetConfigDictionaries();
var customer = CommonHelper.GetConfigDictionary(allConfigs, SystemSettingConstVars.Kuaidi100Customer);
//签名, 用于验证身份, 按param + key + customer 的顺序进行MD5加密注意加密后字符串一定要转大写 不需要加上“+”号, 如{“com”: “yuantong”, “num”: “500306190180”, “from”: “广东省深圳市”, “to”: “北京市朝阳区”}xxxxxxxxxxxxyyyyyyyyyyy yyyyyyyyyyyyyyyyyyyyy
var key = CommonHelper.GetConfigDictionary(allConfigs, SystemSettingConstVars.Kuaidi100Key);
if (string.IsNullOrEmpty(customer) || string.IsNullOrEmpty(key))
{
jm.msg = "快递查询接口公司编码及授权key获取失败";
}
var param = new KuaiDi100ApiPostParam();
param.com = code.ToLowerInvariant();
param.num = no;
param.phone = "";
param.from = "";
param.to = "";
param.resultv2 = 1;
var jsonParamData = JsonConvert.SerializeObject(param);
//签名加密
var str = jsonParamData + key + customer;
var signStr = CommonHelper.Md5For32(str).ToUpper();
//实时查询请求地址
var postUrl = "http://poll.kuaidi100.com/poll/query.do";
var postData = new
{
customer,
param = jsonParamData,
sign = signStr
};
var result = await postUrl.PostUrlEncodedAsync(postData).ReceiveJson<KuaiDi100ApiPostResult>();
if (result.status == "200")
{
jm.status = true;
jm.data = result;
}
else
{
jm.status = false;
jm.msg = !string.IsNullOrEmpty(result.message) ? result.message : "暂无消息";
}
return jm;
}
/// <summary>
/// 发货单统计7天统计
/// </summary>
/// <returns></returns>
public async Task<List<StatisticsOut>> Statistics()
{
return await _dal.Statistics();
}
}
}

View File

@@ -0,0 +1,242 @@
/***********************************************************************
* Project: CoreCms
* ProjectName: 核心内容管理系统
* Web: https://www.corecms.net
* Author: 大灰灰
* Email: jianweie@163.com
* CreateTime: 2021/1/31 21:45:10
* Description: 暂无
***********************************************************************/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using CoreCms.Net.Configuration;
using CoreCms.Net.IRepository;
using CoreCms.Net.IRepository.UnitOfWork;
using CoreCms.Net.IServices;
using CoreCms.Net.Loging;
using CoreCms.Net.Model.Entities;
using CoreCms.Net.Model.ViewModels.UI;
using CoreCms.Net.Utility.Helper;
using SqlSugar;
namespace CoreCms.Net.Services
{
/// <summary>
/// 提货单表 接口实现
/// </summary>
public class CoreCmsBillLadingServices : BaseServices<CoreCmsBillLading>, ICoreCmsBillLadingServices
{
private readonly ICoreCmsBillLadingRepository _dal;
private readonly ICoreCmsClerkRepository _clerkRepository;
private readonly ICoreCmsStoreRepository _storeRepository;
private readonly ICoreCmsOrderItemRepository _orderItemRepository;
private readonly ICoreCmsUserRepository _userRepository;
private readonly IUnitOfWork _unitOfWork;
public CoreCmsBillLadingServices(IUnitOfWork unitOfWork, ICoreCmsBillLadingRepository dal, ICoreCmsClerkRepository clerkRepository, ICoreCmsStoreRepository storeRepository, ICoreCmsOrderItemRepository orderItemRepository, ICoreCmsUserRepository userRepository)
{
this._dal = dal;
_clerkRepository = clerkRepository;
_storeRepository = storeRepository;
_orderItemRepository = orderItemRepository;
_userRepository = userRepository;
base.BaseDal = dal;
_unitOfWork = unitOfWork;
}
/// <summary>
/// 添加提货单
/// </summary>
/// <returns></returns>
public async Task<WebApiCallBack> AddData(string orderId, int storeId, string name, string mobile)
{
return await _dal.AddData(orderId, storeId, name, mobile);
}
/// <summary>
/// 核销提货单
/// </summary>
/// <param name="ids"></param>
/// <param name="userId"></param>
/// <returns></returns>
public async Task<AdminUiCallBack> LadingOperating(string[] ids, int userId = 0)
{
var jm = new AdminUiCallBack();
var list = await _dal.QueryListByClauseAsync(p => ids.Contains(p.id));
if (list.Any())
{
foreach (var item in list)
{
item.clerkId = userId;
item.pickUpTime = DateTime.Now;
item.status = true;
}
var outChanges = await _dal.UpdateAsync(list);
jm.code = outChanges ? 0 : 1;
jm.msg = outChanges ? "操作成功" : "操作失败";
}
else
{
jm.msg = "没有可提货的订单";
}
return jm;
}
/// <summary>
/// 获取店铺提货单列表
/// </summary>
/// <returns></returns>
public async Task<WebApiCallBack> GetStoreLadingList(int userId, int page, int limit)
{
var jm = new WebApiCallBack();
var clerks = await _clerkRepository.QueryListByClauseAsync(p => p.userId == userId);
var storeIds = clerks.Select(p => p.storeId).ToList();
var ladingList = await _dal.QueryPageAsync(p => storeIds.Contains(p.storeId) && p.isDel == false, p => p.status, OrderByType.Asc, page, limit);
jm.status = true;
jm.msg = "获取成功";
jm.data = ladingList;
jm.otherData = new
{
ladingList.TotalCount,
ladingList.TotalPages
};
if (ladingList.Any())
{
var storeModel = await _storeRepository.QueryAsync();
foreach (var item in ladingList)
{
item.orderItems = await _orderItemRepository.QueryListByClauseAsync(p => p.orderId == item.orderId);
item.storeName = storeModel.FirstOrDefault(p => p.id == item.storeId)?.storeName;
var statusInt = item.status
? (int)GlobalEnumVars.BillLadingStatus.Recharge
: (int)GlobalEnumVars.BillLadingStatus.Order;
item.statusName = EnumHelper.GetEnumDescriptionByValue<GlobalEnumVars.BillLadingStatus>(statusInt);
}
}
return jm;
}
/// <summary>
/// 删除提货单(软删除)
/// </summary>
/// <param name="ids"></param>
/// <param name="userId"></param>
/// <returns></returns>
public async Task<WebApiCallBack> LadingDelete(string id, int userId = 0)
{
var jm = new WebApiCallBack();
var model = await _dal.QueryByClauseAsync(p => p.id == id);
if (model != null)
{
if (model.status == false)
{
jm.msg = "未提货的提货单不能删除";
return jm;
}
if (userId > 0)
{
var clerks = await _clerkRepository.ExistsAsync(p => p.userId == userId && p.storeId == model.storeId);
if (!clerks)
{
jm.msg = "你无权删除该提货单";
return jm;
}
}
model.isDel = true;
model.updateTime = DateTime.Now;
var bl = await _dal.UpdateAsync(model);
jm.status = bl;
jm.msg = bl ? "删除成功" : "删除失败";
}
else
{
jm.msg = "未找到提货单";
}
return jm;
}
/// <summary>
/// 获取提货单详情
/// </summary>
/// <returns></returns>
public async Task<WebApiCallBack> GetInfo(string id, int userId = 0)
{
var jm = new WebApiCallBack();
var list = await _dal.QueryListByClauseAsync(p => p.id == id || p.orderId == id || p.mobile == id);
var data = new List<CoreCmsBillLading>();
if (list != null)
{
if (userId > 0)
{
var clerks = await _clerkRepository.QueryListByClauseAsync(p => p.userId == userId);
if (clerks != null && clerks.Any())
{
var storeIds = clerks.Select(p => p.storeId).ToList();
foreach (var item in list)
{
if (storeIds.Contains(item.storeId))
{
data.Add(item);
}
}
}
}
foreach (var item in data)
{
var statusInt = item.status
? (int)GlobalEnumVars.BillLadingStatus.Recharge
: (int)GlobalEnumVars.BillLadingStatus.Order;
item.statusName = EnumHelper.GetEnumDescriptionByValue<GlobalEnumVars.BillLadingStatus>(statusInt);
if (item.clerkId > 0)
{
var userInfo = await _userRepository.QueryByClauseAsync(p => p.id == userId);
if (userInfo != null)
{
item.clerkIdName = !string.IsNullOrEmpty(userInfo.nickName)
? userInfo.nickName + "(" + userInfo.mobile + ")"
: UserHelper.FormatMobile(userInfo.mobile) + "(" + userInfo.mobile + ")";
}
}
else
{
item.clerkIdName = item.status ? "(后台管理员)" : "";
}
item.orderItems = await _orderItemRepository.QueryListByClauseAsync(p => p.orderId == item.orderId);
}
jm.status = true;
jm.msg = "获取成功";
jm.data = data;
}
else
{
jm.msg = "提货单不存在";
}
return jm;
}
}
}

View File

@@ -0,0 +1,839 @@
/***********************************************************************
* Project: CoreCms
* ProjectName: 核心内容管理系统
* Web: https://www.corecms.net
* Author: 大灰灰
* Email: jianweie@163.com
* CreateTime: 2021/1/31 21:45:10
* Description: 暂无
***********************************************************************/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
using CoreCms.Net.Configuration;
using CoreCms.Net.IRepository;
using CoreCms.Net.IRepository.UnitOfWork;
using CoreCms.Net.IServices;
using CoreCms.Net.Loging;
using CoreCms.Net.Model.Entities;
using CoreCms.Net.Model.Entities.Expression;
using CoreCms.Net.Model.ViewModels.Basics;
using CoreCms.Net.Model.ViewModels.DTO;
using CoreCms.Net.Model.ViewModels.UI;
using CoreCms.Net.Utility.Extensions;
using CoreCms.Net.Utility.Helper;
using CoreCms.Net.WeChat.Service.Options;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NLog;
using SqlSugar;
namespace CoreCms.Net.Services
{
/// <summary>
/// 支付单表 接口实现
/// </summary>
public class CoreCmsBillPaymentsServices : BaseServices<CoreCmsBillPayments>, ICoreCmsBillPaymentsServices
{
private readonly ICoreCmsBillPaymentsRepository _dal;
private readonly IUnitOfWork _unitOfWork;
private readonly IServiceProvider _serviceProvider;
private readonly ICoreCmsSettingServices _settingServices;
private readonly ICoreCmsUserBalanceServices _userBalanceServices;
private readonly ICoreCmsFormSubmitServices _formSubmitServices;
private readonly IHttpContextAccessor _httpContextAccessor;
//private IWeChatPayServices _weChatPayServices;
private readonly ICoreCmsPaymentsServices _paymentsServices;
private readonly ICoreCmsOrderItemServices _orderItemServices;
private readonly ICoreCmsServicesServices _servicesServices;
private readonly ICoreCmsUserServicesOrderServices _userServicesOrderServices;
private readonly ICoreCmsUserWeChatInfoServices _userWeChatInfoServices;
private readonly WeChatOptions _weChatOptions;
public CoreCmsBillPaymentsServices(IUnitOfWork unitOfWork
, ICoreCmsBillPaymentsRepository dal
, ICoreCmsSettingServices settingServices
, IHttpContextAccessor httpContextAccessor
, ICoreCmsUserBalanceServices userBalanceServices
, ICoreCmsFormSubmitServices formSubmitServices
//, IWeChatPayServices weChatPayServices
, ICoreCmsPaymentsServices paymentsServices
, ICoreCmsOrderItemServices orderItemServices
, IServiceProvider serviceProvider, ICoreCmsServicesServices servicesServices
, ICoreCmsUserServicesOrderServices userServicesOrderServices
, ICoreCmsUserWeChatInfoServices userWeChatInfoServices
, IOptions<WeChatOptions> weChatOptions
)
{
this._dal = dal;
base.BaseDal = dal;
_unitOfWork = unitOfWork;
_httpContextAccessor = httpContextAccessor;
_settingServices = settingServices;
_userBalanceServices = userBalanceServices;
_formSubmitServices = formSubmitServices;
//_weChatPayServices = weChatPayServices;
_formSubmitServices = formSubmitServices;
_paymentsServices = paymentsServices;
_orderItemServices = orderItemServices;
_serviceProvider = serviceProvider;
_servicesServices = servicesServices;
_userServicesOrderServices = userServicesOrderServices;
_userWeChatInfoServices = userWeChatInfoServices;
_weChatOptions = weChatOptions.Value;
}
#region
/// <summary>
/// 生成支付单的时候,格式化支付单明细
/// </summary>
/// <param name="orderId">订单编号</param>
/// <param name="type"></param>
/// <param name="params"></param>
/// <returns></returns>
public async Task<WebApiCallBack> FormatPaymentRel(string orderId, int type, JObject @params)
{
using var container = _serviceProvider.CreateScope();
var orderServices = container.ServiceProvider.GetService<ICoreCmsOrderServices>();
var jm = new WebApiCallBack();
var dto = new CheckPayDTO();
//订单
if (type == (int)GlobalEnumVars.BillPaymentsType.Order)
{
//如果是订单生成支付单的话取第一条订单的店铺id后面的所有订单都要保证是此店铺的id
var orderModel = await orderServices.QueryByClauseAsync(p =>
p.orderId == orderId && p.payStatus == (int)GlobalEnumVars.OrderPayStatus.No &&
p.status == (int)GlobalEnumVars.OrderStatus.Normal);
if (orderModel != null)
{
dto.rel.Add(new rel()
{
sourceId = orderId,
money = orderModel.orderAmount
});
dto.money += orderModel.orderAmount;
}
else
{
jm.status = false;
jm.msg = "订单号:" + orderId + "没有找到,或不是未支付状态";
return jm;
}
jm.status = true;
jm.data = dto;
}
//充值
else if (type == (int)GlobalEnumVars.BillPaymentsType.Recharge)
{
if (@params != null && @params.ContainsKey("money"))
{
dto.money = @params["money"].ObjectToDecimal(0); //充值金额
}
else
{
jm.status = false;
jm.msg = "请输入正确的充值金额";
return jm;
}
dto.rel.Add(new rel()
{
sourceId = orderId,
money = dto.money
});
jm.status = true;
jm.data = dto;
}
//表单
else if (type == (int)GlobalEnumVars.BillPaymentsType.FormPay || type == (int)GlobalEnumVars.BillPaymentsType.FormOrder)
{
dto.money = 0;
var intId = orderId.ObjectToInt(0);
if (intId <= 0)
{
jm.status = false;
jm.msg = "表单:" + intId + "没有找到,或不是未支付状态";
return jm;
}
var formInfo = await _formSubmitServices.QueryByClauseAsync(p => p.id == intId && p.payStatus == false);
if (formInfo != null)
{
dto.rel.Add(new rel()
{
sourceId = intId.ToString(),
money = formInfo.money
});
dto.money += formInfo.money;
}
else
{
jm.status = false;
jm.msg = "表单:" + intId + "没有找到,或不是未支付状态";
return jm;
}
jm.status = true;
jm.data = dto;
}
else if (type == (int)GlobalEnumVars.BillPaymentsType.ServiceOrder)
{
dto.money = 0;
var order = await _userServicesOrderServices.QueryByClauseAsync(p => p.serviceOrderId == orderId);
var dt = DateTime.Now;
var where = PredicateBuilder.True<CoreCmsServices>();
@where = @where.And(p => p.status == (int)GlobalEnumVars.ServicesStatus.Shelve);
@where = @where.And(p => p.amount > 0);
@where = @where.And(p => p.startTime < dt && p.endTime > dt);
@where = @where.And(p => p.id == order.servicesId);
var serviceInfo = await _servicesServices.QueryByClauseAsync(@where);
if (serviceInfo != null)
{
dto.rel.Add(new rel()
{
sourceId = orderId,
money = serviceInfo.money
});
dto.money += serviceInfo.money;
}
else
{
jm.status = false;
jm.msg = "服务订单:" + orderId + "没有找到,或不是有效状态";
return jm;
}
jm.status = true;
jm.data = dto;
}
else if (false)
{
//todo 其他业务逻辑
}
else
{
jm.status = false;
jm.msg = GlobalErrorCodeVars.Code10054;
jm.data = 10054;
return jm;
}
return jm;
}
#endregion
#region
/// <summary>
/// 生成支付单的时候,格式化支付单明细
/// </summary>
/// <param name="sourceStr"></param>
/// <param name="type"></param>
/// <param name="params"></param>
/// <returns></returns>
public async Task<WebApiCallBack> BatchFormatPaymentRel(string[] sourceStr, int type, JObject @params)
{
using var container = _serviceProvider.CreateScope();
var orderServices = container.ServiceProvider.GetService<ICoreCmsOrderServices>();
var jm = new WebApiCallBack();
var dto = new CheckPayDTO();
//订单
if (type == (int)GlobalEnumVars.BillPaymentsType.Order)
{
//如果是订单生成支付单的话取第一条订单的店铺id后面的所有订单都要保证是此店铺的id
foreach (var item in sourceStr)
{
var orderModel = await orderServices.QueryByClauseAsync(p =>
p.orderId == item && p.payStatus == (int)GlobalEnumVars.OrderPayStatus.No &&
p.status == (int)GlobalEnumVars.OrderStatus.Normal);
if (orderModel != null)
{
dto.rel.Add(new rel()
{
sourceId = item,
money = orderModel.orderAmount
});
dto.money += orderModel.orderAmount;
}
else
{
jm.status = false;
jm.msg = "订单号:" + item + "没有找到,或不是未支付状态";
return jm;
}
}
jm.status = true;
jm.data = dto;
}
//充值
else if (type == (int)GlobalEnumVars.BillPaymentsType.Recharge)
{
if (@params != null && @params.ContainsKey("money"))
{
dto.money = @params["money"].ObjectToDecimal(0); //充值金额
}
else
{
jm.status = false;
jm.msg = "请输入正确的充值金额";
return jm;
}
foreach (var item in sourceStr)
{
dto.rel.Add(new rel()
{
sourceId = item,
money = dto.money
});
}
jm.status = true;
jm.data = dto;
}
//表单
else if (type == (int)GlobalEnumVars.BillPaymentsType.FormPay || type == (int)GlobalEnumVars.BillPaymentsType.FormOrder)
{
dto.money = 0;
var intIds = CommonHelper.StringArrAyToIntArray(sourceStr);
foreach (var item in intIds)
{
var formInfo = await _formSubmitServices.QueryByClauseAsync(p => p.id == item && p.payStatus == false);
if (formInfo != null)
{
dto.rel.Add(new rel()
{
sourceId = item.ToString(),
money = formInfo.money
});
dto.money += formInfo.money;
}
else
{
jm.status = false;
jm.msg = "表单:" + item + "没有找到,或不是未支付状态";
return jm;
}
}
jm.status = true;
jm.data = dto;
}
else if (type == (int)GlobalEnumVars.BillPaymentsType.ServiceOrder)
{
dto.money = 0;
foreach (var item in sourceStr)
{
var order = await _userServicesOrderServices.QueryByClauseAsync(p => p.serviceOrderId == item);
var dt = DateTime.Now;
var where = PredicateBuilder.True<CoreCmsServices>();
@where = @where.And(p => p.status == (int)GlobalEnumVars.ServicesStatus.Shelve);
@where = @where.And(p => p.amount > 0);
@where = @where.And(p => p.startTime < dt && p.endTime > dt);
@where = @where.And(p => p.id == order.servicesId);
var serviceInfo = await _servicesServices.QueryByClauseAsync(@where);
if (serviceInfo != null)
{
dto.rel.Add(new rel()
{
sourceId = item,
money = serviceInfo.money
});
dto.money += serviceInfo.money;
}
else
{
jm.status = false;
jm.msg = "服务订单:" + item + "没有找到,或不是有效状态";
return jm;
}
}
jm.status = true;
jm.data = dto;
}
else if (false)
{
//todo 其他业务逻辑
}
else
{
jm.status = false;
jm.msg = GlobalErrorCodeVars.Code10054;
jm.data = 10054;
return jm;
}
return jm;
}
#endregion
#region
/// <summary>
/// 支付,先生成支付单,然后去支付
/// </summary>
/// <param name="sourceStr">来源一般是订单号或者用户id比如充值</param>
/// <param name="paymentCode">支付方式</param>
/// <param name="userId">用户序列</param>
/// <param name="type">订单/充值/服务订单</param>
/// <param name="params">支付的时候用到的参数如果是微信支付的话这里可以传trade_type=>'JSAPI'(小程序支付),或者'MWEB'(h5支付),当是JSPI的时候可以不传其他参数了默认就可以默认的这个值就是JSAPI如果是MWEB的话需要传wap_url(网站url地址)参数和wap_name网站名称参数其他支付方式需要传什么参数这个以后再说</param>
/// <returns></returns>
public async Task<WebApiCallBack> Pay(string sourceStr, string paymentCode, int userId, int type, JObject @params)
{
using var container = _serviceProvider.CreateScope();
var weChatPayServices = container.ServiceProvider.GetService<IWeChatPayServices>();
var aliPayServices = container.ServiceProvider.GetService<IAliPayServices>();
var balancePayServices = container.ServiceProvider.GetService<IBalancePayServices>();
var offlinePayServices = container.ServiceProvider.GetService<IOfflinePayServices>();
var jm = new WebApiCallBack();
//如果支付类型为余额充值那么资源ID就是用户ID
if (type == (int)GlobalEnumVars.BillPaymentsType.Recharge)
{
sourceStr = userId.ToString();
}
//判断支付方式是否开启
var paymentInfo = await _paymentsServices.QueryByClauseAsync(p => p.code == paymentCode && p.isEnable == true);
if (paymentInfo == null)
{
jm.data = jm.code = 10050;
jm.msg = GlobalErrorCodeVars.Code10050;
return jm;
}
//如果是公众号支付并且没有登陆或者没有open_id的话报错
var res = await CheckOpenId(paymentCode, @params);
if (res.status == false)
{
return res;
}
//生成支付单,只是单纯的生成了支付单
var result = await ToAdd(sourceStr, paymentCode, userId, type, @params);
if (result.status == false)
{
return result;
}
var billPayments = result.data as CoreCmsBillPayments;
//根据支付方式返回支付配置
//微信支付
if (paymentCode == GlobalEnumVars.PaymentsTypes.wechatpay.ToString())
{
jm = await weChatPayServices.PubPay(billPayments);
}
//支付宝支付
else if (paymentCode == GlobalEnumVars.PaymentsTypes.alipay.ToString())
{
jm = aliPayServices.PubPay(billPayments);
}
//余额支付
else if (paymentCode == GlobalEnumVars.PaymentsTypes.balancepay.ToString())
{
jm = await balancePayServices.PubPay(billPayments);
}
//线下支付
else if (paymentCode == GlobalEnumVars.PaymentsTypes.offline.ToString())
{
jm = offlinePayServices.PubPay(billPayments);
}
return jm;
}
#endregion
#region open_id的话
/// <summary>
/// 如果是公众号支付并且没有登陆或者没有open_id的话报错
/// </summary>
/// <param name="paymentCode"></param>
/// <param name="params"></param>
/// <returns></returns>
private async Task<WebApiCallBack> CheckOpenId(string paymentCode, JObject jobj)
{
var jm = new WebApiCallBack { status = true };
//当只有微信支付的时候,才判断
if (paymentCode != "wechatpay") return jm;
if (jobj != null)
{
//当只有公众号支付的时候,才判断
if (jobj.ContainsKey("trade_type") && jobj["trade_type"].ObjectToString() == "JSAPI_OFFICIAL") return jm;
if (jobj.ContainsKey("openid") && jobj["openid"].ObjectToString() != "") return jm;
//到这里基本上就说明
if (!jobj.ContainsKey("url"))
{
jm.data = 10067;
jm.code = 10067;
jm.msg = GlobalErrorCodeVars.Code10067;
return jm;
}
var allConfigs = await _settingServices.GetConfigDictionaries();
var wxOfficialAppid = CommonHelper.GetConfigDictionary(allConfigs, SystemSettingConstVars.WxOfficialAppid);
var redirectUrl = CommonHelper.UrlEncode(jobj["url"].ObjectToString());
jm.status = false;
jm.data = 10006;
jm.msg = $"https://open.weixin.qq.com/connect/oauth2/authorize?appid={_weChatOptions.WeiXinAppId}&redirect_uri={redirectUrl}&response_type={"code"}&scope={3}&state={"corecms"}{"&connect_redirect=1"}#wechat_redirect";
}
return jm;
}
#endregion
#region ,
/// <summary>
/// 生成支付单,只是单纯的生成了支付单
/// </summary>
/// <param name="sourceStr">资源id字段</param>
/// <param name="paymentCode">支付方式</param>
/// <param name="userId">支付用户id</param>
/// <param name="type">支付类型</param>
/// <param name="params">参数</param>
/// <returns></returns>
private async Task<WebApiCallBack> ToAdd(string sourceStr, string paymentCode, int userId = 0, int type = (int)GlobalEnumVars.BillPaymentsType.Order, JObject @params = null)
{
var jm = new WebApiCallBack();
//判断支付方式
var paymentInfo = await _paymentsServices.QueryByClauseAsync(p => p.code == paymentCode && p.isEnable == true);
if (paymentInfo == null)
{
jm.data = jm.code = 10050;
jm.msg = GlobalErrorCodeVars.Code10050;
return jm;
}
var paymentRelData = new CheckPayDTO();
var sourceStrArr = sourceStr.Split(",");
if (sourceStrArr.Length > 0)
{
var paymentRel = await BatchFormatPaymentRel(sourceStrArr, type, @params);
if (paymentRel.status == false)
{
return paymentRel;
}
paymentRelData = paymentRel.data as CheckPayDTO;
}
else
{
var paymentRel = await FormatPaymentRel(sourceStr, type, @params);
if (paymentRel.status == false)
{
return paymentRel;
}
paymentRelData = paymentRel.data as CheckPayDTO;
}
var billPayments = new CoreCmsBillPayments();
billPayments.paymentId = CommonHelper.GetSerialNumberType((int)GlobalEnumVars.SerialNumberType.);
billPayments.sourceId = sourceStr;
billPayments.money = paymentRelData.money;
billPayments.userId = userId;
billPayments.type = type;
billPayments.status = (int)GlobalEnumVars.BillPaymentsStatus.NoPay;
billPayments.paymentCode = paymentCode;
billPayments.ip = _httpContextAccessor.HttpContext?.Connection.RemoteIpAddress != null ? _httpContextAccessor.HttpContext.Connection.RemoteIpAddress.MapToIPv4().ToString() : "127.0.0.1";
billPayments.parameters = @params != null ? JsonConvert.SerializeObject(@params) : "";
billPayments.createTime = DateTime.Now;
await _dal.InsertAsync(billPayments);
//判断支付单金额是否为0如果为0直接支付成功,
if (billPayments.money == 0)
{
//更新订单信息
await ToUpdate(billPayments.paymentId, (int)GlobalEnumVars.BillPaymentsStatus.Payed, billPayments.paymentCode, billPayments.money, "金额为0自动支付成功", "");
jm.data = jm.code = 10059;
jm.msg = GlobalErrorCodeVars.Code10059;
return jm;
}
//取支付标题,就不往数据库里存了吧
billPayments.payTitle = await PayTitle(billPayments);
jm.status = true;
jm.data = billPayments;
return jm;
}
#endregion
#region
/// <summary>
/// 支付成功后,更新支付单状态
/// </summary>
/// <param name="paymentId"></param>
/// <param name="paymentCode"></param>
/// <param name="money"></param>
/// <param name="status"></param>
/// <param name="payedMsg"></param>
/// <param name="tradeNo"></param>
public async Task<WebApiCallBack> ToUpdate(string paymentId, int status, string paymentCode, decimal money, string payedMsg = "", string tradeNo = "")
{
using var container = _serviceProvider.CreateScope();
var orderServices = container.ServiceProvider.GetService<ICoreCmsOrderServices>();
var jm = new WebApiCallBack();
var billPaymentInfo = await _dal.QueryByClauseAsync(p =>
p.paymentId == paymentId && p.money == money &&
p.status != (int)GlobalEnumVars.BillPaymentsStatus.Payed);
if (billPaymentInfo == null)
{
NLogUtil.WriteAll(LogLevel.Trace, LogType.Order, "支付成功后,更新支付单状态", "没有找到此未支付的支付单号");
jm.msg = "没有找到此未支付的支付单号";
return jm;
}
billPaymentInfo.status = status;
billPaymentInfo.paymentCode = paymentCode;
billPaymentInfo.payedMsg = payedMsg;
billPaymentInfo.tradeNo = tradeNo;
billPaymentInfo.updateTime = DateTime.Now;
await _dal.UpdateAsync(billPaymentInfo);
if (status == (int)GlobalEnumVars.BillPaymentsStatus.Payed)
{
if (billPaymentInfo.type == (int)GlobalEnumVars.BillPaymentsType.Order)
{
//如果是订单类型,做支付后处理
await orderServices.Pay(billPaymentInfo.sourceId, paymentCode, billPaymentInfo);
}
else if (billPaymentInfo.type == (int)GlobalEnumVars.BillPaymentsType.Recharge)
{
//给用户做充值
var userId = billPaymentInfo.sourceId.ObjectToInt(0);
await _userBalanceServices.Change(userId, (int)GlobalEnumVars.UserBalanceSourceTypes.Recharge, billPaymentInfo.money, billPaymentInfo.paymentId);
}
else if (billPaymentInfo.type == (int)GlobalEnumVars.BillPaymentsType.ServiceOrder)
{
//给用户做增加购买关系和生成券操作
await _userServicesOrderServices.CreateUserServicesTickets(billPaymentInfo.sourceId, billPaymentInfo.paymentId);
}
else if (billPaymentInfo.type == (int)GlobalEnumVars.BillPaymentsType.FormOrder || billPaymentInfo.type == (int)GlobalEnumVars.BillPaymentsType.FormPay)
{
//form表单支付
var id = billPaymentInfo.sourceId.ObjectToInt(0);
await _formSubmitServices.Pay(id);
}
else
{
//::todo 其他业务逻辑
}
}
jm.status = true;
jm.data = paymentId;
jm.msg = "支付成功";
return jm;
}
#endregion
#region
/// <summary>
/// 获取支付单详情
/// </summary>
/// <returns></returns>
public async Task<WebApiCallBack> GetInfo(string paymentId, int userId = 0)
{
var jm = new WebApiCallBack();
if (string.IsNullOrEmpty(paymentId))
{
jm.msg = GlobalErrorCodeVars.Code13100;
return jm;
}
var where = PredicateBuilder.True<CoreCmsBillPayments>();
where = where.And(p => p.paymentId == paymentId);
if (userId > 0)
{
where = where.And(p => p.userId == userId);
}
var billPayments = await _dal.QueryByClauseAsync(where);
if (billPayments == null)
{
jm.msg = "没有找到此支付记录";
jm.data = jm.code = 10002;
return jm;
}
jm.status = true;
jm.data = billPayments;
return jm;
}
#endregion
//扩展方法==========================================================================================
#region
private async Task<string> PayTitle(CoreCmsBillPayments entity)
{
var res = string.Empty;
switch (entity.type)
{
case (int)GlobalEnumVars.BillPaymentsType.Order:
var orderItem = await _orderItemServices.QueryByClauseAsync(p => p.orderId == entity.sourceId);
if (orderItem != null)
{
res = orderItem.name;
}
break;
case (int)GlobalEnumVars.BillPaymentsType.Recharge:
res = "账户充值";
break;
case (int)GlobalEnumVars.BillPaymentsType.FormPay:
break;
case (int)GlobalEnumVars.BillPaymentsType.FormOrder:
break;
case (int)GlobalEnumVars.BillPaymentsType.ServiceOrder:
break;
default:
break;
}
if (string.IsNullOrEmpty(res))
{
var allConfigs = await _settingServices.GetConfigDictionaries();
res = CommonHelper.GetConfigDictionary(allConfigs, SystemSettingConstVars.ShopName); //店铺名称
}
return res;
}
#endregion
#region
/// <summary>
/// 卖家直接支付操作
/// </summary>
/// <param name="orderId">订单编号</param>
/// <param name="type">支付类型</param>
/// <param name="paymentCode">支付类型编码</param>
/// <returns></returns>
public async Task<WebApiCallBack> ToPay(string orderId, int type, string paymentCode)
{
using (var container = _serviceProvider.CreateScope())
{
var orderServices = container.ServiceProvider.GetService<ICoreCmsOrderServices>();
var jm = new WebApiCallBack();
//查支付人id
var userId = 0;
switch (type)
{
case (int)GlobalEnumVars.BillPaymentsType.Order:
var orderInfo = await orderServices.QueryByIdAsync(orderId);
if (orderInfo == null)
{
jm.code = 10000;
jm.msg = GlobalErrorCodeVars.Code10000;
return jm;
}
userId = orderInfo.userId;
break;
}
//::todo 校验支付方式是否存在
//生成支付单
var result = await ToAdd(orderId, paymentCode, userId, type);
if (!result.status)
{
return result;
}
var data = result.data as CoreCmsBillPayments;
//支付单支付
jm = await ToUpdate(data.paymentId, (int)GlobalEnumVars.BillPaymentsStatus.Payed,
data.paymentCode, data.money, "后台手动支付");
return jm;
}
}
#endregion
#region 7
/// <summary>
/// 支付单7天统计
/// </summary>
/// <returns></returns>
public async Task<List<StatisticsOut>> Statistics()
{
return await _dal.Statistics();
}
#endregion
#region
/// <summary>
/// 重写根据条件查询分页数据
/// </summary>
/// <param name="predicate">判断集合</param>
/// <param name="orderByType">排序方式</param>
/// <param name="pageIndex">当前页面索引</param>
/// <param name="pageSize">分布大小</param>
/// <param name="orderByExpression"></param>
/// <param name="blUseNoLock">是否使用WITH(NOLOCK)</param>
/// <returns></returns>
public new async Task<IPageList<CoreCmsBillPayments>> QueryPageAsync(Expression<Func<CoreCmsBillPayments, bool>> predicate,
Expression<Func<CoreCmsBillPayments, object>> orderByExpression, OrderByType orderByType, int pageIndex = 1,
int pageSize = 20, bool blUseNoLock = false)
{
return await _dal.QueryPageAsync(predicate, orderByExpression, orderByType, pageIndex, pageSize, blUseNoLock);
}
#endregion
}
}

View File

@@ -0,0 +1,270 @@
/***********************************************************************
* Project: CoreCms
* ProjectName: 核心内容管理系统
* Web: https://www.corecms.net
* Author: 大灰灰
* Email: jianweie@163.com
* CreateTime: 2021/1/31 21:45:10
* Description: 暂无
***********************************************************************/
using System;
using System.Linq.Expressions;
using System.Threading.Tasks;
using CoreCms.Net.Configuration;
using CoreCms.Net.IRepository;
using CoreCms.Net.IRepository.UnitOfWork;
using CoreCms.Net.IServices;
using CoreCms.Net.Loging;
using CoreCms.Net.Model.Entities;
using CoreCms.Net.Model.ViewModels.Basics;
using CoreCms.Net.Model.ViewModels.UI;
using CoreCms.Net.Utility.Helper;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using SqlSugar;
namespace CoreCms.Net.Services
{
/// <summary>
/// 退款单表 接口实现
/// </summary>
public class CoreCmsBillRefundServices : BaseServices<CoreCmsBillRefund>, ICoreCmsBillRefundServices
{
private readonly ICoreCmsBillRefundRepository _dal;
private readonly ICoreCmsBillPaymentsServices _billPaymentsServices;
private readonly ICoreCmsMessageCenterServices _messageCenterServices;
private readonly ICoreCmsPaymentsServices _paymentsServices;
private readonly IBalancePayServices _balancePayServices;
private readonly IAliPayServices _aliPayServices;
private readonly IWeChatPayServices _weChatPayServices;
private readonly IUnitOfWork _unitOfWork;
public CoreCmsBillRefundServices(IUnitOfWork unitOfWork, ICoreCmsBillRefundRepository dal, ICoreCmsBillPaymentsServices billPaymentsServices, ICoreCmsMessageCenterServices messageCenterServices, ICoreCmsPaymentsServices paymentsServices, IBalancePayServices balancePayServices, IAliPayServices aliPayServices, IWeChatPayServices weChatPayServices)
{
this._dal = dal;
base.BaseDal = dal;
_unitOfWork = unitOfWork;
_billPaymentsServices = billPaymentsServices;
_messageCenterServices = messageCenterServices;
_paymentsServices = paymentsServices;
_balancePayServices = balancePayServices;
_aliPayServices = aliPayServices;
_weChatPayServices = weChatPayServices;
}
/// <summary>
/// 创建退款单
/// </summary>
/// <param name="userId"></param>
/// <param name="sourceId"></param>
/// <param name="type"></param>
/// <param name="money"></param>
/// <param name="aftersalesId"></param>
/// <returns></returns>
public async Task<WebApiCallBack> ToAdd(int userId, string sourceId, int type, decimal money, string aftersalesId)
{
var jm = new WebApiCallBack();
if (money == 0)
{
jm.data = jm.code = 13208;
jm.msg = GlobalErrorCodeVars.Code13208;
return jm;
}
//创建退款单
var billRefund = new CoreCmsBillRefund();
billRefund.refundId = CommonHelper.GetSerialNumberType((int)GlobalEnumVars.SerialNumberType.退);
billRefund.aftersalesId = aftersalesId;
billRefund.money = money;
billRefund.userId = userId;
billRefund.sourceId = sourceId;
billRefund.type = type;
//取支付成功的支付单号
var paymentsInfo = await _billPaymentsServices.QueryByClauseAsync(p => p.sourceId == sourceId && p.type == type && 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 _dal.InsertAsync(billRefund);
jm.status = true;
jm.msg = "创建成功";
return jm;
}
/// <summary>
/// 退款单去退款或者拒绝
/// </summary>
/// <param name="refundId">退款单id</param>
/// <param name="status">2或者4通过或者拒绝</param>
/// <param name="paymentCodeStr">退款方式,如果和退款单上的一样,说明没有修改,原路返回,否则只记录状态,不做实际退款,如果为空是原路返回</param>
/// <returns></returns>
public async Task<WebApiCallBack> ToRefund(string refundId, int status, string paymentCodeStr = "")
{
var jm = new WebApiCallBack();
var info = await _dal.QueryByClauseAsync(p => p.refundId == refundId && p.status == (int)GlobalEnumVars.BillRefundStatus.STATUS_NOREFUND);
if (info == null)
{
jm.status = false;
jm.msg = GlobalErrorCodeVars.Code13210;
return jm;
}
if (paymentCodeStr == "")
{
paymentCodeStr = info.paymentCode;
}
if (status == (int)GlobalEnumVars.BillRefundStatus.STATUS_REFUND)
{
//退款完成后的钩子
jm.msg = "退款单退款成功";
//如果前端传过来的退款方式和退款单上的退款方式一样的话,就说明是原路返回,试着调用支付方式的退款方法,如果不一样的话,就直接做退款单的退款状态为已退款就可以了
if (paymentCodeStr == info.paymentCode && paymentCodeStr != "offline")
{
jm = await PaymentRefund(refundId);
}
else
{
//只修改状态,不做实际退款,实际退款线下去退。
await _dal.UpdateAsync(p => new CoreCmsBillRefund()
{
status = (int)GlobalEnumVars.BillRefundStatus.STATUS_REFUND,
paymentCode = paymentCodeStr
},
p => p.refundId == refundId && p.status == (int)GlobalEnumVars.BillRefundStatus.STATUS_NOREFUND);
jm.status = true;
}
//退款同意,先发退款消息和钩子,下面原路返回可能失败,但是在业务上相当于退款已经退过了,只是实际的款项可能还没到账
//发送退款消息
await _messageCenterServices.SendMessage(info.userId, GlobalEnumVars.PlatformMessageTypes.RefundSuccess.ToString(), JObject.FromObject(info));
return jm;
}
else if (status == (int)GlobalEnumVars.BillRefundStatus.STATUS_REFUSE)
{
//退款拒绝
await _dal.UpdateAsync(
p => new CoreCmsBillRefund()
{
status = status,
paymentCode = paymentCodeStr
},
p => p.refundId == refundId && p.status == (int)GlobalEnumVars.BillRefundStatus.STATUS_NOREFUND);
jm.status = true;
jm.msg = "退款单拒绝成功";
}
else
{
jm.status = false;
jm.msg = GlobalErrorCodeVars.Code10000;
return jm;
}
return jm;
}
/// <summary>
/// 如果是在线支付的原路退还,去做退款操作
/// </summary>
public async Task<WebApiCallBack> PaymentRefund(string refundId)
{
var jm = new WebApiCallBack();
var info = await _dal.QueryByClauseAsync(p =>
p.refundId == refundId && p.status != (int)GlobalEnumVars.BillRefundStatus.STATUS_REFUND);
if (info == null)
{
jm.status = false;
jm.msg = GlobalErrorCodeVars.Code13210;
return jm;
}
//取支付成功的支付单号
var panyMentsInfo = await _billPaymentsServices.QueryByClauseAsync(p => p.sourceId == info.sourceId && p.type == info.type && p.status == (int)GlobalEnumVars.BillPaymentsStatus.Payed);
if (panyMentsInfo == null)
{
jm.msg = "没有找到支付成功的支付单号";
return jm;
}
if (panyMentsInfo.paymentCode != info.paymentCode)
{
jm.msg = "退款单退款方式和支付方式不一样,原路退还失败";
return jm;
}
//取此支付方式的信息
var paymentsModel = await _paymentsServices.QueryByClauseAsync(p => p.code == info.paymentCode && p.isEnable == true);
if (paymentsModel == null)
{
jm.msg = GlobalErrorCodeVars.Code10050;
return jm;
}
//去退款
//微信退款
if (panyMentsInfo.paymentCode == GlobalEnumVars.PaymentsTypes.wechatpay.ToString())
{
jm = await _weChatPayServices.Refund(info, panyMentsInfo);
}
//支付宝退款
else if (panyMentsInfo.paymentCode == GlobalEnumVars.PaymentsTypes.alipay.ToString())
{
jm.status = false;
jm.msg = "支付宝退款未开通";
}
//余额退款
else if (panyMentsInfo.paymentCode == GlobalEnumVars.PaymentsTypes.balancepay.ToString())
{
jm = await _balancePayServices.Refund(info, panyMentsInfo);
}
if (jm.status)
{
var res = JsonConvert.SerializeObject(jm.data);
await _dal.UpdateAsync(p => new CoreCmsBillRefund() { status = (int)GlobalEnumVars.BillRefundStatus.STATUS_REFUND, memo = res }, p => p.refundId == refundId);
}
else
{
var res = JsonConvert.SerializeObject(jm.data);
await _dal.UpdateAsync(p => new CoreCmsBillRefund() { status = (int)GlobalEnumVars.BillRefundStatus.STATUS_FAIL, memo = res }, p => p.refundId == refundId);
}
return jm;
}
#region
/// <summary>
/// 重写根据条件查询分页数据
/// </summary>
/// <param name="predicate">判断集合</param>
/// <param name="orderByType">排序方式</param>
/// <param name="pageIndex">当前页面索引</param>
/// <param name="pageSize">分布大小</param>
/// <param name="orderByExpression"></param>
/// <param name="blUseNoLock">是否使用WITH(NOLOCK)</param>
/// <returns></returns>
public new async Task<IPageList<CoreCmsBillRefund>> QueryPageAsync(Expression<Func<CoreCmsBillRefund, bool>> predicate,
Expression<Func<CoreCmsBillRefund, object>> orderByExpression, OrderByType orderByType, int pageIndex = 1,
int pageSize = 20, bool blUseNoLock = false)
{
return await _dal.QueryPageAsync(predicate, orderByExpression, orderByType, pageIndex, pageSize, blUseNoLock);
}
#endregion
}
}

View File

@@ -0,0 +1,33 @@
/***********************************************************************
* Project: CoreCms
* ProjectName: 核心内容管理系统
* Web: https://www.corecms.net
* Author: 大灰灰
* Email: jianweie@163.com
* CreateTime: 2021/1/31 21:45:10
* Description: 暂无
***********************************************************************/
using CoreCms.Net.IRepository;
using CoreCms.Net.IRepository.UnitOfWork;
using CoreCms.Net.IServices;
using CoreCms.Net.Model.Entities;
namespace CoreCms.Net.Services
{
/// <summary>
/// 退货单明细表 接口实现
/// </summary>
public class CoreCmsBillReshipItemServices : BaseServices<CoreCmsBillReshipItem>, ICoreCmsBillReshipItemServices
{
private readonly ICoreCmsBillReshipItemRepository _dal;
private readonly IUnitOfWork _unitOfWork;
public CoreCmsBillReshipItemServices(IUnitOfWork unitOfWork, ICoreCmsBillReshipItemRepository dal)
{
_dal = dal;
BaseDal = dal;
_unitOfWork = unitOfWork;
}
}
}

View File

@@ -0,0 +1,143 @@
/***********************************************************************
* Project: CoreCms
* ProjectName: 核心内容管理系统
* Web: https://www.corecms.net
* Author: 大灰灰
* Email: jianweie@163.com
* CreateTime: 2021/1/31 21:45:10
* Description: 暂无
***********************************************************************/
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Threading.Tasks;
using CoreCms.Net.Configuration;
using CoreCms.Net.IRepository;
using CoreCms.Net.IRepository.UnitOfWork;
using CoreCms.Net.IServices;
using CoreCms.Net.Loging;
using CoreCms.Net.Model.Entities;
using CoreCms.Net.Model.ViewModels.Basics;
using CoreCms.Net.Model.ViewModels.UI;
using CoreCms.Net.Utility.Helper;
using SqlSugar;
namespace CoreCms.Net.Services
{
/// <summary>
/// 退货单表 接口实现
/// </summary>
public class CoreCmsBillReshipServices : BaseServices<CoreCmsBillReship>, ICoreCmsBillReshipServices
{
private readonly ICoreCmsBillReshipRepository _dal;
private readonly ICoreCmsBillReshipItemRepository _billReshipItemRepository;
private readonly IUnitOfWork _unitOfWork;
public CoreCmsBillReshipServices(IUnitOfWork unitOfWork
, ICoreCmsBillReshipRepository dal
, ICoreCmsBillReshipItemRepository billReshipItemRepository
)
{
this._dal = dal;
base.BaseDal = dal;
_unitOfWork = unitOfWork;
_billReshipItemRepository = billReshipItemRepository;
}
/// <summary>
/// 创建退货单
/// </summary>
/// <param name="userId"></param>
/// <param name="orderId"></param>
/// <param name="aftersalesId"></param>
/// <param name="aftersalesItems"></param>
/// <returns></returns>
public async Task<WebApiCallBack> ToAdd(int userId, string orderId, string aftersalesId, List<CoreCmsBillAftersalesItem> aftersalesItems)
{
var jm = new WebApiCallBack();
if (aftersalesItems == null || aftersalesItems.Count <= 0)
{
jm.msg = GlobalErrorCodeVars.Code13209;
jm.data = jm.code = 13209;
return jm;
}
var model = new CoreCmsBillReship();
model.reshipId = CommonHelper.GetSerialNumberType((int)GlobalEnumVars.SerialNumberType.退);
model.orderId = orderId;
model.aftersalesId = aftersalesId;
model.userId = userId;
model.status = (int)GlobalEnumVars.BillReshipStatus.退;
model.createTime = DateTime.Now;
await _dal.InsertAsync(model);
var list = new List<CoreCmsBillReshipItem>();
foreach (var item in aftersalesItems)
{
var reshipItem = new CoreCmsBillReshipItem();
reshipItem.reshipId = model.reshipId;
reshipItem.orderItemsId = item.orderItemsId;
reshipItem.goodsId = item.goodsId;
reshipItem.productId = item.productId;
reshipItem.sn = item.sn;
reshipItem.bn = item.bn;
reshipItem.name = item.name;
reshipItem.imageUrl = item.imageUrl;
reshipItem.nums = item.nums;
reshipItem.addon = item.addon;
reshipItem.createTime = DateTime.Now;
list.Add(reshipItem);
//保存退货单明细
}
await _billReshipItemRepository.InsertAsync(list);
jm.status = true;
jm.data = model;
return jm;
}
#region
/// <summary>
/// 重写根据条件查询分页数据
/// </summary>
/// <param name="predicate">判断集合</param>
/// <param name="orderByType">排序方式</param>
/// <param name="pageIndex">当前页面索引</param>
/// <param name="pageSize">分布大小</param>
/// <param name="orderByExpression"></param>
/// <param name="blUseNoLock">是否使用WITH(NOLOCK)</param>
/// <returns></returns>
public async Task<IPageList<CoreCmsBillReship>> QueryPageAsync(Expression<Func<CoreCmsBillReship, bool>> predicate,
Expression<Func<CoreCmsBillReship, object>> orderByExpression, OrderByType orderByType, int pageIndex = 1,
int pageSize = 20)
{
return await _dal.QueryPageAsync(predicate, orderByExpression, orderByType, pageIndex, pageSize);
}
#endregion
#region
/// <summary>
/// 获取单个数据带导航
/// </summary>
/// <param name="predicate"></param>
/// <param name="orderByExpression"></param>
/// <param name="orderByType"></param>
/// <returns></returns>
public async Task<CoreCmsBillReship> GetDetails(Expression<Func<CoreCmsBillReship, bool>> predicate,
Expression<Func<CoreCmsBillReship, object>> orderByExpression, OrderByType orderByType)
{
return await _dal.GetDetails(predicate, orderByExpression, orderByType);
}
#endregion
}
}