OrderService.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  1. using Ant.Core.Utils;
  2. using Ant.Core.WebApi.Enum;
  3. using Ant.Core.WebApi.Model;
  4. using Central.Control.WebApi.DbEntity;
  5. using Central.Control.WebApi.EFDbContext;
  6. using Central.Control.WebApi.Enum;
  7. using Central.Control.WebApi.Models.Request;
  8. using Central.Control.WebApi.Models.Response;
  9. using Central.Control.WebApi.Service.Interface;
  10. using System;
  11. using System.Collections.Generic;
  12. using System.Linq;
  13. using System.Web;
  14. namespace Central.Control.WebApi.Service
  15. {
  16. /// <summary>
  17. ///
  18. /// </summary>
  19. public class OrderService: IOrderService
  20. {
  21. private readonly IDbContext _dbContent;
  22. private readonly IUserService _userService;
  23. /// <summary>
  24. ///
  25. /// </summary>
  26. /// <param name="dbContent"></param>
  27. public OrderService(
  28. IDbContext dbContent,
  29. IUserService userService)
  30. {
  31. _dbContent = dbContent;
  32. _userService = userService;
  33. }
  34. /// <summary>
  35. /// 下单
  36. /// </summary>
  37. /// <param name="req"></param>
  38. /// <returns></returns>
  39. public ApiResult<OrderResponseDto> Order(OrderRequestDto req)
  40. {
  41. #region 1、验证参数
  42. if (req == null
  43. || req.OrderInfo == null
  44. || req.OrderInfo.Count() == 0)
  45. {
  46. return new ApiResult<OrderResponseDto>(ApiStatusCode.InvalidParameter, "请求参数不正确");
  47. }
  48. #endregion
  49. #region 2、验证相应数据和库存
  50. var productIds = req.OrderInfo.Select(p => p.ProductId).ToList();
  51. var products = _dbContent.Set<YW_Product>().Where(p => p.IsDelete == 0 && p.Sale == Enum.SaleEnum.On && productIds.Contains(p.Id)).ToList();
  52. if (products.Count() <= 0)
  53. {
  54. return new ApiResult<OrderResponseDto>(ApiStatusCode.RecordNotFound, "未找到下单的商品");
  55. }
  56. #endregion
  57. #region 3、包装盒库存验证
  58. var session = _userService.GetLoginSession();
  59. // 修改
  60. var devicePackings = _dbContent.Set<YW_DevicePacking>().Where(p => p.IsDelete == 0 && p.DeviceId == session.UserId).ToList();
  61. if (devicePackings == null || devicePackings.Count() == 0)
  62. {
  63. return new ApiResult<OrderResponseDto>(ApiStatusCode.Forbidden, "包装盒库存不足,请联系工作人员添加包装盒");
  64. }
  65. int orderCount = req.OrderInfo.Sum(p => p.Count);
  66. int packingCount = devicePackings.Sum(p => p.Stock * p.Capacity);
  67. if (packingCount < orderCount)
  68. {
  69. return new ApiResult<OrderResponseDto>(ApiStatusCode.Forbidden, "包装盒库存不足,请联系工作人员添加包装盒");
  70. }
  71. // 计算使用的包装盒数量(减包装盒库存)
  72. var orderCountIndex = orderCount;
  73. foreach (var devicePacking in devicePackings)
  74. {
  75. if (orderCountIndex <= 0)
  76. {
  77. break;// 数量为0了,则直接跳出循环
  78. }
  79. int currentPackingStock = devicePacking.Stock;
  80. for (int i = 0; i < currentPackingStock; i++)
  81. {
  82. // 循环库存
  83. if (orderCountIndex <= 0)
  84. {
  85. break;// 数量为0了,则直接跳出循环
  86. }
  87. orderCountIndex = orderCountIndex - devicePacking.Capacity;
  88. devicePacking.Stock--;// 减库存
  89. }
  90. }
  91. #endregion
  92. #region 4、商品库存验证
  93. var orderId = IdGenerator.NewId();
  94. List<YW_OrderDetails> orderDetailAdds = new List<YW_OrderDetails>();
  95. List<YW_OrderProcess> orderProcessAdds = new List<YW_OrderProcess>();
  96. foreach (var o in req.OrderInfo)
  97. {
  98. var currentProduct = products.FirstOrDefault(p => p.Id == o.ProductId);
  99. if (currentProduct == null)
  100. {
  101. return new ApiResult<OrderResponseDto>(ApiStatusCode.RecordNotFound, $"{o.ProductId}商品不存在");
  102. }
  103. if (currentProduct.Stock < o.Count)
  104. {
  105. return new ApiResult<OrderResponseDto>(ApiStatusCode.Forbidden, $"{currentProduct.Name}商品库存不足,请修改后重新下单");
  106. }
  107. // 扣库存
  108. currentProduct.Stock = currentProduct.Stock - o.Count;
  109. // orderDetails
  110. orderDetailAdds.Add(new YW_OrderDetails()
  111. {
  112. Id = IdGenerator.NewId(),
  113. OrderId = orderId,
  114. ProductId = currentProduct.Id,
  115. Name = currentProduct.Name,
  116. Code = currentProduct.Code,
  117. Img = currentProduct.Img,
  118. Info = currentProduct.Info,
  119. Price = currentProduct.Price,
  120. BuyingPrice = currentProduct.BuyingPrice,
  121. Count = o.Count,
  122. CreateBY = session.UserId
  123. });
  124. }
  125. #endregion
  126. #region 5、下单
  127. YW_Order order = new YW_Order()
  128. {
  129. Id = orderId,
  130. DeviceId = session.UserId,
  131. Price = orderDetailAdds.Sum(p => p.Price * p.Count),
  132. PayStatus = PayStatusEnum.UnPay,
  133. OrderStatus = OrderStatusEnum.UnPay,
  134. PaySerialId = Snowflake.Instance().GetId().ToString(),
  135. CreateBY = session.UserId
  136. };
  137. YW_OrderProcess orderProcess = new YW_OrderProcess()
  138. {
  139. Id = IdGenerator.NewId(),
  140. OrderId = order.Id,
  141. DeviceId = session.UserId,
  142. CurrentOrderStatus = OrderStatusEnum.UnPay,
  143. Message = "下单成功",
  144. CreateBY = session.Id
  145. };
  146. #endregion
  147. #region 6、存库
  148. _dbContent.Set<YW_Order>().Add(order);
  149. _dbContent.Set<YW_OrderProcess>().Add(orderProcess);
  150. _dbContent.Set<YW_OrderDetails>().AddRange(orderDetailAdds);
  151. // 数据库执行 库存已经改过了,会自动保存
  152. _dbContent.SaveChanges();
  153. #endregion
  154. return new ApiResult<OrderResponseDto>(new OrderResponseDto()
  155. {
  156. OrderId = order.Id,
  157. Price = order.Price
  158. });
  159. }
  160. /// <summary>
  161. /// 获取待烧烤的商品列表
  162. /// <returns></returns>
  163. public ApiResult<List<QueueOrderResponseDto>> GetQueueOrders()
  164. {
  165. var orders = _dbContent.Set<YW_Order>()
  166. .Where(p => p.IsDelete == 0
  167. && p.PayStatus == PayStatusEnum.Paid
  168. && p.OrderStatus == OrderStatusEnum.Paid)
  169. .OrderBy(p => p.CreateDT).ToList();
  170. var orderIds = orders.Select(p => p.Id).ToList();
  171. var orderDetails = _dbContent.Set<YW_OrderDetails>().Where(p => p.IsDelete == 0 && orderIds.Contains(p.OrderId)).ToList();
  172. List<QueueOrderResponseDto> result = new List<QueueOrderResponseDto>();
  173. orders.ForEach(item => {
  174. QueueOrderResponseDto resultItem = new QueueOrderResponseDto()
  175. {
  176. OrderId = item.Id,
  177. Price = item.Price,
  178. OrderDetails = orderDetails
  179. .Where(p => p.OrderId == item.Id)
  180. .Select(p => SafeClone<YW_OrderDetails, QueueOrderDetailsDto>.Trans(p))
  181. .ToList()
  182. };
  183. resultItem.OrderDetails?.ForEach(p => p.Img = $"{ProductService.ImagePrefix}{p.Img}");
  184. result.Add(resultItem);
  185. });
  186. return new ApiResult<List<QueueOrderResponseDto>>(result);
  187. }
  188. /// <summary>
  189. /// 回写流程状态
  190. /// </summary>
  191. /// <param name="req"></param>
  192. /// <returns></returns>
  193. public ApiResult OrderProcess(OrderProcessRequestDto req)
  194. {
  195. if (req == null)
  196. {
  197. return new ApiResult(ApiStatusCode.InvalidParameter, "请求参数不正确");
  198. }
  199. var order = _dbContent.Set<YW_Order>().FirstOrDefault(p => p.Id == req.OrderId);
  200. if (order == null)
  201. {
  202. return new ApiResult(ApiStatusCode.InvalidParameter, "未找到相应订单");
  203. }
  204. if (order.PayStatus != PayStatusEnum.Paid)
  205. {
  206. return new ApiResult(ApiStatusCode.InvalidParameter, "未支付订单不能回写流程");
  207. }
  208. if (order.OrderStatus == OrderStatusEnum.UnPay
  209. || order.OrderStatus == OrderStatusEnum.Cancel)
  210. {
  211. return new ApiResult(ApiStatusCode.InvalidParameter, "未支付或已取消订单不能回写流程");
  212. }
  213. var seesion = _userService.GetLoginSession();
  214. // 修改订单状态
  215. order.OrderStatus = req.OrderStatus;
  216. // 记录订单流程
  217. YW_OrderProcess orderProcess = new YW_OrderProcess()
  218. {
  219. Id = IdGenerator.NewId(),
  220. OrderId = req.OrderId,
  221. DeviceId = seesion.UserId,
  222. CurrentOrderStatus = req.OrderStatus,
  223. Message = req.Message,
  224. CreateBY = seesion.UserId
  225. };
  226. _dbContent.Set<YW_OrderProcess>().Add(orderProcess);
  227. _dbContent.SaveChanges();
  228. return new ApiResult();
  229. }
  230. /// <summary>
  231. /// 支付回写(雏形,需要根据实际需要接入支付宝或微信)
  232. /// </summary>
  233. /// <param name="req"></param>
  234. /// <returns></returns>
  235. public ApiResult PayWriteBack(PayWriteBackRequestDto req)
  236. {
  237. if (req == null
  238. || string.IsNullOrWhiteSpace(req.PaySerialId))
  239. {
  240. return new ApiResult(ApiStatusCode.InvalidParameter, "请求参数不正确");
  241. }
  242. var order = _dbContent.Set<YW_Order>().FirstOrDefault(p => p.PaySerialId == req.PaySerialId);
  243. if (order == null)
  244. {
  245. return new ApiResult(ApiStatusCode.InvalidParameter, "未找到相应订单");
  246. }
  247. var status = GetStatusByPayWriteBack(req.PayStatus);
  248. // 修改订单状态
  249. order.PayStatus = status.Item1;
  250. order.OrderStatus = status.Item2;
  251. // 记录订单流程
  252. YW_PayCall payCall = new YW_PayCall()
  253. {
  254. Id = IdGenerator.NewId(),
  255. OrderId = order.Id,
  256. PayStatus = status.Item1,
  257. PaySerialId = req.PaySerialId,
  258. PayAccount = req.PayAccount,
  259. CreateBY = req.PayAccount
  260. };
  261. _dbContent.Set<YW_PayCall>().Add(payCall);
  262. _dbContent.SaveChanges();
  263. return new ApiResult();
  264. }
  265. /// <summary>
  266. ///
  267. /// </summary>
  268. /// <param name="payStatusBack"></param>
  269. /// <returns></returns>
  270. private Tuple<PayStatusEnum, OrderStatusEnum> GetStatusByPayWriteBack(int payStatusBack)
  271. {
  272. // 临时:payStatus 0失败,1成功
  273. PayStatusEnum payStatus = PayStatusEnum.Fail;
  274. OrderStatusEnum orderStatus = OrderStatusEnum.UnPay;
  275. switch (payStatusBack)
  276. {
  277. case 1:// 成功
  278. payStatus = PayStatusEnum.Paid;
  279. orderStatus = OrderStatusEnum.Paid;
  280. break;
  281. default:// 失败
  282. break;
  283. }
  284. return new Tuple<PayStatusEnum, OrderStatusEnum>(payStatus, orderStatus);
  285. }
  286. // public Tuple<bool,string> ProcessOrderStock(int )
  287. }
  288. }