order.js 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. 'use strict';
  2. const { CrudService } = require('naf-framework-mongoose-free/lib/service');
  3. const { BusinessError, ErrorCode } = require('naf-core').Error;
  4. const _ = require('lodash');
  5. const assert = require('assert');
  6. //
  7. class OrderService extends CrudService {
  8. constructor(ctx) {
  9. super(ctx, 'order');
  10. this.orderModel = this.ctx.model.Trade.Order;
  11. }
  12. // #region 下单前计算函数
  13. /**
  14. * 计算每个店铺的价格
  15. * @param {Array} list 按店铺分组的商品列表
  16. * list是经过 setCartsGoodsToPageData/setGoodsToPageData 处理过的数据
  17. * @param {String} type 订单类型码: 0常规单,1团购单
  18. */
  19. makeOrder_computedShopTotal(list, type = '0') {
  20. let sell_money_key;
  21. if (type === '1') sell_money_key = 'group_sell_money';
  22. else sell_money_key = 'money';
  23. for (const i of list) {
  24. i.goods_total = i.goods.reduce((p, n) => this.ctx.plus(p, this.ctx.multiply(_.get(n, sell_money_key), n.num)), 0);
  25. i.freight_total = i.goods.reduce((p, n) => this.ctx.plus(p, this.ctx.multiply(n.freight, n.num)), 0);
  26. }
  27. return list;
  28. }
  29. /**
  30. * 计算整个订单的价格
  31. * @param {Array} list 按店铺分组的商品列表
  32. * list是经过 setCartsGoodsToPageData/setGoodsToPageData 处理过的数据
  33. */
  34. makerOrder_computedOrderTotal(list) {
  35. const obj = {
  36. goods_total: list.reduce((p, n) => this.ctx.plus(p, n.goods_total), 0),
  37. freight_total: list.reduce((p, n) => this.ctx.plus(p, n.freight_total), 0),
  38. };
  39. return obj;
  40. }
  41. // #endregion
  42. /**
  43. * 计算需要支付的金额
  44. * @param {Object} order 支付订单信息
  45. * @return {Number} 订单实付金额
  46. */
  47. payOrder_RealPay(order) {
  48. let priceKey;
  49. if (_.get(order, 'type', '0') === '1') priceKey = 'ggrp';
  50. else priceKey = 'grp';
  51. const detail = this.moneyDetail(order);
  52. // 解除店铺层
  53. const sd = Object.values(detail);
  54. // 取出规格层
  55. const sgd = sd.map(i => Object.values(i));
  56. // 将规格明细降维至一维
  57. const oneLevel = _.flattenDeep(sgd);
  58. // 根据订单类型,计算应付(优惠券部分已经按订单类型计算并分配完了.这地方只是复现)
  59. const realPay = oneLevel.reduce((p, n) => this.ctx.plus(p, n[priceKey]), 0);
  60. return realPay;
  61. }
  62. /**
  63. * 计算需要支付的金额
  64. * @param {Object} order 支付订单信息
  65. * @return {Object} 返回:{
  66. * 店铺id:金额
  67. * }
  68. */
  69. shopMoneyTotal(order) {
  70. let priceKey;
  71. if (_.get(order, 'type', '0') === '1') priceKey = 'ggrp';
  72. else priceKey = 'grp';
  73. const detail = this.moneyDetail(order);
  74. const result = {};
  75. for (const s in detail) {
  76. const values = Object.values(_.get(detail, s, {}));
  77. const realPay = values.reduce((p, n) => this.ctx.plus(p, n[priceKey]), 0);
  78. result[s] = realPay;
  79. }
  80. return result;
  81. }
  82. /**
  83. * 计算店铺的金额明细
  84. * @param {Object} order 支付订单信息
  85. * @return {Object} 返回:{
  86. * 店铺id:{
  87. * goods_total:商品总价,
  88. * freight_total:商品总价
  89. * }
  90. * }
  91. */
  92. shopMoneyDetail(order) {
  93. if (!order) throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '未找到订单信息');
  94. let priceKey;
  95. if (_.get(order, 'type', '0') === '1') priceKey = 'ggrp';
  96. else priceKey = 'grp';
  97. const result = {};
  98. const moneyDetail = this.moneyDetail(order);
  99. for (const s in moneyDetail) {
  100. const obj = {};
  101. const d = _.get(moneyDetail, s, {});
  102. obj.goods_total = Object.values(d).reduce((p, n) => this.ctx.plus(p, _.get(n, priceKey, 0)), 0);
  103. obj.freight_total = Object.values(d).reduce((p, n) => this.ctx.plus(p, _.get(n, 'ft', 0)), 0);
  104. result[s] = obj;
  105. }
  106. return result;
  107. }
  108. /**
  109. * 按店铺-商品 计算该订单的价格明细
  110. * @param {Object} data 支付订单数据
  111. * @return {Object} 返回:{
  112. * 店铺id:{
  113. * 规格id:{
  114. * sm: 规格正常销售价格(sell_money),
  115. * f: 规格运费(freight),
  116. * bn: 购买数量(buy_num),
  117. * st: 规格正常销售总价(sell_total: sm * bn)
  118. * ft: 规格运费总价(freight_total: f * bn)
  119. * gt: 商品支付原价(goods_total: st + ft)
  120. * dd: {
  121. * key:优惠券id,
  122. * value:优惠价格
  123. * },
  124. * dt: 优惠总价(d_detail的value之和)
  125. * grp:商品实际支付价格(goods_real_pay: gt - dt)
  126. * gsm:规格团购销售价格(group_sell_money)
  127. * gst: 规格团购销售总价(group_sell_total: gsm * bn)
  128. * ggt: 商品团购支付原价(goods_group_total: gst + ft)
  129. * ggrp: 商品团购实际支付价格(goods_group_real_pay: ggt - dt)
  130. * }
  131. * }
  132. * }
  133. */
  134. moneyDetail(data) {
  135. if (!data) throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '未找到订单信息');
  136. // 优惠部分
  137. const ddt = _.get(data, 'total_detail.discount_detail', {});
  138. // 店铺规格商品数据
  139. const shopGoods = _.get(data, 'goods', []);
  140. const result = {};
  141. for (const s of shopGoods) {
  142. const { goods, shop } = s;
  143. const shopResult = {};
  144. for (const g of goods) {
  145. const { sell_money: sm, freight: f, buy_num: bn, group_config, _id } = g;
  146. const st = this.ctx.multiply(sm, bn);
  147. const ft = this.ctx.multiply(f, bn);
  148. const gt = this.ctx.plus(st, ft);
  149. const dd = {};
  150. for (const uc_id in ddt) {
  151. const detail = _.get(ddt, uc_id, {});
  152. const value = detail[_id];
  153. if (value) dd[uc_id] = value;
  154. }
  155. const dt = Object.values(dd).reduce((p, n) => this.ctx.plus(p, n), 0);
  156. const grp = this.ctx.minus(gt, dt);
  157. let obj = { sm, f, bn, st, ft, gt, dd, dt, grp };
  158. const gsm = _.get(group_config, 'money');
  159. if (gsm) {
  160. const gst = this.ctx.multiply(gsm, bn);
  161. const ggt = this.ctx.plus(gst, ft);
  162. const ggrp = this.ctx.minus(ggt, dt);
  163. obj = { ...obj, gsm, gst, ggt, ggrp };
  164. }
  165. shopResult[_id] = obj;
  166. }
  167. result[shop] = shopResult;
  168. }
  169. return result;
  170. }
  171. }
  172. module.exports = OrderService;