matchExt.controller.ts 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681
  1. import { ApiTags, ApiQuery } from '@midwayjs/swagger';
  2. import { Validate } from '@midwayjs/validate';
  3. import { Controller, Inject, Get, Param, Post, Body, Del, Query } from '@midwayjs/core';
  4. import { cloneDeep, get, omit, pick } from 'lodash';
  5. import { ServiceError, ErrorCode } from '../../error/service.error';
  6. import { BaseController } from '../../frame/BaseController';
  7. import { MatchExtService } from '../../service/match/matchExt.service';
  8. import { MatchRegistrationService } from '../../service/match/matchRegistration.service';
  9. import { UserService } from '../../service/system/user.service';
  10. import { AliyunSmsService } from '../../service/thirdParty/aliyunSms.service';
  11. import { MatchService } from '../../service/platform/match.service';
  12. import dayjs = require('dayjs');
  13. const namePrefix = '创新大赛拓展';
  14. @ApiTags(['创新大赛拓展'])
  15. @Controller('/matchExt', { tagName: namePrefix })
  16. export class MatchExtController implements BaseController {
  17. @Inject()
  18. service: MatchExtService;
  19. @Inject()
  20. matchRegService: MatchRegistrationService;
  21. @Inject()
  22. userService: UserService;
  23. @Inject()
  24. smsService: AliyunSmsService;
  25. @Inject()
  26. matchService: MatchService;
  27. @Get('/')
  28. @ApiTags('列表查询')
  29. @ApiQuery({ name: 'query' })
  30. async index(@Query() query: object) {
  31. const qobj = omit(query, ['skip', 'limit']);
  32. const others: any = pick(query, ['skip', 'limit']);
  33. const result = await this.service.query(qobj, others);
  34. return result;
  35. }
  36. @Get('/:id')
  37. @ApiTags('单查询')
  38. async fetch(@Param('id') id: number) {
  39. const data = await this.service.fetch({ id });
  40. return data;
  41. }
  42. @Post('/', { routerName: `创建${namePrefix}` })
  43. @ApiTags('创建数据')
  44. @Validate()
  45. async create(@Body() data: object) {
  46. // 跟随赛事信息创建,不能直接创建
  47. return false;
  48. }
  49. @Post('/:id', { routerName: `修改${namePrefix}` })
  50. @ApiTags('修改数据')
  51. @Validate()
  52. async update(@Param('id') id: number, @Body() data: object) {
  53. if (!id) throw new ServiceError(ErrorCode.ID_NOT_FOUND);
  54. // 所有的修改,是不允许修改状态的
  55. const newData = omit(data, ['status']);
  56. const result = await this.service.update({ id }, newData);
  57. return result;
  58. }
  59. @Del('/:id', { routerName: `删除${namePrefix}` })
  60. @ApiTags('删除数据')
  61. @Validate()
  62. async delete(@Param('id') id: number) {
  63. if (!id) throw new ServiceError(ErrorCode.ID_NOT_FOUND);
  64. // 不允许删除非报名中的赛事
  65. const data = await this.service.fetch({ id });
  66. if (!data) return;
  67. const status = get(data, 'status');
  68. if (status !== '0') {
  69. // 抛出异常:赛事不处于报名中的状态,无法删除.
  70. throw new ServiceError(ErrorCode.MATCH_EXT_IS_BEGINNING);
  71. }
  72. const result = await this.service.delete({ id });
  73. return result;
  74. }
  75. @Get('/detail/:id')
  76. async detail(@Param('id') id: string) {
  77. const data = await this.service.fetch({ id });
  78. return data;
  79. }
  80. /**
  81. * 进入:报名阶段-已结束
  82. * @param data body
  83. * @property match_id 赛事id
  84. */
  85. @Post('/step1', { routerName: '报名阶段-已结束' })
  86. async step1(@Body() data: object) {
  87. //报名结束,需要检查 报名的创建接口是否允许创建信息----不允许再添加报名信息了
  88. /**
  89. * 检查内容:
  90. * 赛事拓展表:
  91. * ext.status = "0"
  92. * 赛事表:
  93. * match.status = "1"
  94. * 修改内容:
  95. * 赛事拓展表:
  96. * ext.status => "1" 变为 报名阶段-已结束
  97. * 赛事表:
  98. * match.status =>"2" 变为 进行中
  99. * 赛事报名表:
  100. * 处于 报名阶段(ext_status='0') 且 已通过审核的报名信息(status='1') 变为 初审阶段(ext_status='1')且未通过审核(status='0')的报名信息
  101. * reg.ext_status: "0" => "1"
  102. * reg.status: "1" => "0"
  103. */
  104. const match_id = get(data, 'match_id');
  105. await this.service.checkMatchStatus(match_id, '1');
  106. await this.service.checkMatchExtStatus(match_id, '0');
  107. await this.matchService.update({ id: match_id }, { match_status: '2' });
  108. await this.service.update({ match_id }, { status: '1' });
  109. await this.matchRegService.update({ match_id, ext_status: '0', status: '1' }, { ext_status: '1', status: '0' });
  110. return 'ok';
  111. }
  112. // 报名阶段-已结束 到 初审阶段-组织初审 过程只是变化状态码,不需要处理其他内容
  113. /**
  114. * 进入: 初审阶段-组织初审
  115. * @param data body
  116. * @property match_id 赛事id
  117. */
  118. @Post('/step2', { routerName: '初审阶段-组织初审' })
  119. async regBack(@Body() data: object) {
  120. // 只修改状态,不做时间修改,时间修改用另一个接口
  121. /**
  122. * 检查内容:
  123. * 赛事拓展表:
  124. * ext.status = "1"
  125. * 修改内容:
  126. * 赛事拓展表:
  127. * ext.status => "2" 变为 初审阶段-组织初审
  128. * 赛事报名表:
  129. * reg.ext_status: "1" => '2'
  130. */
  131. const match_id = get(data, 'match_id');
  132. await this.service.checkMatchExtStatus(match_id, '1');
  133. await this.service.update({ match_id }, { status: '2' });
  134. await this.matchRegService.update({ match_id, ext_status: '1' }, { ext_status: '2' });
  135. }
  136. /**
  137. * 初审阶段-组织初审 到 初审阶段-公示名单 需要修改 参加初审人员信息的 初审开始时间
  138. * @param data body
  139. * @property match_id 赛事id
  140. * @property start_time 初审时间
  141. * @property ids 报名数据id
  142. */
  143. @Post('/step2/fill', { routerName: '初审阶段-组织初审-补充初审时间信息' })
  144. async step2Fill(@Body() data: object) {
  145. /**
  146. * 检查内容:
  147. * 赛事拓展表:
  148. * ext.status = "2"
  149. * 修改内容:
  150. * 赛事报名表:
  151. * reg.ext_status: '2'
  152. * reg.start_time: => ${start_time}
  153. */
  154. const match_id = get(data, 'match_id');
  155. await this.service.checkMatchExtStatus(match_id, '2');
  156. const start_time = get(data, 'start_time');
  157. // 验证是否是正确的时间格式
  158. const is_time = dayjs(start_time).isValid();
  159. if (!is_time) {
  160. // 抛出异常: 时间格式错误
  161. throw new ServiceError(ErrorCode.TIME_FORMAT_ERROR);
  162. }
  163. // 获取报名信息数据id
  164. const ids = get(data, 'ids', []);
  165. for (const id of ids) {
  166. await this.matchRegService.update({ id: id, ext_status: '2', status: '0' }, { start_time });
  167. }
  168. }
  169. /**
  170. * 进入: 初审阶段-公示名单, 只修改状态即可
  171. * @param data body
  172. * @property match_id 赛事id
  173. */
  174. @Post('/step3', { routerName: '初审阶段-公示名单' })
  175. async step3(@Body() data: object) {
  176. /**
  177. * 检查内容:
  178. * 赛事拓展表:
  179. * ext.status = "2"
  180. * 修改内容:
  181. * 赛事拓展表:
  182. * ext.status => "3" 变为 初审阶段-公示名单
  183. * 赛事报名表:
  184. * reg.ext_status: "2" => '3'
  185. */
  186. const match_id = get(data, 'match_id');
  187. await this.service.checkMatchExtStatus(match_id, '2');
  188. await this.service.update({ match_id }, { status: '3' });
  189. await this.matchRegService.update({ match_id, ext_status: '2' }, { ext_status: '3' });
  190. }
  191. /**
  192. * 查询初审名单
  193. * @param match_id 赛事id
  194. */
  195. @Get('/step3/nameList/:match_id', { routerName: '初审阶段-公示名单-名单查询' })
  196. async step3NameList(@Param('match_id') match_id: string) {
  197. /**
  198. * 检查内容:
  199. * 赛事拓展表:
  200. * ext.status = "3"
  201. * 查询内容:
  202. * 赛事报名表:
  203. * reg.ext_status: "3";
  204. */
  205. await this.service.checkMatchExtStatus(match_id, '3');
  206. const { data } = await this.matchRegService.query({ match_id, ext_status: '3', status: '0' });
  207. const fillList = [];
  208. for (const i of data) {
  209. const newItem = cloneDeep(i);
  210. const user_id = get(i, 'user_id');
  211. const user = await this.userService.fetch({ id: user_id });
  212. if (user) newItem.user_name = get(user, 'nick_name');
  213. const match_id = get(i, 'match_id');
  214. const match = await this.matchService.fetch({ id: match_id });
  215. if (match) newItem.match_name = get(match, 'name');
  216. fillList.push(newItem);
  217. }
  218. return fillList;
  219. }
  220. /**
  221. * 进入: 初审阶段-赛事进行, 只修改状态即可
  222. * @param data body
  223. * @property match_id 赛事id
  224. */
  225. @Post('/step4', { routerName: '初审阶段-赛事进行' })
  226. async step4(@Body() data: object) {
  227. /**
  228. * 检查内容:
  229. * 赛事拓展表:
  230. * ext.status = "3"
  231. * 修改内容:
  232. * 赛事拓展表:
  233. * ext.status => "4" 变为 初审阶段-赛事进行
  234. * 赛事报名表:
  235. * reg.ext_status: "3" => '4'
  236. */
  237. const match_id = get(data, 'match_id');
  238. await this.service.checkMatchExtStatus(match_id, '3');
  239. await this.service.update({ match_id }, { status: '4' });
  240. await this.matchRegService.update({ match_id, ext_status: '3' }, { ext_status: '4' });
  241. }
  242. /**
  243. * 初审阶段-赛事进行-上传成绩, 只上传分数
  244. * @param match_id 赛事id
  245. * @property reg_id 选手id
  246. * @property status 是否通过; 1:通过初审;2未通过初审
  247. * @property score 分数
  248. */
  249. @Post('/step4/score/:match_id', { routerName: '初审阶段-赛事进行-上传成绩' })
  250. async step4Score(@Param('match_id') match_id: string, @Body() data: object) {
  251. /**
  252. * 检查内容:
  253. * 赛事拓展表:
  254. * ext.status = "4"
  255. * 修改内容:
  256. * 赛事报名表:
  257. * reg.ext_status: "4"
  258. * reg.status: '0'
  259. * reg.score = ${score}
  260. */
  261. await this.service.checkMatchExtStatus(match_id, '4');
  262. const reg_id = get(data, 'reg_id');
  263. // const status = get(data, 'status')
  264. const score = get(data, 'score');
  265. const query = { id: reg_id, ext_status: '4', status: '0' };
  266. const regData = await this.matchRegService.fetch(query);
  267. if (!regData) {
  268. // 抛出异常: 该选手不符合上传成绩的要求,请检查选手信息
  269. throw new ServiceError(ErrorCode.MATCH_REG_USER_ERROR);
  270. }
  271. await this.matchRegService.update({ id: reg_id }, { score });
  272. }
  273. /**
  274. * 决定决赛名单
  275. * @param match_id 赛事id
  276. * @param data body
  277. * @property ids 报名信息id
  278. */
  279. @Post('/step4/to5/:match_id', { routerName: '初审阶段-赛事进行-选择决赛名单' })
  280. async step4To5(@Param('match_id') match_id: string, @Body() data: object) {
  281. /**
  282. * 检查内容:
  283. * 赛事拓展表:
  284. * ext.status = "4"
  285. * 修改内容:
  286. * 赛事报名表:
  287. * reg.ext_status: "4"
  288. * reg.status: '0'
  289. * reg.status: '0' => '1'
  290. */
  291. await this.service.checkMatchExtStatus(match_id, '4');
  292. const ids = get(data, 'ids', []);
  293. for (const id of ids) {
  294. await this.matchRegService.update({ id: id, ext_status: '4', status: '0' }, { status: '1' });
  295. }
  296. }
  297. @Post('/step5', { routerName: '决赛阶段-组织决赛' })
  298. async step5(@Body() data: object) {
  299. /**
  300. * 检查内容:
  301. * 赛事拓展表:
  302. * ext.status = "4"
  303. * 修改内容:
  304. * 赛事拓展表:
  305. * ext.status => "5"
  306. * 赛事报名表:
  307. * reg.ext_status: "4"
  308. * reg.status: '1'
  309. * reg.status: '1' => '0'
  310. * reg.ext_status: '4' => '5'
  311. */
  312. const match_id = get(data, 'match_id');
  313. await this.service.checkMatchExtStatus(match_id, '4');
  314. await this.service.update({ match_id }, { status: '5' });
  315. await this.matchRegService.update({ match_id, ext_status: '4', status: '1' }, { status: '0', ext_status: '5' });
  316. }
  317. /**
  318. * 设置某些人决赛时间
  319. * @param match_id 赛事id
  320. * @param data body
  321. * @property ids 报名数据id列表
  322. * @property start_time 决赛开始时间
  323. */
  324. @Post('/step5/time/:match_id', { routerName: '决赛阶段-组织决赛-设置决赛时间' })
  325. async step5SetTime(@Param('match_id') match_id: string, @Body() data: object) {
  326. /**
  327. * 检查内容:
  328. * 赛事拓展表:
  329. * ext.status = "5"
  330. * 修改内容:
  331. * 赛事报名表:
  332. * reg.ext_status: "5"
  333. * reg.status: '0'
  334. * reg.final_start_time => ${start_time}
  335. */
  336. await this.service.checkMatchExtStatus(match_id, '5');
  337. const ids = get(data, 'ids', []);
  338. const start_time = get(data, 'start_time');
  339. for (const id of ids) {
  340. await this.matchRegService.update({ id, ext_status: '5', status: '0' }, { final_start_time: start_time });
  341. }
  342. return 'ok';
  343. }
  344. @Get('/step5/sms/:match_id', { routerName: '决赛阶段-组织决赛-短信通知' })
  345. async step5Sms(@Param('match_id') match_id: string, @Body() data: object) {
  346. /**
  347. * 检查内容:
  348. * 赛事拓展表:
  349. * ext.status = "5"
  350. * 组织内容:
  351. * 赛事报名表:
  352. * reg.ext_status:'5'
  353. * reg.status: '0'
  354. * reg.final_confirm:'1'
  355. * 1.获取赛事信息----标题
  356. * 2.获取赛事报名信息----每个人的决赛时间
  357. * 3.获取用户信息----昵称,电话
  358. * 4.组织短信: ${昵称} 您参加的赛事: ${标题} 将于 ${决赛时间} 开始,
  359. * 请您在网站或小程序中进行确认,以避免主办方将您误认为拒赛而采用其他选手代替
  360. */
  361. await this.service.checkMatchExtStatus(match_id, '5');
  362. const matchInfo = await this.matchService.fetch({ id: match_id });
  363. const match_name = get(matchInfo, 'name');
  364. const { data: extList } = await this.matchRegService.query({ match_id, ext_status: '5', status: '0', final_confirm: '1' });
  365. for (const i of extList) {
  366. const user_id = get(i, 'user_id');
  367. if (!user_id) continue;
  368. const userInfo = await this.userService.fetch({ id: user_id });
  369. if (!userInfo) continue;
  370. const phone = get(userInfo, 'phone');
  371. if (!phone) continue;
  372. const nick_name = get(userInfo, 'nick_name');
  373. if (!nick_name) continue;
  374. const start_time = get(i, 'final_start_time');
  375. if (!start_time) continue;
  376. const smsMsg = `${nick_name} 您参加的赛事: ${match_name} 将于 ${start_time} 开始, 请您在网站或小程序中进行确认,以避免主办方将您误认为拒赛而采用其他选手代替`;
  377. // TODO: 发短信
  378. }
  379. }
  380. /**
  381. * 用户确认参加决赛
  382. * @param match_id 赛事id
  383. * @param data body
  384. * @property user_id 用户id
  385. */
  386. @Post('/step5/confirm/:match_id', { routerName: '决赛阶段-组织决赛-参加决赛确认' })
  387. async step5Confirm(@Param('match_id') match_id: string, @Body() data: object) {
  388. /**
  389. * 检查内容:
  390. * 赛事拓展表:
  391. * ext.status = "5"
  392. * 修改内容:
  393. * 赛事报名表:
  394. * reg.ext_status:'5'
  395. * reg.status: '0'
  396. * final_confirm => '0'
  397. */
  398. await this.service.checkMatchExtStatus(match_id, '5');
  399. const user_id = get(data, 'user_id');
  400. // 默认规定顺序,先来后到
  401. const { data: list } = await this.matchRegService.query({ match_id, ext_status: '5', status: '0', final_confirm: '0' });
  402. // 做默认序号,将已经确认的人查出来,然后排查序号,如果中间有缺少的序号,就先补充到缺少的序号中;如果没有缺少,那就往后默认排
  403. let lastOrderNum = 1;
  404. for (const i of list) {
  405. const thisOrderNum = get(i, 'final_order_no');
  406. // 按理说,不应该出现没有排序的情况
  407. if (!thisOrderNum) continue;
  408. // 顺序不一致,说明少了
  409. if (lastOrderNum !== thisOrderNum) {
  410. // 少了就需要把当前的补上.会出现2种情况, 正常顺序<当前顺序: 按正常顺序进行补充;
  411. // 正常顺序>当前顺序:说明从此开始,后面的序号都是乱的,是不应该出现的情况.如果出现了,就需要人为调整了.所以只考虑第一个情况
  412. break;
  413. }
  414. // 下一个,如果不循环了,那就直接给新数据用
  415. lastOrderNum = lastOrderNum + 1;
  416. }
  417. await this.matchRegService.update({ match_id, user_id, ext_status: '5', status: '0' }, { final_confirm: '0', final_order_no: lastOrderNum });
  418. }
  419. @Post('/step5/refuse/:match_id', { routerName: '决赛阶段-组织决赛-拒绝参加决赛' })
  420. async step5Refuse(@Param('match_id') match_id: string, @Body() data: object) {
  421. /**
  422. * 检查内容:
  423. * 赛事拓展表:
  424. * ext.status = "5"
  425. * 修改内容:
  426. * 赛事报名表:
  427. * reg.ext_status:'5'
  428. * reg.status: '0'
  429. * reg.status => '2'
  430. */
  431. await this.service.checkMatchExtStatus(match_id, '5');
  432. const user_id = get(data, 'user_id');
  433. await this.matchRegService.update({ match_id, user_id, ext_status: '5', status: '0' }, { status: '2' });
  434. }
  435. /**
  436. * 选择初赛中的选手 补充到决赛中
  437. * @param match_id 赛事id
  438. * @param data body
  439. * @property user_id 用户id
  440. */
  441. @Post('/step5/supplement/:match_id', { routerName: '决赛阶段-组织决赛-补充决赛人员' })
  442. async step5Supplement(@Param('match_id') match_id: string, @Body() data: object) {
  443. /**
  444. * 检查内容:
  445. * 赛事拓展表:
  446. * ext.status = "5"
  447. * 修改内容:
  448. * 赛事报名表:
  449. * reg.ext_status:'4'=>'5'
  450. * reg.status =>'0'
  451. */
  452. await this.service.checkMatchExtStatus(match_id, '5');
  453. const user_id = get(data, 'user_id');
  454. await this.matchRegService.update({ match_id, user_id, ext_status: '4' }, { ext_status: '5', status: '0' });
  455. }
  456. @Get('/step5/list/:match_id', { routerName: '决赛阶段-组织决赛-决赛人员名单' })
  457. async step5NameList(@Param('match_id') match_id: string, @Query() query: object) {
  458. /**
  459. * 检查内容:
  460. * 组织内容:
  461. * 赛事报名表:
  462. * reg.ext_status:'5'
  463. * reg.final_confirm =>'0'
  464. */
  465. // await this.service.checkMatchExtStatus(match_id, '5');
  466. // 决赛名单,根据顺序升序
  467. const final_confirm = get(query, 'final_confirm')
  468. const { data: list } = await this.matchRegService.query({ match_id, ext_status: '5', final_confirm }, { order: { final_order_no: 'ASC' } });
  469. const newList = []
  470. for (const i of list) {
  471. let newItem = cloneDeep(i)
  472. newItem = this.matchRegService.dealData(newItem);
  473. newList.push(newItem)
  474. }
  475. return newList;
  476. }
  477. /**
  478. * 决赛人员排序
  479. * @param match_id 赛事id
  480. * @param data body
  481. * @property id 报名数据id
  482. * @property order_no 排名位置
  483. */
  484. @Post('/step5/order/:match_id', { routerName: '决赛阶段-组织决赛-人员排序' })
  485. async step5Order(@Param('match_id') match_id: string, @Body() data: object) {
  486. /**
  487. * 检查内容:
  488. * 赛事拓展表:
  489. * ext.status = "5"
  490. * 组织内容:
  491. * 赛事报名表:
  492. * reg.final_order_no =>'0'
  493. * id,order_no
  494. */
  495. await this.service.checkMatchExtStatus(match_id, '5');
  496. const { data: list } = await this.matchRegService.query({ match_id, ext_status: '5', final_confirm: '0' }, { order: { final_order_no: 'ASC' } });
  497. const id = get(data, 'id');
  498. if (!id) {
  499. // 抛出异常:缺少报名信息
  500. throw new ServiceError(ErrorCode.MATCH_EXT_DATA_NOT_FOUND);
  501. }
  502. const order_no = get(data, 'order_no');
  503. // 没写,直接不该
  504. if (!order_no) return 'ok';
  505. /**数据原索引 */
  506. const oldIndex = list.findIndex(f => f.id === id);
  507. // 没数据,不改
  508. if (oldIndex < 0) {
  509. throw new ServiceError(ErrorCode.MATCH_REG_NOT_FOUND);
  510. }
  511. const oldData = list[oldIndex];
  512. /**目标索引 */
  513. let targetIndex = order_no - 1;
  514. if (oldIndex === targetIndex) {
  515. throw new ServiceError(ErrorCode.MATCH_REG_ORDER_NOT_CHANGE);
  516. }
  517. let removeIndex = oldIndex;
  518. if (targetIndex < oldIndex) {
  519. // 如果要移动到的索引 小于 原数据索引: 是在原数据前添加的,影响删除,需要原索引+1才能删除原数据
  520. removeIndex = removeIndex + 1;
  521. } else {
  522. // 移动的索引要+1
  523. targetIndex = targetIndex + 1;
  524. }
  525. list.splice(targetIndex, 0, oldData);
  526. list.splice(removeIndex, 1);
  527. // 重新排列
  528. for (let index = 0; index < list.length; index++) {
  529. const e = list[index];
  530. const id = get(e, 'id');
  531. await this.matchRegService.update({ id }, { final_order_no: index + 1 });
  532. }
  533. }
  534. @Post('/step6', { routerName: '决赛阶段-名单公示' })
  535. async step6(@Body() data: object) {
  536. /**
  537. * 检查内容:
  538. * 赛事拓展表:
  539. * ext.status = "5"
  540. * 修改内容:
  541. * 赛事拓展表:
  542. * ext.status => "6" 变为 决赛阶段-名单公示
  543. * 赛事报名表:
  544. * reg.final_confirm:'0'
  545. * reg.ext_status: "5" => '6'
  546. */
  547. const match_id = get(data, 'match_id');
  548. await this.service.checkMatchExtStatus(match_id, '5');
  549. await this.service.update({ match_id }, { status: '6' });
  550. await this.matchRegService.update({ match_id, ext_status: '5', final_confirm: '0' }, { ext_status: '6' });
  551. }
  552. @Post('/step7', { routerName: '决赛阶段-赛事进行' })
  553. async step7(@Body() data: object) {
  554. /**
  555. * 检查内容:
  556. * 赛事拓展表:
  557. * ext.status = "6"
  558. * 修改内容:
  559. * 赛事拓展表:
  560. * ext.status => "7" 变为 决赛阶段-赛事进行
  561. * 赛事报名表:
  562. * reg.final_confirm:'0'
  563. * reg.ext_status: "6" => '7'
  564. */
  565. const match_id = get(data, 'match_id');
  566. await this.service.checkMatchExtStatus(match_id, '6');
  567. await this.service.update({ match_id }, { status: '7' });
  568. await this.matchRegService.update({ match_id, ext_status: '6', final_confirm: '0' }, { ext_status: '7' });
  569. }
  570. // TODO:决赛大屏
  571. /**
  572. * 评委打分,前端将评委的数据传来.然后再做总分计算,总分通过平均分方式计算
  573. * @param match_id 赛事id
  574. * @param data body
  575. * @property id 报名数据id
  576. * @property {Object} details 决赛总分数详情
  577. */
  578. @Post('/step7/score/:match_id', { routerName: '决赛阶段-赛事进行-评委打分' })
  579. async step7Score(@Param('match_id') match_id: string, @Body() data: object) {
  580. /**
  581. * 检查内容:
  582. * 赛事拓展表:
  583. * ext.status = "7"
  584. * 修改内容:
  585. * 赛事报名表:
  586. * reg.ext_status: "7"
  587. * reg.final_confirm: "0"
  588. * reg.id: ${id}
  589. * reg.final_score_details=> ${details}
  590. */
  591. await this.service.checkMatchExtStatus(match_id, '7');
  592. const id = get(data, 'id');
  593. if (!id) {
  594. // 抛出异常
  595. throw new ServiceError(ErrorCode.MATCH_REG_NOT_FOUND);
  596. }
  597. const query = { id, match_id, ext_status: '7', final_confirm: '0' };
  598. const regData = await this.matchRegService.fetch(query);
  599. if (!regData) {
  600. throw new ServiceError(ErrorCode.MATCH_REG_NOT_FOUND);
  601. }
  602. // 合并评审记录
  603. const oldDetails: Array<any> = get(regData, 'final_score_details') || [];
  604. const final_score_details: object = get(data, 'details');
  605. if (oldDetails && oldDetails.length > 0) {
  606. // 判断之前的评审记录是否存在
  607. const alreadyGiven = oldDetails.findIndex(f => get(final_score_details, 'name') && f.name === get(final_score_details, 'name'));
  608. if (alreadyGiven >= 0) {
  609. // 已经给过了,最新的覆盖
  610. oldDetails.splice(alreadyGiven, 0, final_score_details);
  611. } else {
  612. // 没有给,那就直接push
  613. oldDetails.push(final_score_details);
  614. }
  615. } else {
  616. // 没有给,那就直接push
  617. oldDetails.push();
  618. }
  619. // 计算总分
  620. const final_score_total = oldDetails.reduce((p, n) => p + get(n, 'score', 0), 0);
  621. const final_score = final_score_total / oldDetails.length;
  622. await this.matchRegService.update(query, { final_score, final_score_details: oldDetails });
  623. }
  624. @Post('/step8', { routerName: '决赛阶段-赛事结束' })
  625. async step8(@Body() data: object) {
  626. /**
  627. * 检查内容:
  628. * 赛事拓展表:
  629. * ext.status = "7"
  630. * 修改内容:
  631. * 赛事拓展表:
  632. * ext.status => "8" 变为 决赛阶段-赛事进行
  633. * 赛事报名表:
  634. * reg.ext_status: "7" => '8'
  635. */
  636. const match_id = get(data, 'match_id');
  637. await this.service.checkMatchExtStatus(match_id, '7');
  638. await this.service.update({ match_id }, { status: '8' });
  639. await this.matchRegService.update({ match_id, ext_status: '7', final_confirm: '0' }, { ext_status: '8' });
  640. }
  641. /**
  642. * 人为规定的决赛实时名单
  643. * @param match_id 赛事id
  644. * @returns
  645. */
  646. @Post('/lastList/:match_id', { routerName: '赛事决赛名单' })
  647. async lastList(@Param('match_id') match_id: string) {
  648. const list = await this.matchRegService.getArrangeList(match_id)
  649. const newList = []
  650. for (const i of list) {
  651. let newItem = cloneDeep(i)
  652. newItem = this.matchRegService.dealData(newItem);
  653. newList.push(newItem)
  654. }
  655. return newList;
  656. }
  657. }