context.js 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544
  1. function contextGenPage() {
  2. var page = '<div id="context_page" style="display: block;">\
  3. <div class="maintitle">\
  4. <div>终端号切换</div>\
  5. <div class="page_description_text">用于开发测试环境终端切换管理。侵入式操作!!<br/>\
  6. 填写终端号以切换终端,填写分行服务IP地址以重新下载集中配置文件,信息有变更时需按照提示重启应用后方能生效。\
  7. </div>\
  8. </div>\
  9. <div id="contextSwitchContent">\
  10. <div class="clearboth" id="apn_list" style="padding-top:70px;">\
  11. <div class="table_top">\
  12. <div class="table_list_title">终端号备选列表\
  13. </div>\
  14. <div class="pull-right">\
  15. <div id="termbackup_new" class="btn_new pull-left">\
  16. &nbsp;\
  17. </div>\
  18. </div>\
  19. </div>\
  20. <div class="border_left border_right color_Darkgray"\
  21. style="width:678px;padding-top:-1px;">\
  22. <div id="termbackup_lists" class="clearboth" style="width:100%;overflow:hidden;">\
  23. </div>\
  24. </div>\
  25. <div class="table_bottom">\
  26. </div>\
  27. </div>\
  28. <div id="add_termbackup_item_win" class="out_win_content submit_background hide">\
  29. <div class="table_top">\
  30. <div style="border-bottom: #E9E9E9 solid 1px;font-size: 16px;text-align:center;line-height: 65px;">\
  31. 终端号相关设置</div>\
  32. </div>\
  33. <div class="border_left border_right margin_bottom_box2 color_background_white"\
  34. style="padding-top: 40px;">\
  35. <div id="add_termbackup_item_win_scroll" style="max-height:300px;">\
  36. <div id="termbackup_env_type_div" class="clearboth">\
  37. <div class="control-label-win"><span>环境</span></div>\
  38. <div class="controls-win">\
  39. <div id="termbackup_env" class="select_on_normal" onclick="SelectItem(this)">\
  40. </div>\
  41. <div id="termbackup_env_list" class="select_list hide" style="display: none;">\
  42. <div id="termbackup_env_list_item_dev" option="1" class="select_medium"">DEV</div>\
  43. <div id="termbackup_env_list_item_st" option="2" class="select_medium">ST</div>\
  44. <div id="termbackup_env_list_item_uat" option="3" class="select_medium">UAT </div>\
  45. <div id="termbackup_env_list_item_all" option="0" class="select_medium">Unclassfied</div>\
  46. </div>\
  47. </div>\
  48. </div>\
  49. <input style="display:none;" id="termbackup_url_profile_index" type="text">\
  50. <div id="termbackup_terminalno_div" class="clearboth" style="padding-top:29px;">\
  51. <div class="control-label-win"><span>终端号</span></div>\
  52. <div class="controls-win input_normal"><input id="termbackup_terminalno"\
  53. onfocus="showInputBorder(this)" onblur="hideInputBorder(this)"\
  54. type="text" maxlength="10"></div>\
  55. </div>\
  56. <div id="termbackup_branch_ip_div" class="clearboth" style="padding-top:29px;">\
  57. <div class="control-label-win"><span>分行服务IP</span></div>\
  58. <div class="controls-win input_normal"><input id="termbackup_branch_ip"\
  59. onfocus="showInputBorder(this)" onblur="hideInputBorder(this)"\
  60. type="text" maxlength="64"></div>\
  61. </div>\
  62. <div id="remark" class="clearboth" style="padding-top:29px;">\
  63. <div class="control-label-win">\
  64. <span">备注</span>\
  65. </div>\
  66. <div class="controls-win input_normal"><input id="input_remark"\
  67. placeholder="(可不填)" onfocus="showInputBorder(this)"\
  68. onblur="hideInputBorder(this)" type="text" maxlength="128"></div>\
  69. </div>\
  70. <div id="termbackup_list_input_set_default_div" class="clearboth"\
  71. style="padding-top: 27px;">\
  72. <div class="control-label-win pull-left">\
  73. <span>设置为当前使用</span>\
  74. </div>\
  75. <div id="termbackup_list_input_set_default"\
  76. class="check_off controls-win pull-right" style="margin-top:8px;">\
  77. </div>\
  78. </div>\
  79. <div id="termbackup_select_blank" style="height: 145px; display: none;" class="hide">\
  80. </div>\
  81. <div class="clearboth"></div>\
  82. </div>\
  83. <div style="padding-top:50px;padding-bottom:8px;" align="center">\
  84. <button id="termbackup_item_cancel" class="btn_normal_short">取消</button>\
  85. <button id="termbackup_item_save"\
  86. class="btn_normal_short btn_disabled margin-left-20">保存</button>\
  87. </div>\
  88. </div>\
  89. <div class="table_bottom"></div>\
  90. </div>\
  91. </div>\
  92. </div>\
  93. <div style="height:40px;">&nbsp;</div>';
  94. $("#rightpagearea").prepend(page);
  95. if (typeof contextRenderPage == "function") {
  96. beforeRenderPage("context");
  97. contextRenderPage();
  98. afterRenderPage("context");
  99. }
  100. }
  101. var contextController = (function() {
  102. var CONST = {
  103. SWITCH_ON: '1',
  104. PROFILE_MAX_NUM: 100
  105. };
  106. var terinalListCount = 0;
  107. var isNewConfig = true;
  108. var modifyIndex = -1;
  109. var profilesArray = [];
  110. var modifyProfile = {};
  111. function loadData(flag) {
  112. let req = new Request();
  113. req.filter1 = 0;
  114. req.filter2 = 0;
  115. req.filter3 = 0;
  116. req.filter4 = '';
  117. profilesArray = [];
  118. termbackuplistCount = 0;
  119. if(typeof flag === 'undefined') {
  120. utilStartSubmitDialog();
  121. }
  122. RVC.CenterSettingEntity.GetTerminalBackupInfoList(req, function(ret) {
  123. if(typeof flag === 'undefined'){
  124. utilStopSubmitDialog();
  125. }
  126. console.log('result: ' + ret.errorCode);
  127. if (ret.errorCode === 0) {
  128. let result = JSON.parse(ret[RVC.CenterSettingEntity.sigResponseUUID])
  129. console.log('count: ' + result.index.length + ' ' + result);
  130. if (result.index.length === 0) {
  131. $('#termbackup_lists').css('height', 0);
  132. $('#termbackup_lists').hide();
  133. return;
  134. } else if (result.index.length <= 8) {
  135. $('#termbackup_lists').css('height', (result.index.length * 70 - 12) + result.index.length + 'px');
  136. } else {
  137. $('#termbackup_lists').css('height', '561px');
  138. }
  139. $('#termbackup_lists').show();
  140. $('#termbackup_lists').empty();
  141. RVC.Scroll.initScroll('#termbackup_lists');
  142. for (var n = 0; n < result.index.length; n++)
  143. {
  144. console.log('profileItemIndex: ' + result.index[n]);
  145. console.log('profileItemName: ' + result.remark[n]);
  146. console.log('profileItemMainUrl: ' + result.terminalNo[n]);
  147. console.log('profileItemAdUrl: ' + result.branchIP[n]);
  148. console.log('profileItemEnvType: ' + result.env[n]);
  149. console.log('profileItemStatus: ' + result.status[n]);
  150. var templateData = {
  151. profileItemIndex: result.index[n],
  152. profileItemName: result.remark[n],
  153. profileItemMainUrl: result.terminalNo[n],
  154. profileItemAdUrl: result.branchIP[n],
  155. profileItemEnvType: result.env[n],
  156. profileItemStatus: result.status[n]
  157. };
  158. profilesArray.push(templateData);
  159. var profileHtml;
  160. if (n === result.index.length - 1) {
  161. profileHtml = '<div id="termbackup_list_{{profileItemIndex}}" style="height:59px;cursor:pointer;" class="list_item_hover">';
  162. profileHtml += '<div id="termbackup_list_name_{{profileItemIndex}}" class="pull-left padding-left-20" style="height:45px;padding-top:14px;width:600px;" onclick="RVC.TerminalBackupConfigController.ShowTerminalBkInfo({{profileItemIndex}})">';
  163. } else {
  164. profileHtml = '<div id="termbackup_list_{{profileItemIndex}}" class="border_bottom list_item_hover" style="height:70px;cursor:pointer;">';
  165. profileHtml += '<div id="termbackup_list_name_{{profileItemIndex}}" class="pull-left padding-left-20" style="height:56px;padding-top:14px;width:600px;" onclick="RVC.TerminalBackupConfigController.ShowTerminalBkInfo({{profileItemIndex}})">';
  166. }
  167. if (templateData.profileItemStatus === 1) { //当前使用
  168. profileHtml += '<pre class="termbackup_profile_name_{{profileItemIndex}}" style="font-size:16px;margin-top:0px;"><span class="termbackup_profile_itemname pull-left" style="line-height:21px;" title="{{profileItemName}}">{{profileItemName}}</span><span class="pull-left" style="line-height:21px;">(当前使用)</span><div class="clearboth"></div></pre>';
  169. } else {
  170. profileHtml += '<pre class="termbackup_profile_name_{{profileItemIndex}}" style="font-size:16px;margin-top:0px;"><span class="termbackup_profile_itemname" title="{{profileItemName}}">{{profileItemName}}</span></pre>';
  171. }
  172. profileHtml += '<div class="termbackup_termbackup_name_{{profileItemIndex}} color_descroption_gray termbackup_profile_itemapnname" style="margin-top:-10px;font-size:14px;" title="{{profileItemMainUrl}}&nbsp;|&nbsp;{{profileItemAdUrl}}">{{profileItemMainUrl}}&nbsp;|&nbsp;{{profileItemAdUrl}}</div></div>';
  173. if (templateData.profileItemStatus === 1 || templateData.profileItemStatus === 2) { //当前正在使用
  174. profileHtml += '<div class="pull-right"></div></div>';
  175. } else {
  176. if (n === 0) {
  177. profileHtml += '<div class="pull-right"><div class="btn_delete mobileconnet_btn_delete" onclick="RVC.TerminalBackupConfigController.RemoveTerminalBkProfile({{profileItemIndex}})" >&nbsp;</div></div></div>';
  178. } else {
  179. profileHtml += '<div class="pull-right"><div class="btn_delete mobileconnet_btn_delete" onclick="RVC.TerminalBackupConfigController.RemoveTerminalBkProfile({{profileItemIndex}})" >&nbsp;</div></div></div>';
  180. }
  181. }
  182. $('#termbackup_lists .scroll_text').secureAppend(profileHtml, templateData);
  183. }
  184. termbackuplistCount = result.index.length;
  185. } else if(typeof flag === 'undefined') {
  186. RVC.CenterSettingEntity.commErrorCallback(ret);
  187. }
  188. });
  189. }
  190. function preShowTermBkList()
  191. {
  192. $('#termbackup_lists').show();
  193. $('#termbackup_lists').empty();
  194. RVC.Scroll.initScroll('#termbackup_lists');
  195. }
  196. function termbkProfileCancel() {
  197. $('#add_termbackup_item_win').hide();
  198. $('#submit_fade').hide();
  199. }
  200. function saveTerminalBkProfileData(newConfig)
  201. {
  202. if (!isButtonEnable('termbackup_item_save')) {
  203. return;
  204. }
  205. var mainUrl = xss($.trim($('#termbackup_terminalno').val()));
  206. var adUrl = xss($.trim($('#termbackup_branch_ip').val()));
  207. var remark = xss($.trim($('#input_remark').val()));
  208. var isSetDefault = $('#termbackup_list_input_set_default').hasClass('check_on') ? true : false;
  209. var envType = parseInt($('#termbackup_env').val());
  210. var index = parseInt($('#termbackup_url_profile_index').val());
  211. if(mainUrl === '') {
  212. utilStartAlertDialog('请输入终端号!');
  213. return;
  214. }
  215. if(adUrl === '') {
  216. utilStartAlertDialog('请输入分行服务IP地址!');
  217. return;
  218. }
  219. let req = new Request();
  220. if(newConfig) {
  221. req.operation = 1;
  222. req.index = 0;
  223. } else {
  224. req.operation = 3;
  225. req.index = index;
  226. }
  227. req.terminalNo = mainUrl;
  228. req.branchIP = adUrl;
  229. req.remark = remark;
  230. req.env = envType;
  231. req.setDefault = isSetDefault;
  232. utilStartSubmitDialog();
  233. RVC.CenterSettingEntity.EditTerminalBackupInfo(req, function(ret) {
  234. utilStopSubmitDialog();
  235. if (ret.errorCode === 0) {
  236. let result = JSON.parse(ret[RVC.CenterSettingEntity.sigResponseUUID])
  237. if(req.setDefault && (result.result === 0 || result.result === 519)) {
  238. termbkProfileCancel();
  239. if(result.addition !== 0) {
  240. console.log('需要更新集中配置!');
  241. var tips = '即将从新服务器IP ' + adUrl + ' 下载集中配置';
  242. utilShowToast(tips, 3000, function() {
  243. utilStartSubmitDialog();
  244. let req2 = new Request();
  245. req2.operation = 0;
  246. req2.strAddr = adUrl;
  247. req2.nPort = 6024;
  248. req2.deleteIfExist = true;
  249. if(result.result === 0){
  250. req2.additional1 = mainUrl;
  251. } else {
  252. req2.additional1 = '';
  253. }
  254. req2.additional2 = '';
  255. req2.additional3 = '';
  256. req2.additional4 = '';
  257. req2.reserved1 = 0;
  258. req2.reserved2 = 0;
  259. RVC.CenterSettingEntity.DownloadCenterFiles(req2, function(ret1) {
  260. utilStopSubmitDialog();
  261. if (ret1.errorCode === 0) {
  262. utilStartAlertDialog('集中配置下载成功,点击确认以【重启应用】', function(){
  263. RVC.HealthmanagerEntityCtrl.RestartApp(true);
  264. });
  265. } else {
  266. if(result.result === 0) {
  267. utilStartConfirmDialog('尝试从' + adUrl + '下载集中配置失败 ' + ErrorCodeStringfy(ret1.errorCode) + ',请稍后在重启后手动下载!<br/>因终端号有更新,建议点击确认以重启应用', function(){
  268. RVC.HealthmanagerEntityCtrl.RestartApp(true);
  269. }, function() {
  270. utilShowToast('重启取消,即将刷新列表(终端号已变更,列表部分信息不准确!)', 1500, function(){
  271. preShowTermBkList();
  272. loadData();
  273. });
  274. });
  275. } else {
  276. utilStartAlertDialog('尝试从' + adUrl + '下载集中配置失败 ' + ErrorCodeStringfy(ret1.errorCode) + ',请稍后自行手动下载!', function() {
  277. utilShowToast('重启取消,即将刷新列表', 1500, function() {
  278. preShowTermBkList();
  279. loadData();
  280. });
  281. });
  282. }
  283. }
  284. });
  285. });
  286. } else if(result.result === 519) {
  287. utilShowToast('检测到与当前的配置一致!', 2000, function() {
  288. preShowTermBkList();
  289. loadData();
  290. });
  291. } else {
  292. utilStartConfirmDialog('终端号已更换,点击确认以【重启应用】!', function() {
  293. RVC.HealthmanagerEntityCtrl.RestartApp(true);
  294. }, function() {
  295. utilShowToast('重启取消,即将刷新列表(终端号已变更,列表信息部分不准确!)', 1500, function(){
  296. preShowTermBkList();
  297. loadData();
  298. });
  299. });
  300. }
  301. } else if(result.result === 0) {
  302. utilStartAlertDialog('操作成功!', function() {
  303. preShowTermBkList();
  304. loadData();
  305. });
  306. }
  307. else {
  308. if(newConfig) {
  309. utilStartAlertDialog('添加失败:' + result.msg);
  310. } else {
  311. utilStartAlertDialog('更新失败:' + result.msg);
  312. }
  313. }
  314. } else {
  315. RVC.CenterSettingEntity.commErrorCallback(ret);
  316. }
  317. });
  318. }
  319. function checkboxDisabled(id) {
  320. var checkElement = $('#' + id);
  321. if (checkElement.hasClass('check_on') && checkElement.hasClass('disabled')) {
  322. checkElement.removeClass('check_on').addClass('check_on_disable').addClass('check_on');
  323. } else {
  324. checkElement.removeClass('check_on_disable');
  325. }
  326. if (checkElement.hasClass('check_off') && checkElement.hasClass('disabled')) {
  327. checkElement.removeClass('check_off').addClass('check_off_disable').addClass('check_off');
  328. } else {
  329. checkElement.removeClass('check_off_disable');
  330. }
  331. }
  332. function showTerminalBkBox() {
  333. clearAllErrorMsg();
  334. $('#termbackup_item_save').addClass('btn_disabled');
  335. var outwin = $('#add_termbackup_item_win');
  336. checkboxDisabled('termbackup_list_input_set_default');
  337. var heightest = $(document).height();
  338. $('#submit_fade').css('height', heightest + 'px');
  339. $('#submit_fade').show();
  340. outwin.show();
  341. }
  342. function setDefaultTeminalBkSwitch() {
  343. if ($('#termbackup_list_input_set_default').hasClass('disabled')) {
  344. return;
  345. }
  346. $('#termbackup_item_save').removeClass('btn_disabled');
  347. if ($('#termbackup_list_input_set_default').hasClass('check_on')) {
  348. $('#termbackup_list_input_set_default').removeClass('check_on').addClass('check_off');
  349. } else {
  350. $('#termbackup_list_input_set_default').removeClass('check_off').addClass('check_on');
  351. }
  352. if ($('#termbackup_list_input_set_default').hasClass('check_off')) {
  353. $('#termbackup_item_save').addClass('btn_disabled');
  354. }
  355. }
  356. function ResetTerminalBackupInfoShowDialog()
  357. {
  358. $('#termbackup_url_profile_index').val('');
  359. $('#add_termbackup_item_win input').val('');
  360. $('#add_termbackup_item_win input').removeAttr('disabled');
  361. $('#add_termbackup_item_win .select_on_normal').removeClass('disabled');
  362. }
  363. RVC.TerminalBackupConfigController = RVC.ObjController.extend({
  364. ShowTerminalBkInfo: function(index) {
  365. modifyIndex = index;
  366. var termbackupUrlShowItem = {};
  367. for (var i = 0; i < profilesArray.length; i++) {
  368. if (profilesArray[i].profileItemIndex === index) {
  369. termbackupUrlShowItem = profilesArray[i];
  370. break;
  371. }
  372. }
  373. /**
  374. profileItemIndex: result.index[n],
  375. profileItemName: result.remark[n],
  376. profileItemMainUrl: result.futureUrl[n],
  377. profileItemAdUrl: result.adUrl[n],
  378. profileItemEnvType: result.env[n],
  379. profileItemFromType: result.type[n],
  380. profileItemStatus: result.status[n]
  381. */
  382. ResetTerminalBackupInfoShowDialog();
  383. modifyProfile = termbackupUrlShowItem;
  384. $('#termbackup_url_profile_index').val(termbackupUrlShowItem.profileItemIndex.toString());
  385. $('#termbackup_terminalno').val(termbackupUrlShowItem.profileItemMainUrl);
  386. $('#termbackup_branch_ip').val(termbackupUrlShowItem.profileItemAdUrl);
  387. $('#input_remark').val(termbackupUrlShowItem.profileItemName);
  388. if (termbackupUrlShowItem.profileItemStatus === 1) { //默认配置
  389. $('#termbackup_list_input_set_default').removeClass('check_off').addClass('check_on');
  390. $('#termbackup_list_input_set_default').addClass('disabled');
  391. } else {
  392. $('#termbackup_list_input_set_default').removeClass('check_on').addClass('check_off');
  393. $('#termbackup_list_input_set_default').removeClass('disabled');
  394. }
  395. showSelectedValue('termbackup_env', termbackupUrlShowItem.profileItemEnvType.toString());
  396. $(document).off('click', '#termbackup_item_save');
  397. $(document).on('click', '#termbackup_item_save', function () {
  398. saveTerminalBkProfileData(false);
  399. });
  400. if(termbackupUrlShowItem.profileItemStatus === 1) { //当前使用的不让修改
  401. $('#add_termbackup_item_win input').attr('disabled', true);
  402. $('#add_termbackup_item_win .select_on_normal').addClass('disabled');
  403. console.log(termbackupUrlShowItem.profileItemName);
  404. }
  405. showTerminalBkBox();
  406. },
  407. RemoveTerminalBkProfile: function(index)
  408. {
  409. utilStartConfirmDialog("确定要移除该配置吗?", function() {
  410. let req = new Request();
  411. req.operation = 2; //删除
  412. req.index = parseInt(index);
  413. req.terminalNo = '';
  414. req.branchIP = '';
  415. req.remark = '';
  416. req.env = 0;
  417. req.setDefault = false;
  418. utilStartSubmitDialog();
  419. RVC.CenterSettingEntity.EditTerminalBackupInfo(req, function(ret) {
  420. utilStopSubmitDialog();
  421. if (ret.errorCode === 0) {
  422. let result = JSON.parse(ret[RVC.CenterSettingEntity.sigResponseUUID])
  423. if(result.result == 0) {
  424. preShowTermBkList();
  425. loadData();
  426. } else {
  427. utilStartAlertDialog('删除失败:' + result.msg);
  428. }
  429. } else {
  430. RVC.CenterSettingEntity.commErrorCallback(ret);
  431. }
  432. });
  433. });
  434. }
  435. });
  436. function bindEvents() {
  437. $('#termbackup_new').click(function () {
  438. $('#termbackup_select_blank').hide();
  439. if (termbackuplistCount === CONST.PROFILE_MAX_NUM) {
  440. utilStartCommonDialog('配置数量超过上限(' + CONST.PROFILE_MAX_NUM + '),请删除再新建!');
  441. setTimeout(function () {
  442. utilStopCommonDialog();
  443. }, 3000);
  444. return;
  445. }
  446. modifyIndex = -1;
  447. ResetTerminalBackupInfoShowDialog();
  448. $('#termbackup_list_input_set_default').removeClass('check_off').addClass('check_on');
  449. $('#termbackup_list_input_set_default').addClass('disabled');
  450. showSelectedValue('termbackup_env', '1');
  451. isNewTerminalBkConfig = true;
  452. showTerminalBkBox();
  453. $(document).off('click', '#termbackup_item_save');
  454. $(document).on('click', '#termbackup_item_save', function () {
  455. saveTerminalBkProfileData(true);
  456. });
  457. $('#termbackup_terminalno').focus();
  458. });
  459. $('#termbackup_item_cancel').click(termbkProfileCancel);
  460. $(document).on('click keyup change', '#add_termbackup_item_win input', function () {
  461. $('#termbackup_item_save').removeClass('btn_disabled');
  462. });
  463. $(document).on('change click', '#add_termbackup_item_win .select_on_normal', function () {
  464. $('#termbackup_item_save').removeClass('btn_disabled');
  465. });
  466. $('#termbackup_list_input_set_default').click(setDefaultTeminalBkSwitch);
  467. $('#termbackup_env').click(function () {
  468. //RVC.Scroll.setTop('#add_termbackup_item_win_scroll', 200);
  469. });
  470. }
  471. function initPage()
  472. {
  473. preShowTermBkList();
  474. loadData(true);
  475. }
  476. var fistTime = true;
  477. function init() {
  478. initPage();
  479. if (fistTime) {
  480. fistTime = false;
  481. bindEvents();
  482. RVC.Scroll.initScroll('#add_termbackup_item_win_scroll');
  483. }
  484. }
  485. function destory() {
  486. clearAllErrorMsg();
  487. }
  488. return { init: init, destory: destory };
  489. }());
  490. window.contextRenderPage = function () {
  491. contextController.init();
  492. };