_SceneInfo.cshtml 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459
  1. @using WeOnlineApp.Configuration
  2. @using WeOnlineApp.Helpers
  3. @model WeOnlineApp.Models.Play.CampPlayModel
  4. @{
  5. string id = "scene-info";
  6. }
  7. <style>
  8. #@id .card-header{
  9. display: flex;
  10. justify-content: space-between
  11. }
  12. #scene-info .card-header:after {
  13. display: none;
  14. }
  15. .current-scene-box {
  16. background: var(--mc);
  17. color: #fff;
  18. padding: 0 15px;
  19. height: 30px;
  20. line-height: 30px;
  21. text-align: center;
  22. border-radius: 0.25rem;
  23. font-size: 14px;
  24. }
  25. .current-scene-box span {
  26. font-weight: bold;
  27. }
  28. .card-scene {
  29. width: 100%;
  30. margin: 10px 0;
  31. border-radius: 0.5rem;
  32. --bg: var(--mc);
  33. }
  34. .card-scene.round {
  35. --bg: #ffdd20;
  36. }
  37. .card-scene.end {
  38. --bg: #ff7c63;
  39. }
  40. .card-scene.active {
  41. border: 1px solid var(--bg);
  42. }
  43. .card-scene > .card-header {
  44. color: var(--bg);
  45. padding: 0.4rem 0.8rem;
  46. border-radius: 0.5rem 0.5rem 0 0;
  47. font-weight: bold;
  48. font-size: 14px;
  49. cursor: pointer;
  50. transition: 0.3s all ease-in;
  51. }
  52. .card-scene.active .card-header {
  53. color: #fff;
  54. background: var(--bg)
  55. }
  56. .card-scene.collapsed-card > .card-header {
  57. border-radius: 0.5rem;
  58. }
  59. .card-scene > .card-header .card-title {
  60. font-weight: bold;
  61. font-size: 15px
  62. }
  63. .card-scene > .card-header .btn-tool {
  64. background: #ddd;
  65. color: var(--bg);
  66. padding: 0;
  67. margin-right: 0.25rem;
  68. width: 28px;
  69. }
  70. .card-scene > .card-header .attach.btn-tool.playing {
  71. color: #fff;
  72. background: var(--bg);
  73. }
  74. .card-scene > .card-header .btn-tool:hover {
  75. color: #fff;
  76. background: var(--bg);
  77. }
  78. .card-scene.active > .card-header .attach.btn-tool.playing {
  79. color: var(--bg);
  80. background: #fff;
  81. }
  82. .card-scene.active > .card-header .btn-tool:hover {
  83. color: var(--bg);
  84. background: #eee;
  85. }
  86. .card-scene > .card-header:before {
  87. content: "";
  88. position: absolute;
  89. left: 0;
  90. top: 0;
  91. width: 7px;
  92. height: 100%;
  93. background: var(--bg);
  94. border-radius: 8px 0 0 0;
  95. transition: 0.3s all ease-in;
  96. }
  97. .card-scene.collapsed-card > .card-header:before {
  98. border-radius: 8px 0 0 8px;
  99. }
  100. .card-scene > .card-body {
  101. color: #8c91a8;
  102. padding: 5px 10px 5px 15px;
  103. font-size: 12px;
  104. border-radius: 0 0 0.5rem 0.5rem;
  105. position: relative;
  106. }
  107. .card-scene > .card-body:before {
  108. content: "";
  109. position: absolute;
  110. left: 0;
  111. top: -1px;
  112. width: 7px;
  113. height: calc(100% + 1px);
  114. background: var(--bg);
  115. border-radius: 0 0 0 8px;
  116. }
  117. .card-scene > .card-body .description {
  118. text-indent: 2em;
  119. }
  120. .guide-box {
  121. font-size: 12px;
  122. color: #666;
  123. padding: 0 8px 5px;
  124. margin: 5px 10px;
  125. border: 1px dashed darkgray;
  126. border-radius: 5px;
  127. }
  128. .guide-title {
  129. font-weight: bold;
  130. margin: 5px 0;
  131. }
  132. .guide-info {
  133. margin: 0 0 5px 0;
  134. text-indent: 2em;
  135. }
  136. .flash-scene .card-title {
  137. animation: flash 1s infinite;
  138. }
  139. .load-box {
  140. position: fixed;
  141. top: 0;
  142. bottom: 0;
  143. left: 0;
  144. right: 0;
  145. display: flex;
  146. justify-content: center;
  147. align-items: center;
  148. font-size: 40px;
  149. font-weight: 600;
  150. color: #007bff;
  151. z-index: 1000;
  152. background: rgba(255,255,255,0.6);
  153. }
  154. .loading {
  155. margin-top:-10%;
  156. }
  157. .loading:after {
  158. overflow: hidden;
  159. display: inline-block;
  160. vertical-align: bottom;
  161. animation: ellipsis 2s infinite;
  162. content: "\2026";
  163. }
  164. @@keyframes ellipsis {
  165. from {
  166. width: 2px;
  167. margin-right:33px;
  168. }
  169. to {
  170. width: 35px;
  171. margin-right: 0;
  172. }
  173. }
  174. @@keyframes flash {
  175. 0% {
  176. opacity: 1.0;
  177. color: inherit;
  178. transform: scale(1);
  179. }
  180. 50% {
  181. opacity: 0.5;
  182. color: red;
  183. transform: scale(0.95);
  184. }
  185. 100% {
  186. opacity: 1.0;
  187. color: inherit;
  188. transform: scale(1);
  189. }
  190. }
  191. </style>
  192. <script>
  193. var roundPath = "P_R", round = 1, isPlaying = false, waitToPlayAttachList = [];
  194. </script>
  195. @Html.Partial("_Run/_AreaBox", $"情景区#{id}")
  196. @using (Html.BeginScripts())
  197. {
  198. <script id="scene-script">
  199. $('#@id .card-header .card-title').after('<div class=\"current-scene-box\">当前情景:<span>无</span><input type=\"hidden\" id=\"current-scene-path\" /></div>');
  200. var $sceneBoxBody = $('#@id .box-body');
  201. var _loadCount = 0, _loadTimeout;
  202. function PreLoad() {
  203. _loadCount++;
  204. console.log("加载数据中... " + _loadCount);
  205. if (!$('.load-box').length) {
  206. $('body').append(`<div class="load-box"> <span class="loading">正在加载演练数据</span></div>`);
  207. }
  208. if (_loadCount > 3) {
  209. $('.load-box').fadeOut();
  210. return;
  211. }
  212. $.iwbAjax5({
  213. url: abp.appUrl + "Query/LoadCampPre?no=@Model.Camp.Id&type=0",
  214. timeout: 1000 * 60 * 5,
  215. success:() => {
  216. clearTimeout(_loadTimeout);
  217. $('.load-box').fadeOut().remove();
  218. $.iwbAjax5({
  219. url: abp.appUrl + "Query/LoadCampPre?no=@Model.Camp.Id&type=1",
  220. timeout: 1000 * 60 * 5,
  221. complete: () => {
  222. console.log("加载中... " + _loadCount);
  223. }
  224. });
  225. },
  226. complete: () => {
  227. console.log("加载中... " + _loadCount);
  228. }
  229. });
  230. clearTimeout(_loadTimeout);
  231. _loadTimeout = setTimeout(PreLoad, 1000 * 60 * 2);
  232. }
  233. function GetScenes() {
  234. $.iwbAjax5({
  235. url: abp.appUrl + 'Query/GetPlayScenes?no=@(Model.Play.Id)',
  236. success: (res) => {
  237. if (res && res.length) {
  238. res.forEach((v) => {
  239. FormatterScene(v);
  240. });
  241. window.Scroll2Bottom($sceneBoxBody.closest('.scroll-box'));
  242. window.GetLogs();
  243. }
  244. }
  245. });
  246. }
  247. function GetSceneInfo(sceneNo) {
  248. $.iwbAjax4({
  249. url: abp.appUrl + 'Query/GetPlaySceneInfo?no=@(Model.Play.Id)&scenePath=' + sceneNo,
  250. success: function(res) {
  251. if (res) {
  252. FormatterScene(res);
  253. window.Scroll2Bottom($sceneBoxBody.closest('.scroll-box'));
  254. if (!window.startFlag) {
  255. window.startFlag = true;
  256. window.GetLogs();
  257. }
  258. } else {
  259. setTimeout(function() { GetSceneInfo(sceneNo); }, 5000);
  260. }
  261. }
  262. });
  263. }
  264. function FormatterScene(data) {
  265. var str = "";
  266. if (data) {
  267. if ($('.card-scene[data-path="' + data.path + '"]').length > 0) {
  268. return ;
  269. }
  270. if (data.path.toUpperCase().indexOf(roundPath + "" + round) == 0) {
  271. str += `<div class="card card-scene round shadow-sm collapsed-card">
  272. <div class="card-header">
  273. <div class="card-title text-center w-100"><span>第&nbsp;${round}&nbsp;轮</span></div>
  274. </div>
  275. </div>`;
  276. round++;
  277. }
  278. var attachStr = "";
  279. if (data.attaches && data.attaches.length) {
  280. data.attaches.forEach((v) => {
  281. v.attachNo = data.id + "_" + v.attachNo;
  282. waitToPlayAttachList.push(v);
  283. var icon = v.fileType === "image" ? "fa-image" : v.fileType === "video" ? "fa-video" : "";
  284. attachStr += `<button id="${v.attachNo}" class="attach btn btn-tool" id="${v.attachNo}" data-type="${v.fileType}" data-path="${v.filePath}" title="点击查看附件:${v.fileTitle}" type="button" onclick="PlayAttach(this)"><i class="fas ${icon}"></i></button>`;
  285. });
  286. }
  287. var str1;
  288. @if (Model.PlayUser!=null&&( Model.PlayUser.PlayerType == CampPlayerTypeDefinition.Creator || Model.Play.PlayModel != CampPlayModelDefinition.Team))
  289. {
  290. <text>
  291. str1 = data.hasEnd
  292. ? ''
  293. : 'title="点击处理此情景" onclick="ActiveScene($(this).closest(\'.card-scene\'))"';
  294. </text>
  295. }
  296. str1 = str1 ? str1 : 'title = "情景已处理"';
  297. var guideIcon = '', guideStr = '';
  298. if (data.guideInfos && data.guideInfos.length) {
  299. guideIcon =
  300. '<button class="btn btn-tool" title="点击查看提示引导信息" onclick="ToggleGuide(this)"><i class="fas fa-question"></i></button>';
  301. guideStr += '<div class="guide-box" style="display:none"><p class="guide-title">提示:</p>';
  302. var i = 0;
  303. data.guideInfos.forEach((v) => {
  304. i++;
  305. guideStr += '<p class="guide-info">{0}、{1}</p>'.format(i, v.description);
  306. });
  307. guideStr += '</div>';
  308. }
  309. str += `<div class="card card-scene shadow-sm ${data.hasEnd ? "collapsed-card end " : "flash-scene "}" data-name="${data.name}" data-path="${data.path}" id="scene_${data.id}">
  310. <div class="card-header" ${str1}>
  311. <div class="card-title"><span>${data.name}</span></div>
  312. <div class="card-tools">
  313. ${attachStr} ${guideIcon}
  314. <button type="button" class="btn btn-tool" data-card-widget="collapse"><i class="fas ${data.hasEnd ? "fa-plus" : "fa-minus"}"></i></button>
  315. </div>
  316. </div>
  317. <div class="card-body">
  318. ${guideStr}
  319. <div class="description">${data.description}</div>
  320. </div>
  321. </div>`;
  322. }
  323. if (str) {
  324. $sceneBoxBody.append(str);
  325. window.PlayNext();
  326. setTimeout(() => {
  327. $sceneBoxBody.find(".flash-scene").removeClass("flash-scene");
  328. }, 1000 * 30);
  329. if (!$('#current-scene-path').val()) {
  330. ActiveScene();
  331. }
  332. }
  333. }
  334. function ToggleGuide($this) {
  335. var $that = $($this);
  336. if ($that.hasClass('open')) {
  337. $that.removeClass('open').attr("title", "点击查看提示引导信息").find("i").removeClass("fa-question-circle").addClass("fa-question");
  338. $that.closest('.card-scene').find('.guide-box').slideUp(400);
  339. } else {
  340. $that.addClass('open').attr("title", "点击收起提示引导信息").find("i").removeClass("fa-question").addClass("fa-question-circle");
  341. $that.closest('.card-scene').find('.guide-box').slideDown(600);
  342. }
  343. }
  344. function PlayAttach($this) {
  345. waitToPlayAttachList = [];
  346. var $that = $($this);
  347. var no = $that.data('id');
  348. var type = $that.data('type');
  349. var path = $that.data('path');
  350. window.Play(path, type, no);
  351. }
  352. function ActiveScene($this) {
  353. var $that = $this ? $($this) : $('.card-scene:not(.end):not(.round)').eq(0);
  354. $(".card-scene").removeClass("active");
  355. $that.addClass("active");
  356. var name = $that.data('name'), path = $that.data("path");
  357. $('.current-scene-box span').html(name);
  358. $('#current-scene-path').val(path);
  359. window.iwbHub.server.sendCurrentScenePath('@Model.Play.InvitationCode', path, name);
  360. }
  361. function DisabledScene1() {
  362. $('.card-scene:not(.round):not(.end)').each(function () {
  363. $(this).addClass('old-scene');
  364. $(this).find('.card-header').removeAttr("onclick");
  365. });
  366. }
  367. function DisabledScene2() {
  368. $('.card-scene.old-scene').each(function() {
  369. $(this).removeClass('old-scene').removeClass('flash-scene').addClass('end');
  370. $(this).CardWidget("collapse");
  371. });
  372. $('.card-scene.active').removeClass('active');
  373. $('#current-scene-path').val('');
  374. $('.current-scene-box span').text('无');
  375. ActiveScene();
  376. }
  377. iwbHub.client.getNewScene = function(msg) {
  378. console.log('getNewScene: ', msg);
  379. abp.ui.clearBusy($('body'));
  380. if (msg) {
  381. try {
  382. var data = typeof msg == 'string' ? JSON.parse(msg) : msg;
  383. if (data) {
  384. if (data.no == '@(Model.Play.Id)') {
  385. if ($sceneBoxBody.find('.card-scene[data-path="' + data.path + '"]').length <= 0) {
  386. setTimeout(DisabledScene2, 1000*2);
  387. GetSceneInfo(data.sceneNo);
  388. window.Scroll2Bottom($sceneBoxBody.closest('.scroll-box'));
  389. }
  390. }
  391. }
  392. } catch (e) {
  393. console.log('getNewScene: ', e);
  394. }
  395. }
  396. };
  397. @if (Model.PlayUser==null || Model.PlayUser.PlayerType != CampPlayerTypeDefinition.Creator)
  398. {
  399. <text>
  400. iwbHub.client.getCurrentScenePath = function(msg) {
  401. console.log('getCurrentScenePath: ', msg);
  402. if (msg) {
  403. try {
  404. var data = JSON.parse(msg);
  405. if (data) {
  406. $('#current-scene-path').val(data.path);
  407. $('.current-scene-box span').text(data.name);
  408. }
  409. } catch (e) {
  410. console.log('getCurrentScenePath: ', e);
  411. }
  412. }
  413. }
  414. </text>
  415. }
  416. </script>
  417. }