'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 OrderService extends CrudService { constructor(ctx) { super(ctx, 'order'); this.orderModel = this.ctx.model.Trade.Order; } // #region 下单前计算函数 /** * 计算每个店铺的价格 * @param {Array} list 按店铺分组的商品列表 * list是经过 setCartsGoodsToPageData/setGoodsToPageData 处理过的数据 * @param {String} type 订单类型码: 0常规单,1团购单 */ makeOrder_computedShopTotal(list, type = '0') { let sell_money_key; if (type === '1') sell_money_key = 'group_sell_money'; else sell_money_key = 'money'; for (const i of list) { i.goods_total = i.goods.reduce((p, n) => this.ctx.plus(p, this.ctx.multiply(_.get(n, sell_money_key), n.num)), 0); i.freight_total = i.goods.reduce((p, n) => this.ctx.plus(p, this.ctx.multiply(n.freight, n.num)), 0); } return list; } /** * 计算整个订单的价格 * @param {Array} list 按店铺分组的商品列表 * list是经过 setCartsGoodsToPageData/setGoodsToPageData 处理过的数据 */ makerOrder_computedOrderTotal(list) { const obj = { goods_total: list.reduce((p, n) => this.ctx.plus(p, n.goods_total), 0), freight_total: list.reduce((p, n) => this.ctx.plus(p, n.freight_total), 0), }; return obj; } // #endregion /** * 计算需要支付的金额 * @param {Object} order 支付订单信息 * @return {Number} 订单实付金额 */ payOrder_RealPay(order) { let priceKey; if (_.get(order, 'type', '0') === '1') priceKey = 'ggrp'; else priceKey = 'grp'; const detail = this.moneyDetail(order); // 解除店铺层 const sd = Object.values(detail); // 取出规格层 const sgd = sd.map(i => Object.values(i)); // 将规格明细降维至一维 const oneLevel = _.flattenDeep(sgd); // 根据订单类型,计算应付(优惠券部分已经按订单类型计算并分配完了.这地方只是复现) const realPay = oneLevel.reduce((p, n) => this.ctx.plus(p, n[priceKey]), 0); return realPay; } /** * 计算需要支付的金额 * @param {Object} order 支付订单信息 * @return {Object} 返回:{ * 店铺id:金额 * } */ shopMoneyTotal(order) { let priceKey; if (_.get(order, 'type', '0') === '1') priceKey = 'ggrp'; else priceKey = 'grp'; const detail = this.moneyDetail(order); const result = {}; for (const s in detail) { const values = Object.values(_.get(detail, s, {})); const realPay = values.reduce((p, n) => this.ctx.plus(p, n[priceKey]), 0); result[s] = realPay; } return result; } /** * 计算店铺的金额明细 * @param {Object} order 支付订单信息 * @return {Object} 返回:{ * 店铺id:{ * goods_total:商品总价, * freight_total:商品总价 * } * } */ shopMoneyDetail(order) { if (!order) throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '未找到订单信息'); let priceKey; if (_.get(order, 'type', '0') === '1') priceKey = 'ggrp'; else priceKey = 'grp'; const result = {}; const moneyDetail = this.moneyDetail(order); for (const s in moneyDetail) { const obj = {}; const d = _.get(moneyDetail, s, {}); obj.goods_total = Object.values(d).reduce((p, n) => this.ctx.plus(p, _.get(n, priceKey, 0)), 0); obj.freight_total = Object.values(d).reduce((p, n) => this.ctx.plus(p, _.get(n, 'ft', 0)), 0); result[s] = obj; } return result; } /** * 按店铺-商品 计算该订单的价格明细 * @param {Object} data 支付订单数据 * @return {Object} 返回:{ * 店铺id:{ * 规格id:{ * sm: 规格正常销售价格(sell_money), * f: 规格运费(freight), * bn: 购买数量(buy_num), * st: 规格正常销售总价(sell_total: sm * bn) * ft: 规格运费总价(freight_total: f * bn) * gt: 商品支付原价(goods_total: st + ft) * dd: { * key:优惠券id, * value:优惠价格 * }, * dt: 优惠总价(d_detail的value之和) * grp:商品实际支付价格(goods_real_pay: gt - dt) * gsm:规格团购销售价格(group_sell_money) * gst: 规格团购销售总价(group_sell_total: gsm * bn) * ggt: 商品团购支付原价(goods_group_total: gst + ft) * ggrp: 商品团购实际支付价格(goods_group_real_pay: ggt - dt) * } * } * } */ moneyDetail(data) { if (!data) throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '未找到订单信息'); // 优惠部分 const ddt = _.get(data, 'total_detail.discount_detail', {}); // 店铺规格商品数据 const shopGoods = _.get(data, 'goods', []); const result = {}; for (const s of shopGoods) { const { goods, shop } = s; const shopResult = {}; for (const g of goods) { const { sell_money: sm, freight: f, buy_num: bn, group_config, _id } = g; const st = this.ctx.multiply(sm, bn); const ft = this.ctx.multiply(f, bn); const gt = this.ctx.plus(st, ft); const dd = {}; for (const uc_id in ddt) { const detail = _.get(ddt, uc_id, {}); const value = detail[_id]; if (value) dd[uc_id] = value; } const dt = Object.values(dd).reduce((p, n) => this.ctx.plus(p, n), 0); const grp = this.ctx.minus(gt, dt); let obj = { sm, f, bn, st, ft, gt, dd, dt, grp }; const gsm = _.get(group_config, 'money'); if (gsm) { const gst = this.ctx.multiply(gsm, bn); const ggt = this.ctx.plus(gst, ft); const ggrp = this.ctx.minus(ggt, dt); obj = { ...obj, gsm, gst, ggt, ggrp }; } shopResult[_id] = obj; } result[shop] = shopResult; } return result; } } module.exports = OrderService;