annotation.js 21 KB

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