matchSmallGroupSchedule.js 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  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 { ObjectId } = require('mongoose').Types;
  7. //
  8. class MatchSmallGroupScheduleService extends CrudService {
  9. constructor(ctx) {
  10. super(ctx, 'matchsmallgroupschedule');
  11. this.model = this.ctx.model.Race.MatchSmallGroupSchedule;
  12. this.baseUserModel = this.ctx.model.Base.User;
  13. this.userModel = this.ctx.model.Race.User;
  14. this.teamApplyModel = this.ctx.model.Race.TeamApply;
  15. // 加入框架
  16. this.defaultModule = this.app.config.defaultModel || 'Race';
  17. }
  18. async saveAll(data) {
  19. for (const i of data) {
  20. const { _id } = i;
  21. if (!_id) {
  22. // TODO: 创建前:需要检查这些人员是否出现在这个项目中的别的组中
  23. await this.model.create(i);
  24. } else {
  25. await this.model.updateOne({ _id }, i);
  26. }
  27. }
  28. }
  29. async beforeCreate(body) {
  30. // 检查数据是否有重复,如果符合检查重复条件,就把之前的删了,用新来的
  31. const { match_id, group_id, project_id, team_id, player_one, player_two } = body;
  32. const query = {
  33. match_id,
  34. group_id,
  35. project_id,
  36. team_id,
  37. $or: [
  38. { player_one, player_two },
  39. { player_one: player_two, player_two: player_one },
  40. ],
  41. };
  42. const d = await this.model.findOne(query);
  43. if (d) await this.model.deleteOne(query);
  44. return body;
  45. }
  46. async beforeQuery(filter) {
  47. // 可查询自己的赛程-user_id / 某人的赛程
  48. // const { user_id, user_name } = filter;
  49. const user_name = _.get(filter, 'user_name');
  50. let user_id = _.get(filter, 'user_id');
  51. // 没有user_id就不需要处理查询条件
  52. if (!user_id && !user_name) return filter;
  53. const usualCondition = _.pick(filter, [ 'match_id', 'group_id', 'project_id' ]);
  54. if (user_name) {
  55. // 要先找比赛用户模块的数据id
  56. const baseUser = await this.baseUserModel.findOne({ name: new RegExp(user_name) }, { _id: 1 });
  57. if (!baseUser) delete filter.user_name;
  58. delete filter.user_name;
  59. const baseUserId = baseUser._id;
  60. const raceUser = await this.userModel.findOne({ user_id: baseUserId, type: '0' });
  61. if (raceUser) user_id = raceUser._id;
  62. }
  63. if (user_id) {
  64. // 需要查:该用户是 单打 和 双打 的情况
  65. // 单打,直接user_id 为player_one/two 就可以,双打需要查teamApply
  66. // 所以先把user_id添加进查询范围里
  67. let probablyList = [ user_id ];
  68. // 尽可能的缩小查询范围
  69. // 接着找组队申请中和该用户有关的人
  70. const teamApplyList = await this.teamApplyModel.find({ ...usualCondition, status: '1', $or: [{ one_member_id: user_id }, { two_member_id: user_id }] }, { _id: 1 });
  71. const teamApplyIds = teamApplyList.map(i => i._id);
  72. probablyList.push(...teamApplyIds);
  73. // 删除user_id.会造成错误
  74. delete filter.user_id;
  75. // 添加该用户正确的范围条件
  76. probablyList = probablyList.map(i => ObjectId(i).toString());
  77. filter.$or = [{ player_one: { $in: probablyList } }, { player_two: { $in: probablyList } }];
  78. }
  79. return filter;
  80. }
  81. async afterQuery(filter, data) {
  82. data = JSON.parse(JSON.stringify(data));
  83. for (const d of data) {
  84. const { player_type, player_one, player_two, referee_id } = d;
  85. if (player_type === 'Race.User') {
  86. const p1 = await this.userModel.findById(player_one, { user_id: 1 }).populate({ path: 'user_id', model: this.baseUserModel, select: 'name' });
  87. const p2 = await this.userModel.findById(player_two, { user_id: 1 }).populate({ path: 'user_id', model: this.baseUserModel, select: 'name' });
  88. d.player_one_name = _.get(p1, 'user_id.name');
  89. d.player_two_name = _.get(p2, 'user_id.name');
  90. } else if (player_type === 'Race.TeamApply') {
  91. const p1 = await this.teamApplyModel.findById(player_one, { one_member_name: 1, two_member_name: 1 });
  92. const p2 = await this.teamApplyModel.findById(player_two, { one_member_name: 1, two_member_name: 1 });
  93. d.player_one_name = `${_.get(p1, 'one_member_name')}-${_.get(p1, 'two_member_name')}`;
  94. d.player_two_name = `${_.get(p2, 'one_member_name')}-${_.get(p2, 'two_member_name')}`;
  95. }
  96. const referee = await this.userModel.findById(referee_id).populate({
  97. path: 'user_id',
  98. model: this.baseUserModel,
  99. });
  100. d.referee_id_name = _.get(referee, 'user_id.name');
  101. }
  102. return data;
  103. }
  104. async fetch(filter, { sort, desc, projection } = {}) {
  105. assert(filter);
  106. filter = await this.beforeFetch(filter);
  107. const { _id, id } = filter;
  108. if (_id || id) filter = { _id: ObjectId(_id || id) };
  109. // 处理排序
  110. if (sort && _.isString(sort)) {
  111. sort = { [sort]: desc ? -1 : 1 };
  112. } else if (sort && _.isArray(sort)) {
  113. sort = sort.map(f => ({ [f]: desc ? -1 : 1 })).reduce((p, c) => ({ ...p, ...c }), {});
  114. }
  115. const { refMods, populate } = this.getRefMods();
  116. let res = await this.model.findOne(filter, projection).populate(populate).exec();
  117. res = JSON.parse(JSON.stringify(res));
  118. for (const obj of refMods) {
  119. const { col, prop, type } = obj;
  120. if (!prop) continue;
  121. if (_.isArray(prop)) {
  122. for (const p of prop) {
  123. if (type === 'String') res[`${col}_${p}`] = _.get(res, `${col}.${p}`);
  124. if (type === 'Array') {
  125. const list = [];
  126. const oList = _.get(res, `${col}`);
  127. for (const d of oList) {
  128. const obj = { _id: d._id };
  129. obj[p] = _.get(d, p);
  130. list.push(obj);
  131. }
  132. res[`${col}_${p}`] = list;
  133. }
  134. }
  135. res[col] = _.get(res, `${col}._id`);
  136. }
  137. }
  138. res = await this.afterFetch(filter, res);
  139. return res;
  140. }
  141. async afterFetch(filter, d) {
  142. const { player_type, player_one, player_two, referee_id } = d;
  143. if (player_type === 'Race.User') {
  144. const p1 = await this.userModel.findById(player_one, { user_id: 1 }).populate({ path: 'user_id', model: this.baseUserModel, select: 'name' });
  145. const p2 = await this.userModel.findById(player_two, { user_id: 1 }).populate({ path: 'user_id', model: this.baseUserModel, select: 'name' });
  146. d.player_one_name = _.get(p1, 'user_id.name');
  147. d.player_two_name = _.get(p2, 'user_id.name');
  148. } else if (player_type === 'Race.TeamApply') {
  149. const p1 = await this.teamApplyModel.findById(player_one, { one_member_name: 1, two_member_name: 1 });
  150. const p2 = await this.teamApplyModel.findById(player_two, { one_member_name: 1, two_member_name: 1 });
  151. d.player_one_name = `${_.get(p1, 'one_member_name')}-${_.get(p1, 'two_member_name')}`;
  152. d.player_two_name = `${_.get(p2, 'one_member_name')}-${_.get(p2, 'two_member_name')}`;
  153. }
  154. const referee = await this.userModel.findById(referee_id).populate({
  155. path: 'user_id',
  156. model: this.baseUserModel,
  157. });
  158. d.referee_id_name = _.get(referee, 'user_id.name');
  159. return d;
  160. }
  161. }
  162. module.exports = MatchSmallGroupScheduleService;