Leader.cshtml 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  1. @using WeApp.Configuration
  2. @using WeApp.TrainingCampGroup.Dto
  3. @{
  4. Layout = "~/Views/Shared/Layout/_Layout.Stu.cshtml";
  5. CampGroupDto group = ViewBag.Group;
  6. ViewBag.Title = "指挥长屏(" + group.Name + ")";
  7. string id = group.Id,
  8. groupName = group.Name,
  9. campNo = group.CampNo;
  10. }
  11. @section css{
  12. <link href="~/Content/Css/ExerciseV2/stu-cmd_leader.min.css" rel="stylesheet" />
  13. <style>
  14. </style>
  15. }
  16. @Html.Partial("Layout/V2/_Bg",false)
  17. <div class="box no-select" style="">
  18. <div id="bg_title">
  19. <span class="title">决策指令下达</span>
  20. </div>
  21. <div class="box-body ">
  22. <div class="box-header">
  23. <span class="title">@(groupName)指挥部 —— 指挥长</span>
  24. </div>
  25. <div class="body">
  26. <div class="body-card table-box">
  27. <table class="table">
  28. <thead>
  29. <tr>
  30. <th style="width: 200px">角色</th>
  31. <th>指令内容</th>
  32. <th style="width: 80px">下达状态</th>
  33. <th style="width: 130px;">操作</th>
  34. </tr>
  35. </thead>
  36. <tbody id="log-box">
  37. <tr class="empty">
  38. <td colspan="5">暂无指令,等待组员发送指令</td>
  39. </tr>
  40. </tbody>
  41. </table>
  42. </div>
  43. <div class="body-card">
  44. <div class="btn" onclick="SubmitNextScene()">进入下一阶段情景</div>
  45. </div>
  46. </div>
  47. </div>
  48. </div>
  49. <div class="question" title="点击处理来电" onclick="ShowQuestion()">
  50. <button type="button" class="btn-danger" style="--w: 80px;">
  51. <i class="fa fa-phone-volume"></i>
  52. </button>
  53. </div>
  54. <div class="modal fade" id="modal" tabindex="-1">
  55. <div class="modal-dialog modal-lg">
  56. <div class="modal-content">
  57. <div class="modal-header" style="cursor: move;">
  58. <h4 class="modal-title">
  59. <span>处置电话提问</span>
  60. </h4>
  61. <button type="button" class="close" data-dismiss="modal"></button>
  62. </div>
  63. <div class="modal-body">
  64. <form class="form-horizontal " id="form">
  65. <input id="id" name="id" type="hidden" value="">
  66. <input id="campNo" name="campNo" type="hidden" value="">
  67. <input id="groupNo" name="groupNo" type="hidden" value="">
  68. <div class="question-text">
  69. </div>
  70. <div class="form-group row">
  71. <div class="" style="width: 100%">
  72. <div class="input-group input-group-sm ">
  73. <textarea rows="5" class="form-control required" id="handleContent" name="handleContent" placeholder="请输入处理内容..." value="" style="" aria-required="true"></textarea>
  74. </div>
  75. </div>
  76. </div>
  77. </form>
  78. </div>
  79. <div class="modal-footer" style="text-align: center;">
  80. <button type="button" class="btn btn-sm btn-outline-iwb waves-effect" data-dismiss="modal" style="min-width:100px;">取消</button>
  81. <button type="button" class="btn btn-iwb btn-sm save-btn waves-effect" style="min-width:100px;">保存</button>
  82. </div>
  83. </div>
  84. </div>
  85. </div>
  86. <audio id="voiceAudio" style="display: none">
  87. <source type="audio/wav" />
  88. </audio>
  89. @section scripts
  90. {
  91. <script>
  92. $(function () {
  93. resizeHeight_Leader();
  94. window.addEventListener('resize', resizeHeight_Leader);
  95. GetLog();
  96. GetQuestionLogs();
  97. OverlayScrollbar($('.leader-box'));
  98. $('#handleContent').keydown(function(e) {
  99. var theEvent = window.event || e;
  100. var code = theEvent.keyCode || theEvent.which || theEvent.charCode;
  101. if (code == 13) {
  102. $('#modal .save-btn').click();
  103. }
  104. });
  105. });
  106. function resizeHeight_Leader() {
  107. resizeHeight((h, wh) => {
  108. var height = 225;
  109. $(".table-box").height(wh - h - height)
  110. })
  111. }
  112. function RoleHandle(that) {
  113. MsgConfirm("您确认下达这条指令吗?",
  114. "下达指令",
  115. function() {
  116. var $that = $(that).closest('tr');
  117. var id = $that.data('id');
  118. $.iwbAjax4({
  119. url: abp.appUrl + "Eval/OperationScene?id=" + id,
  120. success: function() {
  121. $that.removeClass('wait').addClass('send');
  122. $that.find('.state').html('已下达');
  123. $that.find('.action').html('');
  124. }
  125. });
  126. });
  127. }
  128. function SubmitNextScene() {
  129. var log = $("#log-box tr.send");
  130. if (!log || log.length <= 0) {
  131. abp.message.warn("请至少下达一条指令后再操作!");
  132. return;
  133. }
  134. MsgConfirm("您确认进入到下一情景吗?",
  135. "情景流转",
  136. function() {
  137. $.iwbAjax4({
  138. url: abp.appUrl + "Eval/NextFlowNode?groupNo=@(id)&campNo=none",
  139. success: function(res) {
  140. $("#log-box").html('<tr class="empty"><td colspan="5">暂无指令,等待组员发送指令</td></tr>');
  141. }
  142. });
  143. });
  144. }
  145. function GetLog() {
  146. $.iwbAjax5({
  147. url: abp.appUrl + "Query/GetCurrentSceneLog?no=@(id)",
  148. success: function(res) {
  149. if (res) {
  150. $("#box-body").empty();
  151. var str = '';
  152. for (var i = 0; i < res.length; i++) {
  153. var item = res[i];
  154. str += FormatLog(item);
  155. }
  156. if (str) {
  157. $("#log-box").html(str);
  158. }
  159. }
  160. }
  161. });
  162. }
  163. function FormatLog(data) {
  164. var str = "";
  165. if (data) {
  166. var msg = data.word ? data.word : "",
  167. btn = data.logState == '@(LogStateDefinition.New)'
  168. ? '<button type="button" class="btn btn-submit" style="" onclick="RoleHandle(this)">下达指令</button>'
  169. : '',
  170. state = data.logState == '@(LogStateDefinition.New)' ? '待下达' : '已下达',
  171. style = data.logState == '@(LogStateDefinition.New)' ? 'wait' : 'send';
  172. str = '<tr class="{5}" data-id="{0}"><td>{1}</td><td>{2}</td><td><div class="state">{3}</div></td><td class="action">{4}</td></tr>'.format(
  173. data.id,
  174. data.role,
  175. msg,
  176. state,
  177. btn,
  178. style);
  179. //str =
  180. // '<div class="handle-box leader {4}" data-id="{0}"> <div class="handle-content"><span class="role-text">{1}</span><span class="text">:</span><span class="content-text">{2}</span></div><div class="handle-button">{3}</div></div>'
  181. // .format(data.id, data.role, msg, btn, style);
  182. }
  183. return str;
  184. }
  185. function GetQuestionLogs() {
  186. $.iwbAjax4({
  187. url: abp.appUrl + "query/GetQuestionLogs?no=@(id)",
  188. success: function(res) {
  189. if (res && res.length) {
  190. res.forEach(v => {
  191. if (_phoneLogIds.indexOf(v) < 0) {
  192. _phoneLogIds.push(v);
  193. }
  194. });
  195. PhoneQuestion();
  196. }
  197. }
  198. });
  199. }
  200. var _phoneLogIds = [], _currentPhoneLogId, _currentPhoneQuestionText, _voiceText, isPhoning = false;
  201. function PhoneQuestion() {
  202. if (isPhoning) {
  203. return;
  204. }
  205. _currentPhoneLogId = _phoneLogIds.shift();
  206. if (_currentPhoneLogId) {
  207. isPhoning = true;
  208. $('.question').fadeIn();
  209. }
  210. }
  211. function ShowQuestion() {
  212. if (_currentPhoneLogId) {
  213. if (!_currentPhoneQuestionText) {
  214. $.iwbAjax4({
  215. url: abp.appUrl + "query/GetQuestionByLog?no=" + _currentPhoneLogId,
  216. success: function(res) {
  217. _voiceText = _currentPhoneQuestionText = res.content;
  218. $('#modal .question-text').html(_currentPhoneQuestionText);
  219. Show();
  220. }
  221. });
  222. } else {
  223. Show();
  224. }
  225. }
  226. function Show() {
  227. if (_voiceText) {
  228. //voice(_voiceText);
  229. playVoice(_voiceText);
  230. _voiceText = undefined;
  231. }
  232. OpenModal({
  233. url: abp.appUrl + 'eval/OperationPhone',
  234. data: { id: _currentPhoneLogId, campNo: '@(campNo)', groupNo: '@(group.Id)' },
  235. success: function() {
  236. $('.question').fadeOut();
  237. _currentPhoneLogId = undefined;
  238. _currentPhoneQuestionText = undefined;
  239. isPhoning = false;
  240. if (_phoneLogIds.length) {
  241. setTimeout(PhoneQuestion, 1500);
  242. }
  243. }
  244. });
  245. }
  246. }
  247. function voice(text) {
  248. if (!text) {
  249. return;
  250. }
  251. try {
  252. // 语音播报
  253. var utterThis = new window.SpeechSynthesisUtterance();
  254. utterThis.text = text; //播放内容按
  255. window.speechSynthesis.speak(utterThis);
  256. } catch (e) {
  257. console.error("语音播报出错:", e);
  258. }
  259. }
  260. function playVoice(callText) {
  261. //$.iwbAjax5({
  262. // url: abp.appUrl+`Query/voice?txt=${callText}&rate=0`,
  263. // success: function(res) {
  264. // var audioPlay = document.getElementById("voiceAudio");
  265. // audioPlay.src = res;
  266. // audioPlay.play();
  267. // }
  268. //});
  269. if (!callText) {
  270. return;
  271. }
  272. var audioPlay = document.getElementById("voiceAudio");
  273. audioPlay.src = "/Exercise/voice?txt=" + callText;
  274. audioPlay.play();
  275. }
  276. </script>
  277. <script>
  278. abp.signalr.connect(['@(id)', '@(campNo)']);
  279. iwbHub.client.getReloadAll = function(msg) {
  280. console.log('getReloadAll: ', msg);
  281. if (msg) {
  282. try {
  283. var data = JSON.parse(msg);
  284. if (data) {
  285. if (data.no == '@(id)' || data.no == '@(campNo)') {
  286. window.location.reload();
  287. }
  288. }
  289. } catch (e) {
  290. console.log('getReloadAll: ', e);
  291. }
  292. }
  293. };
  294. iwbHub.client.getReloadLeader = function(msg) {
  295. console.log('getReloadLeader: ', msg);
  296. if (msg) {
  297. try {
  298. var data = JSON.parse(msg);
  299. if (data) {
  300. if (data.no == '@(id)' || data.no == '@(campNo)') {
  301. window.location.reload();
  302. }
  303. }
  304. } catch (e) {
  305. console.log('getReloadLeader: ', e);
  306. }
  307. }
  308. };
  309. iwbHub.client.getOperationLog = function(msg) {
  310. console.log('getOperationLog: ', msg);
  311. if (msg) {
  312. try {
  313. var data = JSON.parse(msg);
  314. if (data) {
  315. if (data.no == '@(id)') {
  316. $('tr.empty').remove();
  317. var str = FormatLog(data);
  318. $('#log-box').prepend(str);
  319. }
  320. }
  321. } catch (e) {
  322. console.log('getOperationLog: ', e);
  323. }
  324. }
  325. };
  326. iwbHub.client.getPhoneQuestion = function(msg) {
  327. console.log('getPhoneQuestion: ', msg);
  328. if (msg) {
  329. try {
  330. var data = JSON.parse(msg);
  331. if (!data) {
  332. return;
  333. }
  334. if (data.no == '@(id)') {
  335. if (_phoneLogIds.indexOf(v) < 0) {
  336. _phoneLogIds.push(data.id);
  337. }
  338. PhoneQuestion();
  339. };
  340. } catch (e) {
  341. console.log('getPhoneQuestion: ', e);
  342. }
  343. }
  344. };
  345. </script>
  346. }