Power.js 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684
  1. Ext.QuickTips.init();
  2. Ext.define('erp.controller.ma.Power', {
  3. extend : 'Ext.app.Controller',
  4. requires: ['erp.util.FormUtil','erp.view.core.grid.HeaderFilter','erp.view.core.plugin.CopyPasteMenu'],
  5. views : [ 'ma.Power', 'core.button.Distribute', 'core.grid.GroupPower', 'core.trigger.DbfindTrigger',
  6. 'core.trigger.EmpTrigger', 'core.button.Sync', 'core.trigger.MultiDbfindTrigger','core.trigger.SearchField'],
  7. init : function() {
  8. var me = this;
  9. me.FormUtil = Ext.create('erp.util.FormUtil');
  10. this.control({
  11. 'treepanel[id=powertree]' : {
  12. afterrender : function(tree) {
  13. me.loadTree(tree);
  14. },
  15. itemmousedown : function(selModel, record) {
  16. var tree = selModel.ownerCt;
  17. me.loadTree(tree, record);
  18. },
  19. scrollershow: function(scroller) {
  20. if (scroller && scroller.scrollEl) {
  21. scroller.clearManagedListeners();
  22. scroller.mon(scroller.scrollEl, 'scroll', scroller.onElScroll, scroller);
  23. }
  24. }
  25. },
  26. 'button[id=personal_set]' : {// 个人权限设置
  27. click : function(btn) {
  28. var grid = btn.ownerCt.ownerCt;
  29. if (grid.pp_caller) {
  30. me.showPersonal(grid);
  31. }
  32. }
  33. },
  34. 'button[id=special_set]': {// 设置特殊权限
  35. click: function(btn) {
  36. var grid = btn.ownerCt.ownerCt;
  37. if (grid.pp_caller) {
  38. me.showSpecial(grid);
  39. }
  40. }
  41. },
  42. 'button[id=power_copy]': {// 复制权限
  43. click: function(btn) {
  44. me.showCopyPane();
  45. }
  46. },
  47. 'button[id=power_sync]': {// 同步权限
  48. click: function(btn) {
  49. this.showSyncWin();
  50. }
  51. },
  52. 'button[id=power_cover]': {// 同步所有权限
  53. beforerender:function(btn){
  54. btn.sync=function() {
  55. var masters = btn.getCheckData(), me = btn,w = this.win,
  56. datas = null, cal='PowerCover';
  57. Ext.MessageBox.confirm('提示', '确认将当前帐套所有岗位权限、个人权限、特殊权限,覆盖到目标帐套?', function(but) {
  58. if(but=='yes'){
  59. if (!Ext.isEmpty(masters)) {
  60. w.setLoading(true);
  61. Ext.Ajax.request({
  62. url: basePath + 'hr/employee/vastPostPower.action',
  63. params: {
  64. caller: cal,
  65. to: masters
  66. },
  67. callback: function(opt, s, r) {
  68. w.setLoading(false);
  69. if(s) {
  70. var rs = Ext.decode(r.responseText);
  71. if(rs.data) {
  72. showMessage('提示', rs.data);
  73. } else {
  74. alert('权限覆盖成功!');
  75. }
  76. w.hide();
  77. if(me.autoClearCache) {
  78. me.clearCache();
  79. }
  80. me.fireEvent('aftersync', me, cal, datas, masters);
  81. }
  82. }
  83. });
  84. }
  85. }
  86. });
  87. };
  88. } ,
  89. afterrender: function(btn){
  90. if(em_type && em_type != 'admin'){
  91. btn.hide();
  92. }
  93. }
  94. },
  95. 'multidbfindtrigger[name=em_position]': {
  96. aftertrigger: function(t, rs) {
  97. if(rs.length > 0) {
  98. var m = t.ownerCt;
  99. Ext.Array.each(rs, function(r, i){
  100. if(i == 0) {
  101. t.jo_id = r.get('jo_id');
  102. t.setValue(r.get('jo_name'));
  103. } else {
  104. m.insert(m.items.length - 2, {
  105. xtype: 'multidbfindtrigger',
  106. name: 'em_position',
  107. fieldLabel: '复制到',
  108. jo_id: r.get('jo_id'),
  109. value: r.get('jo_name'),
  110. p: 2,
  111. editable: false,
  112. autoDbfind: false,
  113. clearable: true
  114. });
  115. }
  116. });
  117. } else {
  118. f.setValue(null);
  119. f.jo_id = null;
  120. }
  121. }
  122. }
  123. });
  124. },
  125. loadTree : function(tree, record) {
  126. var pid = 0, me = this;
  127. if (record) {
  128. if (record.get('leaf')) {
  129. me.loadPower(record);
  130. return;
  131. } else {
  132. if (record.isExpanded() && record.childNodes.length > 0) {
  133. record.collapse(true, true);// 收拢
  134. return;
  135. } else {
  136. if (record.childNodes.length != 0) {
  137. record.expand(false, true);// 展开
  138. return;
  139. }
  140. }
  141. }
  142. pid = record.get('id');
  143. }
  144. tree.setLoading(true);
  145. Ext.Ajax.request({
  146. url : basePath + 'ma/lazyTree.action',
  147. params : {
  148. parentId : pid,
  149. condition : 'sn_limit=1'
  150. },
  151. callback : function(options, success, response) {
  152. tree.setLoading(false);
  153. var res = new Ext.decode(response.responseText);
  154. if (res.tree) {
  155. if (record) {
  156. record.appendChild(res.tree);
  157. record.expand(false, true);// 展开
  158. } else {
  159. tree.store.setRootNode({
  160. text : 'root',
  161. id : 'root',
  162. expanded : true,
  163. children : res.tree
  164. });
  165. }
  166. } else if (res.exceptionInfo) {
  167. showError(res.exceptionInfo);
  168. }
  169. }
  170. });
  171. },
  172. loadPower : function(record) {
  173. var caller = record.get('caller'), set = Ext.getCmp('grid');
  174. set.pp_caller = caller;
  175. set.down('tbtext').setText('<font color=gray>权限名:</font>' + record.get('text'));
  176. if (!Ext.isEmpty(caller)) {
  177. set.getGroupData(this.getUrlType(record.get('url')));
  178. } else {
  179. set.store.removeAll();
  180. }
  181. },
  182. getUrlType : function(url) {
  183. if (contains(url, 'datalist.jsp') || contains(url, 'editDatalist.jsp') || contains(url, 'vastDatalist.jsp')
  184. || contains(url, 'turnGoodsSend.jsp') || contains(url, 'turnEstimate.jsp')) {
  185. return 'list';
  186. } else if (contains(url, 'batchDeal.jsp') || contains(url, 'query.jsp') || contains(url, 'print.jsp')
  187. || contains(url, 'batchPrint.jsp') || contains(url, 'gridPage.jsp')|| contains(url, 'redirect.action')) {
  188. return 'deal';
  189. }
  190. return null;
  191. },
  192. showPersonal : function(grid) {
  193. var me = this;
  194. var win = Ext.getCmp('emp-win');
  195. if (!win) {
  196. win = Ext.create('Ext.Window', {
  197. id : 'emp-win',
  198. width : 800,
  199. height : 600,
  200. title : '员工',
  201. modal : true,
  202. closeAction:'hide',
  203. layout: 'anchor',
  204. items : [ {
  205. xtype : 'gridpanel',
  206. anchor: '100% 100%',
  207. autoScroller:true,
  208. columnLines : true,
  209. plugins : [Ext.create(
  210. 'erp.view.core.grid.HeaderFilter'
  211. ), Ext.create('erp.view.core.plugin.CopyPasteMenu')],
  212. selModel : Ext.create(
  213. 'Ext.selection.CheckboxModel', {
  214. checkOnly : true,
  215. headerWidth : 30
  216. }),
  217. columns : [ {
  218. text : 'ID',
  219. dataIndex : 'em_id',
  220. hidden : true
  221. }, {
  222. text : '编号',
  223. dataIndex : 'em_code',
  224. flex : 1,
  225. filter: {xtype: 'textfield', filterName: 'em_code'}
  226. }, {
  227. text : '姓名',
  228. dataIndex : 'em_name',
  229. flex : 1,
  230. filter: {xtype: 'textfield', filterName: 'em_name'}
  231. }, {
  232. text : '部门',
  233. dataIndex : 'em_depart',
  234. flex : 1,
  235. filter: {xtype: 'textfield', filterName: 'em_depart'}
  236. },{
  237. text : '组织',
  238. dataIndex : 'em_defaultorname',
  239. flex : 1,
  240. filter: {xtype: 'textfield', filterName: 'em_defaultorname'}
  241. }, {
  242. text : '职位',
  243. dataIndex : 'em_position',
  244. flex : 1,
  245. filter: {xtype: 'textfield', filterName: 'em_position'}
  246. } ],
  247. store:Ext.create('Ext.data.Store',{
  248. fields : [ {
  249. name : 'em_id',
  250. type : 'number'
  251. }, 'em_code', 'em_name','em_depart','em_defaultorname', 'em_position' ],
  252. data:[],
  253. autoLoad: false
  254. }),
  255. listeners: {
  256. afterrender: function() {
  257. me.getData(this);
  258. }
  259. }
  260. }],
  261. buttonAlign: 'center',
  262. buttons: [{
  263. text: $I18N.common.button.erpConfirmButton,
  264. iconCls: 'x-btn-confirm',
  265. handler: function(btn) {
  266. me.getPersonalPower(grid, btn.ownerCt.ownerCt.down('gridpanel'));
  267. btn.ownerCt.ownerCt.hide();
  268. }
  269. },{
  270. text: $I18N.common.button.erpCloseButton,
  271. iconCls: 'x-btn-close',
  272. handler: function(btn) {
  273. btn.ownerCt.ownerCt.hide();
  274. }
  275. }]
  276. });
  277. }
  278. win.show();
  279. },
  280. getData:function(grid){
  281. var f="nvl(em_class,' ')<>'离职'";
  282. Ext.Ajax.request({
  283. url : basePath + 'ma/update/getEmpdbfindData.action',
  284. method : 'post',
  285. params : {
  286. fields:'em_id,em_code,em_name,em_depart,em_defaultorname,em_position',
  287. condition: f,
  288. page: -1,
  289. pagesize: 0
  290. },
  291. method : 'post',
  292. callback : function(opt, s, res){
  293. var r = new Ext.decode(res.responseText);
  294. if(r.exceptionInfo){
  295. showError(r.exceptionInfo);return;
  296. } else if(r.success && r.data){
  297. var data = Ext.decode(r.data.replace(/,}/g, '}').replace(/,]/g, ']'));
  298. grid.getStore().loadData(data);
  299. }
  300. }
  301. });
  302. },
  303. getPersonalPower: function(grid, gl) {
  304. var em = new Array();
  305. Ext.each(gl.selModel.getSelection(),function(r){
  306. if(!Ext.isEmpty(r.get('em_id')) && r.get('em_id') > 0) {
  307. em.push({em_id: r.get('em_id'), em_name: r.get('em_name')});
  308. }
  309. });
  310. grid.getPersonalData(grid.urlType, em);
  311. },
  312. showSpecial: function(grid) {
  313. var me = this, cal = grid.pp_caller;
  314. function showButton(value,cellmeta){
  315. var returnStr = "<INPUT align='center' type='button' value='删除' onclick='Delete(&quot;"+cal+"&quot;);'>";
  316. return returnStr;
  317. };
  318. var win = Ext.getCmp('special-win-' + cal);
  319. if (!win) {
  320. win = Ext.create('Ext.Window', {
  321. id : 'special-win-' + cal,
  322. width : 500,
  323. height : 360,
  324. title : '特殊权限',
  325. modal : true,
  326. layout: 'anchor',
  327. items: [{
  328. xtype: 'gridpanel',
  329. id:'special'+cal,
  330. anchor: '100% 100%',
  331. columnLines : true,
  332. columns : [ {
  333. text : 'ID',
  334. dataIndex : 'ssp_id',
  335. hidden : true
  336. }, {
  337. text : 'caller',
  338. dataIndex : 'ssp_caller',
  339. hidden : true
  340. }, {
  341. text : '描述',
  342. dataIndex : 'ssp_desc',
  343. flex : 1,
  344. editor: {
  345. xtype: 'textfield'
  346. }
  347. }, {
  348. text : '链接',
  349. dataIndex : 'ssp_action',
  350. flex : 1,
  351. editor: {
  352. xtype: 'textfield'
  353. }
  354. },{
  355. text:'操作',
  356. dataIndex: 'button',
  357. flex:0.2,
  358. renderer:showButton
  359. }],
  360. store : new Ext.data.Store({
  361. fields : [ {
  362. name : 'ssp_id',
  363. type : 'number'
  364. }, 'ssp_caller', 'ssp_desc', 'ssp_action' ],
  365. data : [ {}, {}, {}, {}, {}, {}, {}, {}, {}, {} ]
  366. }),
  367. plugins : [ Ext.create('Ext.grid.plugin.CellEditing', {
  368. clicksToEdit : 1
  369. }) ],
  370. listeners : {
  371. itemclick : function(selModel, record) {
  372. var grid = selModel.ownerCt, store = grid.store, idx = store.indexOf(record), len = store
  373. .getCount();
  374. if (idx == len - 1) {
  375. store.add([ {}, {}, {}, {}, {} ]);
  376. }
  377. }
  378. }
  379. }],
  380. buttonAlign: 'center',
  381. buttons: [{
  382. text: $I18N.common.button.erpSaveButton,
  383. iconCls: 'x-btn-save',
  384. handler: function(btn) {
  385. me.saveSysSpecials(cal, btn.ownerCt.ownerCt.down('gridpanel'));
  386. btn.ownerCt.ownerCt.hide();
  387. }
  388. },{
  389. text: $I18N.common.button.erpCloseButton,
  390. iconCls: 'x-btn-close',
  391. handler: function(btn) {
  392. btn.ownerCt.ownerCt.hide();
  393. }
  394. }]
  395. });
  396. }
  397. win.show();
  398. this.getSysSpecialPowers(cal, win.down('grid'));
  399. },
  400. getSysSpecialPowers: function(cal, grid) {
  401. Ext.Ajax.request({
  402. url: basePath + 'ma/power/getSysSpecialPowers.action',
  403. params: {
  404. caller: cal
  405. },
  406. callback: function(opt, s, r) {
  407. var rs = Ext.decode(r.responseText);
  408. if(rs.exceptionInfo) {
  409. showError(rs.exceptionInfo);
  410. } else if(rs.data){
  411. if(rs.data.length==0){
  412. rs.data=[ {}, {}, {}, {}, {} ];
  413. }
  414. grid.store.loadData(rs.data);
  415. }
  416. }
  417. });
  418. },
  419. saveSysSpecials: function(cal, grid) {
  420. var data = new Array();
  421. grid.store.each(function(item){
  422. if(item.dirty) {
  423. if((!Ext.isEmpty(item.get('ssp_desc')) && !Ext.isEmpty(item.get('ssp_action'))) ||
  424. (item.get('ssp_id') > 0)) {
  425. item.data.ssp_caller = cal;
  426. data.push(item.data);
  427. }
  428. }
  429. });
  430. if(data.length > 0) {
  431. Ext.Ajax.request({
  432. url: basePath + 'ma/power/saveSysSpecialPowers.action',
  433. params: {
  434. caller: cal,
  435. data: unescape(Ext.encode(data).replace(/\\/g,"%"))
  436. },
  437. callback: function(opt, s, r) {
  438. var rs = Ext.decode(r.responseText);
  439. if(rs.exceptionInfo) {
  440. showError(rs.exceptionInfo);
  441. } else if(rs.data){
  442. grid.store.loadData(rs.data);
  443. }
  444. }
  445. });
  446. }
  447. },
  448. showCopyPane: function(grid) {
  449. var me = this, win = Ext.create('Ext.Window', {
  450. width : 500,
  451. height: 300,
  452. title : '复制权限',
  453. modal : true,
  454. layout: 'anchor',
  455. items: [{
  456. xtype: 'container',
  457. anchor: '100% 100%',
  458. autoScroll: true,
  459. layout: 'column',
  460. padding: '10',
  461. defaults: {
  462. labelWidth: 60,
  463. columnWidth: 1,
  464. margin: '3 10 3 10'
  465. },
  466. items: [{
  467. xtype: 'dbfindtrigger',
  468. fieldLabel: '从',
  469. name: 'em_position',
  470. p: 1,
  471. editable: false,
  472. autoDbfind: false,
  473. clearable: true,
  474. listeners: {
  475. aftertrigger: function(f, r) {
  476. f.jo_id = r.get('jo_id');
  477. f.setValue(r.get('jo_name'));
  478. }
  479. }
  480. },{
  481. xtype: 'multidbfindtrigger',
  482. name: 'em_position',
  483. fieldLabel: '复制到',
  484. p: 2,
  485. editable: false,
  486. autoDbfind: false,
  487. clearable: true
  488. },{
  489. xtype: 'displayfield',
  490. columnWidth: .75
  491. },{
  492. xtype: 'button',
  493. text: '添加',
  494. columnWidth: .25,
  495. cls: 'x-dd-drop-ok-add',
  496. iconCls: 'x-dd-drop-icon',
  497. iconAlign: 'right',
  498. handler: function(btn) {
  499. var f = btn.ownerCt;
  500. f.insert(f.items.length - 2, {
  501. xtype: 'multidbfindtrigger',
  502. name: 'em_position',
  503. fieldLabel: '复制到',
  504. p: 2,
  505. editable: false,
  506. autoDbfind: false,
  507. clearable: true
  508. });
  509. }
  510. }]
  511. }],
  512. buttonAlign: 'center',
  513. buttons: [{
  514. text: $I18N.common.button.erpSaveButton,
  515. cls: 'x-btn-blue',
  516. handler: function(btn) {
  517. Ext.MessageBox.show({
  518. title: $I18N.common.msg.title_prompt,
  519. msg: '目标岗位的权限将会被指定岗位覆盖,确定复制?',
  520. buttons: Ext.Msg.YESNO,
  521. icon: Ext.Msg.WARNING,
  522. fn: function(b){
  523. if(b == 'ok' || b == 'yes') {
  524. var w = btn.ownerCt.ownerCt,
  525. from = w.down('dbfindtrigger[p=1]'),
  526. to = w.query('multidbfindtrigger[p=2]'), tos = [];
  527. Ext.Array.each(to, function(t){
  528. if(!Ext.isEmpty(t.getValue()))
  529. tos.push(t.jo_id);
  530. });
  531. if(tos.length > 0)
  532. me.copyPower(from.jo_id, tos.join(','));
  533. w.hide();
  534. }
  535. }
  536. });
  537. }
  538. },{
  539. text: $I18N.common.button.erpCloseButton,
  540. cls: 'x-btn-blue',
  541. handler: function(btn) {
  542. btn.ownerCt.ownerCt.hide();
  543. }
  544. }]
  545. });
  546. win.show();
  547. },
  548. showSyncWin: function() {
  549. var me = this, win = Ext.create('Ext.Window', {
  550. title: '权限同步',
  551. width: 300,
  552. height: 300,
  553. defaults: {
  554. margin: '3 10 10 5'
  555. },
  556. items: [{
  557. xtype: 'radio',
  558. name: 'synctype1',
  559. boxLabel: '按岗位同步',
  560. checked: true,
  561. listeners: {
  562. change: function(f) {
  563. f.ownerCt.down('radio[name=synctype2]').setValue(!f.value);
  564. f.ownerCt.down('dbfindtrigger[name=em_code]').setDisabled(f.value);
  565. f.ownerCt.down('multidbfindtrigger[name=em_position]').setDisabled(!f.value);
  566. }
  567. }
  568. },{
  569. xtype: 'multidbfindtrigger',
  570. name: 'em_position',
  571. editable: false,
  572. fieldLabel: '岗位名称',
  573. listeners: {
  574. aftertrigger: function(f, rs) {
  575. var jo_id = null, name = null;
  576. var p = f.ownerCt.down('field[name=positions]'),
  577. j = p.jobs || new Array(), d = p.descs || new Array();
  578. if(rs && rs.length > 0) {
  579. Ext.each(rs, function(){
  580. jo_id = this.get('jo_id');
  581. name = this.get('jo_name');
  582. if(!Ext.Array.contains(j, jo_id)) {
  583. j.push(jo_id);
  584. d.push(name);
  585. }
  586. });
  587. }
  588. p.jobs = j;
  589. p.descs = d;
  590. p.setValue(d.join('\t'));
  591. f.setValue(null);
  592. f.up('window').down('erpSyncButton[itemId=sync]').syncdatas = j.join(',');
  593. f.up('window').down('erpSyncButton[itemId=sync]').caller ='PositionPower!Post';
  594. }
  595. }
  596. },{
  597. xtype : 'displayfield',
  598. name: 'positions',
  599. width: 280
  600. },{
  601. xtype: 'radio',
  602. name: 'synctype2',
  603. checked: false,
  604. boxLabel: '按个人同步',
  605. listeners: {
  606. change: function(f) {
  607. f.ownerCt.down('radio[name=synctype1]').setValue(!f.value);
  608. f.ownerCt.down('dbfindtrigger[name=em_code]').setDisabled(!f.value);
  609. f.ownerCt.down('multidbfindtrigger[name=em_position]').setDisabled(f.value);
  610. }
  611. }
  612. },{
  613. xtype: 'dbfindtrigger',
  614. name: 'em_code',
  615. fieldLabel: '员工编号',
  616. disabled: true,
  617. listeners: {
  618. aftertrigger: function(f, r) {
  619. f.setValue(r.get('em_code'));
  620. f.up('window').down('erpSyncButton[itemId=sync]').syncdatas = r.get('em_id');
  621. f.up('window').down('erpSyncButton[itemId=sync]').caller ='PersonalPower!Post';
  622. }
  623. }
  624. }],
  625. buttonAlign: 'center',
  626. buttons: [{
  627. cls: 'x-btn-blue',
  628. xtype: 'erpSyncButton',
  629. itemId : 'sync',
  630. autoClearCache: true,
  631. syncUrl:'ma/power/syncPower.action'
  632. }, {
  633. text: $I18N.common.button.erpCloseButton,
  634. cls: 'x-btn-blue',
  635. handler: function(b) {
  636. b.up('window').hide();
  637. }
  638. }]
  639. });
  640. win.show();
  641. },
  642. getAllJobs : function(b) {
  643. Ext.Ajax.request({
  644. url : basePath + 'common/getFieldData.action',
  645. async: false,
  646. params: {
  647. caller: 'Job',
  648. field: 'wmsys.wm_concat(jo_id)',
  649. condition: '1=1'
  650. },
  651. method : 'post',
  652. callback : function(opt, s, res){
  653. var r = new Ext.decode(res.responseText);
  654. if(r.exceptionInfo){
  655. showError(r.exceptionInfo);
  656. } else if(r.success && r.data){
  657. b.syncdatas = r.data;
  658. }
  659. }
  660. });
  661. },
  662. copyPower : function(fid, tid) {
  663. if(fid != tid) {
  664. Ext.Ajax.request({
  665. url: basePath + 'ma/power/copypower.action',
  666. params: {
  667. f : fid,
  668. t : tid
  669. },
  670. callback : function(o, s, r) {
  671. if( s ) {
  672. var e = r.responseText;
  673. if(e == 'success') {
  674. alert('复制成功!');
  675. } else {
  676. alert(e);
  677. }
  678. }
  679. }
  680. });
  681. }
  682. }
  683. });