'use strict'; const { CrudService } = require('naf-framework-mongoose-free/lib/service'); const { BusinessError, ErrorCode } = require('naf-core').Error; const _ = require('lodash'); const assert = require('assert'); // class CartService extends CrudService { constructor(ctx) { super(ctx, 'cart'); this.model = this.ctx.model.Trade.Cart; this.goodsSpecModel = this.ctx.model.Shop.GoodsSpec; } /** * 返回购物车需要的数据格式 * @param {Object} query 查询条件 * @param query.customer 顾客id * @return {Array} */ async selfCart({ customer }) { assert(customer, '缺少顾客信息'); const { populate } = this.getRefMods(); let list = await this.model.find({ customer }).populate(populate); list = JSON.parse(JSON.stringify(list)); list = list.map(i => { const obj = {}; obj.shop_name = _.get(i.shop, 'name'); obj.shop = _.get(i.shop, '_id'); obj.goods = this.setCartGoodsData(i); return obj; }); list = _.groupBy(list, 'shop'); const arr = []; for (const key in list) { const shopGroup = list[key]; const goods = shopGroup.reduce((p, n) => { p.push(n.goods); return p; }, []); const shop = _.omit(_.head(shopGroup), [ 'goods' ]); arr.push({ ...shop, goods }); } return arr; } /** * 重组购物车商品 * @param {Object} goods 商品 * @param {Object} goodsSpec 商品规格 * @param {Object} data 购物车数据 */ setCartGoodsData(data) { const { goods, goodsSpec, _id, num = 1 } = data; const obj = {}; obj.cart_id = _id; obj.goods_id = _.get(goods, '_id'); obj.goods_name = _.get(goods, 'name'); obj.goodsSpec_id = _.get(goodsSpec, '_id'); obj.goodsSpec_name = _.get(goodsSpec, 'name'); obj.money = _.get(goodsSpec, 'sell_money'); obj.num = num; obj.file = _.get(goods, 'file'); return obj; } /** * 创建购物车信息,若找到该店的该商品规格.进行库存校验 * 数量进行合并; * 反之创建 * @param {Object} body 请求参数 * @param body.num 数量 */ async create({ num, ...body }) { const { customer, shop, goods, goodsSpec } = body; assert(customer, '缺少顾客信息'); assert(shop, '缺少店铺信息'); assert(goods, '缺少商品信息'); assert(goodsSpec, '缺少商品规格信息'); const data = await this.model.findOne(body); if (data) { const buyNum = parseInt(data.num) + parseInt(num); const { enough } = await this.checkGoodsNum({ goodsSpecId: goodsSpec, num: buyNum }); if (!enough) throw new BusinessError(ErrorCode.SERVICE_FAULT, '库存不足,无法添加至购物车'); data.num = buyNum; await data.save(); } else { const { enough } = await this.checkGoodsNum({ goodsSpecId: goodsSpec, num }); if (!enough) throw new BusinessError(ErrorCode.SERVICE_FAULT, '库存不足,无法添加至购物车'); await this.model.create({ num, ...body }); } } /** * 检查商品规格的库存 * TODO 检查商品的是否满足销售条件 & 规格是否在销售中 * @param {String} goodsSpecId 商品规格id * @param {Number} num 需要的库存数量 * @return {Boolean} true:库存满足购物车条件;false:库存不满足条件 */ async checkGoodsNum({ goodsSpecId, num }) { const goodsSpec = await this.goodsSpecModel.findById(goodsSpecId); if (!goodsSpec) throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '未找到商品的规格数据'); const { num: gsnum = 0 } = goodsSpec; return { enough: gsnum >= num, total: gsnum }; } } module.exports = CartService;