using System; using System.Collections.Generic; using System.Data.Entity; using System.Linq; using System.Threading.Tasks; using System.Web.Mvc; using Abp.Application.Services.Dto; using Abp.Auditing; using Abp.Authorization; using Abp.Configuration; using Abp.Domain.Repositories; using Abp.Runtime.Caching; using IwbZero.Auditing; using IwbZero.AppServiceBase; using IwbZero.ToolCommon; using IwbZero.ToolCommon.LogHelpers; using IwbZero.ToolCommon.StringModel; using Microsoft.AspNet.SignalR; using WeEngine.CommonDto; using WeEngine.CommonDto.PortraitDto; using WeEngine.CommonDto.ReportDto; using WeEngine.Packages; using WeOnlineApp.Authorization.Users; using WeOnlineApp.Configuration; using WeOnlineApp.Configuration.Cache; using WeOnlineApp.Hubs; using WeOnlineApp.MqttClient; using WeOnlineApp.TrainingCamp; using WeOnlineApp.TrainingCampPlay.Dto; #pragma warning disable CS4014 namespace WeOnlineApp.TrainingCampPlay { [AbpAuthorize, AuditLog("演练营信息")] public class CampPlayAppService : IwbAsyncCrudAppService, ICampPlayAppService { public CampPlayAppService( ICacheManager cacheManager, IRepository repository, IRepository puRepository, IRepository userRepository, IRepository plRepository, IRepository campRepository, IRepository psRepository) : base(repository, "Id") { PuRepository = puRepository; UserRepository = userRepository; PlRepository = plRepository; CampRepository = campRepository; PsRepository = psRepository; CacheManager = cacheManager; IwbHubContext = GlobalHost.ConnectionManager.GetHubContext(); HasReStart = false; } private bool HasReStart { get; set; } protected IHubContext IwbHubContext { get; } private string EngineApiUrl => SettingManager.GetSettingValue(IwbSettingNames.WeEngineIp).Ew("/"); private string DataCenterUrl => SettingManager.GetSettingValue(IwbSettingNames.WeDataCenterIp).Ew("/"); protected IRepository CampRepository { get; } protected override bool KeyIsAuto { get; set; } = false; protected IRepository UserRepository { get; } protected IRepository PuRepository { get; } protected IRepository PlRepository { get; } protected IRepository PsRepository { get; } #region GetSelect [DisableAuditing] public override async Task> GetSelectList() { var list = await Repository.GetAllListAsync(); var sList = new List { new SelectListItem { Text = @"请选择...", Value = "", Selected = true } }; foreach (var l in list) { sList.Add(new SelectListItem { Value = l.Id, Text = l.Name }); } return sList; } [DisableAuditing] public override async Task GetSelectStr() { var list = await Repository.GetAllListAsync(); string str = ""; foreach (var l in list) { str += $""; } return str; } #endregion GetSelect #region CURD //[AbpAuthorize(PermissionNames.PagesCampPlayMgQuery)]Create)] public override async Task Create(CampPlayCreateDto input) { input.Id = await AppGuidManager.GetNextRecordIdAsync(DataLibType.CampPlay); input.PlayState = CampPlayStateDefinition.New; input.InvitationCode = await GenerateCode(); await CreateEntity(input); } public async Task CreatePlay(CampPlayCreateDto input) { input.Id = await AppGuidManager.GetNextRecordIdAsync(DataLibType.CampPlay); input.PlayState = CampPlayStateDefinition.New; input.InvitationCode = await GenerateCode(); if (input.PlayModel == CampPlayModelDefinition.Single) { input.IsPublic = false; } var dto = await CreateEntity(input); await PuRepository.InsertAsync(new CampPlayUserInfo() { CampNo = dto.CampNo, PlayUserId = AbpSession.UserId ?? 0, PlayNo = dto.Id, PlayerState = CampPlayUserStateDefinition.New, PlayerType = CampPlayerTypeDefinition.Creator, Role = "房主" }); await UnitOfWorkManager.Current.SaveChangesAsync(); return dto.InvitationCode; } //[AbpAuthorize(PermissionNames.PagesCampPlayMgQuery)]Update)] public override async Task Update(CampPlayUpdateDto input) { await UpdateEntity(input); } //[AbpAuthorize(PermissionNames.PagesCampPlayMgQuery)]Delete)] public override Task Delete(EntityDto input) { return DeleteEntity(input); } [DisableAuditing] public override async Task> GetAll(IwbPagedRequestDto input) { var query = CreateFilteredQuery(input); query = ApplyFilter(query, input); var totalCount = await AsyncQueryableExecuter.CountAsync(query); query = ApplySorting(query, input); query = ApplyPaging(query, input); var entities = await AsyncQueryableExecuter.ToListAsync(query); var dtoList = new PagedResultDto(totalCount, entities.Select(MapToEntityDto).ToList()); return dtoList; } #region GetEntity/Dto /// /// 查询实体Dto /// /// /// [DisableAuditing] public override async Task GetDto(EntityDto input) { var entity = await GetEntity(input); return MapToEntityDto(entity); } /// /// 查询实体Dto /// /// /// [DisableAuditing] public override async Task GetDtoById(string id) { var entity = await GetEntityById(id); return MapToEntityDto(entity); } /// /// 查询实体Dto(需指明自定义字段) /// /// /// [DisableAuditing] public override async Task GetDtoByNo(string no) { var entity = await GetEntityByNo(no); return MapToEntityDto(entity); } /// /// 查询实体 /// /// /// [DisableAuditing] public override async Task GetEntity(EntityDto input) { var entity = await GetEntityById(input.Id); return entity; } /// /// 查询实体 /// /// /// [DisableAuditing] public override async Task GetEntityById(string id) { return await Repository.FirstOrDefaultAsync(a => a.Id == id); } /// /// 查询实体(需指明自定义字段) /// /// /// [DisableAuditing] public override async Task GetEntityByNo(string no) { //CheckGetPermission(); if (string.IsNullOrEmpty(KeyFiledName)) { ThrowError("NoKeyFieldName"); } return await base.GetEntityByNo(no); } #endregion GetEntity/Dto #region Hide ///// ///// 根据给定的创建 过滤查询. ///// ///// The input. //protected override IQueryable CreateFilteredQuery(IwbPagedRequestDto input) //{ // var query = Repository.GetAll(); // var pagedInput = input as IIwbPagedRequest; // if (pagedInput == null) // { // return query; // } // if (!string.IsNullOrEmpty(pagedInput.KeyWords)) // { // object keyWords = pagedInput.KeyWords; // LambdaObject obj = new LambdaObject() // { // FieldType = (LambdaFieldType)pagedInput.FieldType, // FieldName = pagedInput.KeyField, // FieldValue = keyWords, // ExpType = (LambdaExpType)pagedInput.ExpType // }; // var exp = obj.GetExp(); // query = exp != null ? query.Where(exp) : query; // } // if (pagedInput.SearchList != null && pagedInput.SearchList.Count > 0) // { // List objList = new List(); // foreach (var o in pagedInput.SearchList) // { // if (string.IsNullOrEmpty(o.KeyWords)) // continue; // object keyWords = o.KeyWords; // objList.Add(new LambdaObject // { // FieldType = (LambdaFieldType)o.FieldType, // FieldName = o.KeyField, // FieldValue = keyWords, // ExpType = (LambdaExpType)o.ExpType // }); // } // var exp = objList.GetExp(); // query = exp != null ? query.Where(exp) : query; // } // return query; //} //protected override IQueryable ApplySorting(IQueryable query, IwbPagedRequestDto input) //{ // return query.OrderBy(a => a.No); //} //protected override IQueryable ApplyPaging(IQueryable query, IwbPagedRequestDto input) //{ // if (input is IPagedResultRequest pagedInput) // { // return query.Skip(pagedInput.SkipCount).Take(pagedInput.MaxResultCount); // } // return query; //} #endregion Hide #endregion CURD #region Query /// /// 检查演练是否在运行 /// /// /// public async Task CheckIsRun(string playNo) { return playNo == (await GetRunPlay()); } /// /// 获取用户正在进行的演练 /// /// public async Task GetRunPlay() { var runPlay = await PuRepository.FirstOrDefaultAsync(a => (a.PlayerState != CampPlayUserStateDefinition.End && a.PlayerState != CampPlayUserStateDefinition.Exit && a.PlayUserId == AbpSession.UserId)); return runPlay?.PlayNo; } /// /// 查询演练用户 /// /// /// public async Task GetPlayUser(string no) { var runPlay = await PuRepository.FirstOrDefaultAsync(a => a.PlayNo == no && a.PlayUserId == AbpSession.UserId); var dto = MapPlayUser(runPlay); return dto; } /// /// 查询演练用户 /// /// /// public async Task> GetPlayUsers(string no) { var runPlay = await PuRepository.GetAll().Where(a => a.PlayNo == no).OrderBy(a => a.PlayerType).ToListAsync(); var dtoList = runPlay.Select(MapPlayUser).ToList(); return dtoList; } private User QueryUserInfo(long id) { return CacheManager.GetCache(IwbCacheNames.UserInfoCache).Get($"{id}", () => { var user = UserRepository.FirstOrDefault(a => a.Id == id); return user; }); } /// /// 根据邀请码获取用户演练 /// /// public async Task GetPlayNoByCode(string code) { var play = await Repository.FirstOrDefaultAsync(a => a.InvitationCode == code); return play.Id; } /// /// 根据邀请码获取用户演练 /// /// public async Task GetPlayByCode(string code) { var entity = await Repository.FirstOrDefaultAsync(a => a.InvitationCode == code); var dto = MapToEntityDto(entity); return dto; } #endregion Query #region PlayUserState /// /// 加入演练 /// /// /// public async Task Join(EntityDto input) { var play = await GetEntity(input); if (play == null) { CheckErrors("未查询到演练!"); return; } var runPlay = await PuRepository.FirstOrDefaultAsync(a => a.PlayerState != CampPlayUserStateDefinition.Exit && a.PlayerState != CampPlayUserStateDefinition.End && a.PlayUserId == AbpSession.UserId); if (runPlay != null) { CheckErrors("您还有未退出的演练,不能加入新演练!"); } var playUser = new CampPlayUserInfo() { CampNo = play.CampNo, PlayUserId = AbpSession.UserId ?? 0, PlayNo = play.Id, PlayerState = CampPlayUserStateDefinition.New, PlayerType = CampPlayerTypeDefinition.Member }; await PuRepository.InsertAsync(playUser); await UnitOfWorkManager.Current.SaveChangesAsync(); NoteUserChange(play.InvitationCode, playUser); } /// /// 开始准备 /// /// /// public async Task Ready(PlayRoleDto input) { var play = await GetEntity(input); if (play == null) { CheckErrors("未查询到演练!"); return; } var playUser = await PuRepository.FirstOrDefaultAsync(a => a.PlayNo == play.Id && a.PlayUserId == AbpSession.UserId); if (playUser == null) { CheckErrors("您还未加入到演练!"); return; } playUser.PlayerState = CampPlayUserStateDefinition.Ready; playUser.Role = input.Role; await PuRepository.UpdateAsync(playUser); await UnitOfWorkManager.Current.SaveChangesAsync(); NoteUserChange(play.InvitationCode, playUser); } /// /// 取消准备 /// /// /// public async Task CancelReady(EntityDto input) { var play = await GetEntity(input); if (play == null) { CheckErrors("未查询到演练!"); return; } var playUser = await PuRepository.FirstOrDefaultAsync(a => a.PlayNo == play.Id && a.PlayUserId == AbpSession.UserId); if (playUser == null) { CheckErrors("您还未加入到演练!"); return; } playUser.PlayerState = CampPlayUserStateDefinition.CancelReady; playUser.Role = ""; await PuRepository.UpdateAsync(playUser); await UnitOfWorkManager.Current.SaveChangesAsync(); NoteUserChange(play.InvitationCode, playUser); } /// /// 通知演练用户发生变化 /// /// /// private void NoteUserChange(string code, CampPlayUserInfo input) { var dto = MapPlayUser(input); IwbHubContext.Clients.Group(code).GetUserChange(dto.Obj2StringCamelCase()); } #endregion PlayUserState #region Operation /// /// 进入演练页面成功后反馈 /// /// [AbpAllowAnonymous] public bool StartFeedback(string no) { return WeOnlineAppMsgClientManager.StartPushScene(no); } /// /// 开始演练 /// /// /// [AuditLog("开始演练")] public async Task Start(EntityDto input) { var play = await Repository.GetAllIncluding(a => a.CampInfo).FirstOrDefaultAsync(a => a.Id == input.Id); //var play = await CacheManager.GetPlayInfoAsync(input.Id, Repository); if (play == null) { CheckErrors("未查询到演练!"); return; } if (play.PlayState != CampPlayStateDefinition.New) { CheckErrors("演练已运行或结束!"); } WeOnlineAppMsgClientManager.StopPushScene(play.Id); var camp = play.CampInfo; if (camp == null) { CheckErrors("未查询到课程!"); return; } new TaskFactory().StartNew(() => { CacheManager.GetPackageDetail(camp.PackageNo, DataCenterUrl); }); RunStartPackageDto dto = new RunStartPackageDto() { PackageId = camp.PackageNo, AutoNextRound = true, AssessAuto = !camp.AssessRoleNames.IsEmpty(), AssessRoles = camp.AssessRoleNames?.Split(',').ToList() ?? new List(), RoundScore = camp.RoundScore, Variable = camp.Variable, GroupNos = new List() { play.Id }, //TargetClientId = IwbConsts.ClientName TargetClientId = WeOnlineAppMsgClientManager.GetTargetClient() }; await CacheManager.GetCache(IwbCacheNames.PlayRunningInfoCache).RemoveAsync(play.Id); var url = $"{EngineApiUrl}api/services/Engine/Run/Start"; var result = url.RequestPost(dto.Obj2String()); if (result.Contains("\"success\":false")) { await WriteLog(play, LogCommandDefinition.Start, "启动失败"); CheckErrors("演练启动失败!"); } else { await WriteLog(play, LogCommandDefinition.Start); } } /// /// 重新启动 /// /// /// [AuditLog("重新启动")] public async Task ReStart(EntityDto input) { //var play = await Repository.GetAllIncluding(a => a.CampInfo).FirstOrDefaultAsync(a => a.Id == input.Id); var play = await CacheManager.GetPlayInfoAsync(input.Id, Repository); if (play == null) { CheckErrors("未查询到演练!"); return false; } if (play.PlayState != CampPlayStateDefinition.Run) { CheckErrors("演练未运行,不能重启!"); } var camp = play.CampInfo; ReStartPackageDto dto = new ReStartPackageDto() { PackageId = camp.PackageNo, RunningInfo = play.RunningInfo, AutoNextRound = true, TargetClientId = IwbConsts.ClientName }; var url = $"{EngineApiUrl}api/services/Engine/Run/ReStart"; var result = url.RequestPost(dto.Obj2String()); if (result.Contains("\"success\":false")) { await WriteLog(play, LogCommandDefinition.Start, "启动失败"); CheckErrors("演练启动失败!"); return false; } await WriteLog(play, LogCommandDefinition.Start); return true; } /// /// 下一轮次 /// /// [AuditLog("下一轮次")] public async Task NextRound(EntityDto input) { //var play = await Repository.GetAllIncluding(a => a.CampInfo).FirstOrDefaultAsync(a => a.Id == input.Id); var play = await CacheManager.GetPlayInfoAsync(input.Id, Repository); if (play == null) { CheckErrors("未查询到演练!"); return; } if (play.PlayState != CampPlayStateDefinition.Run) { CheckErrors("演练未运行或结束!"); } await NextPlayRound(input, play); } private async Task NextPlayRound(EntityDto input, CampPlayInfo play) { var url = $"{EngineApiUrl}api/services/Engine/Run/NextRound?groupNo={play.Id}"; var result = url.RequestPost(""); if (result.Contains("\"success\":false")) { await WriteLog(play, LogCommandDefinition.NextRound, "下一轮次失败"); if (!HasReStart && (await ReStart(input))) { HasReStart = true; await NextPlayRound(input, play); } else { CheckErrors("培训营操作失败!"); } } else { HasReStart = false; await WriteLog(play, LogCommandDefinition.NextRound); IwbHubContext.Clients.Group(play.InvitationCode).getDisabledLog(new { no = play.Id, }.Obj2String()); } } /// /// 下一情景流节点 /// /// [AuditLog("下一情景流节点")] public async Task NextFlowNode(EntityDto input) { //var play = await Repository.GetAllIncluding(a => a.CampInfo).FirstOrDefaultAsync(a => a.Id == input.Id); var play = await CacheManager.GetPlayInfoAsync(input.Id, Repository); if (play == null) { CheckErrors("未查询到演练!"); return; } if (play.PlayState != CampPlayStateDefinition.Run) { CheckErrors("演练未运行或结束!"); } await NextPlayFlowNode(input, play); } private async Task NextPlayFlowNode(EntityDto input, CampPlayInfo play) { var url = $"{EngineApiUrl}api/services/Engine/Run/NextGroupFlowNodes?groupNo={play.Id}"; var result = url.RequestPost(""); if (result.Contains("\"success\":false")) { await WriteLog(play, LogCommandDefinition.NextNode, "下一情景流节点失败"); if (!HasReStart && (await ReStart(input))) { HasReStart = true; await NextPlayFlowNode(input, play); } else { CheckErrors("培训营操作失败!"); } } else { HasReStart = false; await WriteLog(play, LogCommandDefinition.NextNode); await ChangeLogState(play); IwbHubContext.Clients.Group(play.InvitationCode).getDisabledLog(new { no = play.Id, }.Obj2String()); } } /// /// 提交指令 /// /// /// [AbpAllowAnonymous, AuditLog("提交指令")] public async Task WriteCmdLog(RunOperationDto input) { //var play = await Repository.GetAllIncluding(a => a.CampInfo).FirstOrDefaultAsync(a => a.Id == input.GroupNo); var play = await CacheManager.GetPlayInfoAsync(input.GroupNo, Repository); if (play == null) { CheckErrors($"未查询编号为【{input.GroupNo}】到培训营!"); return; } if (play.PlayState != CampPlayStateDefinition.Run) { CheckErrors("演练未运行!"); } var log = await SaveCmdLog(input, play); IwbHubContext.Clients.Group(play.InvitationCode).getCmdLog(new { id = log.Id, no = play.Id, role = input.BehaviorRole, word = input.BehaviorWord, logState = log.LogState, imagePath = AbpSession.AvatarImagePath, name = AbpSession.RealName }.Obj2String()); } /// /// 提交并下达指令 /// /// /// [AbpAllowAnonymous, AuditLog("提交并下达指令")] public async Task WriteSubmitCmdLog(RunOperationDto input) { //var play = await Repository.GetAllIncluding(a => a.CampInfo).FirstOrDefaultAsync(a => a.Id == input.GroupNo); var play = await CacheManager.GetPlayInfoAsync(input.GroupNo, Repository); if (play == null) { CheckErrors($"未查询编号为【{input.GroupNo}】到培训营!"); return; } if (play.PlayState != CampPlayStateDefinition.Run) { CheckErrors("演练未运行!"); } var log = await SaveCmdLog(input, play); log = await SubmitSceneCmd(log, play, input.ScenePath); IwbHubContext.Clients.Group(play.InvitationCode).getCmdLog(new { id = log.Id, no = play.Id, role = input.BehaviorRole, word = input.BehaviorWord, logState = log.LogState, imagePath = AbpSession.AvatarImagePath, name = AbpSession.RealName, scenePath = log.ScenePath }.Obj2String()); } /// /// 保存指令 /// /// /// /// private async Task SaveCmdLog(RunOperationDto input, CampPlayInfo play) { var groupLog = new CampPlayLogInfo() { CampNo = play.CampNo, PlayNo = input.GroupNo, LogType = LogTypeDefinition.SceneOperation, LogCommand = LogCommandDefinition.SceneOperation, LogState = LogStateDefinition.New, LogScore = 0, ScenePath = input.ScenePath, RoleName = input.BehaviorRole, LogMessage = input.BehaviorWord, RoundIndex = play.RoundIndex, UserId = AbpSession.UserId ?? 0, UserName = AbpSession.UserName }; var entity = await PlRepository.InsertAsync(groupLog); await CurrentUnitOfWork.SaveChangesAsync(); return entity; } /// /// 下达指令 /// /// /// /// [AbpAllowAnonymous, AuditLog("下达指令")] public async Task SubmitCmd(int id, string scenePath) { var log = await PlRepository.FirstOrDefaultAsync(a => a.Id == id); if (log == null) { CheckErrors("未查询到处理记录!"); return; } //var play = await Repository.GetAllIncluding(a => a.CampInfo).FirstOrDefaultAsync(a => a.Id == log.PlayNo); var play = await CacheManager.GetPlayInfoAsync(log.PlayNo, Repository); if (play == null) { CheckErrors($"未查询编号为【{log.PlayNo}】到培训营!"); return; } if (play.PlayState != CampPlayStateDefinition.Run) { CheckErrors("演练未运行!"); } await SubmitSceneCmd(log, play, scenePath); } /// /// 下达指令 /// /// /// /// /// private async Task SubmitSceneCmd(CampPlayLogInfo log, CampPlayInfo play, string scenePath) { log.LogState = LogStateDefinition.Submit; log.ScenePath = scenePath; log = await PlRepository.UpdateAsync(log); var checkRole = (await SettingManager.GetSettingValueAsync(IwbSettingNames.EvalCheckRole)).UAndT() == "Y" && play.CampInfo.AssessRoleNames.IsNotEmpty(); await SubmitPlaySceneCmd(log, play, scenePath, checkRole); return log; } private async Task SubmitPlaySceneCmd(CampPlayLogInfo log, CampPlayInfo play, string scenePath, bool checkRole) { var dataStr = new { GroupNo = log.PlayNo, BehaviorRole = log.RoleName, BehaviorWord = $"{log.Id}|{log.LogMessage}", ScenePath = scenePath, CheckRole = checkRole }.Obj2String(); string url = $"{EngineApiUrl}api/services/Engine/Run/MatchWord"; var result = url.RequestPost(dataStr); if (result.Contains("\"success\":false")) { if (!HasReStart && (await ReStart(new EntityDto(play.Id)))) { HasReStart = true; await SubmitPlaySceneCmd(log, play, scenePath, checkRole); } else { CheckErrors("培训营操作失败!"); } } else { HasReStart = false; IwbHubContext.Clients.Group(play.InvitationCode).getCmdLogSubmit(new { no = play.Id, logId = log.Id, scenePath = log.ScenePath }.Obj2String()); } } [AbpAllowAnonymous, DisableAuditing] public async Task UpdateLog(UpdateLogDto input) { var log = await PlRepository.FirstOrDefaultAsync(a => a.Id == input.Id); if (log != null) { log.LogMessage = input.Text; await PlRepository.UpdateAsync(log); } } /// /// 情景讨论 /// /// /// [AbpAllowAnonymous, AuditLog("情景讨论")] public async Task Chat(ChatDto input) { //var play = await Repository.GetAllIncluding(a => a.CampInfo).FirstOrDefaultAsync(a => a.Id == input.Id); var play = await CacheManager.GetPlayInfoAsync(input.Id, Repository); if (play == null) { CheckErrors($"未查询编号为【{input.Id}】到演练!"); return; } var log = new CampPlayLogInfo() { CampNo = play.CampNo, PlayNo = input.Id, LogType = LogTypeDefinition.Comment, LogCommand = LogCommandDefinition.Chat, LogState = LogStateDefinition.New, LogScore = 0, LogMessage = input.Msg, RoundIndex = play.RoundIndex, UserId = AbpSession.UserId ?? 0, UserName = AbpSession.UserName }; log = await PlRepository.InsertAsync(log); await CurrentUnitOfWork.SaveChangesAsync(); IwbHubContext.Clients.Group(play.InvitationCode).getChat(new { id = log.Id, no = play.Id, imagePath = AbpSession.AvatarImagePath, word = input.Msg, userId = AbpSession.UserId ?? 0, userName = AbpSession.UserName, name = AbpSession.RealName, logDate = log.CreationTime }.Obj2String()); } /// /// 退出演练 /// /// /// [AbpAllowAnonymous, AuditLog("退出演练")] public async Task ExitPlay(string no) { var player = await PuRepository .FirstOrDefaultAsync(a => a.PlayNo == no && a.PlayUserId == AbpSession.UserId); if (player == null) { CheckErrors("您还未参加演练!"); return; } //var play = player.CampPlayInfo; var play = await CacheManager.GetPlayInfoAsync(no, Repository); if (play == null) { CheckErrors($"未查询编号为【{no}】到演练!"); return; } if (player.PlayerType == CampPlayerTypeDefinition.Creator) { if (play.PlayState == CampPlayStateDefinition.New) { await PuRepository.DeleteAsync(a => a.PlayNo == play.Id); await Repository.DeleteAsync(play); IwbHubContext.Clients.Group(play.InvitationCode).getCreatorExit(new { no = play.Id, id = player.Id, userName = player.UserName, userId = player.PlayUserId }.Obj2String()); return; } await Stop(play, 2); return; } if (play.PlayState != CampPlayStateDefinition.Run || player.PlayerState != CampPlayUserStateDefinition.Run) { await PuRepository.DeleteAsync(player); } else { player.PlayerState = CampPlayUserStateDefinition.Exit; await PuRepository.UpdateAsync(player); } await CurrentUnitOfWork.SaveChangesAsync(); IwbHubContext.Clients.Group(play.InvitationCode).getUserExit(new { no = play.Id, id = player.Id, userName = player.UserName, userId = player.PlayUserId }.Obj2String()); } /// /// 超时退出演练 /// /// /// [AbpAllowAnonymous, AuditLog("超时退出演练")] public async Task OvertimeExitPlay(string no) { var player = await PuRepository //.GetAllIncluding(a => a.CampPlayInfo) .FirstOrDefaultAsync(a => a.PlayNo == no && a.PlayUserId == AbpSession.UserId); if (player == null) { CheckErrors("您还未参加演练!"); return; } //var play = player.CampPlayInfo; var play = await CacheManager.GetPlayInfoAsync(no, Repository); if (play == null) { CheckErrors($"未查询编号为【{no}】到演练!"); return; } await Stop(play, 1); } /// /// 结束演练 /// /// /// /// public async Task Stop(string no, int type) { //var play = await GetEntityById(no); var play = await CacheManager.GetPlayInfoAsync(no, Repository); if (play == null) { CheckErrors("未查询到演练!"); return; } if (play.PlayState != CampPlayStateDefinition.New) { CheckErrors("演练已运行或结束!"); } await Stop(play, type); } /// /// 结束演练 /// /// /// /// private async Task Stop(CampPlayInfo entity, int type) { entity.PlayState = type == 1 ? CampPlayStateDefinition.OverTime : CampPlayStateDefinition.End; var date = DateTime.Now; entity.EndDate = date; entity.TrainingMinute = entity.StartDate?.GetTimeSpanMinute(date) ?? 0; await Repository.UpdateAsync(entity); var users = await PuRepository.GetAllListAsync(a => a.PlayNo == entity.Id && (a.PlayerState == CampPlayUserStateDefinition.Run)); if (users.Any()) { foreach (var u in users) { u.PlayerState = type == 2 ? CampPlayUserStateDefinition.Exit : CampPlayUserStateDefinition.End; await PuRepository.UpdateAsync(u); } } await CurrentUnitOfWork.SaveChangesAsync(); IwbHubContext.Clients.Group(entity.InvitationCode).getPlayStop(new { no = entity.Id }.Obj2String()); } //private async Task ChangeLogState(string no) //{ // var play = await Repository.FirstOrDefaultAsync(a => a.Id == no); // if (play != null) // { // await ChangeLogState(play); // } //} private async Task ChangeLogState(CampPlayInfo play) { var logList = await PlRepository.GetAllListAsync(a => a.PlayNo == play.Id && a.RoundIndex == play.RoundIndex && a.LogType == LogTypeDefinition.SceneOperation && (a.LogState == LogStateDefinition.New || a.LogState == LogStateDefinition.Submit)); if (logList.Any()) { foreach (var log in logList) { log.LogState = log.LogState == LogStateDefinition.New ? LogStateDefinition.NotSend : log.LogState == LogStateDefinition.Submit ? LogStateDefinition.Send : log.LogState; await PlRepository.UpdateAsync(log); } } } /// /// 记录日志 /// /// /// /// /// /// /// /// private async Task WriteLog(CampPlayInfo play, string cmd, string logMsg = "", string role = "", decimal score = 0, int? logType = null) { logType = logType ?? LogTypeDefinition.System; var log = new CampPlayLogInfo() { CampNo = play.CampNo, PlayNo = play.Id, RoundIndex = play.RoundIndex, LogCommand = cmd, LogMessage = logMsg, RoleName = role, LogType = (int)logType, LogScore = score, UserId = AbpSession.UserId ?? 0, UserName = AbpSession.UserName }; await PlRepository.InsertAsync(log); await CurrentUnitOfWork.SaveChangesAsync(); } #endregion Operation #region History /// /// 查询登录用户的历史演练 /// /// /// [DisableAuditing] public async Task> GetHistoryPlay(IwbPagedRequestDto input) { var query = PuRepository.GetAllIncluding(a => a.CampPlayInfo, a => a.CampPlayInfo.CampInfo, a => a.Player) .Where(a => a.PlayUserId == AbpSession.UserId && (a.CampPlayInfo.PlayState == CampPlayStateDefinition.End || a.CampPlayInfo.PlayState == CampPlayStateDefinition.OverTime)); query = ApplyFilter(query, input); var total = await query.CountAsync(); query = query.OrderByDescending(a => a.Id); query = query.Skip(input.SkipCount).Take(input.MaxResultCount); var query1 = query.Select(a => new PlayHistoryDto { Id = a.PlayNo, Name = a.CampPlayInfo.Name, CampNo = a.CampNo, CampName = a.CampPlayInfo.CampInfo.Name, PackageName = a.CampPlayInfo.CampInfo.PackageName, PlayModel = a.CampPlayInfo.PlayModel, StartDate = a.CampPlayInfo.StartDate, EndDate = a.CampPlayInfo.EndDate, TrainingMinute = a.CampPlayInfo.TrainingMinute, UserId = a.PlayUserId, UserName = a.Player.UserName, RealName = a.Player.Name }); var dtoList = await query1.ToListAsync(); return new PagedResultDto(total, dtoList); } /// /// 查询演练报告基础信息 /// /// /// [DisableAuditing] public async Task GetReportPlay(string no) { var dto = await Repository.GetAllIncluding(a => a.CampInfo).Where(a => a.Id == no).Select(a => new PlayReportDto() { Id = a.Id, Name = a.Name, CampNo = a.CampNo, CampName = a.CampInfo.Name, PackageName = a.CampInfo.PackageName, PlayModel = a.PlayModel, PlayRoleNames = a.PlayRoleNames, Purposes = a.CampInfo.Purposes, Organizer = a.CampInfo.Organizer, StartDate = a.StartDate, EndDate = a.EndDate, TrainingMinute = a.TrainingMinute, }).FirstOrDefaultAsync(); return dto; } /// /// 查询演练数据 /// /// /// [DisableAuditing] public async Task GetPlayData(string no) { //var play = await GetEntityById(no); var play = await CacheManager.GetPlayInfoAsync(no, Repository); if (play == null) { return null; } return await CacheManager.GetCache(IwbCacheNames.PlayReportInfoCache).GetAsync(no, async () => { var dto = new PlayReportDto(); var runNode = play.RunningInfo.Str2Obj(); var fullRunningInfo = GetFullRunningInfo(runNode); dto.ChartData = TrainingInfoFrom(fullRunningInfo); dto.EvalQualitativeResult = fullRunningInfo?.EvalQualitativeResult; dto.Scenes = await ReportRoundSceneDtoFrom(fullRunningInfo, no); var groupScores = await PsRepository.GetAllListAsync(a => a.PlayNo == no); dto.ScoreData = await RoundScoreDtoFrom(groupScores); return dto; }); } private PackageDataNode GetFullRunningInfo(PackageDataNode runNode) { return CacheManager.GetCache(IwbCacheNames.PlayReportInfoCache).Get($"RN_{runNode.Id}", () => { var node = CacheManager.GetPackageDataNode(runNode.PackageNo, DataCenterUrl); if (node != null) { runNode.MergeNode(node); } return runNode; }); } private List TrainingInfoFrom(PackageDataNode runningInfo) { var dtoList = new List(); var roundInfos = runningInfo?.Children; if (roundInfos != null) { foreach (var r in roundInfos) { var roundInfo = new TrainingRoundInfoDto(r.RoundIndex); var rt = new TrainingInfoDto($"第{r.RoundIndex}轮", r.Id, r.IsStart); foreach (var b in r.Children) { //var bt = new TrainingInfoDto($"情景块[{b.Path}]", b.Path,b.IsStart); foreach (var f in b.Children) { var ft = new TrainingInfoDto($"情景流[{f.Name}]", f.Id, f.IsStart); ft.Children.AddRange(TrainingInfoNodeFrom(f.Children) ?? new List()); rt.Children.Add(ft); } //rt.Children.Add(bt); } var blockInfo = r.Children.Where(a => a.IsStart).ToList(); foreach (var b2 in blockInfo) { var flows = b2.Children.Where(a => a.IsStart).ToList(); foreach (var f2 in flows) { var fcFlow = FcFlowInfoFrom(f2.Children, new FcFlowInfoDto(f2.Name)); roundInfo.AddFcFlowInfo(fcFlow); } } roundInfo.Infos.Add(rt); dtoList.Add(roundInfo); } } return dtoList; } private List TrainingInfoNodeFrom(List nodes, int i = 0) { i++; var dtoList = new List(); if (nodes != null && nodes.Any()) { foreach (var node in nodes) { var name = string.Join(",", node.SceneNodes.Select(a => a.Name).ToArray()); var nt = new TrainingInfoDto($"情景{i}:{name}", node.Id, node.IsStart); if (node.Children != null && node.Children.Any()) { nt.Children.AddRange(TrainingInfoNodeFrom(node.Children, i)); } dtoList.Add(nt); } } return dtoList; } private FcFlowInfoDto FcFlowInfoFrom(List infos, FcFlowInfoDto fcFlow) { infos = infos.Where(a => a.IsStart).ToList(); foreach (var info in infos) { var scenes = info.SceneNodes.Where(a => a.IsStart).ToList(); foreach (var s in scenes) { fcFlow.FlowInfos.Add(new PointDto(s.Name)); } if (info.Children != null && info.Children.Any()) { fcFlow = FcFlowInfoFrom(info.Children, fcFlow); } } return fcFlow; } private async Task> ReportRoundSceneDtoFrom(PackageDataNode fullRunNode, string playNo) { var list = new List(); var roundInfos = fullRunNode?.Children; if (roundInfos != null) { foreach (var roundInfo in roundInfos) { var roundScene = new ReportRoundSceneDto() { RoundIndex = roundInfo.RoundIndex, SceneInfos = new List() }; if (roundInfo.RunSceneInfos != null) { foreach (var info in roundInfo.RunSceneInfos) { var scene = await GetPlaySceneInfoWithBehavior(playNo, info.Path, fullRunNode); roundScene.SceneInfos.Add(scene); } } list.Add(roundScene); } } return list; } private async Task GetPlaySceneInfoWithBehavior(string no, string scenePath, PackageDataNode fullRunNode) { var playInfo = await Repository.FirstOrDefaultAsync(a => a.Id == no); if (playInfo == null) { CheckErrors($"未查询编号为【{no}】到培训营!"); return null; } try { var detail = await CacheManager.GetCampPackageDetail(playInfo.CampNo, DataCenterUrl, CampRepository); var scene = detail?.Scenes.FirstOrDefault(a => a.Path == scenePath); if (scene == null) { return null; } //var runGroupInfo = await CacheManager.GetGroupRunningInfoAsync(no, Repository); //if (runGroupInfo == null) //{ // return null; //} //var dto = ObjectMapper.Map(scene); var runScene = fullRunNode.RunSceneInfos.FirstOrDefault(a => a.Path == scene.Path); var bList = new List(); if (runScene != null) { //dto.HasEnd = runScene.IsEnd; scene.Variables = scene.Variables.MergeHashtable(runScene.GetVariables()); //dto.Variables = scene.Variables; if (runScene.Children != null && runScene.Children.Count > 0) { foreach (var behavior in runScene.Children) { var bDto = new BehaviorDto(behavior); var b = detail.Behaviors?.FirstOrDefault(a => a.Path == behavior.Path); if (b != null) { bDto.Name = b.Name; bDto.Description = b.Description; } bList.Add(bDto); } } } //if (scene.BehaviorNos.IsNotEmpty()) //{ // var arr = scene.BehaviorNos.Split(','); // foreach (var s in arr) // { // var b = detail.Behaviors?.FirstOrDefault(a => a.ParentPath == scenePath && a.Id == s); // if (b != null) // { // var behavior = runGroupInfo.RunBehaviorInfos?.FirstOrDefault(a => a.Path == b.Path); // if (behavior != null) // { // var bDto = new BehaviorDto(behavior) // { // Description = b.Description // }; // bList.Add(bDto); // } // } // } //} var rDto = new ReportSceneDto(scene) { Behaviors = bList }; return rDto; } catch (Exception e) { this.LogError(e); } return null; } private async Task RoundScoreDtoFrom(List scoreInfos) { scoreInfos = scoreInfos.OrderBy(a => a.RoundIndex).ToList(); var roundScore = new RoundScoreDto() { ScoreInfos = new List(), SiGongInfos = new List(), WuLiInfos = new List() }; var tags = await SettingManager.GetSettingValueAsync(IwbSettingNames.SiGongWuLiTag); var arr = tags.Split('|'); if (arr.Length < 2) { return null; } var sgTagArr = arr[0].Split(','); var wlTagArr = arr[1].Split(','); foreach (var s in sgTagArr) { roundScore.SiGongInfos.Add(new TagScoreDto() { Name = s, TagScoreInfos = new List() }); } foreach (var s in wlTagArr) { roundScore.WuLiInfos.Add(new TagScoreDto() { Name = s, TagScoreInfos = new List() }); } foreach (var info in scoreInfos) { var sScore = Convert.ToDecimal(info.SystemScore.ToString("0.00")); roundScore.ScoreInfos.Add(sScore); var tagScores = info.BehaviorTagScoreInfo?.Str2Obj>() ?? new List(); foreach (var scoreInfo in tagScores) { var sg = roundScore.SiGongInfos.FirstOrDefault(a => a.Name == scoreInfo.TagNo); if (sg != null) { var score = scoreInfo.TotalScore == 0 ? 0 : (scoreInfo.CorrectionScore == 0 ? scoreInfo.SystemScore : scoreInfo.CorrectionScore) * 100 / scoreInfo.TotalScore; score = score > 100 ? 100 : score; score = Convert.ToDecimal(score.ToString("0.00")); sg.TagScoreInfos.Add(score); } var wl = roundScore.WuLiInfos.FirstOrDefault(a => a.Name == scoreInfo.TagNo); if (wl != null) { var score = scoreInfo.TotalScore == 0 ? 0 : (scoreInfo.CorrectionScore == 0 ? scoreInfo.SystemScore : scoreInfo.CorrectionScore) * 100 / scoreInfo.TotalScore; score = score > 100 ? 100 : score; score = Convert.ToDecimal(score.ToString("0.00")); wl.TagScoreInfos.Add(score); } } } return roundScore; } #endregion History private CampPlayUserDto MapPlayUser(CampPlayUserInfo input) { if (input == null) { return null; } var dto = ObjectMapper.Map(input); var user = QueryUserInfo(input.PlayUserId); if (user != null) { dto.PlayerName = $"{user.Name}"; dto.UserName = $"{user.UserName}"; dto.ImagePath = user.ImagePath; } return dto; } /// /// 生成邀请码 /// /// private async Task GenerateCode(int count = 0) { TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1); string str = Convert.ToInt64(ts.TotalSeconds).ToString(); var arr = str.ToCharArray(); char temp1 = arr[0], temp2 = arr[1], temp3 = arr[2], temp4 = arr[4]; arr[0] = arr[arr.Length - 2]; arr[1] = arr[arr.Length - 4]; arr[2] = arr[arr.Length - 5]; arr[4] = arr[arr.Length - 3]; arr[arr.Length - 3] = temp4; arr[arr.Length - 2] = temp3; arr[arr.Length - 4] = temp2; arr[arr.Length - 5] = temp1; //var code = $"{str.Substring(5)}{str.Substring(0, 5)}"; var code = new string(arr); if ((await Repository.CountAsync(a => a.InvitationCode == code)) > 0 && count < 5) { count++; return await GenerateCode(count); } if (count >= 5) { CheckErrors("邀请码生成失败!"); } return code; } } }