CampPlayApplicationService.cs 57 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Data.Entity;
  4. using System.Linq;
  5. using System.Threading.Tasks;
  6. using System.Web.Mvc;
  7. using Abp.Application.Services.Dto;
  8. using Abp.Auditing;
  9. using Abp.Authorization;
  10. using Abp.Configuration;
  11. using Abp.Domain.Repositories;
  12. using Abp.Runtime.Caching;
  13. using IwbZero.Auditing;
  14. using IwbZero.AppServiceBase;
  15. using IwbZero.ToolCommon;
  16. using IwbZero.ToolCommon.LogHelpers;
  17. using IwbZero.ToolCommon.StringModel;
  18. using Microsoft.AspNet.SignalR;
  19. using WeEngine.CommonDto;
  20. using WeEngine.CommonDto.PortraitDto;
  21. using WeEngine.CommonDto.ReportDto;
  22. using WeEngine.Packages;
  23. using WeOnlineApp.Authorization.Users;
  24. using WeOnlineApp.Configuration;
  25. using WeOnlineApp.Configuration.Cache;
  26. using WeOnlineApp.Hubs;
  27. using WeOnlineApp.MqttClient;
  28. using WeOnlineApp.TrainingCamp;
  29. using WeOnlineApp.TrainingCampPlay.Dto;
  30. #pragma warning disable CS4014
  31. namespace WeOnlineApp.TrainingCampPlay
  32. {
  33. [AbpAuthorize, AuditLog("演练营信息")]
  34. public class CampPlayAppService : IwbAsyncCrudAppService<CampPlayInfo, CampPlayDto, string, IwbPagedRequestDto, CampPlayCreateDto, CampPlayUpdateDto>, ICampPlayAppService
  35. {
  36. public CampPlayAppService(
  37. ICacheManager cacheManager,
  38. IRepository<CampPlayInfo, string> repository, IRepository<CampPlayUserInfo> puRepository, IRepository<User, long> userRepository, IRepository<CampPlayLogInfo> plRepository, IRepository<CampInfo, string> campRepository, IRepository<CampPlayScoreInfo> psRepository) : base(repository, "Id")
  39. {
  40. PuRepository = puRepository;
  41. UserRepository = userRepository;
  42. PlRepository = plRepository;
  43. CampRepository = campRepository;
  44. PsRepository = psRepository;
  45. CacheManager = cacheManager;
  46. IwbHubContext = GlobalHost.ConnectionManager.GetHubContext<IwbHub>();
  47. HasReStart = false;
  48. }
  49. private bool HasReStart { get; set; }
  50. protected IHubContext IwbHubContext { get; }
  51. private string EngineApiUrl => SettingManager.GetSettingValue(IwbSettingNames.WeEngineIp).Ew("/");
  52. private string DataCenterUrl => SettingManager.GetSettingValue(IwbSettingNames.WeDataCenterIp).Ew("/");
  53. protected IRepository<CampInfo, string> CampRepository { get; }
  54. protected override bool KeyIsAuto { get; set; } = false;
  55. protected IRepository<User, long> UserRepository { get; }
  56. protected IRepository<CampPlayUserInfo> PuRepository { get; }
  57. protected IRepository<CampPlayLogInfo> PlRepository { get; }
  58. protected IRepository<CampPlayScoreInfo> PsRepository { get; }
  59. #region GetSelect
  60. [DisableAuditing]
  61. public override async Task<List<SelectListItem>> GetSelectList()
  62. {
  63. var list = await Repository.GetAllListAsync();
  64. var sList = new List<SelectListItem> { new SelectListItem { Text = @"请选择...", Value = "", Selected = true } };
  65. foreach (var l in list)
  66. {
  67. sList.Add(new SelectListItem { Value = l.Id, Text = l.Name });
  68. }
  69. return sList;
  70. }
  71. [DisableAuditing]
  72. public override async Task<string> GetSelectStr()
  73. {
  74. var list = await Repository.GetAllListAsync();
  75. string str = "<option value=\"\" selected>请选择...</option>";
  76. foreach (var l in list)
  77. {
  78. str += $"<option value=\"{l.Id}\">{l.Name}</option>";
  79. }
  80. return str;
  81. }
  82. #endregion GetSelect
  83. #region CURD
  84. //[AbpAuthorize(PermissionNames.PagesCampPlayMgQuery)]Create)]
  85. public override async Task Create(CampPlayCreateDto input)
  86. {
  87. input.Id = await AppGuidManager.GetNextRecordIdAsync(DataLibType.CampPlay);
  88. input.PlayState = CampPlayStateDefinition.New;
  89. input.InvitationCode = await GenerateCode();
  90. await CreateEntity(input);
  91. }
  92. public async Task<string> CreatePlay(CampPlayCreateDto input)
  93. {
  94. input.Id = await AppGuidManager.GetNextRecordIdAsync(DataLibType.CampPlay);
  95. input.PlayState = CampPlayStateDefinition.New;
  96. input.InvitationCode = await GenerateCode();
  97. if (input.PlayModel == CampPlayModelDefinition.Single)
  98. {
  99. input.IsPublic = false;
  100. }
  101. var dto = await CreateEntity(input);
  102. await PuRepository.InsertAsync(new CampPlayUserInfo()
  103. {
  104. CampNo = dto.CampNo,
  105. PlayUserId = AbpSession.UserId ?? 0,
  106. PlayNo = dto.Id,
  107. PlayerState = CampPlayUserStateDefinition.New,
  108. PlayerType = CampPlayerTypeDefinition.Creator,
  109. Role = "房主"
  110. });
  111. await UnitOfWorkManager.Current.SaveChangesAsync();
  112. return dto.InvitationCode;
  113. }
  114. //[AbpAuthorize(PermissionNames.PagesCampPlayMgQuery)]Update)]
  115. public override async Task Update(CampPlayUpdateDto input)
  116. {
  117. await UpdateEntity(input);
  118. }
  119. //[AbpAuthorize(PermissionNames.PagesCampPlayMgQuery)]Delete)]
  120. public override Task Delete(EntityDto<string> input)
  121. {
  122. return DeleteEntity(input);
  123. }
  124. [DisableAuditing]
  125. public override async Task<PagedResultDto<CampPlayDto>> GetAll(IwbPagedRequestDto input)
  126. {
  127. var query = CreateFilteredQuery(input);
  128. query = ApplyFilter(query, input);
  129. var totalCount = await AsyncQueryableExecuter.CountAsync(query);
  130. query = ApplySorting(query, input);
  131. query = ApplyPaging(query, input);
  132. var entities = await AsyncQueryableExecuter.ToListAsync(query);
  133. var dtoList = new PagedResultDto<CampPlayDto>(totalCount, entities.Select(MapToEntityDto).ToList());
  134. return dtoList;
  135. }
  136. #region GetEntity/Dto
  137. /// <summary>
  138. /// 查询实体Dto
  139. /// </summary>
  140. /// <param name="input"></param>
  141. /// <returns></returns>
  142. [DisableAuditing]
  143. public override async Task<CampPlayDto> GetDto(EntityDto<string> input)
  144. {
  145. var entity = await GetEntity(input);
  146. return MapToEntityDto(entity);
  147. }
  148. /// <summary>
  149. /// 查询实体Dto
  150. /// </summary>
  151. /// <param name="id"></param>
  152. /// <returns></returns>
  153. [DisableAuditing]
  154. public override async Task<CampPlayDto> GetDtoById(string id)
  155. {
  156. var entity = await GetEntityById(id);
  157. return MapToEntityDto(entity);
  158. }
  159. /// <summary>
  160. /// 查询实体Dto(需指明自定义字段)
  161. /// </summary>
  162. /// <param name="no"></param>
  163. /// <returns></returns>
  164. [DisableAuditing]
  165. public override async Task<CampPlayDto> GetDtoByNo(string no)
  166. {
  167. var entity = await GetEntityByNo(no);
  168. return MapToEntityDto(entity);
  169. }
  170. /// <summary>
  171. /// 查询实体
  172. /// </summary>
  173. /// <param name="input"></param>
  174. /// <returns></returns>
  175. [DisableAuditing]
  176. public override async Task<CampPlayInfo> GetEntity(EntityDto<string> input)
  177. {
  178. var entity = await GetEntityById(input.Id);
  179. return entity;
  180. }
  181. /// <summary>
  182. /// 查询实体
  183. /// </summary>
  184. /// <param name="id"></param>
  185. /// <returns></returns>
  186. [DisableAuditing]
  187. public override async Task<CampPlayInfo> GetEntityById(string id)
  188. {
  189. return await Repository.FirstOrDefaultAsync(a => a.Id == id);
  190. }
  191. /// <summary>
  192. /// 查询实体(需指明自定义字段)
  193. /// </summary>
  194. /// <param name="no"></param>
  195. /// <returns></returns>
  196. [DisableAuditing]
  197. public override async Task<CampPlayInfo> GetEntityByNo(string no)
  198. {
  199. //CheckGetPermission();
  200. if (string.IsNullOrEmpty(KeyFiledName))
  201. {
  202. ThrowError("NoKeyFieldName");
  203. }
  204. return await base.GetEntityByNo(no);
  205. }
  206. #endregion GetEntity/Dto
  207. #region Hide
  208. ///// <summary>
  209. ///// 根据给定的<see cref="IwbPagedRequestDto"/>创建 <see cref="IQueryable{CampPlayInfo}"/>过滤查询.
  210. ///// </summary>
  211. ///// <param name="input">The input.</param>
  212. //protected override IQueryable<CampPlayInfo> CreateFilteredQuery(IwbPagedRequestDto input)
  213. //{
  214. // var query = Repository.GetAll();
  215. // var pagedInput = input as IIwbPagedRequest;
  216. // if (pagedInput == null)
  217. // {
  218. // return query;
  219. // }
  220. // if (!string.IsNullOrEmpty(pagedInput.KeyWords))
  221. // {
  222. // object keyWords = pagedInput.KeyWords;
  223. // LambdaObject obj = new LambdaObject()
  224. // {
  225. // FieldType = (LambdaFieldType)pagedInput.FieldType,
  226. // FieldName = pagedInput.KeyField,
  227. // FieldValue = keyWords,
  228. // ExpType = (LambdaExpType)pagedInput.ExpType
  229. // };
  230. // var exp = obj.GetExp<CampPlayInfo>();
  231. // query = exp != null ? query.Where(exp) : query;
  232. // }
  233. // if (pagedInput.SearchList != null && pagedInput.SearchList.Count > 0)
  234. // {
  235. // List<LambdaObject> objList = new List<LambdaObject>();
  236. // foreach (var o in pagedInput.SearchList)
  237. // {
  238. // if (string.IsNullOrEmpty(o.KeyWords))
  239. // continue;
  240. // object keyWords = o.KeyWords;
  241. // objList.Add(new LambdaObject
  242. // {
  243. // FieldType = (LambdaFieldType)o.FieldType,
  244. // FieldName = o.KeyField,
  245. // FieldValue = keyWords,
  246. // ExpType = (LambdaExpType)o.ExpType
  247. // });
  248. // }
  249. // var exp = objList.GetExp<CampPlayInfo>();
  250. // query = exp != null ? query.Where(exp) : query;
  251. // }
  252. // return query;
  253. //}
  254. //protected override IQueryable<CampPlayInfo> ApplySorting(IQueryable<CampPlayInfo> query, IwbPagedRequestDto input)
  255. //{
  256. // return query.OrderBy(a => a.No);
  257. //}
  258. //protected override IQueryable<CampPlayInfo> ApplyPaging(IQueryable<CampPlayInfo> query, IwbPagedRequestDto input)
  259. //{
  260. // if (input is IPagedResultRequest pagedInput)
  261. // {
  262. // return query.Skip(pagedInput.SkipCount).Take(pagedInput.MaxResultCount);
  263. // }
  264. // return query;
  265. //}
  266. #endregion Hide
  267. #endregion CURD
  268. #region Query
  269. /// <summary>
  270. /// 检查演练是否在运行
  271. /// </summary>
  272. /// <param name="playNo"></param>
  273. /// <returns></returns>
  274. public async Task<bool> CheckIsRun(string playNo)
  275. {
  276. return playNo == (await GetRunPlay());
  277. }
  278. /// <summary>
  279. /// 获取用户正在进行的演练
  280. /// </summary>
  281. /// <returns></returns>
  282. public async Task<string> GetRunPlay()
  283. {
  284. var runPlay = await PuRepository.FirstOrDefaultAsync(a =>
  285. (a.PlayerState != CampPlayUserStateDefinition.End && a.PlayerState != CampPlayUserStateDefinition.Exit && a.PlayUserId == AbpSession.UserId));
  286. return runPlay?.PlayNo;
  287. }
  288. /// <summary>
  289. /// 查询演练用户
  290. /// </summary>
  291. /// <param name="no"></param>
  292. /// <returns></returns>
  293. public async Task<CampPlayUserDto> GetPlayUser(string no)
  294. {
  295. var runPlay = await PuRepository.FirstOrDefaultAsync(a => a.PlayNo == no && a.PlayUserId == AbpSession.UserId);
  296. var dto = MapPlayUser(runPlay);
  297. return dto;
  298. }
  299. /// <summary>
  300. /// 查询演练用户
  301. /// </summary>
  302. /// <param name="no"></param>
  303. /// <returns></returns>
  304. public async Task<List<CampPlayUserDto>> GetPlayUsers(string no)
  305. {
  306. var runPlay = await PuRepository.GetAll().Where(a => a.PlayNo == no).OrderBy(a => a.PlayerType).ToListAsync();
  307. var dtoList = runPlay.Select(MapPlayUser).ToList();
  308. return dtoList;
  309. }
  310. private User QueryUserInfo(long id)
  311. {
  312. return CacheManager.GetCache(IwbCacheNames.UserInfoCache).Get($"{id}", () =>
  313. {
  314. var user = UserRepository.FirstOrDefault(a => a.Id == id);
  315. return user;
  316. });
  317. }
  318. /// <summary>
  319. /// 根据邀请码获取用户演练
  320. /// </summary>
  321. /// <returns></returns>
  322. public async Task<string> GetPlayNoByCode(string code)
  323. {
  324. var play = await Repository.FirstOrDefaultAsync(a => a.InvitationCode == code);
  325. return play.Id;
  326. }
  327. /// <summary>
  328. /// 根据邀请码获取用户演练
  329. /// </summary>
  330. /// <returns></returns>
  331. public async Task<CampPlayDto> GetPlayByCode(string code)
  332. {
  333. var entity = await Repository.FirstOrDefaultAsync(a => a.InvitationCode == code);
  334. var dto = MapToEntityDto(entity);
  335. return dto;
  336. }
  337. #endregion Query
  338. #region PlayUserState
  339. /// <summary>
  340. /// 加入演练
  341. /// </summary>
  342. /// <param name="input"></param>
  343. /// <returns></returns>
  344. public async Task Join(EntityDto<string> input)
  345. {
  346. var play = await GetEntity(input);
  347. if (play == null)
  348. {
  349. CheckErrors("未查询到演练!");
  350. return;
  351. }
  352. var runPlay = await PuRepository.FirstOrDefaultAsync(a =>
  353. a.PlayerState != CampPlayUserStateDefinition.Exit && a.PlayerState != CampPlayUserStateDefinition.End &&
  354. a.PlayUserId == AbpSession.UserId);
  355. if (runPlay != null)
  356. {
  357. CheckErrors("您还有未退出的演练,不能加入新演练!");
  358. }
  359. var playUser = new CampPlayUserInfo()
  360. {
  361. CampNo = play.CampNo,
  362. PlayUserId = AbpSession.UserId ?? 0,
  363. PlayNo = play.Id,
  364. PlayerState = CampPlayUserStateDefinition.New,
  365. PlayerType = CampPlayerTypeDefinition.Member
  366. };
  367. await PuRepository.InsertAsync(playUser);
  368. await UnitOfWorkManager.Current.SaveChangesAsync();
  369. NoteUserChange(play.InvitationCode, playUser);
  370. }
  371. /// <summary>
  372. /// 开始准备
  373. /// </summary>
  374. /// <param name="input"></param>
  375. /// <returns></returns>
  376. public async Task Ready(PlayRoleDto input)
  377. {
  378. var play = await GetEntity(input);
  379. if (play == null)
  380. {
  381. CheckErrors("未查询到演练!");
  382. return;
  383. }
  384. var playUser =
  385. await PuRepository.FirstOrDefaultAsync(a => a.PlayNo == play.Id && a.PlayUserId == AbpSession.UserId);
  386. if (playUser == null)
  387. {
  388. CheckErrors("您还未加入到演练!");
  389. return;
  390. }
  391. playUser.PlayerState = CampPlayUserStateDefinition.Ready;
  392. playUser.Role = input.Role;
  393. await PuRepository.UpdateAsync(playUser);
  394. await UnitOfWorkManager.Current.SaveChangesAsync();
  395. NoteUserChange(play.InvitationCode, playUser);
  396. }
  397. /// <summary>
  398. /// 取消准备
  399. /// </summary>
  400. /// <param name="input"></param>
  401. /// <returns></returns>
  402. public async Task CancelReady(EntityDto<string> input)
  403. {
  404. var play = await GetEntity(input);
  405. if (play == null)
  406. {
  407. CheckErrors("未查询到演练!");
  408. return;
  409. }
  410. var playUser =
  411. await PuRepository.FirstOrDefaultAsync(a => a.PlayNo == play.Id && a.PlayUserId == AbpSession.UserId);
  412. if (playUser == null)
  413. {
  414. CheckErrors("您还未加入到演练!");
  415. return;
  416. }
  417. playUser.PlayerState = CampPlayUserStateDefinition.CancelReady;
  418. playUser.Role = "";
  419. await PuRepository.UpdateAsync(playUser);
  420. await UnitOfWorkManager.Current.SaveChangesAsync();
  421. NoteUserChange(play.InvitationCode, playUser);
  422. }
  423. /// <summary>
  424. /// 通知演练用户发生变化
  425. /// </summary>
  426. /// <param name="code"></param>
  427. /// <param name="input"></param>
  428. private void NoteUserChange(string code, CampPlayUserInfo input)
  429. {
  430. var dto = MapPlayUser(input);
  431. IwbHubContext.Clients.Group(code).GetUserChange(dto.Obj2StringCamelCase());
  432. }
  433. #endregion PlayUserState
  434. #region Operation
  435. /// <summary>
  436. /// 进入演练页面成功后反馈
  437. /// </summary>
  438. /// <param name="no"></param>
  439. [AbpAllowAnonymous]
  440. public bool StartFeedback(string no)
  441. {
  442. return WeOnlineAppMsgClientManager.StartPushScene(no);
  443. }
  444. /// <summary>
  445. /// 开始演练
  446. /// </summary>
  447. /// <param name="input"></param>
  448. /// <returns></returns>
  449. [AuditLog("开始演练")]
  450. public async Task Start(EntityDto<string> input)
  451. {
  452. var play = await Repository.GetAllIncluding(a => a.CampInfo).FirstOrDefaultAsync(a => a.Id == input.Id);
  453. //var play = await CacheManager.GetPlayInfoAsync(input.Id, Repository);
  454. if (play == null)
  455. {
  456. CheckErrors("未查询到演练!");
  457. return;
  458. }
  459. if (play.PlayState != CampPlayStateDefinition.New)
  460. {
  461. CheckErrors("演练已运行或结束!");
  462. }
  463. WeOnlineAppMsgClientManager.StopPushScene(play.Id);
  464. var camp = play.CampInfo;
  465. if (camp == null)
  466. {
  467. CheckErrors("未查询到课程!");
  468. return;
  469. }
  470. new TaskFactory().StartNew(() => { CacheManager.GetPackageDetail(camp.PackageNo, DataCenterUrl); });
  471. RunStartPackageDto dto = new RunStartPackageDto()
  472. {
  473. PackageId = camp.PackageNo,
  474. AutoNextRound = true,
  475. AssessAuto = !camp.AssessRoleNames.IsEmpty(),
  476. AssessRoles = camp.AssessRoleNames?.Split(',').ToList() ?? new List<string>(),
  477. RoundScore = camp.RoundScore,
  478. Variable = camp.Variable,
  479. GroupNos = new List<string>() { play.Id },
  480. //TargetClientId = IwbConsts.ClientName
  481. TargetClientId = WeOnlineAppMsgClientManager.GetTargetClient()
  482. };
  483. await CacheManager.GetCache(IwbCacheNames.PlayRunningInfoCache).RemoveAsync(play.Id);
  484. var url = $"{EngineApiUrl}api/services/Engine/Run/Start";
  485. var result = url.RequestPost(dto.Obj2String());
  486. if (result.Contains("\"success\":false"))
  487. {
  488. await WriteLog(play, LogCommandDefinition.Start, "启动失败");
  489. CheckErrors("演练启动失败!");
  490. }
  491. else
  492. {
  493. await WriteLog(play, LogCommandDefinition.Start);
  494. }
  495. }
  496. /// <summary>
  497. /// 重新启动
  498. /// </summary>
  499. /// <param name="input"></param>
  500. /// <returns></returns>
  501. [AuditLog("重新启动")]
  502. public async Task<bool> ReStart(EntityDto<string> input)
  503. {
  504. //var play = await Repository.GetAllIncluding(a => a.CampInfo).FirstOrDefaultAsync(a => a.Id == input.Id);
  505. var play = await CacheManager.GetPlayInfoAsync(input.Id, Repository);
  506. if (play == null)
  507. {
  508. CheckErrors("未查询到演练!");
  509. return false;
  510. }
  511. if (play.PlayState != CampPlayStateDefinition.Run)
  512. {
  513. CheckErrors("演练未运行,不能重启!");
  514. }
  515. var camp = play.CampInfo;
  516. ReStartPackageDto dto = new ReStartPackageDto()
  517. {
  518. PackageId = camp.PackageNo,
  519. RunningInfo = play.RunningInfo,
  520. AutoNextRound = true,
  521. TargetClientId = IwbConsts.ClientName
  522. };
  523. var url = $"{EngineApiUrl}api/services/Engine/Run/ReStart";
  524. var result = url.RequestPost(dto.Obj2String());
  525. if (result.Contains("\"success\":false"))
  526. {
  527. await WriteLog(play, LogCommandDefinition.Start, "启动失败");
  528. CheckErrors("演练启动失败!");
  529. return false;
  530. }
  531. await WriteLog(play, LogCommandDefinition.Start);
  532. return true;
  533. }
  534. /// <summary>
  535. /// 下一轮次
  536. /// </summary>
  537. /// <returns></returns>
  538. [AuditLog("下一轮次")]
  539. public async Task NextRound(EntityDto<string> input)
  540. {
  541. //var play = await Repository.GetAllIncluding(a => a.CampInfo).FirstOrDefaultAsync(a => a.Id == input.Id);
  542. var play = await CacheManager.GetPlayInfoAsync(input.Id, Repository);
  543. if (play == null)
  544. {
  545. CheckErrors("未查询到演练!");
  546. return;
  547. }
  548. if (play.PlayState != CampPlayStateDefinition.Run)
  549. {
  550. CheckErrors("演练未运行或结束!");
  551. }
  552. await NextPlayRound(input, play);
  553. }
  554. private async Task NextPlayRound(EntityDto<string> input, CampPlayInfo play)
  555. {
  556. var url = $"{EngineApiUrl}api/services/Engine/Run/NextRound?groupNo={play.Id}";
  557. var result = url.RequestPost("");
  558. if (result.Contains("\"success\":false"))
  559. {
  560. await WriteLog(play, LogCommandDefinition.NextRound, "下一轮次失败");
  561. if (!HasReStart && (await ReStart(input)))
  562. {
  563. HasReStart = true;
  564. await NextPlayRound(input, play);
  565. }
  566. else
  567. {
  568. CheckErrors("培训营操作失败!");
  569. }
  570. }
  571. else
  572. {
  573. HasReStart = false;
  574. await WriteLog(play, LogCommandDefinition.NextRound);
  575. IwbHubContext.Clients.Group(play.InvitationCode).getDisabledLog(new
  576. {
  577. no = play.Id,
  578. }.Obj2String());
  579. }
  580. }
  581. /// <summary>
  582. /// 下一情景流节点
  583. /// </summary>
  584. /// <returns></returns>
  585. [AuditLog("下一情景流节点")]
  586. public async Task NextFlowNode(EntityDto<string> input)
  587. {
  588. //var play = await Repository.GetAllIncluding(a => a.CampInfo).FirstOrDefaultAsync(a => a.Id == input.Id);
  589. var play = await CacheManager.GetPlayInfoAsync(input.Id, Repository);
  590. if (play == null)
  591. {
  592. CheckErrors("未查询到演练!");
  593. return;
  594. }
  595. if (play.PlayState != CampPlayStateDefinition.Run)
  596. {
  597. CheckErrors("演练未运行或结束!");
  598. }
  599. await NextPlayFlowNode(input, play);
  600. }
  601. private async Task NextPlayFlowNode(EntityDto<string> input, CampPlayInfo play)
  602. {
  603. var url = $"{EngineApiUrl}api/services/Engine/Run/NextGroupFlowNodes?groupNo={play.Id}";
  604. var result = url.RequestPost("");
  605. if (result.Contains("\"success\":false"))
  606. {
  607. await WriteLog(play, LogCommandDefinition.NextNode, "下一情景流节点失败");
  608. if (!HasReStart && (await ReStart(input)))
  609. {
  610. HasReStart = true;
  611. await NextPlayFlowNode(input, play);
  612. }
  613. else
  614. {
  615. CheckErrors("培训营操作失败!");
  616. }
  617. }
  618. else
  619. {
  620. HasReStart = false;
  621. await WriteLog(play, LogCommandDefinition.NextNode);
  622. await ChangeLogState(play);
  623. IwbHubContext.Clients.Group(play.InvitationCode).getDisabledLog(new
  624. {
  625. no = play.Id,
  626. }.Obj2String());
  627. }
  628. }
  629. /// <summary>
  630. /// 提交指令
  631. /// </summary>
  632. /// <param name="input"></param>
  633. /// <returns></returns>
  634. [AbpAllowAnonymous, AuditLog("提交指令")]
  635. public async Task WriteCmdLog(RunOperationDto input)
  636. {
  637. //var play = await Repository.GetAllIncluding(a => a.CampInfo).FirstOrDefaultAsync(a => a.Id == input.GroupNo);
  638. var play = await CacheManager.GetPlayInfoAsync(input.GroupNo, Repository);
  639. if (play == null)
  640. {
  641. CheckErrors($"未查询编号为【{input.GroupNo}】到培训营!");
  642. return;
  643. }
  644. if (play.PlayState != CampPlayStateDefinition.Run)
  645. {
  646. CheckErrors("演练未运行!");
  647. }
  648. var log = await SaveCmdLog(input, play);
  649. IwbHubContext.Clients.Group(play.InvitationCode).getCmdLog(new
  650. {
  651. id = log.Id,
  652. no = play.Id,
  653. role = input.BehaviorRole,
  654. word = input.BehaviorWord,
  655. logState = log.LogState,
  656. imagePath = AbpSession.AvatarImagePath,
  657. name = AbpSession.RealName
  658. }.Obj2String());
  659. }
  660. /// <summary>
  661. /// 提交并下达指令
  662. /// </summary>
  663. /// <param name="input"></param>
  664. /// <returns></returns>
  665. [AbpAllowAnonymous, AuditLog("提交并下达指令")]
  666. public async Task WriteSubmitCmdLog(RunOperationDto input)
  667. {
  668. //var play = await Repository.GetAllIncluding(a => a.CampInfo).FirstOrDefaultAsync(a => a.Id == input.GroupNo);
  669. var play = await CacheManager.GetPlayInfoAsync(input.GroupNo, Repository);
  670. if (play == null)
  671. {
  672. CheckErrors($"未查询编号为【{input.GroupNo}】到培训营!");
  673. return;
  674. }
  675. if (play.PlayState != CampPlayStateDefinition.Run)
  676. {
  677. CheckErrors("演练未运行!");
  678. }
  679. var log = await SaveCmdLog(input, play);
  680. log = await SubmitSceneCmd(log, play, input.ScenePath);
  681. IwbHubContext.Clients.Group(play.InvitationCode).getCmdLog(new
  682. {
  683. id = log.Id,
  684. no = play.Id,
  685. role = input.BehaviorRole,
  686. word = input.BehaviorWord,
  687. logState = log.LogState,
  688. imagePath = AbpSession.AvatarImagePath,
  689. name = AbpSession.RealName,
  690. scenePath = log.ScenePath
  691. }.Obj2String());
  692. }
  693. /// <summary>
  694. /// 保存指令
  695. /// </summary>
  696. /// <param name="input"></param>
  697. /// <param name="play"></param>
  698. /// <returns></returns>
  699. private async Task<CampPlayLogInfo> SaveCmdLog(RunOperationDto input, CampPlayInfo play)
  700. {
  701. var groupLog = new CampPlayLogInfo()
  702. {
  703. CampNo = play.CampNo,
  704. PlayNo = input.GroupNo,
  705. LogType = LogTypeDefinition.SceneOperation,
  706. LogCommand = LogCommandDefinition.SceneOperation,
  707. LogState = LogStateDefinition.New,
  708. LogScore = 0,
  709. ScenePath = input.ScenePath,
  710. RoleName = input.BehaviorRole,
  711. LogMessage = input.BehaviorWord,
  712. RoundIndex = play.RoundIndex,
  713. UserId = AbpSession.UserId ?? 0,
  714. UserName = AbpSession.UserName
  715. };
  716. var entity = await PlRepository.InsertAsync(groupLog);
  717. await CurrentUnitOfWork.SaveChangesAsync();
  718. return entity;
  719. }
  720. /// <summary>
  721. /// 下达指令
  722. /// </summary>
  723. /// <param name="id"></param>
  724. /// <param name="scenePath"></param>
  725. /// <returns></returns>
  726. [AbpAllowAnonymous, AuditLog("下达指令")]
  727. public async Task SubmitCmd(int id, string scenePath)
  728. {
  729. var log = await PlRepository.FirstOrDefaultAsync(a => a.Id == id);
  730. if (log == null)
  731. {
  732. CheckErrors("未查询到处理记录!");
  733. return;
  734. }
  735. //var play = await Repository.GetAllIncluding(a => a.CampInfo).FirstOrDefaultAsync(a => a.Id == log.PlayNo);
  736. var play = await CacheManager.GetPlayInfoAsync(log.PlayNo, Repository);
  737. if (play == null)
  738. {
  739. CheckErrors($"未查询编号为【{log.PlayNo}】到培训营!");
  740. return;
  741. }
  742. if (play.PlayState != CampPlayStateDefinition.Run)
  743. {
  744. CheckErrors("演练未运行!");
  745. }
  746. await SubmitSceneCmd(log, play, scenePath);
  747. }
  748. /// <summary>
  749. /// 下达指令
  750. /// </summary>
  751. /// <param name="log"></param>
  752. /// <param name="play"></param>
  753. /// <param name="scenePath"></param>
  754. /// <returns></returns>
  755. private async Task<CampPlayLogInfo> SubmitSceneCmd(CampPlayLogInfo log, CampPlayInfo play, string scenePath)
  756. {
  757. log.LogState = LogStateDefinition.Submit;
  758. log.ScenePath = scenePath;
  759. log = await PlRepository.UpdateAsync(log);
  760. var checkRole = (await SettingManager.GetSettingValueAsync(IwbSettingNames.EvalCheckRole)).UAndT() == "Y" && play.CampInfo.AssessRoleNames.IsNotEmpty();
  761. await SubmitPlaySceneCmd(log, play, scenePath, checkRole);
  762. return log;
  763. }
  764. private async Task SubmitPlaySceneCmd(CampPlayLogInfo log, CampPlayInfo play, string scenePath, bool checkRole)
  765. {
  766. var dataStr = new
  767. {
  768. GroupNo = log.PlayNo,
  769. BehaviorRole = log.RoleName,
  770. BehaviorWord = $"{log.Id}|{log.LogMessage}",
  771. ScenePath = scenePath,
  772. CheckRole = checkRole
  773. }.Obj2String();
  774. string url = $"{EngineApiUrl}api/services/Engine/Run/MatchWord";
  775. var result = url.RequestPost(dataStr);
  776. if (result.Contains("\"success\":false"))
  777. {
  778. if (!HasReStart && (await ReStart(new EntityDto<string>(play.Id))))
  779. {
  780. HasReStart = true;
  781. await SubmitPlaySceneCmd(log, play, scenePath, checkRole);
  782. }
  783. else
  784. {
  785. CheckErrors("培训营操作失败!");
  786. }
  787. }
  788. else
  789. {
  790. HasReStart = false;
  791. IwbHubContext.Clients.Group(play.InvitationCode).getCmdLogSubmit(new { no = play.Id, logId = log.Id, scenePath = log.ScenePath }.Obj2String());
  792. }
  793. }
  794. [AbpAllowAnonymous, DisableAuditing]
  795. public async Task UpdateLog(UpdateLogDto input)
  796. {
  797. var log = await PlRepository.FirstOrDefaultAsync(a => a.Id == input.Id);
  798. if (log != null)
  799. {
  800. log.LogMessage = input.Text;
  801. await PlRepository.UpdateAsync(log);
  802. }
  803. }
  804. /// <summary>
  805. /// 情景讨论
  806. /// </summary>
  807. /// <param name="input"></param>
  808. /// <returns></returns>
  809. [AbpAllowAnonymous, AuditLog("情景讨论")]
  810. public async Task Chat(ChatDto input)
  811. {
  812. //var play = await Repository.GetAllIncluding(a => a.CampInfo).FirstOrDefaultAsync(a => a.Id == input.Id);
  813. var play = await CacheManager.GetPlayInfoAsync(input.Id, Repository);
  814. if (play == null)
  815. {
  816. CheckErrors($"未查询编号为【{input.Id}】到演练!");
  817. return;
  818. }
  819. var log = new CampPlayLogInfo()
  820. {
  821. CampNo = play.CampNo,
  822. PlayNo = input.Id,
  823. LogType = LogTypeDefinition.Comment,
  824. LogCommand = LogCommandDefinition.Chat,
  825. LogState = LogStateDefinition.New,
  826. LogScore = 0,
  827. LogMessage = input.Msg,
  828. RoundIndex = play.RoundIndex,
  829. UserId = AbpSession.UserId ?? 0,
  830. UserName = AbpSession.UserName
  831. };
  832. log = await PlRepository.InsertAsync(log);
  833. await CurrentUnitOfWork.SaveChangesAsync();
  834. IwbHubContext.Clients.Group(play.InvitationCode).getChat(new
  835. {
  836. id = log.Id,
  837. no = play.Id,
  838. imagePath = AbpSession.AvatarImagePath,
  839. word = input.Msg,
  840. userId = AbpSession.UserId ?? 0,
  841. userName = AbpSession.UserName,
  842. name = AbpSession.RealName,
  843. logDate = log.CreationTime
  844. }.Obj2String());
  845. }
  846. /// <summary>
  847. /// 退出演练
  848. /// </summary>
  849. /// <param name="no"></param>
  850. /// <returns></returns>
  851. [AbpAllowAnonymous, AuditLog("退出演练")]
  852. public async Task ExitPlay(string no)
  853. {
  854. var player =
  855. await PuRepository
  856. .FirstOrDefaultAsync(a => a.PlayNo == no && a.PlayUserId == AbpSession.UserId);
  857. if (player == null)
  858. {
  859. CheckErrors("您还未参加演练!");
  860. return;
  861. }
  862. //var play = player.CampPlayInfo;
  863. var play = await CacheManager.GetPlayInfoAsync(no, Repository);
  864. if (play == null)
  865. {
  866. CheckErrors($"未查询编号为【{no}】到演练!");
  867. return;
  868. }
  869. if (player.PlayerType == CampPlayerTypeDefinition.Creator)
  870. {
  871. if (play.PlayState == CampPlayStateDefinition.New)
  872. {
  873. await PuRepository.DeleteAsync(a => a.PlayNo == play.Id);
  874. await Repository.DeleteAsync(play);
  875. IwbHubContext.Clients.Group(play.InvitationCode).getCreatorExit(new { no = play.Id, id = player.Id, userName = player.UserName, userId = player.PlayUserId }.Obj2String());
  876. return;
  877. }
  878. await Stop(play, 2);
  879. return;
  880. }
  881. if (play.PlayState != CampPlayStateDefinition.Run || player.PlayerState != CampPlayUserStateDefinition.Run)
  882. {
  883. await PuRepository.DeleteAsync(player);
  884. }
  885. else
  886. {
  887. player.PlayerState = CampPlayUserStateDefinition.Exit;
  888. await PuRepository.UpdateAsync(player);
  889. }
  890. await CurrentUnitOfWork.SaveChangesAsync();
  891. IwbHubContext.Clients.Group(play.InvitationCode).getUserExit(new { no = play.Id, id = player.Id, userName = player.UserName, userId = player.PlayUserId }.Obj2String());
  892. }
  893. /// <summary>
  894. /// 超时退出演练
  895. /// </summary>
  896. /// <param name="no"></param>
  897. /// <returns></returns>
  898. [AbpAllowAnonymous, AuditLog("超时退出演练")]
  899. public async Task OvertimeExitPlay(string no)
  900. {
  901. var player =
  902. await PuRepository //.GetAllIncluding(a => a.CampPlayInfo)
  903. .FirstOrDefaultAsync(a => a.PlayNo == no && a.PlayUserId == AbpSession.UserId);
  904. if (player == null)
  905. {
  906. CheckErrors("您还未参加演练!");
  907. return;
  908. }
  909. //var play = player.CampPlayInfo;
  910. var play = await CacheManager.GetPlayInfoAsync(no, Repository);
  911. if (play == null)
  912. {
  913. CheckErrors($"未查询编号为【{no}】到演练!");
  914. return;
  915. }
  916. await Stop(play, 1);
  917. }
  918. /// <summary>
  919. /// 结束演练
  920. /// </summary>
  921. /// <param name="no"></param>
  922. /// <param name="type"></param>
  923. /// <returns></returns>
  924. public async Task Stop(string no, int type)
  925. {
  926. //var play = await GetEntityById(no);
  927. var play = await CacheManager.GetPlayInfoAsync(no, Repository);
  928. if (play == null)
  929. {
  930. CheckErrors("未查询到演练!");
  931. return;
  932. }
  933. if (play.PlayState != CampPlayStateDefinition.New)
  934. {
  935. CheckErrors("演练已运行或结束!");
  936. }
  937. await Stop(play, type);
  938. }
  939. /// <summary>
  940. /// 结束演练
  941. /// </summary>
  942. /// <param name="entity"></param>
  943. /// <param name="type"></param>
  944. /// <returns></returns>
  945. private async Task Stop(CampPlayInfo entity, int type)
  946. {
  947. entity.PlayState = type == 1 ? CampPlayStateDefinition.OverTime : CampPlayStateDefinition.End;
  948. var date = DateTime.Now;
  949. entity.EndDate = date;
  950. entity.TrainingMinute = entity.StartDate?.GetTimeSpanMinute(date) ?? 0;
  951. await Repository.UpdateAsync(entity);
  952. var users = await PuRepository.GetAllListAsync(a =>
  953. a.PlayNo == entity.Id && (a.PlayerState == CampPlayUserStateDefinition.Run));
  954. if (users.Any())
  955. {
  956. foreach (var u in users)
  957. {
  958. u.PlayerState = type == 2 ? CampPlayUserStateDefinition.Exit : CampPlayUserStateDefinition.End;
  959. await PuRepository.UpdateAsync(u);
  960. }
  961. }
  962. await CurrentUnitOfWork.SaveChangesAsync();
  963. IwbHubContext.Clients.Group(entity.InvitationCode).getPlayStop(new { no = entity.Id }.Obj2String());
  964. }
  965. //private async Task ChangeLogState(string no)
  966. //{
  967. // var play = await Repository.FirstOrDefaultAsync(a => a.Id == no);
  968. // if (play != null)
  969. // {
  970. // await ChangeLogState(play);
  971. // }
  972. //}
  973. private async Task ChangeLogState(CampPlayInfo play)
  974. {
  975. var logList = await PlRepository.GetAllListAsync(a =>
  976. a.PlayNo == play.Id && a.RoundIndex == play.RoundIndex &&
  977. a.LogType == LogTypeDefinition.SceneOperation &&
  978. (a.LogState == LogStateDefinition.New || a.LogState == LogStateDefinition.Submit));
  979. if (logList.Any())
  980. {
  981. foreach (var log in logList)
  982. {
  983. log.LogState = log.LogState == LogStateDefinition.New ? LogStateDefinition.NotSend :
  984. log.LogState == LogStateDefinition.Submit ? LogStateDefinition.Send : log.LogState;
  985. await PlRepository.UpdateAsync(log);
  986. }
  987. }
  988. }
  989. /// <summary>
  990. /// 记录日志
  991. /// </summary>
  992. /// <param name="play"></param>
  993. /// <param name="cmd"></param>
  994. /// <param name="logMsg"></param>
  995. /// <param name="role"></param>
  996. /// <param name="score"></param>
  997. /// <param name="logType"></param>
  998. /// <returns></returns>
  999. private async Task WriteLog(CampPlayInfo play, string cmd, string logMsg = "", string role = "", decimal score = 0, int? logType = null)
  1000. {
  1001. logType = logType ?? LogTypeDefinition.System;
  1002. var log = new CampPlayLogInfo()
  1003. {
  1004. CampNo = play.CampNo,
  1005. PlayNo = play.Id,
  1006. RoundIndex = play.RoundIndex,
  1007. LogCommand = cmd,
  1008. LogMessage = logMsg,
  1009. RoleName = role,
  1010. LogType = (int)logType,
  1011. LogScore = score,
  1012. UserId = AbpSession.UserId ?? 0,
  1013. UserName = AbpSession.UserName
  1014. };
  1015. await PlRepository.InsertAsync(log);
  1016. await CurrentUnitOfWork.SaveChangesAsync();
  1017. }
  1018. #endregion Operation
  1019. #region History
  1020. /// <summary>
  1021. /// 查询登录用户的历史演练
  1022. /// </summary>
  1023. /// <param name="input"></param>
  1024. /// <returns></returns>
  1025. [DisableAuditing]
  1026. public async Task<PagedResultDto<PlayHistoryDto>> GetHistoryPlay(IwbPagedRequestDto input)
  1027. {
  1028. var query = PuRepository.GetAllIncluding(a => a.CampPlayInfo, a => a.CampPlayInfo.CampInfo, a => a.Player)
  1029. .Where(a => a.PlayUserId == AbpSession.UserId && (a.CampPlayInfo.PlayState == CampPlayStateDefinition.End || a.CampPlayInfo.PlayState == CampPlayStateDefinition.OverTime));
  1030. query = ApplyFilter(query, input);
  1031. var total = await query.CountAsync();
  1032. query = query.OrderByDescending(a => a.Id);
  1033. query = query.Skip(input.SkipCount).Take(input.MaxResultCount);
  1034. var query1 = query.Select(a => new PlayHistoryDto
  1035. {
  1036. Id = a.PlayNo,
  1037. Name = a.CampPlayInfo.Name,
  1038. CampNo = a.CampNo,
  1039. CampName = a.CampPlayInfo.CampInfo.Name,
  1040. PackageName = a.CampPlayInfo.CampInfo.PackageName,
  1041. PlayModel = a.CampPlayInfo.PlayModel,
  1042. StartDate = a.CampPlayInfo.StartDate,
  1043. EndDate = a.CampPlayInfo.EndDate,
  1044. TrainingMinute = a.CampPlayInfo.TrainingMinute,
  1045. UserId = a.PlayUserId,
  1046. UserName = a.Player.UserName,
  1047. RealName = a.Player.Name
  1048. });
  1049. var dtoList = await query1.ToListAsync();
  1050. return new PagedResultDto<PlayHistoryDto>(total, dtoList);
  1051. }
  1052. /// <summary>
  1053. /// 查询演练报告基础信息
  1054. /// </summary>
  1055. /// <param name="no"></param>
  1056. /// <returns></returns>
  1057. [DisableAuditing]
  1058. public async Task<PlayReportDto> GetReportPlay(string no)
  1059. {
  1060. var dto = await Repository.GetAllIncluding(a => a.CampInfo).Where(a => a.Id == no).Select(a =>
  1061. new PlayReportDto()
  1062. {
  1063. Id = a.Id,
  1064. Name = a.Name,
  1065. CampNo = a.CampNo,
  1066. CampName = a.CampInfo.Name,
  1067. PackageName = a.CampInfo.PackageName,
  1068. PlayModel = a.PlayModel,
  1069. PlayRoleNames = a.PlayRoleNames,
  1070. Purposes = a.CampInfo.Purposes,
  1071. Organizer = a.CampInfo.Organizer,
  1072. StartDate = a.StartDate,
  1073. EndDate = a.EndDate,
  1074. TrainingMinute = a.TrainingMinute,
  1075. }).FirstOrDefaultAsync();
  1076. return dto;
  1077. }
  1078. /// <summary>
  1079. /// 查询演练数据
  1080. /// </summary>
  1081. /// <param name="no"></param>
  1082. /// <returns></returns>
  1083. [DisableAuditing]
  1084. public async Task<PlayReportDto> GetPlayData(string no)
  1085. {
  1086. //var play = await GetEntityById(no);
  1087. var play = await CacheManager.GetPlayInfoAsync(no, Repository);
  1088. if (play == null)
  1089. {
  1090. return null;
  1091. }
  1092. return await CacheManager.GetCache(IwbCacheNames.PlayReportInfoCache).GetAsync(no, async () =>
  1093. {
  1094. var dto = new PlayReportDto();
  1095. var runNode = play.RunningInfo.Str2Obj<PackageDataNode>();
  1096. var fullRunningInfo = GetFullRunningInfo(runNode);
  1097. dto.ChartData = TrainingInfoFrom(fullRunningInfo);
  1098. dto.EvalQualitativeResult = fullRunningInfo?.EvalQualitativeResult;
  1099. dto.Scenes = await ReportRoundSceneDtoFrom(fullRunningInfo, no);
  1100. var groupScores = await PsRepository.GetAllListAsync(a => a.PlayNo == no);
  1101. dto.ScoreData = await RoundScoreDtoFrom(groupScores);
  1102. return dto;
  1103. });
  1104. }
  1105. private PackageDataNode GetFullRunningInfo(PackageDataNode runNode)
  1106. {
  1107. return CacheManager.GetCache(IwbCacheNames.PlayReportInfoCache).Get($"RN_{runNode.Id}", () =>
  1108. {
  1109. var node = CacheManager.GetPackageDataNode(runNode.PackageNo, DataCenterUrl);
  1110. if (node != null)
  1111. {
  1112. runNode.MergeNode(node);
  1113. }
  1114. return runNode;
  1115. });
  1116. }
  1117. private List<TrainingRoundInfoDto> TrainingInfoFrom(PackageDataNode runningInfo)
  1118. {
  1119. var dtoList = new List<TrainingRoundInfoDto>();
  1120. var roundInfos = runningInfo?.Children;
  1121. if (roundInfos != null)
  1122. {
  1123. foreach (var r in roundInfos)
  1124. {
  1125. var roundInfo = new TrainingRoundInfoDto(r.RoundIndex);
  1126. var rt = new TrainingInfoDto($"第{r.RoundIndex}轮", r.Id, r.IsStart);
  1127. foreach (var b in r.Children)
  1128. {
  1129. //var bt = new TrainingInfoDto($"情景块[{b.Path}]", b.Path,b.IsStart);
  1130. foreach (var f in b.Children)
  1131. {
  1132. var ft = new TrainingInfoDto($"情景流[{f.Name}]", f.Id, f.IsStart);
  1133. ft.Children.AddRange(TrainingInfoNodeFrom(f.Children) ?? new List<TrainingInfoDto>());
  1134. rt.Children.Add(ft);
  1135. }
  1136. //rt.Children.Add(bt);
  1137. }
  1138. var blockInfo = r.Children.Where(a => a.IsStart).ToList();
  1139. foreach (var b2 in blockInfo)
  1140. {
  1141. var flows = b2.Children.Where(a => a.IsStart).ToList();
  1142. foreach (var f2 in flows)
  1143. {
  1144. var fcFlow = FcFlowInfoFrom(f2.Children, new FcFlowInfoDto(f2.Name));
  1145. roundInfo.AddFcFlowInfo(fcFlow);
  1146. }
  1147. }
  1148. roundInfo.Infos.Add(rt);
  1149. dtoList.Add(roundInfo);
  1150. }
  1151. }
  1152. return dtoList;
  1153. }
  1154. private List<TrainingInfoDto> TrainingInfoNodeFrom(List<FlowNodeDataNode> nodes, int i = 0)
  1155. {
  1156. i++;
  1157. var dtoList = new List<TrainingInfoDto>();
  1158. if (nodes != null && nodes.Any())
  1159. {
  1160. foreach (var node in nodes)
  1161. {
  1162. var name = string.Join(",", node.SceneNodes.Select(a => a.Name).ToArray());
  1163. var nt = new TrainingInfoDto($"情景{i}:{name}", node.Id, node.IsStart);
  1164. if (node.Children != null && node.Children.Any())
  1165. {
  1166. nt.Children.AddRange(TrainingInfoNodeFrom(node.Children, i));
  1167. }
  1168. dtoList.Add(nt);
  1169. }
  1170. }
  1171. return dtoList;
  1172. }
  1173. private FcFlowInfoDto FcFlowInfoFrom(List<FlowNodeDataNode> infos, FcFlowInfoDto fcFlow)
  1174. {
  1175. infos = infos.Where(a => a.IsStart).ToList();
  1176. foreach (var info in infos)
  1177. {
  1178. var scenes = info.SceneNodes.Where(a => a.IsStart).ToList();
  1179. foreach (var s in scenes)
  1180. {
  1181. fcFlow.FlowInfos.Add(new PointDto(s.Name));
  1182. }
  1183. if (info.Children != null && info.Children.Any())
  1184. {
  1185. fcFlow = FcFlowInfoFrom(info.Children, fcFlow);
  1186. }
  1187. }
  1188. return fcFlow;
  1189. }
  1190. private async Task<List<ReportRoundSceneDto>> ReportRoundSceneDtoFrom(PackageDataNode fullRunNode, string playNo)
  1191. {
  1192. var list = new List<ReportRoundSceneDto>();
  1193. var roundInfos = fullRunNode?.Children;
  1194. if (roundInfos != null)
  1195. {
  1196. foreach (var roundInfo in roundInfos)
  1197. {
  1198. var roundScene = new ReportRoundSceneDto() { RoundIndex = roundInfo.RoundIndex, SceneInfos = new List<ReportSceneDto>() };
  1199. if (roundInfo.RunSceneInfos != null)
  1200. {
  1201. foreach (var info in roundInfo.RunSceneInfos)
  1202. {
  1203. var scene = await GetPlaySceneInfoWithBehavior(playNo, info.Path, fullRunNode);
  1204. roundScene.SceneInfos.Add(scene);
  1205. }
  1206. }
  1207. list.Add(roundScene);
  1208. }
  1209. }
  1210. return list;
  1211. }
  1212. private async Task<ReportSceneDto> GetPlaySceneInfoWithBehavior(string no, string scenePath, PackageDataNode fullRunNode)
  1213. {
  1214. var playInfo = await Repository.FirstOrDefaultAsync(a => a.Id == no);
  1215. if (playInfo == null)
  1216. {
  1217. CheckErrors($"未查询编号为【{no}】到培训营!");
  1218. return null;
  1219. }
  1220. try
  1221. {
  1222. var detail = await CacheManager.GetCampPackageDetail(playInfo.CampNo, DataCenterUrl, CampRepository);
  1223. var scene = detail?.Scenes.FirstOrDefault(a => a.Path == scenePath);
  1224. if (scene == null)
  1225. {
  1226. return null;
  1227. }
  1228. //var runGroupInfo = await CacheManager.GetGroupRunningInfoAsync(no, Repository);
  1229. //if (runGroupInfo == null)
  1230. //{
  1231. // return null;
  1232. //}
  1233. //var dto = ObjectMapper.Map<SceneDto>(scene);
  1234. var runScene = fullRunNode.RunSceneInfos.FirstOrDefault(a => a.Path == scene.Path);
  1235. var bList = new List<BehaviorDto>();
  1236. if (runScene != null)
  1237. {
  1238. //dto.HasEnd = runScene.IsEnd;
  1239. scene.Variables = scene.Variables.MergeHashtable(runScene.GetVariables());
  1240. //dto.Variables = scene.Variables;
  1241. if (runScene.Children != null && runScene.Children.Count > 0)
  1242. {
  1243. foreach (var behavior in runScene.Children)
  1244. {
  1245. var bDto = new BehaviorDto(behavior);
  1246. var b = detail.Behaviors?.FirstOrDefault(a => a.Path == behavior.Path);
  1247. if (b != null)
  1248. {
  1249. bDto.Name = b.Name;
  1250. bDto.Description = b.Description;
  1251. }
  1252. bList.Add(bDto);
  1253. }
  1254. }
  1255. }
  1256. //if (scene.BehaviorNos.IsNotEmpty())
  1257. //{
  1258. // var arr = scene.BehaviorNos.Split(',');
  1259. // foreach (var s in arr)
  1260. // {
  1261. // var b = detail.Behaviors?.FirstOrDefault(a => a.ParentPath == scenePath && a.Id == s);
  1262. // if (b != null)
  1263. // {
  1264. // var behavior = runGroupInfo.RunBehaviorInfos?.FirstOrDefault(a => a.Path == b.Path);
  1265. // if (behavior != null)
  1266. // {
  1267. // var bDto = new BehaviorDto(behavior)
  1268. // {
  1269. // Description = b.Description
  1270. // };
  1271. // bList.Add(bDto);
  1272. // }
  1273. // }
  1274. // }
  1275. //}
  1276. var rDto = new ReportSceneDto(scene)
  1277. {
  1278. Behaviors = bList
  1279. };
  1280. return rDto;
  1281. }
  1282. catch (Exception e)
  1283. {
  1284. this.LogError(e);
  1285. }
  1286. return null;
  1287. }
  1288. private async Task<RoundScoreDto> RoundScoreDtoFrom(List<CampPlayScoreInfo> scoreInfos)
  1289. {
  1290. scoreInfos = scoreInfos.OrderBy(a => a.RoundIndex).ToList();
  1291. var roundScore = new RoundScoreDto()
  1292. {
  1293. ScoreInfos = new List<decimal>(),
  1294. SiGongInfos = new List<TagScoreDto>(),
  1295. WuLiInfos = new List<TagScoreDto>()
  1296. };
  1297. var tags = await SettingManager.GetSettingValueAsync(IwbSettingNames.SiGongWuLiTag);
  1298. var arr = tags.Split('|');
  1299. if (arr.Length < 2)
  1300. {
  1301. return null;
  1302. }
  1303. var sgTagArr = arr[0].Split(',');
  1304. var wlTagArr = arr[1].Split(',');
  1305. foreach (var s in sgTagArr)
  1306. {
  1307. roundScore.SiGongInfos.Add(new TagScoreDto() { Name = s, TagScoreInfos = new List<decimal>() });
  1308. }
  1309. foreach (var s in wlTagArr)
  1310. {
  1311. roundScore.WuLiInfos.Add(new TagScoreDto() { Name = s, TagScoreInfos = new List<decimal>() });
  1312. }
  1313. foreach (var info in scoreInfos)
  1314. {
  1315. var sScore = Convert.ToDecimal(info.SystemScore.ToString("0.00"));
  1316. roundScore.ScoreInfos.Add(sScore);
  1317. var tagScores = info.BehaviorTagScoreInfo?.Str2Obj<List<TagScoreInfo>>() ?? new List<TagScoreInfo>();
  1318. foreach (var scoreInfo in tagScores)
  1319. {
  1320. var sg = roundScore.SiGongInfos.FirstOrDefault(a => a.Name == scoreInfo.TagNo);
  1321. if (sg != null)
  1322. {
  1323. var score = scoreInfo.TotalScore == 0
  1324. ? 0
  1325. : (scoreInfo.CorrectionScore == 0
  1326. ? scoreInfo.SystemScore
  1327. : scoreInfo.CorrectionScore) * 100 / scoreInfo.TotalScore;
  1328. score = score > 100 ? 100 : score;
  1329. score = Convert.ToDecimal(score.ToString("0.00"));
  1330. sg.TagScoreInfos.Add(score);
  1331. }
  1332. var wl = roundScore.WuLiInfos.FirstOrDefault(a => a.Name == scoreInfo.TagNo);
  1333. if (wl != null)
  1334. {
  1335. var score = scoreInfo.TotalScore == 0
  1336. ? 0
  1337. : (scoreInfo.CorrectionScore == 0
  1338. ? scoreInfo.SystemScore
  1339. : scoreInfo.CorrectionScore) * 100 / scoreInfo.TotalScore;
  1340. score = score > 100 ? 100 : score;
  1341. score = Convert.ToDecimal(score.ToString("0.00"));
  1342. wl.TagScoreInfos.Add(score);
  1343. }
  1344. }
  1345. }
  1346. return roundScore;
  1347. }
  1348. #endregion History
  1349. private CampPlayUserDto MapPlayUser(CampPlayUserInfo input)
  1350. {
  1351. if (input == null)
  1352. {
  1353. return null;
  1354. }
  1355. var dto = ObjectMapper.Map<CampPlayUserDto>(input);
  1356. var user = QueryUserInfo(input.PlayUserId);
  1357. if (user != null)
  1358. {
  1359. dto.PlayerName = $"{user.Name}";
  1360. dto.UserName = $"{user.UserName}";
  1361. dto.ImagePath = user.ImagePath;
  1362. }
  1363. return dto;
  1364. }
  1365. /// <summary>
  1366. /// 生成邀请码
  1367. /// </summary>
  1368. /// <returns></returns>
  1369. private async Task<string> GenerateCode(int count = 0)
  1370. {
  1371. TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1);
  1372. string str = Convert.ToInt64(ts.TotalSeconds).ToString();
  1373. var arr = str.ToCharArray();
  1374. char temp1 = arr[0], temp2 = arr[1], temp3 = arr[2], temp4 = arr[4];
  1375. arr[0] = arr[arr.Length - 2];
  1376. arr[1] = arr[arr.Length - 4];
  1377. arr[2] = arr[arr.Length - 5];
  1378. arr[4] = arr[arr.Length - 3];
  1379. arr[arr.Length - 3] = temp4;
  1380. arr[arr.Length - 2] = temp3;
  1381. arr[arr.Length - 4] = temp2;
  1382. arr[arr.Length - 5] = temp1;
  1383. //var code = $"{str.Substring(5)}{str.Substring(0, 5)}";
  1384. var code = new string(arr);
  1385. if ((await Repository.CountAsync(a => a.InvitationCode == code)) > 0 && count < 5)
  1386. {
  1387. count++;
  1388. return await GenerateCode(count);
  1389. }
  1390. if (count >= 5)
  1391. {
  1392. CheckErrors("邀请码生成失败!");
  1393. }
  1394. return code;
  1395. }
  1396. }
  1397. }