order.js 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  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.redis = this.app.redis;
  11. this.redisKey = this.app.config.redisKey;
  12. this.model = this.ctx.model.Trade.Order;
  13. this.goodsModel = this.ctx.model.Shop.Goods;
  14. this.goodsSpecModel = this.ctx.model.Shop.GoodsSpec;
  15. this.addressModel = this.ctx.model.User.Address;
  16. this.cartModel = this.ctx.model.Trade.Cart;
  17. }
  18. /**
  19. * 进入下单页面
  20. * @param {Object} body 请求参数
  21. * @param body.key 缓存key
  22. */
  23. async toMakeOrder({ key }) {
  24. key = `${this.redisKey.orderKeyPrefix}${key}`;
  25. let data = await this.redis.get(key);
  26. if (!data) throw new BusinessError(ErrorCode.SERVICE_FAULT, '请求超时,请重新进入下单页');
  27. data = JSON.parse(data);
  28. console.log(data);
  29. let specsData = [];
  30. if (_.isArray(data)) {
  31. // 购物车来的: 1.循环校验 规格商品; 2.按店铺分组
  32. const { populate } = this.ctx.service.trade.cart.getRefMods();
  33. const carts = await this.cartModel.find({ _id: data }).populate(populate);
  34. for (const cart of carts) {
  35. const { result, msg } = await this.ctx.service.util.trade.checkCanBuy(cart, false);
  36. if (!result) throw new BusinessError(ErrorCode.DATA_INVALID, msg);
  37. }
  38. specsData = this.setCartsGoodsToPageData(carts);
  39. } else if (_.isObject(data)) {
  40. // 商品页单独买: 1.校验规格商品; 2:按店铺分组
  41. const { result, msg } = await this.ctx.service.util.trade.checkCanBuy(data, false);
  42. if (!result) throw new BusinessError(ErrorCode.DATA_INVALID, msg);
  43. const { populate } = this.ctx.service.shop.goodsSpec.getRefMods();
  44. const list = await this.goodsSpecModel.find({ _id: data.goodsSpec }).populate(populate);
  45. specsData = this.setGoodsToPageData(list, data.num);
  46. } else throw new BusinessError(ErrorCode.DATA_INVALID, '数据不正确,请重新下单');
  47. // 组装页面的数据
  48. const user = this.ctx.user;
  49. const customer = _.get(user, '_id');
  50. if (!customer) throw new BusinessError(ErrorCode.NOT_LOGIN, '未找到用户信息');
  51. const pageData = {};
  52. // 找到默认地址
  53. const address = await this.addressModel.findOne({ customer, is_default: '1' });
  54. pageData.address = address;
  55. // // 商品总价,各店铺的价格明细
  56. specsData = this.computedShopTotal(specsData);
  57. const shopTotalDetail = this.computedAllTotal(specsData);
  58. pageData.goodsData = specsData;
  59. pageData.orderTotal = shopTotalDetail;
  60. return pageData;
  61. }
  62. /**
  63. * 计算商店的结算
  64. * @param {Array} list 按店铺分组的商品列表
  65. */
  66. computedShopTotal(list) {
  67. for (const i of list) {
  68. i.goods_total = i.goods.reduce((p, n) => p + (n.money || 0) * (n.num || 0), 0);
  69. i.freight_total = i.goods.reduce((p, n) => p + (n.freight || 0) * (n.num || 0), 0);
  70. console.log(i);
  71. }
  72. return list;
  73. }
  74. /**
  75. * 计算订单的结算
  76. * @param {Array} list 按店铺分组的商品列表
  77. */
  78. computedAllTotal(list) {
  79. const obj = {
  80. goods_total: list.reduce((p, n) => p + (n.goods_total || 0), 0),
  81. freight_total: list.reduce((p, n) => p + (n.freight_total || 0), 0),
  82. };
  83. return obj;
  84. }
  85. /**
  86. * 单商品整理数据,剩下的可以简略
  87. * @param {Array} list 规格数组
  88. * @param num 购买数量
  89. */
  90. setGoodsToPageData(list, num) {
  91. // 按店铺分组,精简字段
  92. const arr = [];
  93. for (const i of list) {
  94. const obj = {};
  95. obj.shop_name = _.get(i.goods, 'shop.name');
  96. obj.shop = _.get(i.goods, 'shop._id');
  97. const goods = {};
  98. goods.goods_id = _.get(i.goods, '_id');
  99. goods.goods_name = _.get(i.goods, 'name');
  100. goods.goodsSpec_id = _.get(i, '_id');
  101. goods.goodsSpec_name = _.get(i, 'name');
  102. goods.freight = _.get(i, 'freight');
  103. goods.money = _.get(i, 'sell_money');
  104. goods.num = num;
  105. goods.file = _.get(i.goods, 'file');
  106. obj.goods = [ goods ];
  107. arr.push(obj);
  108. }
  109. return arr;
  110. }
  111. /**
  112. *购物车数据整理
  113. * @param {Array} list 规格数组
  114. */
  115. setCartsGoodsToPageData(list) {
  116. const arr = [];
  117. list = _.groupBy(list, 'shop._id');
  118. for (const key in list) {
  119. const data = list[key];
  120. const shopData = _.get(_.head(data), 'shop');
  121. const obj = {};
  122. obj.shop = _.get(shopData, '_id');
  123. obj.shop_name = _.get(shopData, 'name');
  124. const goodsList = [];
  125. for (const i of data) {
  126. const goods = {};
  127. goods.cart_id = _.get(i, '_id');
  128. goods.goods_id = _.get(i.goods, '_id');
  129. goods.goods_name = _.get(i.goods, 'name');
  130. goods.goodsSpec_id = _.get(i.goodsSpec, '_id');
  131. goods.goodsSpec_name = _.get(i.goodsSpec, 'name');
  132. goods.freight = _.get(i.goodsSpec, 'freight');
  133. goods.money = _.get(i.goodsSpec, 'sell_money');
  134. goods.num = _.get(i, 'num');
  135. goods.file = _.get(i.goods, 'file', []);
  136. goodsList.push(goods);
  137. }
  138. obj.goods = goodsList;
  139. arr.push(obj);
  140. }
  141. return arr;
  142. }
  143. /**
  144. * 重组购物车商品
  145. * @param {Object} goods 商品
  146. * @param {Object} goodsSpec 商品规格
  147. * @param {Object} data 购物车数据
  148. */
  149. setCartGoodsData(data) {
  150. const { goods, goodsSpec, _id, num = 1 } = data;
  151. const obj = {};
  152. obj.cart_id = _id;
  153. obj.goods_id = _.get(goods, '_id');
  154. obj.goods_name = _.get(goods, 'name');
  155. obj.goodsSpec_id = _.get(goodsSpec, '_id');
  156. obj.goodsSpec_name = _.get(goodsSpec, 'name');
  157. obj.freight = _.get(goodsSpec, 'freight');
  158. obj.money = _.get(goodsSpec, 'sell_money');
  159. obj.num = num;
  160. obj.file = _.get(goods, 'file');
  161. return obj;
  162. }
  163. }
  164. module.exports = OrderService;