order.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  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. }
  17. /**
  18. * 进入下单页面
  19. * @param {Object} body 请求参数
  20. * @param body.key 缓存key
  21. */
  22. async toMakeOrder({ key }) {
  23. key = `${this.redisKey.orderKeyPrefix}${key}`;
  24. let data = await this.redis.get(key);
  25. if (!data) throw new BusinessError(ErrorCode.SERVICE_FAULT, '请求超时,请重新进入下单页');
  26. data = JSON.parse(data);
  27. const { populate } = this.ctx.service.shop.goodsSpec.getRefMods();
  28. let specsData = [];
  29. if (_.isArray(data)) {
  30. // 购物车来的: 1.循环校验 规格商品; 2.按店铺分组
  31. } else if (_.isObject(data)) {
  32. // 商品页单独买: 1.校验规格商品; 2:按店铺分组
  33. const { result, msg } = await this.ctx.service.util.trade.checkCanBuy(data, false);
  34. if (!result) throw new BusinessError(ErrorCode.DATA_INVALID, msg);
  35. const list = await this.goodsSpecModel.find({ _id: data.goodsSpec }).populate(populate);
  36. specsData = this.setGoodsToPageData(list, data.num);
  37. } else throw new BusinessError(ErrorCode.DATA_INVALID, '数据不正确,请重新下单');
  38. // 组装页面的数据
  39. const user = this.ctx.user;
  40. const customer = _.get(user, '_id');
  41. if (!customer) throw new BusinessError(ErrorCode.NOT_LOGIN, '未找到用户信息');
  42. const pageData = {};
  43. // 找到默认地址
  44. const address = await this.addressModel.findOne({ customer, is_default: '1' });
  45. pageData.address = address;
  46. // 商品总价,各店铺的价格明细
  47. specsData = this.computedShopTotal(specsData);
  48. const shopTotalDetail = this.computedAllTotal(specsData);
  49. pageData.goodsData = specsData;
  50. pageData.orderTotal = shopTotalDetail;
  51. return pageData;
  52. }
  53. /**
  54. * 计算商店的结算
  55. * @param {Array} list 按店铺分组的商品列表
  56. */
  57. computedShopTotal(list) {
  58. for (const i of list) {
  59. i.goods_total = i.goods.reduce((p, n) => p + (n.money || 0), 0);
  60. i.freight_total = i.goods.reduce((p, n) => p + (n.freight || 0), 0);
  61. }
  62. return list;
  63. }
  64. /**
  65. * 计算订单的结算
  66. * @param {Array} list 按店铺分组的商品列表
  67. */
  68. computedAllTotal(list) {
  69. const obj = {
  70. goods_total: list.reduce((p, n) => p + (n.goods_total || 0), 0),
  71. freight_total: list.reduce((p, n) => p + (n.freight_total || 0), 0),
  72. };
  73. return obj;
  74. }
  75. /**
  76. * 单商品整理数据,需要商品与规格的快照,剩下的可以简略
  77. * @param {Array} list 规格数组
  78. * @param num 购买数量
  79. */
  80. setGoodsToPageData(list, num) {
  81. // 按店铺分组,精简字段
  82. const arr = [];
  83. for (const i of list) {
  84. const obj = {};
  85. obj.shop_name = _.get(i.goods, 'shop.name');
  86. obj.shop = _.get(i.goods, 'shop._id');
  87. const goods = {};
  88. goods.goods_id = _.get(i.goods, '_id');
  89. goods.goods_name = _.get(i.goods, 'name');
  90. goods.goodsSpec_id = _.get(i, '_id');
  91. goods.goodsSpec_name = _.get(i, 'name');
  92. goods.freight = _.get(i, 'freight');
  93. goods.money = _.get(i, 'sell_money');
  94. goods.num = num;
  95. goods.file = _.get(i.goods, 'file');
  96. obj.goods = [ goods ];
  97. arr.push(obj);
  98. }
  99. return arr;
  100. }
  101. /**
  102. * 重组购物车商品
  103. * @param {Object} goods 商品
  104. * @param {Object} goodsSpec 商品规格
  105. * @param {Object} data 购物车数据
  106. */
  107. setCartGoodsData(data) {
  108. const { goods, goodsSpec, _id, num = 1 } = data;
  109. const obj = {};
  110. obj.cart_id = _id;
  111. obj.goods_id = _.get(goods, '_id');
  112. obj.goods_name = _.get(goods, 'name');
  113. obj.goodsSpec_id = _.get(goodsSpec, '_id');
  114. obj.goodsSpec_name = _.get(goodsSpec, 'name');
  115. obj.freight = _.get(goodsSpec, 'freight');
  116. obj.money = _.get(goodsSpec, 'sell_money');
  117. obj.num = num;
  118. obj.file = _.get(goods, 'file');
  119. return obj;
  120. }
  121. }
  122. module.exports = OrderService;