cart.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  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 CartService extends CrudService {
  8. constructor(ctx) {
  9. super(ctx, 'cart');
  10. this.model = this.ctx.model.Trade.Cart;
  11. this.goodsSpecModel = this.ctx.model.Shop.GoodsSpec;
  12. }
  13. /**
  14. * 返回购物车需要的数据格式
  15. * @param {Object} query 查询条件
  16. * @param query.customer 顾客id
  17. * @return {Array}
  18. */
  19. async selfCart({ customer }) {
  20. assert(customer, '缺少顾客信息');
  21. const { populate } = this.getRefMods();
  22. let list = await this.model.find({ customer }).populate(populate);
  23. list = JSON.parse(JSON.stringify(list));
  24. list = list.map(i => {
  25. const obj = {};
  26. obj.cart = _.get(i, '_id');
  27. obj.shop_name = _.get(i.shop, 'name');
  28. obj.shop = _.get(i.shop, '_id');
  29. obj.goods = this.setCartGoodsData(i.goods, i.goodsSpec);
  30. return obj;
  31. });
  32. list = _.groupBy(list, 'shop');
  33. const arr = [];
  34. for (const key in list) {
  35. const shopGroup = list[key];
  36. const goods = shopGroup.reduce((p, n) => {
  37. p.push(n.goods);
  38. return p;
  39. }, []);
  40. const shop = _.omit(_.head(shopGroup), [ 'goods' ]);
  41. arr.push({ ...shop, goods });
  42. }
  43. return arr;
  44. }
  45. /**
  46. * 重组购物车商品
  47. * @param {Object} goods 商品
  48. * @param {Object} goodsSpec 商品规格
  49. */
  50. setCartGoodsData(goods, goodsSpec) {
  51. const obj = {};
  52. obj.goods_id = _.get(goods, '_id');
  53. obj.goods_name = _.get(goods, 'name');
  54. obj.goodsSpec_id = _.get(goodsSpec, '_id');
  55. obj.goodsSpec_name = _.get(goodsSpec, 'name');
  56. obj.money = _.get(goodsSpec, 'sell_money');
  57. obj.num = _.get(goodsSpec, 'num');
  58. obj.file = _.get(goods, 'file');
  59. return obj;
  60. }
  61. /**
  62. * 创建购物车信息,若找到该店的该商品规格.进行库存校验
  63. * 数量进行合并;
  64. * 反之创建
  65. * @param {Object} body 请求参数
  66. * @param body.num 数量
  67. */
  68. async create({ num, ...body }) {
  69. const { customer, shop, goods, goodsSpec } = body;
  70. assert(customer, '缺少顾客信息');
  71. assert(shop, '缺少店铺信息');
  72. assert(goods, '缺少商品信息');
  73. assert(goodsSpec, '缺少商品规格信息');
  74. const data = await this.model.findOne(body);
  75. if (data) {
  76. const buyNum = parseInt(data.num) + parseInt(num);
  77. const { enough } = await this.checkGoodsNum({ goodsSpecId: goodsSpec, num: buyNum });
  78. if (!enough) throw new BusinessError(ErrorCode.SERVICE_FAULT, '库存不足,无法添加至购物车');
  79. data.num = buyNum;
  80. await data.save();
  81. } else {
  82. const { enough } = await this.checkGoodsNum({ goodsSpecId: goodsSpec, num });
  83. if (!enough) throw new BusinessError(ErrorCode.SERVICE_FAULT, '库存不足,无法添加至购物车');
  84. await this.model.create({ num, ...body });
  85. }
  86. }
  87. /**
  88. * 检查商品规格的库存
  89. * @param {String} goodsSpecId 商品规格id
  90. * @param {Number} num 需要的库存数量
  91. * @return {Boolean} true:库存满足购物车条件;false:库存不满足条件
  92. */
  93. async checkGoodsNum({ goodsSpecId, num }) {
  94. const goodsSpec = await this.goodsSpecModel.findById(goodsSpecId);
  95. if (!goodsSpec) throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '未找到商品的规格数据');
  96. const { num: gsnum = 0 } = goodsSpec;
  97. return { enough: gsnum >= num, total: gsnum };
  98. }
  99. }
  100. module.exports = CartService;