|
@@ -20,6 +20,7 @@ class OrderService extends CrudService {
|
|
this.userCouponModel = this.ctx.model.User.UserCoupon;
|
|
this.userCouponModel = this.ctx.model.User.UserCoupon;
|
|
this.platformActModel = this.ctx.model.System.PlatformAct;
|
|
this.platformActModel = this.ctx.model.System.PlatformAct;
|
|
this.gjaModel = this.ctx.model.Shop.GoodsJoinAct;
|
|
this.gjaModel = this.ctx.model.Shop.GoodsJoinAct;
|
|
|
|
+ this.orderUtil = this.ctx.service.util.order;
|
|
this.tran = new Transaction();
|
|
this.tran = new Transaction();
|
|
}
|
|
}
|
|
|
|
|
|
@@ -210,21 +211,23 @@ class OrderService extends CrudService {
|
|
}
|
|
}
|
|
const { result, msg } = await this.ctx.service.util.trade.checkCanBuy(data, false);
|
|
const { result, msg } = await this.ctx.service.util.trade.checkCanBuy(data, false);
|
|
if (!result) throw new BusinessError(ErrorCode.DATA_INVALID, msg);
|
|
if (!result) throw new BusinessError(ErrorCode.DATA_INVALID, msg);
|
|
- // 正常整理商品的内容
|
|
|
|
- specsData = await this.getPageData(data);
|
|
|
|
|
|
+ // 本次订单 有关活动的数据
|
|
|
|
+ const actList = await this.getActList(data);
|
|
|
|
+ // 正常整理商品的内容,与活动结合
|
|
|
|
+ specsData = await this.getPageData(data, actList);
|
|
// 组装页面的数据
|
|
// 组装页面的数据
|
|
const user = this.ctx.user;
|
|
const user = this.ctx.user;
|
|
const customer = _.get(user, '_id');
|
|
const customer = _.get(user, '_id');
|
|
if (!customer) throw new BusinessError(ErrorCode.NOT_LOGIN, '未找到用户信息');
|
|
if (!customer) throw new BusinessError(ErrorCode.NOT_LOGIN, '未找到用户信息');
|
|
const pageData = {};
|
|
const pageData = {};
|
|
- // 找到默认地址
|
|
|
|
- const address = await this.addressModel.findOne({ customer, is_default: '1' });
|
|
|
|
- pageData.address = address;
|
|
|
|
// 商品总价,各店铺的价格明细
|
|
// 商品总价,各店铺的价格明细
|
|
specsData = this.ctx.service.util.order.makeOrder_computedShopTotal(specsData);
|
|
specsData = this.ctx.service.util.order.makeOrder_computedShopTotal(specsData);
|
|
const shopTotalDetail = this.ctx.service.util.order.makerOrder_computedOrderTotal(specsData);
|
|
const shopTotalDetail = this.ctx.service.util.order.makerOrder_computedOrderTotal(specsData);
|
|
pageData.goodsData = specsData;
|
|
pageData.goodsData = specsData;
|
|
pageData.orderTotal = shopTotalDetail;
|
|
pageData.orderTotal = shopTotalDetail;
|
|
|
|
+ // 找到默认地址
|
|
|
|
+ const address = await this.addressModel.findOne({ customer, is_default: '1' });
|
|
|
|
+ pageData.address = address;
|
|
// 优惠券列表
|
|
// 优惠券列表
|
|
// 查询优惠券列表
|
|
// 查询优惠券列表
|
|
const couponList = await this.ctx.service.user.userCoupon.toMakeOrder_getList(specsData);
|
|
const couponList = await this.ctx.service.user.userCoupon.toMakeOrder_getList(specsData);
|
|
@@ -233,10 +236,31 @@ class OrderService extends CrudService {
|
|
const inviter = data.find(f => ObjectId.isValid(f.inviter));
|
|
const inviter = data.find(f => ObjectId.isValid(f.inviter));
|
|
pageData.inviter = inviter;
|
|
pageData.inviter = inviter;
|
|
// 活动部分
|
|
// 活动部分
|
|
- // 每个数据中都有act字段.这个字段表明商品参加了哪些活动
|
|
|
|
- // await this.dealAct();
|
|
|
|
|
|
+ pageData.actList = actList.filter(f => ![ '2', '3' ].includes(f.platform_act_type));
|
|
return pageData;
|
|
return pageData;
|
|
}
|
|
}
|
|
|
|
+ /**
|
|
|
|
+ * 活动相关第一步: 处理规格和活动的问题
|
|
|
|
+ * @param {Array} goodsList 商店商品列表
|
|
|
|
+ * @param {Array} actList 活动列表
|
|
|
|
+ */
|
|
|
|
+ async dealAct(goodsList, actList) {
|
|
|
|
+ // 活动根据类型有优先级设置,需要按优先级进行处理
|
|
|
|
+ // 特价(3)>满减(5)>满折(6)>加价购(4); 买赠(2)无所谓
|
|
|
|
+ const spActs = actList.filter(f => f.platform_act_type === '3');
|
|
|
|
+ this.orderUtil.dealAct_sp(goodsList, spActs);
|
|
|
|
+ const dmActs = actList.filter(f => f.platform_act_type === '5');
|
|
|
|
+ await this.orderUtil.dealAct_discount(goodsList, dmActs);
|
|
|
|
+ const dpActs = actList.filter(f => f.platform_act_type === '6');
|
|
|
|
+ await this.orderUtil.dealAct_discount(goodsList, dpActs);
|
|
|
|
+ let plusActs = actList.filter(f => f.platform_act_type === '4');
|
|
|
|
+ await this.orderUtil.dealAct_plus(goodsList, plusActs);
|
|
|
|
+ plusActs = plusActs.filter(f => f.activity);
|
|
|
|
+ const giftActs = actList.filter(f => f.platform_act_type === '2');
|
|
|
|
+ await this.orderUtil.dealAct_gift(goodsList, giftActs);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* 处理该订单活动部分
|
|
* 处理该订单活动部分
|
|
* * 该商品可能会参加多个活动,活动之间有叠加问题
|
|
* * 该商品可能会参加多个活动,活动之间有叠加问题
|
|
@@ -245,18 +269,20 @@ class OrderService extends CrudService {
|
|
* * 加价购: 满足下限金额时,组织数据,允许前端进行加价购
|
|
* * 加价购: 满足下限金额时,组织数据,允许前端进行加价购
|
|
* * 满减/折: 针对整个订单而言. 满足就处理,不满足就是不处理
|
|
* * 满减/折: 针对整个订单而言. 满足就处理,不满足就是不处理
|
|
* * 套装:暂不处理
|
|
* * 套装:暂不处理
|
|
- * * ps: 特价与满减/折叠加, 按特价计算总价再看满减/折; 加价购不在满减/折的金额下限计算范围内
|
|
|
|
|
|
+ * * ps1: 特价与满减/折叠加, 按特价计算总价再看满减/折; 加价购不在满减/折的金额下限计算范围内
|
|
|
|
+ * * ps2: 满减与满折的优先级为:先满减,后满折(理论上不应该同时出现在一个商品上)
|
|
* @param {Array} data 购物车数据(直接购买也会组织成购物车数据)
|
|
* @param {Array} data 购物车数据(直接购买也会组织成购物车数据)
|
|
*/
|
|
*/
|
|
- async dealAct(data) {
|
|
|
|
|
|
+ async getActList(data) {
|
|
const actList = [];
|
|
const actList = [];
|
|
for (const i of data) {
|
|
for (const i of data) {
|
|
- const { act = [], spec } = i;
|
|
|
|
|
|
+ const { act = [], goodsSpec: spec } = i;
|
|
if (act.length <= 0) continue;
|
|
if (act.length <= 0) continue;
|
|
for (const a of act) {
|
|
for (const a of act) {
|
|
- const platformAct = await this.platformActModel.findById(a);
|
|
|
|
|
|
+ let platformAct = await this.platformActModel.findById(a);
|
|
// 没有找到活动,略过
|
|
// 没有找到活动,略过
|
|
if (!platformAct) continue;
|
|
if (!platformAct) continue;
|
|
|
|
+ platformAct = JSON.parse(JSON.stringify(platformAct));
|
|
// 活动未开启,略过
|
|
// 活动未开启,略过
|
|
if (_.get(platformAct, 'is_use') !== '0') continue;
|
|
if (_.get(platformAct, 'is_use') !== '0') continue;
|
|
// 活动类型为 0&1不需要处理
|
|
// 活动类型为 0&1不需要处理
|
|
@@ -277,31 +303,38 @@ class OrderService extends CrudService {
|
|
if (type === '2') {
|
|
if (type === '2') {
|
|
// 买赠,直接去到活动中找到赠品
|
|
// 买赠,直接去到活动中找到赠品
|
|
const gja = await this.gjaModel.findOne({ platform_act: platformAct._id, 'spec._id': spec }, { config: 1 });
|
|
const gja = await this.gjaModel.findOne({ platform_act: platformAct._id, 'spec._id': spec }, { config: 1 });
|
|
|
|
+ if (!gja) continue;
|
|
const gift = _.get(gja, 'config.gift', []);
|
|
const gift = _.get(gja, 'config.gift', []);
|
|
- actList.push({ platform_act_type: type, spec, gift });
|
|
|
|
|
|
+ actList.push({ platform_act: platformAct._id, platform_act_type: type, spec, gift });
|
|
} else if (type === '3') {
|
|
} else if (type === '3') {
|
|
// 特价,找出特价
|
|
// 特价,找出特价
|
|
const gja = await this.gjaModel.findOne({ platform_act: platformAct._id, 'spec._id': spec }, { config: 1 });
|
|
const gja = await this.gjaModel.findOne({ platform_act: platformAct._id, 'spec._id': spec }, { config: 1 });
|
|
|
|
+ if (!gja) continue;
|
|
const sp_price = _.get(gja, 'config.sp_price');
|
|
const sp_price = _.get(gja, 'config.sp_price');
|
|
|
|
+ actList.push({ platform_act: platformAct._id, platform_act_type: type, spec, sp_price });
|
|
} else if (type === '4') {
|
|
} else if (type === '4') {
|
|
// 加价购,找出加价购下限;如果判断下限够了,那就可以让前端去加价购
|
|
// 加价购,找出加价购下限;如果判断下限够了,那就可以让前端去加价购
|
|
const plus_money = _.get(platformAct, 'config.plus_money', 0);
|
|
const plus_money = _.get(platformAct, 'config.plus_money', 0);
|
|
- } else if (type === '5') {
|
|
|
|
- // 满减
|
|
|
|
- const discount = _.get(platformAct, 'discount', []);
|
|
|
|
- } else if (type === '6') {
|
|
|
|
- // 满折
|
|
|
|
- const discount = _.get(platformAct, 'discount', []);
|
|
|
|
|
|
+ const obj = { platform_act: platformAct._id, platform_act_type: type, plus_money };
|
|
|
|
+ const r = actList.find(f => _.isEqual(f, obj));
|
|
|
|
+ if (!r) actList.push(obj);
|
|
|
|
+ } else if (type === '5' || type === '6') {
|
|
|
|
+ // 满减/折
|
|
|
|
+ const discount = _.get(platformAct, 'config.discount', []);
|
|
|
|
+ const obj = { platform_act: platformAct._id, platform_act_type: type, discount };
|
|
|
|
+ const r = actList.find(f => _.isEqual(f, obj));
|
|
|
|
+ if (!r) actList.push(obj);
|
|
} else if (type === '7') {
|
|
} else if (type === '7') {
|
|
// 套装先不考虑
|
|
// 套装先不考虑
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+ return actList;
|
|
}
|
|
}
|
|
|
|
|
|
// 直接购买&购物车,这俩字段基本没差, 组织订单页商品数据
|
|
// 直接购买&购物车,这俩字段基本没差, 组织订单页商品数据
|
|
- async getPageData(data) {
|
|
|
|
- let arr = [];
|
|
|
|
|
|
+ async getPageData(data, actList) {
|
|
|
|
+ const arr = [];
|
|
for (const i of data) {
|
|
for (const i of data) {
|
|
const { goodsSpec, num } = i;
|
|
const { goodsSpec, num } = i;
|
|
const d = await this.goodsSpecModel.aggregate([
|
|
const d = await this.goodsSpecModel.aggregate([
|
|
@@ -346,15 +379,31 @@ class OrderService extends CrudService {
|
|
file: '$goods.file',
|
|
file: '$goods.file',
|
|
tags: '$goods.tags',
|
|
tags: '$goods.tags',
|
|
act_tags: '$goods.act_tags',
|
|
act_tags: '$goods.act_tags',
|
|
|
|
+ price: { $toDouble: '$sell_money' },
|
|
},
|
|
},
|
|
},
|
|
},
|
|
]);
|
|
]);
|
|
- arr.push(...d);
|
|
|
|
|
|
+ let gs = _.head(d);
|
|
|
|
+ if (gs) gs = JSON.parse(JSON.stringify(gs));
|
|
|
|
+ arr.push(gs);
|
|
}
|
|
}
|
|
- arr = Object.values(_.groupBy(arr, 'shop'));
|
|
|
|
|
|
+ // 平铺数据后,需要处理活动相关部分
|
|
|
|
+ // 经过处理后的数据,会添加act字段,表明与活动有关的信息
|
|
|
|
+ await this.dealAct(arr, actList);
|
|
|
|
+ const result = await this.toMakeGroupData(arr);
|
|
|
|
+ return result;
|
|
|
|
+ }
|
|
|
|
+ /**
|
|
|
|
+ * 将平铺的数据按店铺分组形成
|
|
|
|
+ * * [ { shop:${value}, shop_name:${value}, goods:${value} } ]
|
|
|
|
+ * 的形式
|
|
|
|
+ * @param {Array} list 平铺的数据集合
|
|
|
|
+ */
|
|
|
|
+ async toMakeGroupData(list) {
|
|
|
|
+ list = Object.values(_.groupBy(list, 'shop'));
|
|
const result = [];
|
|
const result = [];
|
|
// 按店铺分组
|
|
// 按店铺分组
|
|
- for (const i of arr) {
|
|
|
|
|
|
+ for (const i of list) {
|
|
const head = _.head(i);
|
|
const head = _.head(i);
|
|
const obj = { shop: _.get(head, 'shop'), shop_name: _.get(head, 'shop_name') };
|
|
const obj = { shop: _.get(head, 'shop'), shop_name: _.get(head, 'shop_name') };
|
|
const goods = i.map(e => _.omit(e, [ 'shop', 'shop_name' ]));
|
|
const goods = i.map(e => _.omit(e, [ 'shop', 'shop_name' ]));
|