123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 |
- '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 moment = require('moment');
- const { ObjectId } = require('mongoose').Types;
- //
- class GroupService extends CrudService {
- constructor(ctx) {
- super(ctx, 'group');
- this.model = this.ctx.model.Group.Group;
- this.goodsModel = this.ctx.model.Shop.Goods;
- this.goodsSpecModel = this.ctx.model.Shop.GoodsSpec;
- this.userModel = this.ctx.model.User.User;
- this.orderModel = this.ctx.model.Trade.Order;
- this.joinErrorRefundCode = _.get(this.app, 'config.errcode.groupJoinRefund');
- }
- /**
- * 生成团
- * @param {Object} orderDetail 订单详情数据
- * @param {Transaction} tran 数据库事务实例
- */
- async create(orderDetail, tran) {
- const { goods: goodsInfos, customer, shop } = orderDetail;
- const g = _.head(goodsInfos);
- const goods_id = _.get(g, 'goods._id');
- const goods = await this.goodsModel.findById(goods_id);
- const goodsSpec_id = _.get(g, '_id');
- const goodsSpec = await this.goodsSpecModel.findById(goodsSpec_id);
- const person_limit = _.get(goodsSpec, 'group_config.need_person');
- const leader = customer;
- const persons = [{ customer, status: '0', join_time: moment().format('YYYY-MM-DD HH:mm:ss') }];
- const obj = { shop, goods, goodsSpec, leader, persons, person_limit };
- const id = tran.insert('Group', obj);
- return id;
- }
- /**
- * 加入团
- * @param {String} customer 用户id
- * @param {String} group_id 团id
- * @param {Transaction} tran 数据库事务实例
- */
- async join(customer, group_id, tran) {
- const result = await this.checkGroupCanJoin({ id: group_id, customer });
- if (!result.result) throw new BusinessError(this.joinErrorRefundCode, result.msg);
- const data = await this.model.findById(group_id);
- if (!data) throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '未找到团信息');
- const { persons = [], person_limit } = data;
- const nps = JSON.parse(JSON.stringify(persons));
- nps.push({ customer, status: '0', join_time: moment().format('YYYY-MM-DD HH:mm:ss') });
- const updateData = { persons: nps };
- if (person_limit <= nps.length) updateData.status = '1';
- tran.update('Group', group_id, updateData);
- }
- // 检查是否可以加入团
- async checkGroupCanJoin({ id, customer }) {
- const data = await this.model.findById(id);
- if (!data) throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '未找到团数据');
- const { person_limit, persons = [], status } = data;
- if (status === '1') return { result: false, msg: '当前团已结束' };
- else if (status === '-1') return { result: false, msg: '当前团已关闭' };
- // 检查是否已经参团
- const cus = _.get(this.ctx, 'user._id', customer);
- if (!cus) throw new BusinessError(ErrorCode.NOT_LOGIN, '用户未登录');
- const r = data.persons.find(f => f.customer === cus);
- if (r) return { result: false, msg: '您已参团' };
- // 为0是正常的团员
- const realPersons = persons.filter(f => f.status === '0');
- if (realPersons.length < person_limit) return { result: true };
- return { result: false, msg: '当前参团人数已足够' };
- }
- /**
- * 团购退货(订单取消&售后退款/退货)
- * @param {Object} params 参数
- * @param params.group 团id
- * @param params.customer 用户id
- * @param tran
- */
- async refund({ group, customer }, tran) {
- let groupData = await this.model.findById(group);
- if (!groupData) throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '未找到拼团数据');
- groupData = JSON.parse(JSON.stringify(groupData));
- const { persons, leader, status } = groupData;
- // 检查团状态,如果已经结束,就不需要该团这边的数据了
- if (status !== '0') return;
- const newPersons = JSON.parse(JSON.stringify(persons));
- const findPersonCondition = (c1, c2) => ObjectId(c1).equals(c2);
- const p = newPersons.find(f => findPersonCondition(f.customer, customer));
- if (!p) throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '未找到要退团的用户');
- const i = newPersons.findIndex(f => findPersonCondition(f.customer, customer));
- p.status = '1';
- p.out_time = moment().format('YYYY-MM-DD HH:mm:ss');
- newPersons[i] = p;
- const updateData = { persons: newPersons };
- // 团长退团了,根据入团时间降序,顺位成为团长
- if (ObjectId(leader).equals(customer)) {
- let newLeader;
- const orderList = _.orderBy(newPersons.filter(f => f.customer !== customer), [ 'status', 'join_time' ], [ 'asc', 'asc' ]);
- const head = _.head(orderList);
- if (head && head.status === '0') {
- newLeader = _.get(head, 'customer');
- updateData.leader = newLeader;
- }
- }
- // 判断是否都退团了
- const allRefund = newPersons.every(e => e.status === '1');
- if (allRefund) updateData.status = '-1';
- tran.update('Group', group, updateData);
- }
- /**
- * 获取团信息
- * @param {Object} query 地址参数
- * @param {String} query.order_id 订单id
- */
- async getGroup({ order_id }) {
- assert(order_id, '缺少订单信息');
- const order = await this.orderModel.findById(order_id, { group: 1 });
- if (!order) throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '未找到订单信息');
- const group = _.get(order, 'group');
- return group;
- }
- async beforeQuery(filter) {
- const gsv = _.get(filter, 'goodsSpec._id');
- if (gsv) filter['goodsSpec._id'] = ObjectId(gsv);
- const gv = _.get(filter, 'goods._id');
- if (gv) filter['goods._id'] = ObjectId(gv);
- // const p = _.get(filter, 'persons.customer');
- // if (p) {
- // filter['persons.status'] = '0';
- // }
- return filter;
- }
- async afterQuery(filter, data) {
- data = JSON.parse(JSON.stringify(data));
- for (const i of data) {
- const { persons = [] } = i;
- for (const p of persons) {
- const user = await this.getUserInfo(p.customer);
- p.name = _.get(user, 'name');
- p.icon = _.get(user, 'icon');
- }
- }
- return data;
- }
- async afterFetch(filter, data) {
- data = JSON.parse(JSON.stringify(data));
- const { persons = [] } = data;
- for (const p of persons) {
- const user = await this.getUserInfo(p.customer);
- p.name = _.get(user, 'name');
- p.icon = _.get(user, 'icon');
- }
- return data;
- }
- async getUserInfo(id) {
- const user = await this.userModel.findById(id, { name: 1, icon: 1 });
- return user;
- }
- }
- module.exports = GroupService;
|