123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134 |
- '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 Transaction = require('mongoose-transactions');
- //
- class GoodsService extends CrudService {
- constructor(ctx) {
- super(ctx, 'goods');
- this.model = this.ctx.model.Shop.Goods;
- this.goodsSpecmodel = this.ctx.model.Shop.GoodsSpec;
- this.tran = new Transaction();
- }
- async beforeCreate(data) {
- // 为商品随机生成不重复的code
- if (!data.code) data.code = await this.makeCode();
- await this.checkCode(data.code);
- return data;
- }
- async beforeUpdate(filter, update) {
- const id = _.get(filter, 'id', _.get(filter, '_id'));
- const code = _.get(update, 'code');
- await this.checkCode(code, id);
- return { filter, update };
- }
- async query(filter, { skip = 0, limit, sort, desc, projection } = {}) {
- // 处理排序
- let condition = _.cloneDeep(filter);
- condition = this.dealFilter(condition);
- const pipeline = this.getQueryPipeline(condition);
- if (parseInt(skip)) pipeline.push({ $skip: parseInt(skip) });
- if (parseInt(limit)) pipeline.push({ $limit: parseInt(limit) });
- const rs = await this.model.aggregate(pipeline);
- return rs;
- }
- async count(filter) {
- let condition = _.cloneDeep(filter);
- condition = this.dealFilter(condition);
- const pipeline = this.getQueryPipeline(condition);
- pipeline.push({ $count: 'total' });
- const total = await this.model.aggregate(pipeline);
- return _.get(_.head(total), 'total', 0);
- }
- getQueryPipeline(filter) {
- const pipeline = [];
- const { tags, spec_name, ...others } = filter;
- const $match = { ...others };
- if (tags) {
- $match.tags = { $elemMatch: { $elemMatch: { $eq: tags } } };
- }
- pipeline.push({ $match });
- if (spec_name) {
- const $addFields = { goods_id: { $toString: '$_id' } };
- const $lookup = {
- from: 'goodsSpec',
- localField: 'goods_id',
- foreignField: 'goods',
- pipeline: [{ $match: { name: new RegExp(spec_name) } }],
- as: 'sp',
- };
- const $unwind = '$sp';
- const $project = { sp: 0, goods_id: 0 };
- pipeline.push({ $addFields }, { $lookup }, { $unwind }, { $project });
- }
- pipeline.push({ $sort: { sort: -1 } });
- return pipeline;
- }
- /**
- * 检查商品编码是否唯一,若传id,则将该id排除在外
- * @param {String} code 商品唯一编码
- * @param {String} id 商品id
- */
- async checkCode(code, id) {
- if (!code) return;
- const query = { code };
- if (id) query.id = { $ne: id };
- const num = await this.model.find(query);
- if (num > 0) throw new BusinessError(ErrorCode.DATA_EXISTED, '该编码已被其他商品使用');
- return;
- }
- // 生成商品编码
- async makeCode() {
- let code = '';
- let is_has = false;
- do {
- code = Math.random().toString(36).substring(3, 11);
- const num = await this.model.find({ code });
- is_has = num > 0;
- } while (is_has);
- return code;
- }
- async toDuplicate({ id }) {
- const data = await this.model.findById(id);
- if (!data) throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '未找到数据');
- let specList = await this.goodsSpecmodel.find({ goods: id });
- if (specList.length > 0) specList = JSON.parse(JSON.stringify(specList));
- const nd = JSON.parse(JSON.stringify(data));
- nd.name = `${nd.name}-复制-${new Date().getTime()}`;
- delete nd.id;
- delete nd._id;
- delete nd.meta;
- delete nd.__v;
- try {
- const id = this.tran.insert('Goods', nd);
- specList = specList.map(i => {
- delete i.id;
- delete i._id;
- delete i.meta;
- delete i.__v;
- i.goods = id;
- return i;
- });
- for (const i of specList) this.tran.insert('GoodsSpec', i);
- await this.tran.run();
- } catch (error) {
- console.log(error);
- await this.tran.rollback();
- } finally {
- this.tran.clean();
- }
- }
- }
- module.exports = GoodsService;
|