|
@@ -11,6 +11,7 @@ class GoodsService extends CrudService {
|
|
|
super(ctx, 'goods');
|
|
|
this.goodsModel = this.ctx.model.Shop.Goods;
|
|
|
this.goodsSpecModel = this.ctx.model.Shop.GoodsSpec;
|
|
|
+ this.gjaModel = this.ctx.model.Shop.GoodsJoinAct;
|
|
|
}
|
|
|
/**
|
|
|
*
|
|
@@ -18,26 +19,107 @@ class GoodsService extends CrudService {
|
|
|
* @param query.id 商品数据id
|
|
|
*/
|
|
|
async goodsDetail({ id }) {
|
|
|
- // 添加宝贝数,商店3个评价
|
|
|
- const { populate } = this.ctx.service.shop.goods.getRefMods();
|
|
|
- let goods = await this.goodsModel.findById(id, { file: 1, tags: 1, name: 1, shot_brief: 1, brief: 1, send_time: 1, shop: 1, view_num: 1 }).populate(populate);
|
|
|
- if (!goods) throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '未找到商品数据');
|
|
|
- goods = JSON.parse(JSON.stringify(goods));
|
|
|
- let specs = await this.goodsSpecModel.find({ goods: id, status: '0' }, { sell_money: 1, flow_money: 1, freight: 1, name: 1, num: 1, can_group: 1, group_config: 1, file: 1 });
|
|
|
- specs = JSON.parse(JSON.stringify(specs));
|
|
|
- goods = _.omit(goods, [ 'meta', '__v' ]);
|
|
|
- const shop = _.pick(goods.shop, [ 'logo', 'name', 'person', 'phone', '_id', 'goods_score', 'send_score', 'service_score' ]);
|
|
|
- delete goods.shop;
|
|
|
- const goodsNum = await this.goodsModel.count({ shop, status: '1' });
|
|
|
- shop.goods_num = goodsNum;
|
|
|
- // goods: 商品信息; specs:商品规格信息; shop:店铺信息
|
|
|
- const returnData = { goods, specs, shop };
|
|
|
- // 添加浏览次数
|
|
|
- await this.goodsModel.updateOne({ _id: id }, { view_num: (goods.view_num || 0) + 1 });
|
|
|
-
|
|
|
- return returnData;
|
|
|
+ assert(id, '缺少商品信息');
|
|
|
+ const pipeline = [{ $match: { _id: ObjectId(id) } }];
|
|
|
+ const goodsProject = { file: 1, tags: 1, name: 1, shot_brief: 1, brief: 1, send_time: 1, shop: 1, view_num: 1 };
|
|
|
+ // 找店铺信息
|
|
|
+ pipeline.push({ $addFields: { shop_id: { $toObjectId: '$shop' } } });
|
|
|
+ pipeline.push({
|
|
|
+ $lookup: {
|
|
|
+ from: 'shop',
|
|
|
+ localField: 'shop_id',
|
|
|
+ foreignField: '_id',
|
|
|
+ pipeline: [
|
|
|
+ { $addFields: { shop_id: { $toString: '$_id' } } },
|
|
|
+ // 计算店铺商品总数
|
|
|
+ {
|
|
|
+ $lookup: {
|
|
|
+ from: 'goods',
|
|
|
+ localField: 'shop_id',
|
|
|
+ foreignField: 'shop',
|
|
|
+ pipeline: [{ $match: { status: '1' } }, { $count: 'gn' }],
|
|
|
+ as: 'gn',
|
|
|
+ },
|
|
|
+ },
|
|
|
+ { $project: { logo: 1, name: 1, person: 1, phone: 1, _id: 1, goods_score: 1, send_score: 1, service_score: 1, goods_num: { $first: '$gn.gn' } } },
|
|
|
+ ],
|
|
|
+ as: 'shopInfo',
|
|
|
+ },
|
|
|
+ });
|
|
|
+ pipeline.push({ $project: { ...goodsProject, shopInfo: { $first: '$shopInfo' } } });
|
|
|
+ // 找规格
|
|
|
+ pipeline.push({ $addFields: { goods_id: { $toString: '$_id' } } });
|
|
|
+ pipeline.push({
|
|
|
+ $lookup: {
|
|
|
+ from: 'goodsSpec',
|
|
|
+ localField: 'goods_id',
|
|
|
+ foreignField: 'goods',
|
|
|
+ pipeline: [
|
|
|
+ {
|
|
|
+ $project: {
|
|
|
+ sell_money: { $toDouble: '$sell_money' },
|
|
|
+ flow_money: { $toDouble: '$flow_money' },
|
|
|
+ freight: { $toDouble: '$freight' },
|
|
|
+ name: 1,
|
|
|
+ num: 1,
|
|
|
+ can_group: 1,
|
|
|
+ group_config: 1,
|
|
|
+ file: 1,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ as: 'specs',
|
|
|
+ },
|
|
|
+ });
|
|
|
+ pipeline.push({ $project: { ...goodsProject, goods_id: 1, specs: 1, shopInfo: 1 } });
|
|
|
+ // 找到商品是否参与活动,且该活动是否正在进行
|
|
|
+ pipeline.push({
|
|
|
+ $lookup: {
|
|
|
+ from: 'goodsJoinAct',
|
|
|
+ localField: 'goods_id',
|
|
|
+ foreignField: 'goods._id',
|
|
|
+ pipeline: [
|
|
|
+ { $addFields: { pa: { $toObjectId: '$platform_act' } } },
|
|
|
+ {
|
|
|
+ $lookup: {
|
|
|
+ from: 'platformAct',
|
|
|
+ localField: 'pa',
|
|
|
+ foreignField: '_id',
|
|
|
+ pipeline: [{ $match: { is_use: '0' } }],
|
|
|
+ as: 'act',
|
|
|
+ },
|
|
|
+ },
|
|
|
+ { $unwind: '$act' },
|
|
|
+ { $replaceRoot: { newRoot: '$act' } },
|
|
|
+ { $project: { act_time: 1, config: 1 } },
|
|
|
+ ],
|
|
|
+ as: 'act',
|
|
|
+ },
|
|
|
+ });
|
|
|
+ // // 整理数据
|
|
|
+ pipeline.push({
|
|
|
+ $project: {
|
|
|
+ _id: 0,
|
|
|
+ goods: {
|
|
|
+ _id: '$$CURRENT._id',
|
|
|
+ brief: '$$CURRENT.brief',
|
|
|
+ file: '$$CURRENT.file',
|
|
|
+ name: '$$CURRENT.name',
|
|
|
+ send_time: '$$CURRENT.send_time',
|
|
|
+ tags: '$$CURRENT.tags',
|
|
|
+ shot_brief: '$$CURRENT.shot_brief',
|
|
|
+ view_num: '$$CURRENT.view_num',
|
|
|
+ },
|
|
|
+ shop: '$shopInfo',
|
|
|
+ specs: '$specs',
|
|
|
+ act: '$act',
|
|
|
+ },
|
|
|
+ });
|
|
|
+ const res = await this.goodsModel.aggregate(pipeline);
|
|
|
+ return res;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
async indexGoodsList(condition, { skip = 0, limit = 20 } = {}) {
|
|
|
condition = this.dealFilter(condition);
|
|
|
const pipline = [{ $match: { status: { $ne: '0' } } }]; // { $sort: { sort: 1 } },
|