equipment_purchase_view.js 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558
  1. let unitOptions = ['m', 'm2', 'm3', 'km', 't', 'kg', '台班', '工日', '昼夜', '元', '项', '处', '个', '件',
  2. '根', '组', '系统', '台', '套', '株', '丛', '缸', '支', '只', '块', '座', '对', '份', '樘', '攒', '榀']
  3. let equipmentPurchaseObj = {
  4. IDMap:{},
  5. parentMap:{},
  6. setting:{
  7. header: [
  8. {headerName: "编号", headerWidth: 160, dataCode: "code", dataType: "String",formatter: "@",spanRows: [2]},
  9. {headerName: "设备名称", headerWidth: 200, dataCode: "name", dataType: "String",spanRows: [2]},
  10. {headerName: "单位", headerWidth: 60, dataCode: "unit", dataType: "String",hAlign: "center",cellType:'comboBox',editable:true,options:unitOptions,spanRows: [2]},
  11. {headerName: ["设备价格","设备原价"], headerWidth: 160, dataCode: "originalPrice", hAlign: "right", dataType: "Number",validator:'number',spanCols: [4,1]},
  12. {headerName: ["","设备运杂费"], headerWidth: 160, dataCode: "freight", hAlign: "right", dataType: "Number",validator:'number',spanCols: [0,1]},
  13. {headerName: ["","备品备件费"], headerWidth: 160, dataCode: "sparePartCost", hAlign: "right", dataType: "Number",validator:'number',spanCols: [0,1]},
  14. {headerName: ["","单价"], headerWidth: 160, dataCode: "unitPrice", hAlign: "right", dataType: "Number",validator:'number',spanCols: [0,1]},
  15. {headerName: "数量", headerWidth: 160, dataCode: "quantity", hAlign: "right", dataType: "Number",validator:'number',spanRows: [2]},
  16. {headerName: "合价", headerWidth: 160, dataCode: "totalPrice", hAlign: "right", dataType: "Number",spanRows: [2]},
  17. ],
  18. headRows:2,
  19. view: {
  20. lockColumns: ["totalPrice",'unitPrice'],
  21. rowHeaderWidth:40,
  22. }
  23. },
  24. sheet:null,
  25. initSpread:function () {
  26. if(this.sheet == null){
  27. this.spread = SheetDataHelper.createNewSpread($("#equipmentSpread")[0]);
  28. sheetCommonObj.spreadDefaultStyle(this.spread);
  29. this.sheet = this.spread.getSheet(0);
  30. sheetCommonObj.initSheet(this.sheet, this.setting, 0);
  31. this.sheet.bind(GC.Spread.Sheets.Events.ValueChanged,this.onValueChange);
  32. this.sheet.bind(GC.Spread.Sheets.Events.RangeChanged, this.onSheetRangeChange);
  33. this.sheet.bind(GC.Spread.Sheets.Events.EditStarting, this.onEditStarting);
  34. this.sheet.bind(GC.Spread.Sheets.Events.SelectionChanged, function (e,args) {
  35. args.sheet.repaint();
  36. equipmentPurchaseObj.checkBtn();
  37. });
  38. if (projectReadOnly) {
  39. sheetCommonObj.disableSpread(this.spread);
  40. } else {
  41. this.initRightClick();
  42. }
  43. }
  44. },
  45. checkBtn:function(){
  46. let me = equipmentPurchaseObj;
  47. let selected = me.getSelected();
  48. let preNode = me.getPreNode(selected);
  49. let afterNode = me.getAfterNode(selected);
  50. //工具栏按钮的有效性
  51. me.validateBtn($('#equipment_upMove'),preNode);
  52. me.validateBtn($('#equipment_downMove'),afterNode);
  53. me.validateBtn($('#equipment_upLevel'),selected && selected.ParentID !=='-1');
  54. me.validateBtn($('#equipment_downLevel'),preNode);
  55. },
  56. validateBtn:function(btn,validate){
  57. if(validate){
  58. btn.removeClass('disabled');
  59. }else{
  60. btn.addClass('disabled');
  61. }
  62. },
  63. getTreeData:function(){
  64. let treeData = [];
  65. let roots = this.parentMap['-1'];
  66. let me = this;
  67. getChildren(roots,treeData);
  68. return treeData;
  69. function getChildren(nodes,data){
  70. if(nodes){
  71. for(let n of nodes){
  72. data.push(n);
  73. getChildren(me.parentMap[n.ID],data)
  74. }
  75. }
  76. }
  77. },
  78. getSelected:function(){
  79. let sel = this.sheet.getSelections()[0];
  80. let row = sel.row == -1 || sel.row == "" ? 0 : sel.row;
  81. if(this.data && this.data.length>0){
  82. return this.data[row];
  83. }
  84. return null;
  85. },
  86. getParentNode:function(node){
  87. if(node.ParentID === '-1') return null;
  88. return this.IDMap[node.ParentID];
  89. },
  90. //取前兄弟节点
  91. getPreNode:function(node){
  92. if(node){
  93. let nodes = this.parentMap[node.ParentID];
  94. let index = nodes.indexOf(node);
  95. return nodes[index-1]
  96. }
  97. return null;
  98. },
  99. //取后兄弟节点
  100. getAfterNode:function(node){
  101. if(node){
  102. let nodes = this.parentMap[node.ParentID];
  103. let index = nodes.indexOf(node);
  104. return nodes[index+1]
  105. }
  106. return null;
  107. },
  108. //取所有后兄弟节点
  109. getAllAfterNodes:function(node){
  110. let brothers = this.parentMap[node.ParentID];
  111. let index = brothers.indexOf(node);
  112. if(brothers.length >= index + 2){
  113. return brothers.slice(index+1);
  114. }
  115. return [];
  116. },
  117. //插入为最后一个子节点的序号
  118. getLastChildrenSeq:function(node){
  119. let seq = 1;
  120. let children = this.parentMap[node.ID];
  121. if(children && children.length > 0){
  122. return children[children.length-1].seq +1
  123. }
  124. return seq;
  125. },
  126. showData:function(){
  127. let equipment_purchase = projectObj.project.equipment_purchase;
  128. this.sourceData = equipment_purchase.datas;
  129. let data = this.sourceData.equipments;
  130. this.IDMap = {};
  131. this.parentMap = {};
  132. data = _.sortBy(data,'seq');
  133. for(let d of data){
  134. let node = ({...d,collapsed:false})
  135. this.IDMap[node.ID] = node;
  136. this.parentMap[node.ParentID] ?this.parentMap[node.ParentID].push(node):this.parentMap[node.ParentID]=[node];
  137. }
  138. let treeData = this.getTreeData();
  139. this.data = treeData;
  140. sheetCommonObj.showTreeData(this.sheet, this.setting,treeData);
  141. this.checkBtn();
  142. $('#equipment_total').text(this.sourceData.total);
  143. },
  144. onEditStarting: function (sender, args) {
  145. let me = equipmentPurchaseObj;
  146. let row = args.row;
  147. let col = args.col;
  148. if (me.editChecking(row, col) == false) {
  149. args.cancel = true;
  150. }
  151. },
  152. editChecking:function (row,col) {
  153. let me = equipmentPurchaseObj
  154. let dataCode = me.setting.header[col].dataCode;
  155. let equipment = me.data[row];
  156. let children = me.parentMap[equipment.ID];
  157. if(children && children.length>0){//父节点只有这三列才能编辑
  158. return dataCode === 'unit'||dataCode === 'name'||dataCode === 'code'
  159. }
  160. return true;
  161. },
  162. onValueChange:function (e,info) {
  163. let me = equipmentPurchaseObj,row = info.row, col = info.col;
  164. let dataCode = me.setting.header[col].dataCode;
  165. let value = info.newValue;
  166. let equipment = me.data[row];
  167. if (value&&! sheetCommonObj.checkData(col,me.setting,value)) {
  168. alert('输入的数据类型不对,请重新输入!');
  169. return me.showData();
  170. }
  171. let data = {doc:{},ID:equipment.ID};
  172. if(dataCode == 'quantity' || dataCode == 'originalPrice'|| dataCode == 'freight'|| dataCode == 'sparePartCost'){
  173. value = me.calcTotalPrice(value,dataCode,data.doc,equipment);
  174. }
  175. if(equipment[dataCode] == value) return me.showData();
  176. data.doc[dataCode] = value;
  177. me.updateEquipments([data]);
  178. },
  179. //计算父节点
  180. calcParent:function(updateData){
  181. let me = this;
  182. let temIDMap = {};
  183. let temParentMap = {};
  184. let deleteMap = {};
  185. for(let d of updateData){
  186. if(d.doc){
  187. temIDMap[d.ID] = d;
  188. if(d.doc.ParentID){
  189. temParentMap[d.doc.ParentID]?temParentMap[d.doc.ParentID].push(d):temParentMap[d.doc.ParentID]=[d];
  190. }
  191. }
  192. if(d.type === 'delete')deleteMap[d.ID] = true
  193. }
  194. for(let d of this.data){
  195. let children = this.parentMap[d.ID];
  196. let newChildren = temParentMap[d.ID];
  197. if((children&&children.length > 0) || (newChildren && newChildren.length > 0)){
  198. let totalPrice = getTotalPrice(d.ID);
  199. if(d.totalPrice !== totalPrice) updateData.push({ID:d.ID,doc: {totalPrice,unitPrice:'',sparePartCost:'',freight:'',originalPrice:'',quantity:''} })
  200. }
  201. }
  202. function getTotalPrice(ID){
  203. let sum = 0;
  204. let children = me.parentMap[ID];
  205. let newChildren = temParentMap[ID];
  206. if((children&&children.length > 0) || (newChildren && newChildren.length > 0)){
  207. if(children&&children.length > 0){
  208. for(let c of children){
  209. let newChild = temIDMap[c.ID];
  210. if(deleteMap[c.ID]) continue;//如果是删除操作,不用计算
  211. if(newChild && newChild.doc){
  212. if(newChild.doc.ParentID && newChild.doc.ParentID!=ID) continue;//升级操作时,子节点可能已经不是它的子节点了
  213. }
  214. let totalPrice = getTotalPrice(c.ID);
  215. sum = scMathUtil.roundForObj(sum + totalPrice,getDecimal('process'));
  216. }
  217. }
  218. if(newChildren && newChildren.length > 0){
  219. for(let c of newChildren){
  220. let totalPrice = getTotalPrice(c.ID);
  221. sum = scMathUtil.roundForObj(sum + totalPrice,getDecimal('process'));
  222. }
  223. }
  224. return scMathUtil.roundForObj(sum,getDecimal('glj.unitPrice'));
  225. }
  226. let tem = temIDMap[ID];
  227. if(tem && tem.doc){
  228. let doc = tem.doc;
  229. if(gljUtil.isDef(doc.totalPrice)) return doc.totalPrice;
  230. }
  231. return me.IDMap[ID].totalPrice?scMathUtil.roundForObj(me.IDMap[ID].totalPrice,getDecimal('glj.unitPrice')):0
  232. }
  233. },
  234. calcTotalPrice:function(newValue = 0,dataCode,doc,equipment){
  235. //设备原价
  236. let originalPrice = equipment.originalPrice?scMathUtil.roundForObj(equipment.originalPrice,getDecimal('glj.unitPrice')):0;
  237. //设备运杂费
  238. let freight = equipment.freight?scMathUtil.roundForObj(equipment.freight,getDecimal('glj.unitPrice')):0;
  239. //备品备件费
  240. let sparePartCost = equipment.sparePartCost?scMathUtil.roundForObj(equipment.sparePartCost,getDecimal('glj.quantity')):0;
  241. let quantity = equipment.quantity?scMathUtil.roundForObj(equipment.quantity,getDecimal('glj.quantity')):0;
  242. let unitPrice = 0;
  243. if(gljUtil.isDef(doc.originalPrice)) originalPrice = doc.originalPrice;
  244. if(gljUtil.isDef(doc.freight)) freight = doc.freight;
  245. if(gljUtil.isDef(doc.sparePartCost)) sparePartCost = doc.sparePartCost;
  246. if(gljUtil.isDef(doc.quantity)) quantity = doc.quantity;
  247. if(dataCode === 'quantity') {
  248. newValue = scMathUtil.roundForObj(newValue,getDecimal('glj.quantity'));
  249. quantity = newValue;
  250. }
  251. if(dataCode === 'originalPrice') {
  252. newValue = scMathUtil.roundForObj(newValue,getDecimal('glj.unitPrice'));
  253. originalPrice = newValue;
  254. }
  255. if(dataCode === 'freight') {
  256. newValue = scMathUtil.roundForObj(newValue,getDecimal('glj.unitPrice'));
  257. freight = newValue;
  258. }
  259. if(dataCode === 'sparePartCost') {
  260. newValue = scMathUtil.roundForObj(newValue,getDecimal('glj.unitPrice'));
  261. sparePartCost = newValue;
  262. }
  263. unitPrice = scMathUtil.roundForObj(originalPrice + freight,getDecimal('process'));
  264. unitPrice = scMathUtil.roundForObj(unitPrice + sparePartCost,getDecimal('glj.unitPrice'));
  265. doc.unitPrice = unitPrice;
  266. doc.totalPrice = scMathUtil.roundForObj(quantity * unitPrice,getDecimal('glj.unitPrice'));
  267. return newValue;
  268. },
  269. //计算序列号,返回要改变的兄弟节点数据
  270. calcSeq:function(ParentID,seq){
  271. let data = [];
  272. let nodes = this.parentMap[ParentID];
  273. let temSeq = seq+1;
  274. if(nodes && nodes.length > 0){
  275. for(let n of nodes){
  276. if(n.seq >= seq){
  277. data.push({doc:{seq:temSeq},ID:n.ID})
  278. temSeq+=1;
  279. }
  280. }
  281. }
  282. return data;
  283. },
  284. onSheetRangeChange:function(e,args){
  285. let updateMap = {};
  286. let updateData = []
  287. let me = equipmentPurchaseObj;
  288. for(let c of args.changedCells){
  289. let dataCode = me.setting.header[c.col].dataCode;
  290. let value= args.sheet.getCell(c.row, c.col).text();
  291. let equipment = me.data[c.row];
  292. if (me.editChecking(c.row, c.col) == false) {
  293. continue
  294. }
  295. if (value&&!sheetCommonObj.checkData(c.col,me.setting,value)) {
  296. alert('输入的数据类型不对,请重新输入!');
  297. me.showData();
  298. return ;
  299. }
  300. let tem = updateMap[equipment.ID]?updateMap[equipment.ID]:{};
  301. if(dataCode == 'quantity' || dataCode == 'originalPrice'|| dataCode == 'freight'|| dataCode == 'sparePartCost'){
  302. value = me.calcTotalPrice(value,dataCode,tem,equipment);
  303. }
  304. tem[dataCode] = value;
  305. updateMap[equipment.ID] = tem;
  306. }
  307. for(let ID in updateMap){
  308. let data = {doc:updateMap[ID],ID:ID};
  309. updateData.push(data);
  310. }
  311. updateData.length > 0? me.updateEquipments(updateData): me.showData();
  312. },
  313. newEquipment:function(ParentID='-1',seq=0){
  314. return {ID:uuid.v1(),ParentID,seq}
  315. },
  316. sumTotal: function(updateData){
  317. let dataMap = {};
  318. let temParentMap = {};
  319. let total = 0;
  320. let deleteMap = {};
  321. for(let d of updateData){
  322. if(d.doc){
  323. dataMap[d.ID] = d;
  324. if(d.doc.ParentID){
  325. temParentMap[d.doc.ParentID]?temParentMap[d.doc.ParentID].push(d):temParentMap[d.doc.ParentID]=[d];
  326. }
  327. }
  328. if(d.type === 'delete')deleteMap[d.ID] = true
  329. }
  330. for(let d of this.data){
  331. //累加所有底层节点就行
  332. if(!this.parentMap[d.ID] && !temParentMap[d.ID] ){
  333. if(deleteMap[d.ID]) continue;
  334. let totalPrice = d.totalPrice?scMathUtil.roundForObj(d.totalPrice,getDecimal('glj.unitPrice')):0;
  335. let data = dataMap[d.ID];
  336. if(data && gljUtil.isDef(data.doc.totalPrice))totalPrice = data.doc.totalPrice;
  337. total =scMathUtil.roundForObj(total + totalPrice,getDecimal('glj.unitPrice'))
  338. }
  339. }
  340. return total;
  341. },
  342. //上移
  343. moveUp:async function(node){
  344. let preNode = this.getPreNode(node);
  345. if(preNode){
  346. let updateData = [];
  347. updateData.push({doc:{seq:node.seq},ID:preNode.ID});
  348. updateData.push({doc:{seq:preNode.seq},ID:node.ID});
  349. await this.updateEquipments(updateData);
  350. }
  351. },
  352. updateEquipments:async function(updateData){
  353. try {
  354. this.calcParent(updateData);
  355. $.bootstrapLoading.start();
  356. let projectID = projectObj.project.ID();
  357. let total = this.sumTotal(updateData);
  358. await ajaxPost('/equipmentPurchase/updateEquipments', { projectID, updateData,total });
  359. for(let data of updateData){
  360. if(data.type === 'insert'){
  361. this.sourceData.equipments.push(...data.documents);
  362. }else if (data.type === 'delete'){
  363. _.remove( this.sourceData.equipments,{ID:data.ID});
  364. } else{
  365. let equipment = _.find(this.sourceData.equipments,{ID:data.ID});
  366. if(equipment){
  367. Object.assign(equipment,data.doc);
  368. }
  369. }
  370. }
  371. projectObj.project.equipment_purchase.datas.total = total;
  372. } catch (error) {
  373. console.log(error);
  374. alert('更新失败,请重试');
  375. }
  376. this.showData();
  377. $.bootstrapLoading.end();
  378. },
  379. insertEquipments:async function(equipments){
  380. try {
  381. $.bootstrapLoading.start();
  382. let projectID = projectObj.project.ID();
  383. await ajaxPost('/equipmentPurchase/insertData', { projectID, equipments });
  384. this.sourceData.equipments.push(...equipments)
  385. this.showData();
  386. } catch (error) {
  387. alert('插入失败,请重试');
  388. }
  389. $.bootstrapLoading.end();
  390. },
  391. deleteEquipment:async function(ID){
  392. try {
  393. let projectID = projectObj.project.ID();
  394. await ajaxPost('/equipmentPurchase/deleteEquipment', { projectID, ID });
  395. _.remove( this.sourceData.equipments,{ID});
  396. this.showData();
  397. } catch (error) {
  398. alert('删除失败,请重试');
  399. }
  400. },
  401. registerInputContextMenuItem:function(){
  402. const insertEquipmentHtml = `<span>插入&nbsp;&nbsp;<input id='insert-equipment-number' class="menu-input" type="text" value="1" onfocus="this.select()">&nbsp;&nbsp;行</span>`;
  403. let me = this;
  404. return sheetCommonObj.registerInputContextMenuItem('insertEquipment', insertEquipmentHtml, 'fa-sign-in', async function () {
  405. const number = +$('#insert-equipment-number').val();
  406. if (!number) {
  407. return;
  408. }
  409. const newData = [];
  410. let row = me.rightClickTarget.row;
  411. let seq = 0;
  412. let ParentID = '-1';
  413. let brotherNodes = [];
  414. if(row == undefined){//没有选中节点的情况,添加到最后
  415. brotherNodes = me.parentMap['-1'];
  416. if(brotherNodes && brotherNodes.length > 0){
  417. seq = brotherNodes[brotherNodes.length -1].seq;
  418. }
  419. }else{
  420. let node = me.data[row];//选中节点时插入为选中的下一行
  421. seq = node.seq;
  422. ParentID = node.ParentID;
  423. }
  424. for (let i = 0; i < number; i++) {
  425. seq+=1;
  426. newData.push(me.newEquipment(ParentID,seq));
  427. }
  428. let updateData = me.calcSeq(ParentID,seq);
  429. updateData.push({documents:newData,type:'insert'});
  430. me.updateEquipments(updateData)
  431. });
  432. },
  433. initRightClick: function () {
  434. let me = this;
  435. $.contextMenu({
  436. selector: '#equipmentSpread',
  437. build: function ($trigger, e) {
  438. me.rightClickTarget = SheetDataHelper.safeRightClickSelection($trigger, e, me.spread);
  439. me.checkBtn();
  440. return me.rightClickTarget.hitTestType === GC.Spread.Sheets.SheetArea.viewport ||
  441. me.rightClickTarget.hitTestType === GC.Spread.Sheets.SheetArea.rowHeader;
  442. },
  443. items: {
  444. "insert": {
  445. type: me.registerInputContextMenuItem(),
  446. disabled: function () {
  447. return false;
  448. },
  449. /* callback: function (key, opt) {
  450. me.insertEquipments([me.newEquipment()])
  451. } */
  452. },
  453. "delete": {
  454. name: "删除",
  455. icon: 'fa-times',
  456. disabled: function () {
  457. return me.rightClickTarget.row === undefined;
  458. },
  459. callback: function (key, opt) {
  460. let row = me.rightClickTarget.row;
  461. me.updateEquipments([{ID:me.data[row].ID,type:'delete'}]);
  462. //me.preApplyInfoPrice(row);
  463. }
  464. }
  465. }
  466. });
  467. },
  468. }
  469. $(function () {
  470. $('#tab_equipment_purchase').on('shown.bs.tab', function (e) {
  471. sessionStorage.setItem('mainTab', '#tab_equipment_purchase');
  472. $(e.relatedTarget.hash).removeClass('active');
  473. equipmentPurchaseObj.initSpread();
  474. equipmentPurchaseObj.showData();
  475. })
  476. //降级
  477. $('#equipment_downLevel').click(function(){
  478. let me = equipmentPurchaseObj;
  479. let selected = me.getSelected();
  480. if(selected){
  481. let preNode = me.getPreNode(selected);
  482. if(preNode){
  483. let seq = me.getLastChildrenSeq(preNode);
  484. me.updateEquipments([{doc:{ParentID:preNode.ID,seq},ID:selected.ID}])
  485. }
  486. }
  487. })
  488. //升级 - 后兄弟节点变成子节点
  489. $('#equipment_upLevel').click(function(){
  490. let me = equipmentPurchaseObj;
  491. let selected = me.getSelected();
  492. if(selected){
  493. let parentNode = me.getParentNode(selected);
  494. if(parentNode){
  495. let seq = parentNode.seq+1;
  496. let updateData = me.calcSeq(parentNode.ParentID,seq);
  497. updateData.push({doc:{ParentID:parentNode.ParentID,seq},ID:selected.ID})
  498. let brothers = me.getAllAfterNodes(selected);
  499. let subSeq = 0;
  500. //后兄弟节点变成子节点
  501. for(let b of brothers){
  502. subSeq+=1;
  503. updateData.push({doc:{ParentID:selected.ID,seq:subSeq},ID:b.ID})
  504. }
  505. me.updateEquipments(updateData)
  506. }
  507. }
  508. })
  509. //上移
  510. $('#equipment_upMove').click(async function (){
  511. let me = equipmentPurchaseObj;
  512. let selected = me.getSelected();
  513. if(selected){
  514. let sel = me.sheet.getSelections()[0];
  515. me.sheet.setSelection(sel.row -1 , sel.col, sel.rowCount, sel.colCount);
  516. await me.moveUp(selected);
  517. }
  518. })
  519. //下移
  520. $('#equipment_downMove').click(async function(){
  521. let me = equipmentPurchaseObj;
  522. let selected = me.getSelected();
  523. if(selected){
  524. let sel = me.sheet.getSelections()[0];
  525. let node = me.getAfterNode(selected);
  526. if(node){
  527. me.sheet.setSelection(sel.row +1 , sel.col, sel.rowCount, sel.colCount);
  528. await me.moveUp(node);
  529. }
  530. }
  531. })
  532. })