group.js 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. 'use strict';
  2. const { CrudService } = require('naf-framework-mongoose-free/lib/service');
  3. const { BusinessError, ErrorCode } = require('naf-core').Error;
  4. const _ = require('lodash');
  5. const assert = require('assert');
  6. const moment = require('moment');
  7. //
  8. class GroupService extends CrudService {
  9. constructor(ctx) {
  10. super(ctx, 'group');
  11. this.model = this.ctx.model.Group.Group;
  12. this.goodsModel = this.ctx.model.Shop.Goods;
  13. this.goodsSpecModel = this.ctx.model.Shop.GoodsSpec;
  14. this.userModel = this.ctx.model.User.User;
  15. }
  16. /**
  17. * 生成团
  18. * @param {Object} orderDetail 订单详情数据
  19. * @param {Transaction} tran 数据库事务实例
  20. */
  21. async create(orderDetail, tran) {
  22. const { goods: goodsInfos, customer, shop } = orderDetail;
  23. const g = _.head(goodsInfos);
  24. const goods_id = _.get(g, 'goods._id');
  25. const goods = await this.goodsModel.findById(goods_id);
  26. const goodsSpec_id = _.get(g, '_id');
  27. const goodsSpec = await this.goodsSpecModel.findById(goodsSpec_id);
  28. const person_limit = _.get(goodsSpec, 'group_config.need_person');
  29. const leader = customer;
  30. const persons = [{ customer, status: '0', join_time: moment().format('YYYY-MM-DD HH:mm:ss') }];
  31. const obj = { shop, goods, goodsSpec, leader, persons, person_limit };
  32. const id = tran.insert('Group', obj);
  33. return id;
  34. }
  35. /**
  36. * 加入团
  37. * @param {String} customer 用户id
  38. * @param {String} group_id 团id
  39. * @param {Transaction} tran 数据库事务实例
  40. */
  41. async join(customer, group_id, tran) {
  42. const result = await this.checkGroupCanJoin({ id: group_id });
  43. if (!result.result) throw new BusinessError(ErrorCode.DATA_INVALID, result.msg);
  44. const data = await this.model.findById(group_id);
  45. if (!data) throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '未找到团信息');
  46. const { persons = [], person_limit } = data;
  47. const nps = JSON.parse(JSON.stringify(persons));
  48. nps.push({ customer, status: '0', join_time: moment().format('YYYY-MM-DD HH:mm:ss') });
  49. const updateData = { persons: nps };
  50. if (person_limit <= nps.length) updateData.status = '1';
  51. tran.update('Group', group_id, updateData);
  52. }
  53. // 检查是否可以加入团
  54. async checkGroupCanJoin({ id }) {
  55. const data = await this.model.findById(id);
  56. if (!data) throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '未找到团数据');
  57. const { person_limit, persons = [], status } = data;
  58. if (status === '1') return { result: false, msg: '当前团已结束' };
  59. else if (status === '-1') return { result: false, msg: '当前团已关闭' };
  60. // 为0是正常的团员
  61. const realPersons = persons.filter(f => f.status === '0');
  62. if (realPersons.length < person_limit) return { result: true };
  63. return { result: false, msg: '当前参团人数已足够' };
  64. }
  65. /**
  66. * 团购退货(订单取消&售后退款/退货)
  67. * @param {Object} params 参数
  68. * @param params.group 团id
  69. * @param params.customer 用户id
  70. * @param tran
  71. */
  72. async refund({ group, customer }, tran) {
  73. const groupData = await this.model.findById(group);
  74. if (!groupData) throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '未找到拼团数据');
  75. const { persons, leader } = groupData;
  76. const newPersons = JSON.parse(JSON.stringify(persons));
  77. const findPersonCondition = (c1, c2) => c1 === c2;
  78. const p = newPersons.find(f => findPersonCondition(f.customer, customer));
  79. if (!p) throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '未找到要退团的用户');
  80. const i = newPersons.findIndex(f => findPersonCondition(f.customer, customer));
  81. p.status = '1';
  82. newPersons[i] = p;
  83. const updateData = { newPersons };
  84. // 团长退团了,根据入团时间降序,顺位成为团长
  85. if (leader === customer) {
  86. let newLeader;
  87. const orderList = _.orderBy(newPersons, [ 'status', 'join_time' ], [ 'asc', 'asc' ]);
  88. const head = _.head(orderList);
  89. if (head && head.status === '0') {
  90. newLeader = _.get(head, 'customer');
  91. updateData.leader = newLeader;
  92. }
  93. }
  94. tran.update('Group', group, updateData);
  95. }
  96. async afterQuery(filter, data) {
  97. data = JSON.parse(JSON.stringify(data));
  98. for (const i of data) {
  99. const { persons = [] } = i;
  100. for (const p of persons) {
  101. const user = await this.userModel.findById(p.customer, { name: 1 });
  102. p.name = _.get(user, 'name');
  103. }
  104. }
  105. return data;
  106. }
  107. }
  108. module.exports = GroupService;