'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'); const { ObjectId } = require('mongoose').Types; // class OrderService extends CrudService { constructor(ctx) { super(ctx, 'order'); this.orderModel = this.ctx.model.Trade.Order; this.orderDetailModel = this.ctx.model.Trade.OrderDetail; this.shopModel = this.ctx.model.Shop.Shop; this.goodsRateModel = this.ctx.model.Shop.GoodsRate; this.afterSaleModel = this.ctx.model.Trade.AfterSale; } async getOrder({ id }) { const num = await this.orderModel.count({ _id: id }); if (num > 0) return this.ctx.service.trade.order.fetch({ id }); return this.ctx.service.trade.orderDetail.fetch({ id }); } async allOrder(query = {}) { const { skip, limit } = query; const customer = _.get(this.ctx, 'user._id'); if (!customer) throw new BusinessError(ErrorCode.NOT_LOGIN); const pipeline = []; const step1 = [ { $addFields: { order_id: { $toString: '$_id' } } }, { $lookup: { from: 'orderDetail', localField: 'order_id', foreignField: 'order', as: 'orderDetails', }, }, ]; pipeline.push(...step1); const step2 = [ { $project: { data: { $cond: { if: { $gt: [{ $size: '$orderDetails' }, 0 ] }, then: '$orderDetails', else: '$$CURRENT', }, }, }, }, ]; pipeline.push(...step2); pipeline.push({ $unwind: '$data' }); pipeline.push({ $replaceRoot: { newRoot: '$data' } }); pipeline.push({ $match: { customer } }); const qp = _.cloneDeep(pipeline); qp.push({ $sort: { 'meta.createdAt': -1 } }); if (skip && limit) qp.push({ $skip: parseInt(skip) }, { $limit: parseInt(limit) }); const data = await this.orderModel.aggregate(qp); const tr = await this.orderModel.aggregate([ ...pipeline, { $count: 'total' }]); const newArr = []; for (const i of data) { const { pay, goods } = i; let obj = {}; if (pay) { // 这个是order表的数据,需要用order的计算方式 const buy_num_total = goods.reduce((p, n) => { let num = 0; if (_.get(n, 'is_set') === '0') num = _.get(n, 'buy_num'); else { const goods = _.get(n, 'goods', []); num = goods.reduce((np, nn) => this.ctx.plus(np, nn.buy_num), 0); } return this.ctx.plus(p, num); }, 0); obj.buy_num_total = buy_num_total; obj.real_pay = _.get(i, 'pay.pay_money'); const shopData = _.pick(_.head(goods), [ 'shop', 'shop_name' ]); obj.shop = { _id: shopData.shop, name: shopData.shop_name }; if (!_.get(shopData, 'name')) { const d = await this.shopModel.findById(shopData.shop, { name: 1 }).lean(); obj.shop.name = d.name; } const specs = []; for (const shop of goods) { const { goods: specGoods, is_set = '1' } = shop; if (is_set === '1') { for (const sg of specGoods) { const spec = _.pick(sg, [ '_id', 'name', 'file', 'act', 'buy_num', 'gift', 'price', 'freight', 'sp_price' ]); if (!spec.price) spec.price = _.get(sg, 'sell_money'); const goods = _.pick(sg.goods, [ '_id', 'name', 'file' ]); spec.goods = goods; specs.push(spec); } } else { const goods = _.get(shop, 'goods', []); const obj = _.omit(shop, [ 'goods', 'meta' ]); const newGoods = goods.map(i => { const ngo = { goods: { name: _.get(i, 'goods.name'), file: _.get(i, 'goods.file') }, spec: { name: _.get(i, 'spec.name'), file: _.get(i, 'spec.file') }, set_num: _.get(i, 'set_num'), }; return ngo; }); obj.goods = newGoods; specs.push(obj); } } obj.spec = specs; const others = _.pick(i, [ '_id', 'status', 'is_afterSale', 'is_rate', 'price', 'total_detail', 'type' ]); obj = { ...obj, ...others, is_order: true }; } else { // 是orderDetail表的数据,需要用orderDetail的计算方式 const real_pay = this.ctx.service.util.orderDetail.computedRealPay(i); obj.real_pay = real_pay; obj.buy_num_total = goods.reduce((p, n) => this.ctx.plus(p, n.buy_num), 0); const others = _.pick(i, [ '_id', 'status', 'is_afterSale', 'is_rate', 'price', 'total_detail', 'type', 'transport', 'transport_type' ]); const shop = await this.shopModel.findById(i.shop, { name: 1 }).lean(); obj.shop = shop; const afterSale = await this.afterSaleModel.find({ order_detail: i._id }); const rate = await this.goodsRateModel.find({ orderDetail: i._id }); const specs = []; for (const sg of goods) { const { is_set = '1' } = sg; if (is_set === '1') { const spec = _.pick(sg, [ '_id', 'name', 'file', 'act', 'buy_num', 'gift', 'price', 'freight', 'sp_price' ]); if (!spec.price) spec.price = _.get(sg, 'sell_money'); const goods = _.pick(sg.goods, [ '_id', 'name', 'file' ]); spec.goods = goods; const r = afterSale.find(f => ObjectId(_.get(f, 'goods._id')).equals(sg._id)); if (r) spec.is_afterSale = true; else spec.is_afterSale = false; const r2 = rate.find(f => ObjectId(_.get(f, 'goodsSpec')).equals(sg._id)); if (r2) { spec.is_rate = true; spec.rate = r2._id; } else spec.is_rate = false; specs.push(spec); } else { const goods = _.get(sg, 'goods', []); const obj = _.omit(sg, [ 'goods', 'meta' ]); const newGoods = goods.map(i => { const ngo = { goods: { name: _.get(i, 'goods.name'), file: _.get(i, 'goods.file') }, spec: { name: _.get(i, 'spec.name'), file: _.get(i, 'spec.file') }, set_num: _.get(i, 'set_num'), }; const r = afterSale.find(f => _.get(f, 'goods._id') === _.get(i, 'spec._id')); if (r) ngo.is_afterSale = true; else ngo.is_afterSale = false; const r2 = rate.find(f => _.get(f, 'goodsSpec') === _.get(i, 'spec._id')); if (r2) { ngo.is_rate = true; ngo.rate = r2._id; } else ngo.is_rate = false; return ngo; }); obj.goods = newGoods; specs.push(obj); } } obj.spec = specs; obj = { ...obj, ...others, is_order: false }; } newArr.push(obj); } const total = _.get(_.head(tr), 'total', 0); return { data: newArr, total }; } } module.exports = OrderService;