jobContent.js 21 KB

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