order.js 7.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. const { ObjectId } = require('mongoose').Types;
  7. //
  8. class OrderService extends CrudService {
  9. constructor(ctx) {
  10. super(ctx, 'order');
  11. this.orderModel = this.ctx.model.Trade.Order;
  12. this.orderDetailModel = this.ctx.model.Trade.OrderDetail;
  13. this.shopModel = this.ctx.model.Shop.Shop;
  14. this.goodsRateModel = this.ctx.model.Shop.GoodsRate;
  15. this.afterSaleModel = this.ctx.model.Trade.AfterSale;
  16. }
  17. async getOrder({ id }) {
  18. const num = await this.orderModel.count({ _id: id });
  19. if (num > 0) return this.ctx.service.trade.order.fetch({ id });
  20. return this.ctx.service.trade.orderDetail.fetch({ id });
  21. }
  22. async allOrder(query = {}) {
  23. const { skip, limit } = query;
  24. const customer = _.get(this.ctx, 'user._id');
  25. if (!customer) throw new BusinessError(ErrorCode.NOT_LOGIN);
  26. const pipeline = [];
  27. const step1 = [
  28. { $addFields: { order_id: { $toString: '$_id' } } },
  29. {
  30. $lookup: {
  31. from: 'orderDetail',
  32. localField: 'order_id',
  33. foreignField: 'order',
  34. as: 'orderDetails',
  35. },
  36. },
  37. ];
  38. pipeline.push(...step1);
  39. const step2 = [
  40. {
  41. $project: {
  42. data: {
  43. $cond: {
  44. if: { $gt: [{ $size: '$orderDetails' }, 0 ] },
  45. then: '$orderDetails',
  46. else: '$$CURRENT',
  47. },
  48. },
  49. },
  50. },
  51. ];
  52. pipeline.push(...step2);
  53. pipeline.push({ $unwind: '$data' });
  54. pipeline.push({ $replaceRoot: { newRoot: '$data' } });
  55. pipeline.push({ $match: { customer } });
  56. const qp = _.cloneDeep(pipeline);
  57. qp.push({ $sort: { 'meta.createdAt': -1 } });
  58. if (skip && limit) qp.push({ $skip: parseInt(skip) }, { $limit: parseInt(limit) });
  59. const data = await this.orderModel.aggregate(qp);
  60. const tr = await this.orderModel.aggregate([ ...pipeline, { $count: 'total' }]);
  61. const newArr = [];
  62. for (const i of data) {
  63. const { pay, goods } = i;
  64. let obj = {};
  65. if (pay) {
  66. // 这个是order表的数据,需要用order的计算方式
  67. const buy_num_total = goods.reduce((p, n) => {
  68. let num = 0;
  69. if (_.get(n, 'is_set') === '0') num = _.get(n, 'buy_num');
  70. else {
  71. const goods = _.get(n, 'goods', []);
  72. num = goods.reduce((np, nn) => this.ctx.plus(np, nn.buy_num), 0);
  73. }
  74. return this.ctx.plus(p, num);
  75. }, 0);
  76. obj.buy_num_total = buy_num_total;
  77. obj.real_pay = _.get(i, 'pay.pay_money');
  78. const shopData = _.pick(_.head(goods), [ 'shop', 'shop_name' ]);
  79. obj.shop = { _id: shopData.shop, name: shopData.shop_name };
  80. if (!_.get(shopData, 'name')) {
  81. const d = await this.shopModel.findById(shopData.shop, { name: 1 }).lean();
  82. obj.shop.name = d.name;
  83. }
  84. const specs = [];
  85. for (const shop of goods) {
  86. const { goods: specGoods, is_set = '1' } = shop;
  87. if (is_set === '1') {
  88. for (const sg of specGoods) {
  89. const spec = _.pick(sg, [ '_id', 'name', 'file', 'act', 'buy_num', 'gift', 'price', 'freight', 'sp_price' ]);
  90. if (!spec.price) spec.price = _.get(sg, 'sell_money');
  91. const goods = _.pick(sg.goods, [ '_id', 'name', 'file' ]);
  92. spec.goods = goods;
  93. specs.push(spec);
  94. }
  95. } else {
  96. const goods = _.get(shop, 'goods', []);
  97. const obj = _.omit(shop, [ 'goods', 'meta' ]);
  98. const newGoods = goods.map(i => {
  99. const ngo = {
  100. goods: { name: _.get(i, 'goods.name'), file: _.get(i, 'goods.file') },
  101. spec: { name: _.get(i, 'spec.name'), file: _.get(i, 'spec.file') },
  102. set_num: _.get(i, 'set_num'),
  103. };
  104. return ngo;
  105. });
  106. obj.goods = newGoods;
  107. specs.push(obj);
  108. }
  109. }
  110. obj.spec = specs;
  111. const others = _.pick(i, [ '_id', 'status', 'is_afterSale', 'is_rate', 'price', 'total_detail', 'type' ]);
  112. obj = { ...obj, ...others, is_order: true };
  113. } else {
  114. // 是orderDetail表的数据,需要用orderDetail的计算方式
  115. const real_pay = this.ctx.service.util.orderDetail.computedRealPay(i);
  116. obj.real_pay = real_pay;
  117. obj.buy_num_total = goods.reduce((p, n) => this.ctx.plus(p, n.buy_num), 0);
  118. const others = _.pick(i, [ '_id', 'status', 'is_afterSale', 'is_rate', 'price', 'total_detail', 'type', 'transport', 'transport_type' ]);
  119. const shop = await this.shopModel.findById(i.shop, { name: 1 }).lean();
  120. obj.shop = shop;
  121. const afterSale = await this.afterSaleModel.find({ order_detail: i._id });
  122. const rate = await this.goodsRateModel.find({ orderDetail: i._id });
  123. const specs = [];
  124. for (const sg of goods) {
  125. const { is_set = '1' } = sg;
  126. if (is_set === '1') {
  127. const spec = _.pick(sg, [ '_id', 'name', 'file', 'act', 'buy_num', 'gift', 'price', 'freight', 'sp_price' ]);
  128. if (!spec.price) spec.price = _.get(sg, 'sell_money');
  129. const goods = _.pick(sg.goods, [ '_id', 'name', 'file' ]);
  130. spec.goods = goods;
  131. const r = afterSale.find(f => ObjectId(_.get(f, 'goods._id')).equals(sg._id));
  132. if (r) spec.is_afterSale = true;
  133. else spec.is_afterSale = false;
  134. const r2 = rate.find(f => ObjectId(_.get(f, 'goodsSpec')).equals(sg._id));
  135. if (r2) {
  136. spec.is_rate = true;
  137. spec.rate = r2._id;
  138. } else spec.is_rate = false;
  139. specs.push(spec);
  140. } else {
  141. const goods = _.get(sg, 'goods', []);
  142. const obj = _.omit(sg, [ 'goods', 'meta' ]);
  143. const newGoods = goods.map(i => {
  144. const ngo = {
  145. goods: { name: _.get(i, 'goods.name'), file: _.get(i, 'goods.file') },
  146. spec: { name: _.get(i, 'spec.name'), file: _.get(i, 'spec.file') },
  147. set_num: _.get(i, 'set_num'),
  148. };
  149. const r = afterSale.find(f => _.get(f, 'goods._id') === _.get(i, 'spec._id'));
  150. if (r) ngo.is_afterSale = true;
  151. else ngo.is_afterSale = false;
  152. const r2 = rate.find(f => _.get(f, 'goodsSpec') === _.get(i, 'spec._id'));
  153. if (r2) {
  154. ngo.is_rate = true;
  155. ngo.rate = r2._id;
  156. } else ngo.is_rate = false;
  157. return ngo;
  158. });
  159. obj.goods = newGoods;
  160. specs.push(obj);
  161. }
  162. }
  163. obj.spec = specs;
  164. obj = { ...obj, ...others, is_order: false };
  165. }
  166. newArr.push(obj);
  167. }
  168. const total = _.get(_.head(tr), 'total', 0);
  169. return { data: newArr, total };
  170. }
  171. }
  172. module.exports = OrderService;