cart.js 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  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. ** 添加促销部分:
  16. ** 买赠,特价,加价购: 需要查询每个商品是否参与了这三项活动,需要给出对应数据
  17. ** 满减/折:不需要在购物车出现
  18. ** 套装:最后下单时组合,购物车中不需要额外修改
  19. * @param {Object} query 查询条件
  20. * @param query.customer 顾客id
  21. * @return {Array}
  22. */
  23. async selfCart({ customer }) {
  24. assert(customer, '缺少顾客信息');
  25. const data = await this.model.find({ customer });
  26. const actList = await this.ctx.service.trade.order.getActList(data);
  27. const pageData = await this.ctx.service.trade.order.getPageData(data, actList);
  28. return pageData;
  29. }
  30. /**
  31. * 重组购物车商品
  32. * @param {Object} goods 商品
  33. * @param {Object} goodsSpec 商品规格
  34. * @param {Object} data 购物车数据
  35. */
  36. setCartGoodsData(data) {
  37. const { goods, goodsSpec, _id, num = 1 } = data;
  38. const obj = {};
  39. obj.cart_id = _id;
  40. obj.goods_id = _.get(goods, '_id');
  41. obj.goods_name = _.get(goods, 'name');
  42. obj.goodsSpec_id = _.get(goodsSpec, '_id');
  43. obj.goodsSpec_name = _.get(goodsSpec, 'name');
  44. obj.money = _.get(goodsSpec, 'sell_money');
  45. obj.num = num;
  46. obj.file = _.get(goods, 'file');
  47. return obj;
  48. }
  49. /**
  50. ** 创建购物车信息,若找到该店的该商品规格.进行库存校验
  51. ** 数量进行合并;
  52. ** 反之创建
  53. ** 添加促销活动部分:
  54. ** 买赠,特价,加价购: 不需要在创建时处理,而是在查询时实时处理,显示相关信息
  55. ** 满减/折:不需要在购物车出现
  56. ** 套装:只有套装需要记录在购物车中,以同一商品形式出现
  57. * @param {Object} body 请求参数
  58. * @param body.num 数量
  59. */
  60. async create({ num, ...body }) {
  61. const { customer, shop, goods, goodsSpec, act } = body;
  62. assert(customer, '缺少顾客信息');
  63. assert(shop, '缺少店铺信息');
  64. assert(goods, '缺少商品信息');
  65. assert(goodsSpec, '缺少商品规格信息');
  66. const query = _.pick(body, [ 'customer', 'shop', 'goods', 'goodsSpec' ]);
  67. const data = await this.model.findOne(query);
  68. if (data) {
  69. const buyNum = this.ctx.plus(data.num, num);
  70. const { enough } = await this.checkGoodsNum({ goodsSpecId: goodsSpec, num: buyNum });
  71. if (!enough) throw new BusinessError(ErrorCode.SERVICE_FAULT, '库存不足,无法添加至购物车');
  72. data.num = buyNum;
  73. if (act) data.act = act;
  74. await data.save();
  75. } else {
  76. const { enough } = await this.checkGoodsNum({ goodsSpecId: goodsSpec, num });
  77. if (!enough) throw new BusinessError(ErrorCode.SERVICE_FAULT, '库存不足,无法添加至购物车');
  78. await this.model.create({ num, ...body });
  79. }
  80. }
  81. /**
  82. * 检查商品规格的库存
  83. * @param {String} goodsSpecId 商品规格id
  84. * @param {String} cartId 购物车id
  85. * @param {Number} num 需要的库存数量
  86. * @param {Boolean} update 修改购物车
  87. * @return {Boolean} true:库存满足购物车条件;false:库存不满足条件
  88. */
  89. async checkGoodsNum({ cartId, goodsSpecId, num }, update = true) {
  90. const { populate } = this.ctx.service.shop.goodsSpec.getRefMods();
  91. const goodsSpec = await this.goodsSpecModel.findById(goodsSpecId).populate(populate);
  92. if (!goodsSpec) throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '未找到商品的规格数据');
  93. const goods = _.get(goodsSpec, 'goods');
  94. const shop = _.get(goods, 'shop');
  95. const shopRes = this.ctx.service.util.trade.checkShop(shop);
  96. if (shopRes.result !== true) throw new BusinessError(ErrorCode.DATA_INVALID, shopRes.msg);
  97. const goodsRes = this.ctx.service.util.trade.checkGoods(goods);
  98. if (goodsRes.result !== true) throw new BusinessError(ErrorCode.DATA_INVALID, goodsRes.msg);
  99. const gsRes = this.ctx.service.util.trade.checkGoodsSpec(goodsSpec, num);
  100. const { num: gsnum = 0 } = goodsSpec;
  101. if (gsRes.result !== true) {
  102. return { enough: false, total: gsnum, msg: gsRes.msg };
  103. }
  104. if (update && cartId) {
  105. await this.model.updateOne({ _id: cartId }, { num });
  106. }
  107. return { enough: true, total: gsnum };
  108. }
  109. }
  110. module.exports = CartService;