123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 |
- '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 = this.ctx.plus(data.num, 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 });
- }
- }
- /**
- * 检查商品规格的库存
- * @param {String} goodsSpecId 商品规格id
- * @param {String} cartId 购物车id
- * @param {Number} num 需要的库存数量
- * @param {Boolean} update 修改购物车
- * @return {Boolean} true:库存满足购物车条件;false:库存不满足条件
- */
- async checkGoodsNum({ cartId, goodsSpecId, num }, update = true) {
- const { populate } = this.ctx.service.shop.goodsSpec.getRefMods();
- const goodsSpec = await this.goodsSpecModel.findById(goodsSpecId).populate(populate);
- if (!goodsSpec) throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '未找到商品的规格数据');
- const goods = _.get(goodsSpec, 'goods');
- const shop = _.get(goods, 'shop');
- const shopRes = this.ctx.service.util.trade.checkShop(shop);
- if (shopRes.result !== true) throw new BusinessError(ErrorCode.DATA_INVALID, shopRes.msg);
- const goodsRes = this.ctx.service.util.trade.checkGoods(goods);
- if (goodsRes.result !== true) throw new BusinessError(ErrorCode.DATA_INVALID, goodsRes.msg);
- const gsRes = this.ctx.service.util.trade.checkGoodsSpec(goodsSpec, num);
- const { num: gsnum = 0 } = goodsSpec;
- if (gsRes.result !== true) {
- return { enough: false, total: gsnum, msg: gsRes.msg };
- }
- if (update && cartId) {
- await this.model.updateOne({ _id: cartId }, { num });
- }
- return { enough: true, total: gsnum };
- }
- }
- module.exports = CartService;
|