Ready.cshtml 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494
  1. @using IwbZero.ToolCommon.StringModel
  2. @using WeApp.TrainingCamp.Dto
  3. @using WeOnlineApp.Configuration
  4. @using WeOnlineApp.Models.Play
  5. @using WeOnlineApp.TrainingCamp.Dto
  6. @using WeOnlineApp.TrainingCampPlay.Dto
  7. @model WeOnlineApp.Models.Play.CampPlayModel
  8. @{
  9. Layout = "~/Views/Shared/Layout/_Layout.None.cshtml";
  10. ViewBag.PageId = "start";
  11. ViewBag.Title = "等待演练";
  12. CampPlayModel campPlay = Model;
  13. CampPlayDto play = campPlay.Play;
  14. CampDto camp = campPlay.Camp;
  15. CampPlayUserDto playUser = campPlay.PlayUser;
  16. var imagePath = string.IsNullOrEmpty(AbpSession.AvatarImagePath) ? "/Content/Image/user.png" : AbpSession.AvatarImagePath;
  17. }
  18. <style>
  19. body {
  20. --mc: #3168f5;
  21. width: 100vw;
  22. height: 100vh;
  23. color: var(--mc);
  24. background-image: linear-gradient(45deg,#f2f6fe,#f2f6fe);
  25. }
  26. .menu {
  27. --h: 35px;
  28. position: absolute;
  29. top: 30px;
  30. right: 10px;
  31. width: 80%;
  32. padding-right: 20px;
  33. line-height: var(--h);
  34. display: inline-block;
  35. list-style: none;
  36. display: flex;
  37. justify-content: flex-end;
  38. }
  39. .menu a {
  40. color: var(--mc);
  41. padding: 3px 5px;
  42. margin: 0 10px;
  43. line-height: var(--h);
  44. }
  45. .menu a:hover {
  46. border-bottom: 1px solid var(--mc);
  47. }
  48. .header {
  49. margin: 60px 20px 0;
  50. min-height: 80px;
  51. display: flex;
  52. justify-content: center;
  53. align-items: center;
  54. }
  55. .friend-box {
  56. margin: 50px 100px 10px;
  57. min-height: 100px;
  58. display: flex;
  59. flex-wrap: wrap;
  60. justify-content: flex-start;
  61. align-items: center;
  62. border: 2px solid var(--mc);
  63. font-size: 1rem;
  64. border-radius: .75rem;
  65. }
  66. .self-box {
  67. margin: 20px 0;
  68. width: 100%;
  69. min-height: 100px;
  70. display: flex;
  71. flex-direction: column;
  72. justify-content: center;
  73. align-items: center;
  74. }
  75. .self-box > div {
  76. margin-top: 15px;
  77. }
  78. .code {
  79. color: var(--mc);
  80. font-weight: 600;
  81. font-size: 24px;
  82. }
  83. .img-box {
  84. width: auto;
  85. }
  86. img {
  87. width: 100px;
  88. height: 100px;
  89. border: 1px solid #ddd;
  90. border-radius: .5rem;
  91. }
  92. .name {
  93. }
  94. .role {
  95. font-size: 90%;
  96. font-weight: bold;
  97. color: #f08080;
  98. margin-top: 0 !important;
  99. text-align: center;
  100. }
  101. .self-box .img-box img {
  102. width: 200px;
  103. height: 200px;
  104. border: 2px solid #ddd;
  105. border-radius: 50%;
  106. }
  107. .self-box .name {
  108. font-weight: 600;
  109. font-size: 22px;
  110. }
  111. .friend {
  112. margin: 10px;
  113. display: flex;
  114. flex-direction: column;
  115. justify-content: center;
  116. align-items: center;
  117. }
  118. .friend > div {
  119. margin-top: 8px;
  120. }
  121. .friend .img-box {
  122. position: relative;
  123. }
  124. .role-box .select2-selection {
  125. height: 38px;
  126. }
  127. .select2-results__option {
  128. color: var(--mc) !important;
  129. }
  130. .select2-results__option.select2-results__option--highlighted {
  131. color: #fff !important;
  132. background: var(--mc) !important;
  133. }
  134. .select2-results__option[aria-selected=true] {
  135. color: #eee !important;
  136. background: var(--mc) !important;
  137. }
  138. .select2-selection__arrow b {
  139. margin-top: 4px !important;
  140. }
  141. .btn-box {
  142. width: 100px;
  143. margin: 15px auto 0;
  144. }
  145. .btn-box button {
  146. width: 100%;
  147. }
  148. </style>
  149. <div class="header">
  150. <h2>@(play.Name) (@(camp?.Name)) </h2>
  151. </div>
  152. <ul class="menu">
  153. <li>
  154. <a href="@Url.Action("Index","Play")"><i class="fa fa-home"></i>&nbsp;&nbsp;返回主页</a>
  155. </li>
  156. <li>
  157. <a href="javascript:void(0)" onclick="Exit()"><i class="fas fa-backspace"></i>&nbsp;&nbsp;退出演练</a>
  158. </li>
  159. <li>
  160. <a href="javascript:void(0)" onclick="LoginOut()"><i class="fas fa-sign-out-alt"></i>&nbsp;&nbsp;注销账号</a>
  161. </li>
  162. </ul>
  163. <div class="self-box">
  164. <div class="img-box">
  165. <img src="@(imagePath)" alt="@(AbpSession.RealName)" />
  166. </div>
  167. <div class="name">@(AbpSession.RealName)</div>
  168. @if (playUser == null)
  169. {
  170. <div class="btn-box"><button type="button" class="btn btn-success" onclick="Join()">加入演练</button></div>
  171. }
  172. else if (playUser.PlayerType == CampPlayerTypeDefinition.Creator)
  173. {
  174. <div class="btn-box"> <button type="button" class="btn btn-success" onclick="Start()">开始演练</button></div>
  175. <div class="code">
  176. <span>邀请码:@(play.InvitationCode)</span>
  177. </div>
  178. }
  179. else
  180. {
  181. string style1 = "display:none", style2 = "display:none";
  182. if (playUser.PlayerState == CampPlayUserStateDefinition.Ready)
  183. {
  184. style1 = "display:block";
  185. }
  186. else if (playUser.PlayerState == CampPlayUserStateDefinition.New || playUser.PlayerState == CampPlayUserStateDefinition.CancelReady)
  187. {
  188. style2 = "display:block";
  189. }
  190. var roleNames = "<option value=\"\">请选择一个角色开始准备</option>"; ;
  191. if (play.PlayRoleNames.IsNotEmpty())
  192. {
  193. var arr = play.PlayRoleNames.Split(',');
  194. foreach (var role in arr)
  195. {
  196. roleNames += "<option value=\"" + role + "\">" + role + "</option>";
  197. }
  198. }
  199. <div id="noReady" style="@(style2)">
  200. <div class="role-box">
  201. <select id="role" class="form-control" style="width: 250px" autocomplete="off">
  202. @(Html.Raw(roleNames))
  203. </select>
  204. </div>
  205. <div class="btn-box"><button type="button" class="btn btn-success" onclick="Ready()">准备演练</button></div>
  206. </div>
  207. <div id="hasReady" style="@(style1)">
  208. <div class="role">@(playUser.Role)</div>
  209. <div class="btn-box"><button type="button" class="btn btn-danger" onclick="Cancel()">取消准备</button></div>
  210. </div>
  211. }
  212. </div>
  213. @if (play.PlayModel == CampPlayModelDefinition.Team)
  214. {
  215. <div class="friend-box"></div>
  216. }
  217. @section scripts
  218. {
  219. <script>
  220. $(function() {
  221. abp.signalr.connect('@(play.InvitationCode)');
  222. $('#role').select2();
  223. @if (play.PlayModel == CampPlayModelDefinition.Team)
  224. {
  225. <text>
  226. GetPlayUsers();
  227. </text>
  228. }
  229. });
  230. function Exit() {
  231. MsgConfirm("退出后无法再加入演练,您确定退出演练吗?",
  232. "退出演练",
  233. function () {
  234. @if (playUser?.PlayerType == CampPlayerTypeDefinition.Creator)
  235. {
  236. <text>
  237. MsgConfirm("演练还未开始!您是房主,退出后演练后会删除演练,确定退出吗?",
  238. "再次确认",
  239. function() {
  240. $.iwbAjax({
  241. url: abp.appUrl + '/CampPlay/ExitPlay?no=@(play.Id)',
  242. success: function() {
  243. window.location.href = "@Url.Action("Start", "Play")";
  244. }
  245. });
  246. });
  247. </text>
  248. }
  249. else
  250. {
  251. <text>
  252. $.iwbAjax({
  253. url: abp.appUrl + '/CampPlay/ExitPlay?no=@(play.Id)',
  254. success: function() {
  255. window.location.href = "@Url.Action("Start", "Play")";
  256. }
  257. });
  258. </text>
  259. }
  260. });
  261. }
  262. function LoginOut() {
  263. MsgConfirm("您确定注销账号吗?",
  264. "注销账号",
  265. function () {
  266. @if (playUser?.PlayerType == CampPlayerTypeDefinition.Creator)
  267. {
  268. <text>
  269. MsgConfirm("您是房主,注销后演练进程无法继续,注销退出吗?",
  270. "再次确认",
  271. function() {
  272. window.location.href = "/Account/LogOut";
  273. });
  274. </text>
  275. }
  276. else
  277. {
  278. <text>
  279. window.location.href = "/Account/LogOut";
  280. </text>
  281. }
  282. });
  283. }
  284. function GetPlayUsers() {
  285. $.iwbAjax4({
  286. url: abp.appUrl + "CampPlay/GetPlayUsers?no=@(play.Id)",
  287. success: function(res) {
  288. FormatterPlayUsers(res);
  289. }
  290. });
  291. }
  292. function FormatterPlayUsers(data) {
  293. var str = "";
  294. if (data && data.length) {
  295. data.forEach(function(v) {
  296. str += '<div class="friend" id="user-{0}">'.format(v.id);
  297. str += FormatterPlayUser(v);
  298. str += '</div>';
  299. });
  300. }
  301. if (str) {
  302. $('.friend-box').html(str);
  303. }
  304. }
  305. function FormatterPlayUser(data) {
  306. var str = "";
  307. if (data) {
  308. var ribbon = '<div class="ribbon-wrapper"><div class="ribbon bg-danger">未准备</div></div>';
  309. if (data.playerType == @(CampPlayerTypeDefinition.Creator)) {
  310. ribbon = '<div class="ribbon-wrapper"><div class="ribbon bg-warning">房主</div></div>';
  311. } else if (data.playerState == @(CampPlayUserStateDefinition.Ready)) {
  312. ribbon = '<div class="ribbon-wrapper"><div class="ribbon bg-success">已准备</div></div>';
  313. }
  314. var img = data.imagePath ? data.imagePath : "/Content/Image/user.png";
  315. str += '<div class="img-box"><img src="{0}" alt="{1}" />{2}</div>'.format(img, data.playerName, ribbon);
  316. str += '<div class="name">{0}</div>'.format(data.playerName);
  317. str += '<div class="role">{0}</div>'.format(data.role ? data.role : "未准备");
  318. }
  319. return str;
  320. }
  321. </script>
  322. <script>
  323. function Join() {
  324. MsgConfirm("确认加入演练吗?",
  325. "加入演练",
  326. function() {
  327. $.iwbAjax1({
  328. url: abp.appUrl + "/CampPlay/Join",
  329. data: { id: '@(play.Id)' },
  330. success: function() {
  331. window.location.reload();
  332. }
  333. });
  334. });
  335. }
  336. function Cancel() {
  337. MsgConfirm("确认取消准备吗?",
  338. "取消准备",
  339. function() {
  340. $.iwbAjax1({
  341. url: abp.appUrl + "/CampPlay/CancelReady",
  342. data: { id: '@(play.Id)' },
  343. success: function() {
  344. $('#hasReady').hide();
  345. $('#noReady').fadeIn(500);
  346. }
  347. });
  348. });
  349. }
  350. function Ready() {
  351. var role = $('#role').val();
  352. if (role) {
  353. $.iwbAjax4({
  354. url: abp.appUrl + "/CampPlay/Ready",
  355. data: { id: '@(play.Id)', role: role },
  356. success: function() {
  357. $('#noReady').hide();
  358. $('#hasReady').fadeIn(500);
  359. }
  360. });
  361. } else {
  362. abp.message.warn('请选择一个角色!');
  363. }
  364. }
  365. function Start() {
  366. var msg = "确认开始演练吗?";
  367. MsgConfirm(msg,
  368. "开始演练",
  369. function() {
  370. $.iwbAjax4({
  371. url: abp.appUrl + "/CampPlay/Start",
  372. data: { id: '@(play.Id)' },
  373. success: function() {
  374. abp.message.success("演练启动完成。");
  375. },
  376. error: function() {
  377. }
  378. });
  379. });
  380. }
  381. </script>
  382. <script id="hub-s">
  383. iwbHub.client.getReloadPage = function (msg) {
  384. console.log('getReloadPage: ', msg);
  385. if (msg) {
  386. try {
  387. var data = JSON.parse(msg);
  388. if (data.no=='@(play.Id)') {
  389. window.location.reload();
  390. }
  391. } catch (e) {
  392. console.log('getReloadPage: ', e);
  393. }
  394. }
  395. };
  396. iwbHub.client.getUserChange = function (msg) {
  397. console.log('getUserChange: ', msg);
  398. if (msg) {
  399. try {
  400. var data = JSON.parse(msg);
  401. if (data) {
  402. var str = FormatterPlayUser(data);
  403. var $user = $('#user-' + data.id);
  404. if ($user.length > 0) {
  405. $user.html(str);
  406. } else {
  407. str = '<div class="friend" id="user-{0}">{1}</div>'.format(data.id, str);
  408. $('.friend-box').append(str);
  409. }
  410. }
  411. } catch (e) {
  412. console.log('getUserChange: ', e);
  413. }
  414. }
  415. };
  416. iwbHub.client.getUserExit = function (msg) {
  417. console.log('getUserExit: ', msg);
  418. if (msg) {
  419. try {
  420. var data = JSON.parse(msg);
  421. if (data) {
  422. var $user = $('#user-' + data.id);
  423. if ($user.length > 0) {
  424. $user.remove();
  425. }
  426. }
  427. } catch (e) {
  428. console.log('getUserExit: ', e);
  429. }
  430. }
  431. };
  432. @if (play.PlayModel == CampPlayModelDefinition.Team&& playUser?.PlayerType != CampPlayerTypeDefinition.Creator)
  433. {
  434. <text>
  435. iwbHub.client.getCreatorExit = function (msg) {
  436. console.log('getCreatorExit: ', msg);
  437. if (msg) {
  438. try {
  439. var data = JSON.parse(msg);
  440. if (data) {
  441. abp.message.warn('房主已退出演练,演练已结束!',"演练结束").done(function() {
  442. window.location.href = "@Url.Action("Start", "Play")";
  443. });
  444. }
  445. } catch (e) {
  446. console.log('getCreatorExit: ', e);
  447. }
  448. }
  449. };
  450. </text>
  451. }
  452. </script>
  453. }