jobContent.js 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528
  1. /**
  2. * Created by Zhong on 2017/12/20.
  3. */
  4. //工作内容
  5. let jobContentOprObj = {
  6. workBook: null,
  7. container: $('#editJobCodeSpread'),
  8. situations: {ALL: 'ALL', PARTIAL: 'PARTIAL', NONE: 'NONE'},//所有ALL(包括未定义本项工作内容)、部分PARTIA,不可用NONE(无定额时)
  9. currentSituation: null,//本项适用情况
  10. currentTreeNode: null,
  11. preTreeNode: null,
  12. radios: $("input[name = 'optionsRadios']"),
  13. tableAll: $('#tableAll'),
  14. tablePartial: $('#tablePartial'),
  15. currentOprTr: null,
  16. currentJobContent: null,
  17. currentRationItems: null,
  18. addCon: $('#addCon'),//勾选编码模态框
  19. updateCon: $('#updateCon'),//编辑编码模态框
  20. setAttribute: function (preNode, currentNode) {
  21. let me = jobContentOprObj;
  22. me.preTreeNode = preNode;
  23. me.currentTreeNode = currentNode;
  24. },
  25. setting: {
  26. header:[
  27. {headerName:"编码",headerWidth:240,dataCode:"code", dataType: "String", formatter: "@", hAlign: "left", vAlign: "center"},
  28. {headerName:"选择",headerWidth:40,dataCode:"select", hAlign: "center", vAlign: "center"},
  29. ],
  30. },
  31. buildSheet: function () {
  32. let me = this;
  33. me.workBook = sheetCommonObj.buildSheet(me.container[0], me.setting, 30);
  34. me.workBook.options.showDragFillSmartTag = false;
  35. me.workBook.options.defaultDragFillType = GC.Spread.Sheets.Fill.AutoFillType.fillWithoutFormatting;
  36. me.workBook.refresh();
  37. me.workBook.bind(GC.Spread.Sheets.Events.ButtonClicked, me.onButtonClick);
  38. let sheet = me.workBook.getSheet(0);
  39. sheet.options.isProtected = true;
  40. sheet.getRange(-1, 0, -1, 1).locked(true);
  41. sheet.getRange(-1, 1, -1, 1).locked(false);
  42. },
  43. renderSheet: function (func) {
  44. let me = this;
  45. let sheet = me.workBook.getSheet(0);
  46. sheet.suspendPaint();
  47. sheet.suspendEvent();
  48. if (func) {
  49. func();
  50. }
  51. sheet.resumePaint();
  52. sheet.resumeEvent();
  53. },
  54. onButtonClick: function (sender, args) {
  55. if (args.sheet.isEditing()) {
  56. args.sheet.endEdit();
  57. }
  58. },
  59. showData: function (datas) {
  60. let me = this,
  61. sheet = me.workBook.getSheet(0),
  62. headers = me.setting.header;
  63. let fuc = function () {
  64. sheet.setRowCount(datas.length);
  65. //复选框
  66. let checkBoxType = new GC.Spread.Sheets.CellTypes.CheckBox();
  67. sheet.setCellType(-1, 1, checkBoxType);
  68. for(let col = 0, cLen = headers.length; col < cLen; col++){
  69. if(headers[col].formatter){
  70. sheet.setFormatter(-1, col, headers[col].formatter);
  71. }
  72. sheet.getRange(-1, col, -1, 1).hAlign(GC.Spread.Sheets.HorizontalAlign[headers[col]['hAlign']]);
  73. sheet.getRange(-1, col, -1, 1).vAlign(GC.Spread.Sheets.VerticalAlign[headers[col]['vAlign']]);
  74. for(let row = 0, rLen = datas.length; row < rLen; row++){
  75. sheet.setValue(row, col, datas[row][headers[col]['dataCode']]);
  76. }
  77. }
  78. };
  79. me.renderSheet(fuc);
  80. },
  81. clickUpdate: function (txtarea) {//解决编辑完后在未失去焦点的时候直接定额章节树
  82. let me = jobContentOprObj;
  83. if(txtarea.is(':focus')){
  84. let jobContent = txtarea.val();
  85. if(jobContent !== me.currentJobContent){
  86. me.preTreeNode.data.jobContent = jobContent;
  87. me.unbindEvents(txtarea);
  88. txtarea.blur();
  89. let updateCodes = [];
  90. for(let i = 0, len = me.currentRationItems.length; i < len; i++){
  91. updateCodes.push(me.currentRationItems[i].code);
  92. me.currentRationItems[i].jobContent = jobContent;
  93. }
  94. me.updateJobContent(pageOprObj.rationLibId, me.getUpdateArr(updateCodes, jobContent), function () {
  95. me.bindAllEvents(txtarea);
  96. })
  97. }
  98. else {
  99. txtarea.blur();
  100. }
  101. }
  102. },
  103. getGroup: function (rationItems) {
  104. let rst = [];//rst = [{jobContent: String, items: Array}]
  105. for(let i = 0, len = rationItems.length; i < len; i++){
  106. if(typeof rationItems[i].jobContent !== 'undefined' && rationItems[i].jobContent.toString().trim().length > 0){
  107. let isExist = false;
  108. for(let j = 0, jLen = rst.length; j < jLen; j++){
  109. if(rst[j].jobContent === rationItems[i].jobContent){
  110. isExist = true;
  111. rst[j].items.push(rationItems[i].code);
  112. break;
  113. }
  114. }
  115. if(!isExist){
  116. rst.push({jobContent: rationItems[i].jobContent, items: [rationItems[i].code]});
  117. }
  118. }
  119. }
  120. return rst;
  121. },
  122. hideTable: function (tableAll, tablePartial) {
  123. if(tableAll){
  124. tableAll.hide();
  125. }
  126. if(tablePartial){
  127. tablePartial.hide();
  128. }
  129. },
  130. //建table
  131. buildTablePartial: function (table, group) {
  132. let me = jobContentOprObj;
  133. table.empty();
  134. let $thead = $("<thead><tr style='display: block'><th></th><th>编码</th><th>工作内容</th>/tr></thead>");
  135. let $tbody = $("<tbody id='partialBody' style='display:block; overflow: auto;'></tbody>");
  136. let count = 1;
  137. for(let i = 0, len = group.length; i < len; i++){
  138. let $newTr = me.getNewTr($tbody, group[i].items, group[i].jobContent);
  139. $tbody.append($newTr);
  140. count++;
  141. }
  142. let $trEnd = $("<tr><td>"+ count +"</td><td><a href data-toggle='modal' data-target='#editBianma' class='m-0'>点击勾选编码</a></td><td><textarea class='form-control'></textarea></td></tr>");//勾选行
  143. $($trEnd.children().children()[0]).bind('click', function () {
  144. me.onclickFuncAdd($(this));
  145. me.currentOprTr = $trEnd;
  146. me.currentJobContent = $(me.currentOprTr.children()[2]).children().val();
  147. });
  148. $tbody.append($trEnd);
  149. table.append($thead);
  150. table.append($tbody);
  151. autoFlashHeight();
  152. },
  153. //新增一行tr
  154. getNewTr: function (tbody, codes, jobContent) {
  155. let me = jobContentOprObj;
  156. let count = tbody.children().length > 0 ? tbody.children().length : 1;
  157. let $textTd = $("<td></td>");
  158. let $textarea = $("<textarea class='form-control'></textarea>");
  159. $textarea.val(jobContent);
  160. $textTd.append($textarea);
  161. let $tr = $("<tr><td>" + count + "</td><td><a href data-toggle='modal' data-target='#editBianmaQ' class='m-0'>编辑编码</a></td></tr>");
  162. $tr.children().children().bind('click', function () {
  163. me.currentOprTr = $tr;
  164. me.currentJobContent = $(me.currentOprTr.children()[2]).children().val();
  165. me.onclickFuncEdit($(this));
  166. });
  167. //文本变化;
  168. $textarea.bind('change', function () {
  169. let codes = me.getUpdateCodes($($(this).parent().parent().children()[1]).children());
  170. let jobContent = $(this).val();
  171. me.updateJobContent(pageOprObj.rationLibId, me.getUpdateArr(codes, jobContent), function () {
  172. if(jobContent.trim().length === 0){
  173. me.buildTablePartial(me.tablePartial, me.getGroup(me.currentRationItems));
  174. }
  175. });
  176. });
  177. $tr.append($textTd);
  178. for(let i = 0, len = codes.length; i < len; i ++){
  179. let $p = $("<p class='m-0'>" + codes[i] + "</p>");
  180. $tr.children()[1].append($p[0]);
  181. }
  182. me.setTextareaHeight($textarea, codes.length + 1);
  183. return $tr[0];
  184. },
  185. onclickFuncAdd: function (obj) {
  186. let me = jobContentOprObj;
  187. let txtarea = $(obj.parent().parent().children().children()[1]);
  188. let jobContent = txtarea.val();
  189. if(jobContent.trim().length > 0){//工作内容不为空才可添加编码
  190. /* let codesObj = me.getAddCodes(me.currentRationItems);
  191. me.buildCheckCodesCon(me.addCon, codesObj.checkedCodes, codesObj.disabledCodes)*/
  192. obj.attr('data-target', '#editBianmaQ');
  193. if (!me.workBook) {
  194. setTimeout(function () {
  195. me.buildSheet();
  196. me.showData(me.getShowDatas(me.currentRationItems, []));
  197. me.workBook.getSheet(0).setActiveCell(0, 0);
  198. }, 200);
  199. } else {
  200. me.showData(me.getShowDatas(me.currentRationItems, []));
  201. me.workBook.getSheet(0).setActiveCell(0, 0);
  202. }
  203. }
  204. else{
  205. obj.attr('data-target', '');
  206. alert("工作内容不能为空!");
  207. }
  208. },
  209. onclickFuncEdit: function (obj) {
  210. let me = jobContentOprObj;
  211. //me.buildEditableCodesCon(me.currentRationItems, me.updateCon, me.getUpdateCodes(obj));
  212. if (!me.workBook) {
  213. setTimeout(function () {
  214. me.buildSheet();
  215. me.showData(me.getShowDatas(me.currentRationItems, me.getUpdateCodes(obj)));
  216. me.workBook.getSheet(0).setActiveCell(0, 0);
  217. }, 200);
  218. } else {
  219. me.showData(me.getShowDatas(me.currentRationItems, me.getUpdateCodes(obj)));
  220. me.workBook.getSheet(0).setActiveCell(0, 0);
  221. }
  222. },
  223. //获取弹出选择编码的数据
  224. getShowDatas: function (rationItems, codes) {
  225. let rst = [];
  226. for(let i = 0, len = codes.length; i < len; i++){
  227. rst.push({code: codes[i], select: true});
  228. }
  229. for(let i = 0, len = rationItems.length; i < len; i++){
  230. if(!codes.includes(rationItems[i].code)){
  231. if (typeof rationItems[i].jobContent === 'undefined' || rationItems[i].jobContent.toString().trim().length <= 0) {
  232. rst.push({code: rationItems[i].code, select: false});
  233. }
  234. }
  235. }
  236. return rst;
  237. },
  238. //获取编码td中的编码
  239. getUpdateCodes: function (jq) {
  240. let rst = [];
  241. let nodes = jq.parent().children();
  242. for(let i = 1, len = nodes.length; i < len; i++){
  243. rst.push(nodes[i].textContent);
  244. }
  245. return rst;
  246. },
  247. //建一个编码checkbox Div
  248. buildCodeOption: function (code, attr) {
  249. let $div = $("<div class='col'><label class='form-check-label'><input class='form-check-input' type='checkbox' value= "+ code +"> "+ code +"</label></div>");
  250. let $checkBox = $div.children().children();
  251. if(attr){
  252. $checkBox.attr(attr, true);
  253. }
  254. return $div;
  255. },
  256. //建修改编码弹窗
  257. buildEditableCodesCon: function (rationItems, container,codes) {
  258. let me = jobContentOprObj;
  259. let codeDivs = [];
  260. container.empty();
  261. for(let i = 0, len = codes.length; i < len; i++){
  262. codeDivs.push({code: codes[i], attr: 'checked'});
  263. }
  264. for(let i = 0, len = rationItems.length; i < len; i++){
  265. if(codes.indexOf(rationItems[i].code) === -1){
  266. if(typeof rationItems[i].jobContent !== 'undefined' && rationItems[i].jobContent.toString().trim().length > 0){
  267. codeDivs.push({code: rationItems[i].code, attr: 'disabled'});
  268. }
  269. else{
  270. codeDivs.push({code: rationItems[i].code, attr: ''});
  271. }
  272. }
  273. }
  274. //排序
  275. codeDivs.sort(function (a, b) {
  276. let rst = 0;
  277. if(a.code > b.code) rst = 1;
  278. else if(a.code < b.code) rst = -1;
  279. return rst;
  280. });
  281. for(let i = 0, len = codeDivs.length; i < len; i++){
  282. container.append(me.buildCodeOption(codeDivs[i].code, codeDivs[i].attr));
  283. }
  284. },
  285. //建勾选编码弹窗
  286. buildCheckCodesCon: function (container, checkedCodes, disabledCodes) {
  287. let me = jobContentOprObj;
  288. container.empty();
  289. for(let i = 0, len = checkedCodes.length; i < len; i++){
  290. let $codeDiv = me.buildCodeOption(checkedCodes[i], 'checked');
  291. container.append($codeDiv);
  292. }
  293. for(let i = 0, len = disabledCodes.length; i < len; i++){
  294. let $codeDiv = me.buildCodeOption(disabledCodes[i], 'disabled');
  295. container.append($codeDiv);
  296. }
  297. },
  298. getAddCodes: function (rationItems) {
  299. let me = jobContentOprObj;
  300. let rst = {checkedCodes: [], disabledCodes: []};
  301. for(let i = 0, len = rationItems.length; i < len; i++){
  302. if(typeof rationItems[i].jobContent !== 'undefined' && rationItems[i].jobContent.toString().trim().length > 0){
  303. rst.disabledCodes.push(rationItems[i].code);
  304. }
  305. else{
  306. rst.checkedCodes.push(rationItems[i].code);
  307. }
  308. }
  309. return rst;
  310. },
  311. //获取选择后的编码窗口的编码及状态
  312. /*getCodesAfterS: function (checkNodes) {
  313. let rst = {checked: [], unchecked: []};
  314. for(let i = 0, len = checkNodes.length; i < len; i++){
  315. if(checkNodes[i].checked){
  316. rst.checked.push(checkNodes[i].value);
  317. }
  318. else if(!checkNodes[i].checked && !checkNodes[i].disabled){
  319. rst.unchecked.push(checkNodes[i].value);
  320. }
  321. }
  322. return rst;
  323. },*/
  324. getCodesAfterS: function () {
  325. let rst = {checked: [], unchecked: []};
  326. let sheet = this.workBook.getSheet(0);
  327. for(let i = 0; i < sheet.getRowCount(); i++){
  328. let code = sheet.getValue(i, 0),
  329. checked = sheet.getValue(i, 1);
  330. if (checked) {
  331. rst.checked.push(code);
  332. } else {
  333. rst.unchecked.push(code);
  334. }
  335. }
  336. return rst;
  337. },
  338. setRadiosChecked: function (situation, radios) {
  339. let me = jobContentOprObj;
  340. if(situation === me.situations.ALL){
  341. radios[0].checked = true;
  342. radios[1].checked = false;
  343. $('#txtareaAll').val(me.currentRationItems.length > 0 ? me.currentRationItems[0].jobContent : '');
  344. me.currentJobContent = me.currentRationItems.length > 0 ? me.currentRationItems[0].jobContent : '';
  345. me.tableAll.show();
  346. me.tablePartial.hide();
  347. }
  348. else if(situation === me.situations.PARTIAL){
  349. radios[0].checked = false;
  350. radios[1].checked = true;
  351. me.tableAll.hide();
  352. me.tablePartial.show();
  353. }
  354. else if(situation === me.situations.NONE){
  355. radios[0].checked = false;
  356. radios[1].checked = false;
  357. me.tableAll.hide();
  358. me.tablePartial.hide();
  359. }
  360. },
  361. //radios是否可用,只有在定额章节树的底层节点才可用
  362. setRadiosDisabled: function (val, radios) {
  363. let me =jobContentOprObj;
  364. if(val){
  365. radios[0].checked = false;
  366. radios[1].checked = false;
  367. me.currentSituation = me.situations.NONE;
  368. }
  369. radios.attr('disabled', val);
  370. },
  371. radiosChange: function (radios, tableAll, tablePartial) {
  372. let me = jobContentOprObj;
  373. radios.change(function () {
  374. let val = $("input[name = 'optionsRadios']:checked").val();
  375. let selectedNode = sectionTreeObj.tree.selected;
  376. me.updateSituation(pageOprObj.rationLibId, selectedNode.getID(), val, function () {
  377. selectedNode.data.jobContentSituation = val;
  378. me.currentSituation = val;
  379. if(val === me.situations.ALL){
  380. let updateCodes = [];
  381. for(let i = 0, len = me.currentRationItems.length; i < len; i++){
  382. updateCodes.push(me.currentRationItems[i].code);
  383. }
  384. me.updateJobContent(pageOprObj.rationLibId, me.getUpdateArr(updateCodes, ''), function () {
  385. me.currentJobContent = '';
  386. $('#txtareaAll').val('');
  387. tableAll.show();
  388. tablePartial.hide();
  389. });
  390. }
  391. else{
  392. me.buildTablePartial(me.tablePartial, me.getGroup(me.currentRationItems));
  393. tableAll.hide();
  394. tablePartial.show();
  395. }
  396. });
  397. });
  398. },
  399. setTextareaHeight: function (textarea, nodesCount) {
  400. const perHeight = 21.6;
  401. textarea.height(nodesCount * 21.6);
  402. },
  403. bindEvents: function (txtarea) {
  404. let me = jobContentOprObj;
  405. txtarea.bind('change', function () {
  406. let jobContent = txtarea.val();
  407. let jqNodes = txtarea.parent().parent().children()[1].children;
  408. let updateCodes = me.getUpdateCodes(jqNodes);
  409. txtarea.attr('disabled', true);
  410. me.updateJobContent(pageOprObj.rationLibId, me.getUpdateArr(updateCodes, jobContent), function () {
  411. txtarea.attr('disabled', false);
  412. });
  413. });
  414. },
  415. bindAllEvents: function (txtarea) {
  416. let me = jobContentOprObj;
  417. txtarea.bind('change', function () {
  418. let met = this;
  419. let jobContent = $(met).val();
  420. $(met).attr('disabled', true);
  421. let updateCodes = [];
  422. for(let i = 0, len = me.currentRationItems.length; i < len; i++){
  423. updateCodes.push(me.currentRationItems[i].code);
  424. me.currentRationItems[i].jobContent = jobContent;
  425. }
  426. me.currentJobContent = jobContent;
  427. me.updateJobContent(pageOprObj.rationLibId, me.getUpdateArr(updateCodes, jobContent), function () {
  428. $(met).attr('disabled', false);
  429. });
  430. });
  431. },
  432. unbindEvents: function (txtarea) {
  433. txtarea.unbind();
  434. },
  435. //定额工作内容相关操作
  436. rationJobContentOpr: function (rationItems) {
  437. let me = jobContentOprObj;
  438. me.setRadiosDisabled(sectionTreeObj.tree.selected.children.length === 0 ? false : true, me.radios);
  439. me.setRadiosChecked(me.currentSituation, me.radios);
  440. me.buildTablePartial(me.tablePartial, me.getGroup(rationItems));
  441. },
  442. getUpdateArr: function (updateCodes, jobContent) {
  443. let rst = [];
  444. for(let i = 0, len = updateCodes.length; i < len; i++){
  445. rst.push({code: updateCodes[i], jobContent: jobContent});
  446. }
  447. return rst;
  448. },
  449. bindAddConBtn: function () {
  450. let me = jobContentOprObj;
  451. return function () {
  452. let codesObj = me.getCodesAfterS(me.addCon.children().children().children());
  453. let $tbody = $('#tablePartial tbody');
  454. let lastEle = $tbody[0].lastElementChild;
  455. let txtare = lastEle.lastElementChild.children[0];
  456. if(me.currentJobContent.trim().length > 0){//工作内容不为空才可添加编码
  457. let updateArr = me.getUpdateArr(codesObj.checked, me.currentJobContent);
  458. me.updateJobContent(pageOprObj.rationLibId, updateArr, function () {
  459. me.buildTablePartial(me.tablePartial, me.getGroup(me.currentRationItems));
  460. $(txtare).val('');
  461. });
  462. }
  463. else{
  464. alert("工作内容不能为空!");
  465. }
  466. }
  467. },
  468. bindUpdateConBtn: function () {
  469. let me = jobContentOprObj;
  470. return function () {
  471. console.log('enter');
  472. let codesObj = me.getCodesAfterS();
  473. let updateC = me.getUpdateArr(codesObj.checked, me.currentJobContent),
  474. updateUnC = me.getUpdateArr(codesObj.unchecked, ''),
  475. updateArr = updateC.concat(updateUnC);
  476. me.updateJobContent(pageOprObj.rationLibId, updateArr, function () {
  477. me.buildTablePartial(me.tablePartial, me.getGroup(me.currentRationItems));
  478. });
  479. }
  480. },
  481. //更新缓存的定额
  482. updateRationItem: function (rationItems, updateArr) {
  483. for(let i = 0, len = rationItems.length; i < len; i++){
  484. for(let j = 0, jLen = updateArr.length; j < jLen; j++){
  485. if(rationItems[i].code === updateArr[j].code){
  486. rationItems[i].jobContent = updateArr[j].jobContent;
  487. break;
  488. }
  489. }
  490. }
  491. },
  492. updateJobContent: function (repId, updateArr, callback){
  493. let me = jobContentOprObj;
  494. $.ajax({
  495. type: 'post',
  496. url: 'api/updateJobContent',
  497. data: {lastOpr: userAccount, repId: pageOprObj.rationLibId, updateArr: JSON.stringify(updateArr)},
  498. dataType: 'json',
  499. success: function (result) {
  500. if(!result.error){
  501. me.updateRationItem(jobContentOprObj.currentRationItems, updateArr);
  502. callback();
  503. }
  504. }
  505. });
  506. },
  507. updateSituation: function (repId, nodeId, situation, callback) {
  508. let me = jobContentOprObj;
  509. $.ajax({
  510. type: 'post',
  511. url: 'api/updateSituation',
  512. data: {lastOpr: userAccount, repId: pageOprObj.rationLibId, nodeId: nodeId, situation: situation},
  513. dataType: 'json',
  514. success: function (result) {
  515. if(!result.error){
  516. if(callback){
  517. callback();
  518. }
  519. }
  520. }
  521. })
  522. }
  523. };
  524. $(document).ready(function () {
  525. $('#gznr').on('shown.bs.tab', function () {
  526. autoFlashHeight();
  527. });
  528. });