AppController.js 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612
  1. Ext.define('uas.AppController', {
  2. extend: 'Ext.app.ViewController',
  3. alias: 'controller.app',
  4. privates: {
  5. dynamicViews: {}
  6. },
  7. init: function () {
  8. this.onLaunch();
  9. this.control({
  10. 'dynamicform': {
  11. boxready: 'onViewInitEvent'
  12. },
  13. 'tab': {
  14. activate: 'onTabChangeEvent'
  15. },
  16. 'button': {
  17. click: 'onButtonClickEvent'
  18. },
  19. 'menuitem': {
  20. click: 'onMenuItemClickEvent'
  21. },
  22. 'grouplist': {
  23. itemclick: 'onListItemClickEvent'
  24. },
  25. 'field': {
  26. change: 'onFieldChangeEvent'
  27. },
  28. 'searchfield': {
  29. search: 'onFieldSearchEvent',
  30. labelclick: 'onFieldLabelClickEvent'
  31. },
  32. 'gridpanel': {
  33. selectionchange: 'onGridSelectionChangeEvent',
  34. paging: 'onPagingEvent',
  35. schemechange: 'onSchemeChangeEvent',
  36. cellclick: 'onGridCellClickEvent',
  37. itemdblclick: 'onGridItemDbClickEvent'
  38. }
  39. });
  40. },
  41. /**
  42. * 单页应用启动
  43. */
  44. onLaunch() {
  45. var me = this;
  46. Ext.Ajax.promise({
  47. url: '/api/web/launch',
  48. headers: me.getRequestHeader()
  49. }).then(function (res) {
  50. var actions = res.data.actions;
  51. if (actions) {
  52. actions.forEach(action => {
  53. me.invokeAction(me, action);
  54. });
  55. }
  56. }).catch(function (e) {
  57. console.error(e);
  58. me.showToast(null, [(e ? e.message : null) || '出现错误']);
  59. }).finally(function () {
  60. Ext.getBody().removeCls('launching');
  61. });
  62. },
  63. /**
  64. * 执行后端动作指令
  65. *
  66. * @param {*} action
  67. */
  68. invokeAction: function (trigger, action) {
  69. var me = this;
  70. if (action.type == 'invokeMethod') {
  71. var methodName = action.params.methodName,
  72. args = action.params.args,
  73. viewId = action.params.viewId;
  74. if (me[methodName]) {
  75. me[methodName].apply(me, [trigger, args, viewId]);
  76. } else {
  77. console.error('Unknown action ', action);
  78. }
  79. } else if (action.type == 'invokeCmpMethod') {
  80. var itemId = action.params.itemId,
  81. methodName = action.params.methodName,
  82. args = action.params.args,
  83. viewId = action.params.viewId,
  84. view = me.dynamicViews[viewId],
  85. cmp = view.down('#' + itemId);
  86. if (cmp && cmp[methodName]) {
  87. cmp[methodName].apply(cmp, args);
  88. } else {
  89. console.error('Unknown item method', action);
  90. }
  91. }
  92. },
  93. setUuid: function (trigger, args) {
  94. this.uuid = args[0];
  95. sessionStorage.setItem("uuid", this.uuid);
  96. },
  97. getUuid: function () {
  98. var me = this, uuid = me.uuid;
  99. if (!uuid) {
  100. me.uuid = uuid = sessionStorage.getItem("uuid");
  101. }
  102. return uuid;
  103. },
  104. getRequestHeader: function () {
  105. var me = this, uuid = me.getUuid();
  106. if (uuid) {
  107. return {
  108. uuid: uuid
  109. };
  110. }
  111. return null;
  112. },
  113. setTitle: function (trigger, args, viewId) {
  114. var me = this, view = me.dynamicViews[viewId];
  115. if (view && view.setTitle) {
  116. view.setTitle(args[0]);
  117. }
  118. },
  119. /**
  120. * 打开视图
  121. *
  122. * @param {*} args
  123. */
  124. addView: function (trigger, args) {
  125. var me = this,
  126. viewConfig = args[0],
  127. cacheId = viewConfig.viewName + "_" + viewConfig.viewType,
  128. dataStr = localStorage.getItem(cacheId);
  129. if (dataStr) {
  130. // TODO 考虑版本
  131. var metadata = JSON.parse(dataStr);
  132. me.addDynamicForm(trigger, viewConfig, metadata);
  133. } else {
  134. me.loadViewMetadata(viewConfig).then(function (res) {
  135. var metadata = res.data;
  136. localStorage.setItem(cacheId, JSON.stringify(metadata));
  137. me.addDynamicForm(trigger, viewConfig, metadata);
  138. }).catch(function (e) {
  139. console.error(e);
  140. me.showToast(trigger, [(e ? e.message : null) || '出现错误']);
  141. });
  142. }
  143. },
  144. /**
  145. * 获取视图元数据
  146. *
  147. * @param {*} viewConfig
  148. */
  149. loadViewMetadata: function (viewConfig) {
  150. var me = this;
  151. return Ext.Ajax.promise({
  152. url: '/api/web/view',
  153. headers: me.getRequestHeader(),
  154. params: {
  155. viewId: viewConfig.viewId
  156. }
  157. });
  158. },
  159. addDynamicForm: function (trigger, viewConfig, viewMetadata) {
  160. var me = this;
  161. // 主视图
  162. if (viewConfig.openType == 'page') {
  163. me.setMainContent(viewConfig, viewMetadata);
  164. } else if (viewConfig.openType == 'card') {
  165. me.addCard(viewConfig, viewMetadata);
  166. } else if (viewConfig.openType == 'floating') {
  167. me.addFloating(trigger, viewConfig, viewMetadata);
  168. } else if (viewConfig.openType == 'window') {
  169. me.addWindow(viewConfig, viewMetadata);
  170. }
  171. },
  172. setMainContent: function (viewConfig, viewMetadata) {
  173. if (viewConfig.title) {
  174. document.title = viewConfig.title;
  175. }
  176. var me = this, viewport = me.getView();
  177. viewport.removeAll();
  178. viewport.add(Ext.apply(viewMetadata, {
  179. xtype: 'dynamicform',
  180. viewId: viewConfig.viewId,
  181. formId: viewConfig.viewName,
  182. height: window.innerHeight
  183. }));
  184. me.dynamicViews[viewConfig.viewId] = viewport;
  185. },
  186. addCard: function (viewConfig, viewMetadata) {
  187. var me = this, mainTabPanel = me.getView().down('tabpanel');
  188. var card = mainTabPanel.insert(mainTabPanel.items.length + 1, {
  189. iconCls: viewMetadata.iconCls,
  190. title: viewConfig.title,
  191. closable: viewConfig.closable,
  192. items: [Ext.apply(viewMetadata, {
  193. xtype: 'dynamicform',
  194. viewId: viewConfig.viewId,
  195. formId: viewConfig.viewName
  196. })]
  197. });
  198. mainTabPanel.setActiveTab(card);
  199. me.dynamicViews[viewConfig.viewId] = card;
  200. },
  201. addFloating: function (trigger, viewConfig, viewMetadata) {
  202. var me = this,
  203. cacheId = viewConfig.viewName + "_" + viewConfig.viewType,
  204. panel = trigger[cacheId];
  205. if (panel) {
  206. if (!panel.isExpanded) {
  207. panel.expand();
  208. } else {
  209. panel.collapse();
  210. }
  211. } else {
  212. panel = Ext.create('uas.panel.Floating', {
  213. scope: trigger,
  214. items: [Ext.apply(viewMetadata, {
  215. xtype: 'dynamicform',
  216. viewId: viewConfig.viewId,
  217. formId: viewConfig.viewName
  218. })]
  219. });
  220. panel.expand();
  221. trigger[cacheId] = panel;
  222. me.dynamicViews[viewConfig.viewId] = panel;
  223. }
  224. },
  225. /**
  226. * 打开窗口
  227. *
  228. * @param {*} viewConfig
  229. * @param {*} viewMetadata
  230. */
  231. addWindow: function (viewConfig, viewMetadata) {
  232. var win = Ext.create('Ext.window.Window', {
  233. autoShow: true,
  234. closeAction: 'destroy',
  235. width: viewConfig.width || '60%',
  236. height: viewConfig.height || '80%',
  237. renderTo: Ext.getBody(),
  238. title: viewConfig.title,
  239. ui: 'form',
  240. scrollable: true,
  241. layout: 'fit',
  242. items: [Ext.apply(viewMetadata, {
  243. xtype: 'dynamicform',
  244. viewId: viewConfig.viewId,
  245. formId: viewConfig.viewName
  246. })]
  247. });
  248. this.dynamicViews[viewConfig.viewId] = win;
  249. },
  250. close: function (trigger, args, viewId) {
  251. var me = this, view = me.dynamicViews[viewId];
  252. if (view) {
  253. view.close();
  254. }
  255. },
  256. clearState: function (trigger, args, viewId) {
  257. var me = this, view = me.dynamicViews[viewId];
  258. if (view) {
  259. view.down('dynamicform').clearState();
  260. }
  261. },
  262. bindData: function(trigger, args, viewId) {
  263. var me = this, view = me.dynamicViews[viewId];
  264. if (view) {
  265. var vm = view.down('dynamicform').getViewModel(),
  266. key = args[0],
  267. value = args[1];
  268. vm.set(key, value);
  269. }
  270. },
  271. updateHeadData: function(trigger, args, viewId) {
  272. var me = this, view = me.dynamicViews[viewId];
  273. if (view) {
  274. var vm = view.down('dynamicform').getViewModel(),
  275. headName = args[0],
  276. headData = args[1];
  277. data = vm.get(headName) || {};
  278. data = Ext.Object.merge(data, headData);
  279. // 服务端推送的字段数据,无需标记dirty
  280. Ext.Object.each(headData, function(field, value){
  281. var item = view.down('#' + headName + "_" + field);
  282. if (item) {
  283. item.originalValue = value;
  284. }
  285. });
  286. vm.set(headName, data);
  287. }
  288. },
  289. setStoreData: function(trigger, args, viewId) {
  290. var me = this, view = me.dynamicViews[viewId];
  291. if (view) {
  292. var vm = view.down('dynamicform').getViewModel(),
  293. storeId = args[0],
  294. store = vm.get(storeId),
  295. data = args[1] || [];
  296. if (!store) {
  297. store = new Ext.data.Store();
  298. vm.set(storeId, store);
  299. }
  300. store.loadData(data);
  301. }
  302. },
  303. addStoreData: function(trigger, args, viewId) {
  304. var me = this, view = me.dynamicViews[viewId];
  305. if (view) {
  306. var vm = view.down('dynamicform').getViewModel(),
  307. storeId = args[0],
  308. store = vm.get(storeId),
  309. data = args[1] || {};
  310. if (!store) {
  311. store = new Ext.data.Store();
  312. vm.set(storeId, store);
  313. }
  314. store.add(data);
  315. }
  316. },
  317. insertStoreData: function(trigger, args, viewId) {
  318. var me = this, view = me.dynamicViews[viewId];
  319. if (view) {
  320. var vm = view.down('dynamicform').getViewModel(),
  321. storeId = args[0],
  322. store = vm.get(storeId),
  323. rowIndex = args[1],
  324. data = args[2] || {};
  325. if (!store) {
  326. store = new Ext.data.Store();
  327. vm.set(storeId, store);
  328. }
  329. store.add(rowIndex, data);
  330. }
  331. },
  332. updateStoreData: function(trigger, args, viewId) {
  333. var me = this, view = me.dynamicViews[viewId];
  334. if (view) {
  335. var vm = view.down('dynamicform').getViewModel(),
  336. storeId = args[0],
  337. store = vm.get(storeId),
  338. rowIndex = args[1],
  339. data = args[2];
  340. if (store) {
  341. var record = store.getAt(rowIndex);
  342. if (record && data) {
  343. Ext.Object.each(data, function(k, v){
  344. record.set(k, v);
  345. });
  346. }
  347. }
  348. }
  349. },
  350. removeStoreData: function(trigger, args, viewId) {
  351. var me = this, view = me.dynamicViews[viewId];
  352. if (view) {
  353. var vm = view.down('dynamicform').getViewModel(),
  354. storeId = args[0],
  355. store = vm.get(storeId),
  356. rowIndex = args[1];
  357. if (store) {
  358. store.removeAt(rowIndex);
  359. }
  360. }
  361. },
  362. setListSchemes: function(trigger, args, viewId) {
  363. var me = this, view = me.dynamicViews[viewId];
  364. if (view) {
  365. view.down('gridpanel').setSchemes(args[0]);
  366. }
  367. },
  368. setListColumns: function(trigger, args, viewId) {
  369. var me = this, view = me.dynamicViews[viewId];
  370. if (view) {
  371. view.down('gridpanel').reconfigure(args[0]);
  372. }
  373. },
  374. setListData: function(trigger, args, viewId) {
  375. var me = this, view = me.dynamicViews[viewId];
  376. if (view) {
  377. var data = args[0],
  378. page = args[1],
  379. grid = view.down('gridpanel'),
  380. store = grid.getStore();
  381. if (page) {
  382. store.totalCount = page.totalCount;
  383. store.pageSize = page.pageSize;
  384. store.currentPage = page.currentPage;
  385. }
  386. store.loadData(data);
  387. }
  388. },
  389. showToast: function (trigger, args, viewId) {
  390. Ext.toast({
  391. html: args[0],
  392. closable: false,
  393. align: 't',
  394. slideDUration: 400,
  395. autoCloseDelay: 5000,
  396. autoClose: true,
  397. maxWidth: 400
  398. });
  399. },
  400. updateState: function(trigger, args, viewId) {
  401. var me = this, view = me.dynamicViews[viewId];
  402. if (view) {
  403. var stateMap = args[0];
  404. Ext.Object.each(stateMap, function(itemId, states){
  405. var item = view.down('#' + itemId);
  406. if (item) {
  407. Ext.Object.each(states, function(prop, val){
  408. if (prop == 'disabled') {
  409. item.setDisabled && item.setDisabled(val);
  410. } else if (prop == 'editable') {
  411. item.setEditable && item.setEditable(val);
  412. } else if (prop == 'hidden') {
  413. item.hidden && item.hidden(val);
  414. } else if (prop == 'required') {
  415. item.setRequired && item.setRequired(val);
  416. } else if (prop == 'value') {
  417. item.setValue && item.setValue(val);
  418. } else if (prop == 'options') {
  419. // 下拉框store
  420. item.setOptions && item.setOptions(val);
  421. }
  422. });
  423. }
  424. });
  425. }
  426. },
  427. setActive: function(trigger, args, viewId) {
  428. var me = this,
  429. mainTabPanel = me.getView().down('tabpanel'),
  430. view = me.dynamicViews[viewId];
  431. mainTabPanel.setActiveTab(view);
  432. },
  433. /**
  434. * 查找并执行动态服务
  435. *
  436. * @param {触发动作的组件} trigger
  437. */
  438. handleEvent: function (trigger, event, args) {
  439. var me = this,
  440. view = (trigger.xtype == 'dynamicform' ? trigger : trigger.up('dynamicform')),
  441. viewId = view.viewId;
  442. if (Ext.isArray(trigger.actions)) {
  443. trigger.actions.forEach(action => {
  444. me.invokeAction(trigger, action);
  445. });
  446. } else {
  447. view.mask('请稍等...');
  448. Ext.Ajax.payload({
  449. url: '/api/web/event',
  450. headers: me.getRequestHeader(),
  451. params: {
  452. viewId: viewId,
  453. itemId: trigger.itemId,
  454. event: event,
  455. args: args
  456. }
  457. }).then(function (res) {
  458. var actions = res.data.actions;
  459. if (actions) {
  460. actions.forEach(action => {
  461. me.invokeAction(trigger, action);
  462. });
  463. }
  464. }).catch(function (e) {
  465. console.error(e);
  466. me.showToast(trigger, [(e ? e.message : null) || '出现错误']);
  467. }).finally(function () {
  468. view.isMasked() && view.unmask();
  469. });
  470. }
  471. },
  472. onViewInitEvent: function (form) {
  473. this.handleEvent(form, 'initialize');
  474. },
  475. onTabChangeEvent: function (tab) {
  476. var me = this, card = tab.card;
  477. if (card.eventArgs && !card.items.length) {
  478. // tab activate 1th
  479. me.handleEvent(card, 'tabInit', card.eventArgs);
  480. }
  481. },
  482. onButtonClickEvent: function (btn) {
  483. var me = this, operation = btn.operation;
  484. if (operation) {
  485. var data = btn.up('dynamicform').getViewModel().getData();
  486. me.handleEvent(btn, 'click', [operation, data]);
  487. }
  488. },
  489. onMenuItemClickEvent: function (item) {
  490. var me = this, operation = item.operation;
  491. if (operation) {
  492. var view = item.up('dynamicform');
  493. if (item.valid && !view.isValid()) {
  494. view.showError();
  495. return;
  496. }
  497. me.handleEvent(item, 'menuItemClick', [operation, view.getValues(true)]);
  498. }
  499. },
  500. onListItemClickEvent: function (view, record) {
  501. var me = this;
  502. me.handleEvent(view, 'itemClick', [view.getItemValue(record)]);
  503. },
  504. onFieldChangeEvent: function (field) {
  505. if (field.fireChangeEvent) {
  506. var args;
  507. if (field.bind) {
  508. args = field.bind.value.stub.path.split(".");
  509. } else {
  510. args = [field.ownerCt.grid.entity, field.name];
  511. }
  512. args.push(field.getValue());
  513. this.handleEvent(field, 'change', args);
  514. }
  515. },
  516. onFieldSearchEvent: function (field) {
  517. var args;
  518. if (field.bind) {
  519. args = field.bind.value.stub.path.split(".");
  520. } else {
  521. args = [field.ownerCt.grid.entity, field.name];
  522. }
  523. args.push(field.getValue());
  524. // 点击搜索基础资料列表
  525. this.handleEvent(field, 'fieldSearch', args);
  526. },
  527. onFieldLabelClickEvent: function (field) {
  528. var args;
  529. if (field.bind) {
  530. args = field.bind.value.stub.path.split(".");
  531. } else {
  532. args = [field.ownerCt.grid.entity, field.name];
  533. }
  534. args.push(field.getValue());
  535. // 点击label查看基础资料列表/表单
  536. this.handleEvent(field, 'fieldView', args);
  537. },
  538. onGridSelectionChangeEvent: function (selModel, selected) {
  539. var grid = selModel.view.ownerCt, lastSelectedIndex = null, selectedIndex = [];
  540. if (selected.length) {
  541. lastSelectedIndex = selModel.view.store.indexOf(selModel.lastSelected);
  542. selected.forEach(function (select) {
  543. selectedIndex.push(selModel.view.store.indexOf(select));
  544. })
  545. }
  546. this.handleEvent(grid, 'selectionChange', [grid.entity, lastSelectedIndex, selectedIndex]);
  547. },
  548. onPagingEvent: function (grid, pageParam) {
  549. this.handleEvent(grid, 'paging', [grid.entity, pageParam]);
  550. },
  551. onSchemeChangeEvent: function (grid, selectedIndex) {
  552. this.handleEvent(grid, 'schemeChange', [grid.entity, selectedIndex]);
  553. },
  554. onGridCellClickEvent: function(grid, cell, cellIndex, record, row, rowIndex, e) {
  555. var me = this,
  556. column = e.position.column,
  557. rowIdx = e.position.rowIdx,
  558. colIdx = e.position.colIdx;
  559. if (column.enableCellEvent) {
  560. me.handleEvent(grid, 'cellClick', [grid.entity, column.dataIndex, rowIdx, colIdx]);
  561. }
  562. },
  563. onGridItemDbClickEvent: function(grid, record, row, index) {
  564. this.handleEvent(grid, 'itemDbClick', [grid.entity, index]);
  565. }
  566. });