pm_newMain.js 84 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263
  1. /**
  2. * 项目管理相关js
  3. *
  4. * @author CaiAoLin
  5. * @date 2017/8/22
  6. * @version
  7. */
  8. let Tree = null;//
  9. let movetoZTree = null;
  10. let copytoZTree = null;
  11. let engineering = [];
  12. let feeRateData = [];
  13. let isSaving = false;
  14. let projectProperty = [];
  15. let fileDelObj = null;
  16. let projectType = {
  17. folder: 'Folder',
  18. tender: 'Tender',
  19. project: 'Project',
  20. engineering: 'Engineering'
  21. };
  22. let fileType = {
  23. unitPriceFile: 'UnitPriceFile',
  24. feeRateFile: 'FeeRateFile'
  25. };
  26. const projTreeObj = {
  27. tree: null,
  28. workBook: null,
  29. setting: {
  30. tree: {
  31. id: 'ID',
  32. pid: 'ParentID',
  33. nid: 'NextSiblingID',
  34. rootId: -1,
  35. autoUpdate: false
  36. },
  37. header: [
  38. {name: '工程列表', dataCode: 'name', width: 800, vAlign: 'center', hAlign: 'left'},
  39. {name: '工程造价', dataCode: 'engineeringCost', width: 170, vAlign: 'center', hAlign: 'right'},
  40. {name: '单价文件', dataCode: 'unitPriceFile', width: 250, vAlign: 'center', hAlign: 'left'},
  41. {name: '费率文件', dataCode: 'feeRateFile', width: 250, vAlign: 'center', hAlign: 'left'},
  42. {name: '创建日期', dataCode: 'createDateTime', width: 170, vAlign: 'center', hAlign: 'left'}
  43. ],
  44. options: {
  45. tabStripVisible: false,
  46. allowCopyPasteExcelStyle : false,
  47. allowExtendPasteRange: false,
  48. allowUserDragDrop : false,
  49. allowUserDragFill: false,
  50. scrollbarMaxAlign : true
  51. }
  52. },
  53. renderSheetFuc: function (sheet, fuc) {
  54. sheet.suspendPaint();
  55. sheet.suspendEvent();
  56. fuc();
  57. sheet.resumePaint();
  58. sheet.resumeEvent();
  59. },
  60. setOptions: function (workbook, opts) {
  61. for(let opt in opts){
  62. workbook.options[opt] = opts[opt];
  63. }
  64. },
  65. bindEvent: function (workBook) {
  66. const _events = GC.Spread.Sheets.Events;
  67. let sheet = workBook.getActiveSheet();
  68. //改变选中节点set selected
  69. sheet.bind(_events.SelectionChanging, this.onSelectionChanging);
  70. },
  71. buildHeader: function (sheet, headers) {
  72. let me = this;
  73. let fuc = function () {
  74. sheet.options.isProtected = true;
  75. sheet.options.protectionOptions = {
  76. allowResizeRows: true,
  77. allowResizeColumns: true
  78. };
  79. sheet.setColumnCount(headers.length);
  80. sheet.setRowHeight(0, 40, GC.Spread.Sheets.SheetArea.colHeader);
  81. for(let i = 0, len = headers.length; i < len; i++){
  82. sheet.setValue(0, i, headers[i].name, GC.Spread.Sheets.SheetArea.colHeader);
  83. sheet.setColumnWidth(i, headers[i].width, GC.Spread.Sheets.SheetArea.colHeader);
  84. }
  85. };
  86. me.renderSheetFuc(sheet, fuc);
  87. },
  88. buildSheet: function () {
  89. if(!this.workBook){
  90. this.workBook = new GC.Spread.Sheets.Workbook($('#projSpread')[0], {sheetCount: 1});
  91. this.setOptions(this.workBook, this.setting.options);
  92. this.buildHeader(this.workBook.getActiveSheet(), this.setting.header);
  93. this.bindEvent(this.workBook);
  94. }
  95. },
  96. initSelection: function (row) {
  97. let me = this;
  98. let node = me.tree.items[row];
  99. me.tree.selected = node;
  100. $(".tools-btn > a").not(".disabled").addClass("disabled");
  101. $("#add-engineering-btn").addClass("disabled");
  102. $('#add-tender-btn').removeClass('disabled');
  103. if(node){
  104. switch(node.data.projType) {
  105. case projectType.project:
  106. $("#del-btn").removeClass("disabled");
  107. $("#add-engineering-btn").removeClass("disabled");
  108. break;
  109. case projectType.folder:
  110. if(!node.children || node.children.length === 0){
  111. $("#del-btn").removeClass("disabled");
  112. }
  113. break;
  114. case projectType.engineering:
  115. $("#del-btn").removeClass("disabled");
  116. $("#add-engineering-btn").removeClass("disabled");
  117. break;
  118. case projectType.tender:
  119. $("#add-engineering-btn").removeClass("disabled");
  120. $("#move-to-btn").removeClass("disabled");
  121. $("#copy-to-btn").removeClass("disabled");
  122. $("#share-btn").removeClass("disabled");
  123. $("#cooperate-btn").removeClass("disabled");
  124. $("#del-btn").removeClass("disabled");
  125. break;
  126. }
  127. $("#rename-btn").removeClass("disabled");
  128. }
  129. },
  130. onSelectionChanging: function (sender, args) {
  131. let me = projTreeObj;
  132. me.initSelection(args.newSelections[0].row);
  133. },
  134. getShowData: function (datas) {
  135. for(let data of datas){
  136. data.name = data.name ? data.name : '';
  137. if(data.projType !== projectType.tender){
  138. data.engineeringCost = '';
  139. data.unitPriceFile = '';
  140. data.feeRateFile = '';
  141. data.createDateTime = '';
  142. }
  143. else{
  144. data.engineeringCost = data.engineeringCost ? data.engineeringCost : 0;
  145. data.unitPriceFile = data.property && data.property.unitPriceFile && data.property.unitPriceFile.name ? data.property.unitPriceFile.name : '';
  146. data.feeRateFile = data.property && data.property.feeFile && data.property.feeFile.name ? data.property.feeFile.name : '';
  147. data.createDateTime = data.createDateTime ? new Date(data.createDateTime).Format('yyyy-MM-dd') : '';
  148. }
  149. }
  150. },
  151. getTreeNodeCell: function (tree) {
  152. let indent = 20;
  153. let levelIndent = -5;
  154. let halfBoxLength = 5;
  155. let halfExpandLength = 3;
  156. let imgWidth = 18;
  157. let imgHeight = 14;
  158. let TreeNodeCellType = function () {
  159. };
  160. TreeNodeCellType.prototype = new GC.Spread.Sheets.CellTypes.Text();
  161. TreeNodeCellType.prototype.paint = function (ctx, value, x, y, w, h, style, options) {
  162. if (style.backColor) {
  163. ctx.save();
  164. ctx.fillStyle = style.backColor;
  165. ctx.fillRect(x, y, w, h);
  166. ctx.restore();
  167. } else {
  168. ctx.clearRect(x, y, w, h);
  169. }
  170. let drawLine = function (canvas, x1, y1, x2, y2, color) {
  171. ctx.save();
  172. ctx.translate(0.5, 0.5);
  173. ctx.beginPath();
  174. ctx.moveTo(x1, y1);
  175. ctx.lineTo(x2, y2);
  176. ctx.strokeStyle = color;
  177. ctx.stroke();
  178. ctx.restore();
  179. };
  180. let drawExpandBox = function (ctx, x, y, w, h, centerX, centerY, expanded) {
  181. let rect = {}, h1, h2, offset = 1;
  182. rect.top = centerY - halfBoxLength;
  183. rect.bottom = centerY + halfBoxLength;
  184. rect.left = centerX - halfBoxLength;
  185. rect.right = centerX + halfBoxLength;
  186. if (rect.left < x + w) {
  187. rect.right = Math.min(rect.right, x + w);
  188. ctx.save();
  189. ctx.translate(0.5, 0.5);
  190. ctx.strokeStyle = 'black';
  191. ctx.beginPath();
  192. ctx.moveTo(rect.left, rect.top);
  193. ctx.lineTo(rect.left, rect.bottom);
  194. ctx.lineTo(rect.right, rect.bottom);
  195. ctx.lineTo(rect.right, rect.top);
  196. ctx.lineTo(rect.left, rect.top);
  197. ctx.stroke();
  198. ctx.fillStyle = 'white';
  199. ctx.fill();
  200. ctx.restore();
  201. // Draw Horizontal Line
  202. h1 = centerX - halfExpandLength;
  203. h2 = Math.min(centerX + halfExpandLength, x + w);
  204. if (h2 > h1) {
  205. drawLine(ctx, h1, centerY, h2, centerY, 'black');
  206. }
  207. // Draw Vertical Line
  208. if (!expanded && (centerX < x + w)) {
  209. drawLine(ctx, centerX, centerY - halfExpandLength, centerX, centerY + halfExpandLength, 'black');
  210. }
  211. }
  212. }
  213. let node = tree.items[options.row];
  214. let showTreeLine = true;
  215. if (!node) { return; }
  216. let centerX = Math.floor(x) + node.depth() * indent + node.depth() * levelIndent + indent / 2;
  217. let x1 = centerX + indent / 2;
  218. let centerY = Math.floor((y + (y + h)) / 2);
  219. let y1;
  220. // Draw Sibling Line
  221. if (showTreeLine) {
  222. // Draw Horizontal Line
  223. if (centerX < x + w) {
  224. drawLine(ctx, centerX, centerY, Math.min(x1, x + w), centerY, 'gray');
  225. let img;
  226. if(node.data.projType === projectType.folder){
  227. img = document.getElementById('folder_open_pic');
  228. imgWidth = 15;
  229. }
  230. else if(node.data.projType === projectType.project){
  231. img = document.getElementById('proj_pic');
  232. imgWidth = 18;
  233. }
  234. else if(node.data.projType === projectType.engineering){
  235. img = document.getElementById('eng_pic');
  236. imgWidth = 14;
  237. }
  238. else if(node.data.projType === projectType.tender){
  239. img = document.getElementById('tender_pic');
  240. imgWidth = 14;
  241. }
  242. ctx.drawImage(img, centerX+indent/2+3, centerY - 7, imgWidth,imgHeight);
  243. }
  244. // Draw Vertical Line
  245. if (centerX < x + w) {
  246. y1 = node.isLast() ? centerY : y + h;
  247. if (node.isFirst() && !node.parent.parent) {
  248. drawLine(ctx, centerX, centerY, centerX, y1, 'gray');
  249. } else {
  250. drawLine(ctx, centerX, y, centerX, y1, 'gray');
  251. }
  252. }
  253. }
  254. // Draw Expand Box
  255. if (node.children.length > 0) {
  256. drawExpandBox(ctx, x, y, w, h, centerX, centerY, node.expanded);
  257. }
  258. // Draw Parent Line
  259. if (showTreeLine) {
  260. var parent = node.parent, parentCenterX = centerX - indent - levelIndent;
  261. while (parent.parent) {
  262. if (!parent.isLast()) {
  263. if (parentCenterX < x + w) {
  264. drawLine(ctx, parentCenterX, y, parentCenterX, y + h, 'gray');
  265. }
  266. }
  267. parent = parent.parent;
  268. parentCenterX -= (indent + levelIndent);
  269. }
  270. };
  271. // Draw Text
  272. //x = x + (node.depth() + 1) * indent + node.depth() * levelIndent;
  273. x = x + (node.depth() + 1) * indent + node.depth() * levelIndent + imgWidth + 3;
  274. GC.Spread.Sheets.CellTypes.Text.prototype.paint.apply(this, arguments);
  275. };
  276. TreeNodeCellType.prototype.getHitInfo = function (x, y, cellStyle, cellRect, context) {
  277. return {
  278. x: x,
  279. y: y,
  280. row: context.row,
  281. col: context.col,
  282. cellStyle: cellStyle,
  283. cellRect: cellRect,
  284. sheetArea: context.sheetArea,
  285. isReservedLocation: true
  286. };
  287. };
  288. TreeNodeCellType.prototype.processMouseDown = function (hitinfo) {
  289. let offset = -1;
  290. let node = tree.items[hitinfo.row];
  291. tree.selected = node;
  292. let centerX = hitinfo.cellRect.x + offset + node.depth() * indent + node.depth() * levelIndent + indent / 2;
  293. let centerY = (hitinfo.cellRect.y + offset + (hitinfo.cellRect.y + offset + hitinfo.cellRect.height)) / 2;
  294. let text = hitinfo.sheet.getText(hitinfo.row, hitinfo.col);
  295. let value = hitinfo.sheet.getValue(hitinfo.row, hitinfo.col);
  296. let acStyle = hitinfo.sheet.getActualStyle(hitinfo.row, hitinfo.col),
  297. zoom = hitinfo.sheet.zoom();
  298. let textLength = this.getAutoFitWidth(value, text, acStyle, zoom, {sheet: hitinfo.sheet, row: hitinfo.row, col: hitinfo.col, sheetArea: GC.Spread.Sheets.SheetArea.viewport});
  299. //(图标+名字)区域
  300. function withingClickArea(){
  301. return hitinfo.x > centerX + halfBoxLength && hitinfo.x < centerX + halfBoxLength + imgWidth + indent/2+3 + textLength;
  302. }
  303. //建设项目,侧滑汇总
  304. if(node.data.projType === projectType.project && withingClickArea()){
  305. setDataToSideBar();
  306. $(".slide-sidebar").animate({width:"800"}).addClass("open");
  307. $('body').unbind('click');
  308. setTimeout(function () {
  309. $("body").bind('click', function (event) {
  310. var e = event || window.event; //浏览器兼容性
  311. if (!$(event.target).is('a')) {
  312. var elem = event.target || e.srcElement;
  313. while (elem) { //循环判断至跟节点,防止点击的是div子元素
  314. if (elem.className == "open-sidebar" || elem.className == 'slide-sidebar open') {
  315. return false;
  316. }
  317. elem = elem.parentNode;
  318. }
  319. $(".slide-sidebar").animate({width: "0"}).removeClass("open")// 关闭处理
  320. }
  321. });
  322. }, 100);
  323. }
  324. //单项文件,进入造价书界面
  325. else if(node.data.projType === projectType.tender && withingClickArea()){
  326. let newTab = window.open('about:blank');
  327. BeforeOpenProject(node.data.ID, {'fullFolder': GetFullFolder(node.parent)}, function () {
  328. let mainUrl = `/main?project=${node.data.ID}`;
  329. CommonAjax.get(mainUrl, [], function () {
  330. newTab.location.href = mainUrl;
  331. });
  332. });
  333. return;
  334. }
  335. if (!node || node.children.length === 0) { return; }
  336. if (hitinfo.x > centerX - halfBoxLength && hitinfo.x < centerX + halfBoxLength && hitinfo.y > centerY - halfBoxLength && hitinfo.y < centerY + halfBoxLength) {
  337. node.setExpanded(!node.expanded);
  338. TREE_SHEET_HELPER.massOperationSheet(hitinfo.sheet, function () {
  339. let iCount = node.posterityCount(), i, child;
  340. for (i = 0; i < iCount; i++) {
  341. child = tree.items[hitinfo.row + i + 1];
  342. hitinfo.sheet.setRowVisible(hitinfo.row + i + 1, child.visible, hitinfo.sheetArea);
  343. }
  344. hitinfo.sheet.invalidateLayout();
  345. });
  346. hitinfo.sheet.repaint();
  347. }
  348. };
  349. TreeNodeCellType.prototype.processMouseMove = function (hitInfo) {
  350. let sheet = hitInfo.sheet;
  351. let div = sheet.getParent().getHost();
  352. let canvasId = div.id + "vp_vp";
  353. let canvas = $(`#${canvasId}`)[0];
  354. //改变鼠标图案
  355. let node = tree.items[hitInfo.row];
  356. let offset = -1;
  357. let centerX = hitInfo.cellRect.x + offset + node.depth() * indent + node.depth() * levelIndent + indent / 2;
  358. let text = hitInfo.sheet.getText(hitInfo.row, hitInfo.col);
  359. let value = hitInfo.sheet.getValue(hitInfo.row, hitInfo.col);
  360. let acStyle = hitInfo.sheet.getActualStyle(hitInfo.row, hitInfo.col),
  361. zoom = hitInfo.sheet.zoom();
  362. let textLength = this.getAutoFitWidth(value, text, acStyle, zoom, {sheet: hitInfo.sheet, row: hitInfo.row, col: hitInfo.col, sheetArea: GC.Spread.Sheets.SheetArea.viewport});
  363. if (sheet && hitInfo.x > centerX + halfBoxLength && hitInfo.x < centerX + halfBoxLength + imgWidth + indent/2+3 + textLength) {
  364. canvas.style.cursor='pointer';
  365. return true;
  366. }else{
  367. canvas.style.cursor='default';
  368. }
  369. return false;
  370. };
  371. return new TreeNodeCellType();
  372. },
  373. showTreeData: function (nodes, headers) {
  374. let me = this;
  375. let sheet = me.workBook.getActiveSheet();
  376. let fuc = function(){
  377. sheet.setRowCount(nodes.length);
  378. for(let i = 0; i < nodes.length; i++){
  379. let treeNodeCell = me.getTreeNodeCell(me.tree);
  380. sheet.getCell(i, 0).cellType(treeNodeCell);
  381. for(let j = 0; j < headers.length; j++){
  382. sheet.getRange(-1, j, -1, 1).hAlign(GC.Spread.Sheets.HorizontalAlign[headers[j]['hAlign']]);
  383. sheet.getRange(-1, j, -1, 1).vAlign(GC.Spread.Sheets.VerticalAlign[headers[j]['vAlign']]);
  384. let dataCode = headers[j].dataCode;
  385. sheet.setValue(i, j, nodes[i]['data'][dataCode]);
  386. }
  387. }
  388. };
  389. me.renderSheetFuc(sheet, fuc);
  390. },
  391. refreshNodeData: function (sheet, node) {
  392. let me = this;
  393. //解决字段名不同
  394. if(node.data.projType !== projectType.tender){
  395. node.data.engineeringCost = '';
  396. node.data.unitPriceFile = '';
  397. node.data.feeRateFile = '';
  398. node.data.createDateTime = '';
  399. }
  400. else{
  401. node.data.engineeringCost = node.data.engineeringCost ? node.data.engineeringCost : 0;
  402. node.data.unitPriceFile = node.data.property && node.data.property.unitPriceFile && node.data.property.unitPriceFile.name ? node.data.property.unitPriceFile.name : '';
  403. node.data.feeRateFile = node.data.property && node.data.property.feeFile && node.data.property.feeFile.name ? node.data.property.feeFile.name : '';
  404. node.data.createDateTime = node.data.createDateTime ? new Date(node.data.createDateTime).Format('yyyy-MM-dd') : '';
  405. }
  406. let rIdx = me.tree.items.indexOf(node);
  407. for(let col = 0; col < me.setting.header.length; col++){
  408. let dataCode = me.setting.header[col]['dataCode'];
  409. sheet.setValue(rIdx, col, node.data[dataCode]);
  410. }
  411. },
  412. insert: function (data, parent, next) {
  413. let node = this.tree.addNodeData(data, parent, next);
  414. this.addRow(node);
  415. return node;
  416. },
  417. addRow: function (node) {
  418. const me = this;
  419. const sheet = this.workBook.getActiveSheet();
  420. me.renderSheetFuc(sheet, function () {
  421. const items = me.tree.items;
  422. const rIdx = items.indexOf(node);
  423. const cIdx = sheet.getActiveColumnIndex();
  424. sheet.addRows(rIdx, 1);
  425. //set selection selected
  426. sheet.setSelection(rIdx, cIdx, 1, 1);
  427. me.tree.selected = node;
  428. //父节点收起时添加子节点,子节点添加完后隐藏
  429. if(node.parent && !node.parent.expanded){
  430. sheet.setRowVisible(rIdx, false);
  431. }
  432. sheet.getCell(rIdx, 0).cellType(me.getTreeNodeCell(me.tree));
  433. me.refreshNodeData(sheet, node);
  434. });
  435. },
  436. remove: function (sheet, rIdx, count) {
  437. let me = this;
  438. me.renderSheetFuc(sheet, function () {
  439. sheet.deleteRows(rIdx, count);
  440. sheet.setRowCount(me.tree.items.length);
  441. me.initSelection(sheet.getActiveRowIndex());
  442. });
  443. },
  444. move: function (orgRow, newRow) {
  445. this.workBook.getActiveSheet().deleteRows(orgRow, 1);
  446. this.addRow(this.tree.items[newRow]);
  447. }
  448. };
  449. $(document).ready(function() {
  450. init();
  451. $('#tab_pm_all').on('show.bs.tab', function () {
  452. gcTree = null;
  453. init();
  454. });
  455. // 侧滑数据
  456. /* $(".poj-list").on('click', ".open-sidebar", function() {
  457. setDataToSideBar();
  458. $(".slide-sidebar").animate({width:"800"}).addClass("open");
  459. });*/
  460. //单价、费率文件删除确认
  461. $('#fileDelConfirm').click(function () {
  462. if(fileDelObj && fileDelObj.id){
  463. let updateObj = Object.create(null);
  464. updateObj.updateType = 'delete';
  465. updateObj.updateData = Object.create(null);
  466. if(fileDelObj.fileType === fileType.unitPriceFile){
  467. updateObj.updateData.id = fileDelObj.id;
  468. }
  469. else if(fileDelObj.fileType === fileType.feeRateFile){
  470. updateObj.updateData.ID = fileDelObj.id;
  471. }
  472. updateObj.fileType = fileDelObj.fileType;
  473. a_updateFiles([updateObj], function () {
  474. fileDelObj = null;
  475. $('#fileDelCancel').click();
  476. //refresh front?
  477. });
  478. }
  479. });
  480. //绑定新建建设项目、新建单项工程、新建文件夹、重命名Enter键事件
  481. bindInputs($('#project-name'), $('#engineering-name'), $('#folder-name'), $('#rename-name'));
  482. //绑定新建建设项目、新建单项工程、新建文件夹、重命名弹窗隐藏事件
  483. bindModalsHidden($('#add-project-dialog'), $('#add-engineering-dialog'), $('#add-folder-dialog'), $('#rename-dialog'));
  484. // 新增建设项目点击
  485. $('#add-project-btn').click(function () {
  486. let selectedItem = projTreeObj.tree.selected;
  487. $('#add-project-dialog').modal('show');
  488. });
  489. // 新增建设项目操作
  490. $('#addProjOk').click(function () {
  491. AddProject();
  492. });
  493. // 选择计价方式
  494. $("input[name='valuation_type']").click(function() {
  495. let type = $(this).val();
  496. let targetData = type === 'bill' ? JSON.parse(billValuation) : JSON.parse(rationValuation);
  497. let html = '<option value="">请选择计价规则</option>';
  498. for(let valuation of targetData) {
  499. if (valuation === null) {
  500. continue;
  501. }
  502. html += '<option value="'+ valuation._id +'">'+ valuation.name +'</option>';
  503. }
  504. $("#valuation").html(html);
  505. $("#tender-engineering").html('<option value="">请选择对应的工程专业</option>');
  506. });
  507. //选择计价规则
  508. $("#valuation").change(function () {
  509. let engineeringList = getEngineeringList();
  510. let engineeringHtml = getEngineeringHtml(engineeringList);
  511. $("#tender-engineering").html(engineeringHtml);
  512. $('#valuation-info').hide();
  513. });
  514. // 新增单项项目点击
  515. $("#add-engineering-btn").click(function() {
  516. let selectedItem = projTreeObj.tree.selected;
  517. try {
  518. if(selectedItem !== null && selectedItem.data.projType !== projectType.folder){
  519. $("#add-engineering-dialog").modal("show");
  520. }
  521. } catch (error) {
  522. alert(error);
  523. }
  524. });
  525. // 新增单项工程操作
  526. $("#add-engineering-confirm").click(function() {
  527. AddEngineering();
  528. });
  529. // 新增单位工程点击
  530. $("#add-tender-btn").click(function() {
  531. let selectedItem = projTreeObj.tree.selected;
  532. $("#add-tender-dialog").modal("show");
  533. });
  534. //新建单位工程-建设项目提示
  535. $('#poj-name').change(function () {
  536. let pojName = $('#poj-name').val().trim();
  537. let nameList = getNameList($('#poj-name-list').children());
  538. let isExist = hasListName(nameList, pojName);
  539. if(!isExist){
  540. if(pojName !== ''){
  541. replaceClass($('#poj-name-info'), 'text-danger', 'text-info');
  542. setDangerInfo($('#poj-name-info'), `新建“${pojName}”`);
  543. }
  544. //清空单项工程下拉和文件下拉
  545. setEngOptions(null);
  546. setFileOptions(null);
  547. }
  548. else {
  549. $('#poj-name-info').hide();
  550. }
  551. });
  552. //新建单位工程-单项工程提示
  553. $('#eng-name').change(function () {
  554. let engName = $('#eng-name').val().trim();
  555. let nameList = getNameList($('#eng-name-list').children());
  556. let isExist = hasListName(nameList, engName);
  557. if(!isExist){
  558. if(engName !== ''){
  559. replaceClass($('#eng-name-info'), 'text-danger', 'text-info');
  560. setDangerInfo($('#eng-name-info'), `新建“${engName}”`);
  561. }
  562. }
  563. else {
  564. $('#eng-name-info').hide();
  565. }
  566. });
  567. //新建单位工程-单位工程提示
  568. $('#tender-name').change(function () {
  569. let selected = projTreeObj.tree.selected;
  570. let pojName = $('#poj-name').val().trim();
  571. let engName = $('#eng-name').val().trim();
  572. let tenderName = $('#tender-name').val().trim();
  573. let isExist = hasTender(selected, pojName, engName, tenderName);
  574. if(isExist){
  575. if(tenderName !== '')
  576. setDangerInfo($('#tender-name-info'), `已存在“${tenderName}”`);
  577. }
  578. else {
  579. $('#tender-name-info').hide();
  580. }
  581. });
  582. //下拉是否含有输入的名字
  583. function hasListName(nameList, name){
  584. for(let i = 0, len = nameList.length; i < len; i++){
  585. if(nameList[i] === name){
  586. return true;
  587. }
  588. }
  589. return false;
  590. }
  591. function getNameList(list){
  592. let rst = [];
  593. for(let i = 0, len = list.length; i < len; i++){
  594. rst.push($(list[i]).text());
  595. }
  596. return rst;
  597. }
  598. // 新增单位工程弹层改变
  599. $('#add-tender-dialog').on('show.bs.modal', function() {
  600. //clear info
  601. $('#poj-name-info').hide();
  602. $('#eng-name-info').hide();
  603. $('#tender-name-info').hide();
  604. $('#tender-name').val('');
  605. $('#valuation-info').hide();
  606. $('#engineering-info').hide();
  607. //获取建设项目
  608. let selected = projTreeObj.tree.selected;
  609. let projs = getProjs(selected);
  610. setProjOptions(projs, selected);
  611. $($("input[name='valuation_type']")[0]).click();
  612. });
  613. // 新增单位工程
  614. $("#add-tender-confirm").click(function() {
  615. AddTender();
  616. });
  617. // 新增文件夹按钮点击
  618. $("#add-folder-btn").click(function() {
  619. $("#add-folder-dialog").modal("show");
  620. });
  621. // 新增文件夹操作
  622. $("#add-folder-confirm").click(function() {
  623. AddFolder();
  624. });
  625. // 删除按钮点击
  626. $('#del-btn').click(function() {
  627. if (projTreeObj.tree && projTreeObj.tree.selected) {
  628. $('#del').modal('show');
  629. }
  630. });
  631. // 删除时文字替换
  632. $('#del').on('show.bs.modal', function() {
  633. let hasTenderChild = function (children) {
  634. for (let i = 0; i < children.length; i++) {
  635. if (children[i].children.length === 0) {
  636. if (children[i].data.projType === 'Tender') {
  637. return true;
  638. }
  639. } else if (hasTenderChild(children[i].children)) {
  640. return true;
  641. }
  642. }
  643. return false;
  644. };
  645. // 显示内容
  646. let tenderHintElement = $('#tenderHint');
  647. let folderHintElement = $('#folderHint');
  648. if (projTreeObj.tree.selected.children.length === 0) {
  649. tenderHintElement.show();
  650. tenderHintElement.text('删除 "' + projTreeObj.tree.selected.data.name +'" ?');
  651. folderHintElement.hide();
  652. } else {
  653. tenderHintElement.hide();
  654. folderHintElement.show();
  655. folderHintElement.text('删除 "'+ projTreeObj.tree.selected.data.name +'" 以及它包含的子项?');
  656. }
  657. // 显示是否可以找回
  658. if (hasTenderChild([projTreeObj.tree.selected])) {
  659. $('#restoreHint').show();
  660. } else {
  661. $('#restoreHint').hide();
  662. }
  663. });
  664. // 删除操作
  665. $('#delete-confirm').click(function () {
  666. let updateData = null;
  667. let dialog = $('#del');
  668. if (projTreeObj.tree) {
  669. updateData = GetDeleteUpdateData(projTreeObj.tree.selected);
  670. UpdateProjectData(updateData, function () {
  671. dialog.modal('hide');
  672. //删除行号
  673. let rIdx = projTreeObj.tree.items.indexOf(projTreeObj.tree.selected);
  674. //删除行数
  675. let rCout = projTreeObj.tree.selected.posterityCount() + 1;
  676. projTreeObj.tree.removeNode(projTreeObj.tree.selected);
  677. //delete view
  678. let sheet = projTreeObj.workBook.getActiveSheet();
  679. projTreeObj.remove(sheet, rIdx, rCout);
  680. });
  681. }
  682. });
  683. // 重命名按钮点击
  684. $('#rename-btn').click(function() {
  685. if (!projTreeObj.tree) {
  686. return false;
  687. }
  688. if (!projTreeObj.tree.selected) {
  689. alert('请选择需要重命名的数据');
  690. return false;
  691. }
  692. $('#rename-dialog').modal('show');
  693. });
  694. // 重命名操作
  695. $("#rename-confirm").click(function() {
  696. let select = projTreeObj.tree.selected;
  697. let newName = $('#rename-name').val();
  698. let dialog = $('#rename-dialog');
  699. if (newName === '') {
  700. setDangerInfo($('#rename-name-info'), '请输入重命名');
  701. return false;
  702. }
  703. if (newName === select.data.name) {
  704. dialog.modal('hide');
  705. return false;
  706. }
  707. RenameProject(select.id(), newName, select.data.ParentID, function () {
  708. setDangerInfo($('#rename-name-info'), '', false);
  709. dialog.modal('hide');
  710. select.data.name = newName;
  711. let sheet = projTreeObj.workBook.getActiveSheet();
  712. sheet.setValue(sheet.getActiveRowIndex(), 0, newName);
  713. });
  714. });
  715. // 移动到按钮点击
  716. $('#move-to-btn').click(function () {
  717. if (projTreeObj.tree && projTreeObj.tree.selected) {
  718. $('#move-to-dialog').modal('show');
  719. }
  720. });
  721. // 移动到窗口内容重组
  722. $('#move-to-dialog').on('show.bs.modal', function () {
  723. movetoZTree = ConvertTreeToZtree(projTreeObj.tree, $('#treeDemo'), projTreeObj.tree.selected);
  724. });
  725. // 移动到操作
  726. $('#move-to-confirm').click(function () {
  727. let updateData = null;
  728. let dialog = $('#move-to-dialog');
  729. let target = GetTargetTreeNode($.fn.zTree.getZTreeObj('treeDemo'));
  730. let cur = projTreeObj.tree.selected;
  731. if (!target) {
  732. dialog.modal('hide');
  733. return false;
  734. }
  735. if (target.data.projType !== projectType.engineering) {
  736. alert("请移动到单项工程中!");
  737. return false;
  738. }
  739. // 判断同级是否有同名
  740. if (target.children.length > 0) {
  741. for (let tmp in target.children) {
  742. if (tmp === 0) {
  743. continue;
  744. }
  745. if (target.children[tmp].data.name === cur.data.name) {
  746. alert("对应单项工程中存在同名数据!");
  747. return false;
  748. }
  749. }
  750. }
  751. let parent = target;
  752. let next = target.firstChild();
  753. if (parent !== cur.parent || (next !== cur && next !== cur.nextSibling)){
  754. let typeInfo = {
  755. updateType: 'update',
  756. projectType: null
  757. };
  758. updateData = GetUpdateData(null, parent, next, '', null, projTreeObj.tree.selected.id(), typeInfo);
  759. //维护cur pre
  760. let curPre = cur.preSibling();
  761. if(curPre){
  762. updateData.push({updateType: 'update', updateData: {ID: curPre.id(), NextSiblingID: cur.nid()}});
  763. }
  764. UpdateProjectData(updateData, function (data) {
  765. dialog.modal('hide');
  766. let orgRow = projTreeObj.tree.items.indexOf(projTreeObj.tree.selected);
  767. projTreeObj.tree.move(projTreeObj.tree.selected, parent, next);
  768. let newRow = projTreeObj.tree.items.indexOf(projTreeObj.tree.selected);
  769. //view move
  770. projTreeObj.move(orgRow, newRow);
  771. });
  772. } else {
  773. dialog.modal('hide');
  774. }
  775. });
  776. // 复制到按钮点击
  777. $('#copy-to-btn').click(function () {
  778. let selectedItem = projTreeObj.tree.selected;
  779. try {
  780. let selectedType = selectedItem !== null && selectedItem.data !== undefined ?
  781. selectedItem.data.projType : '';
  782. if (selectedType !== projectType.tender) {
  783. throw '请选择单位工程进行复制';
  784. }
  785. } catch (error) {
  786. alert(error);
  787. return false;
  788. }
  789. $('#copy-to-dialog').modal('show');
  790. });
  791. // 复制到弹层替换
  792. $('#copy-to-dialog').on('show.bs.modal', function () {
  793. copytoZTree = ConvertTreeToZtree(projTreeObj.tree, $('#treeDemo2'), null);
  794. });
  795. // 复制到操作
  796. $("#copy-to-confirm").click(function() {
  797. let dialog = $('#copy-to-dialog');
  798. let target = GetTargetTreeNode($.fn.zTree.getZTreeObj('treeDemo2'));
  799. let parent = null;
  800. let next = null;
  801. let pre = null;
  802. let cur = projTreeObj.tree.selected;
  803. if (!target) {
  804. return false;
  805. }
  806. if (target.data.projType !== projectType.engineering) {
  807. alert("请移动到单项工程中!");
  808. return false;
  809. }
  810. if (target.data.projType !== projectType.tender && target.children.length !== 0 &&
  811. target.firstChild().data.projType !== projectType.tender) {
  812. dialog.modal('hide');
  813. }
  814. // 判断同级是否有同名
  815. if (target.children.length > 0) {
  816. for (let tmp in target.children) {
  817. if (tmp === 0) {
  818. continue;
  819. }
  820. if (target.children[tmp].data.name === cur.data.name) {
  821. alert("对应单项工程中存在同名数据!");
  822. return false;
  823. }
  824. }
  825. }
  826. if (target.data.projType === projectType.tender) {
  827. parent = target.parent;
  828. next = target.nextSibling;
  829. } else {
  830. parent = target;
  831. next = target.firstChild();
  832. }
  833. if (parent !== cur.parent || (next !== cur && next !== cur.nextSibling)){
  834. CommonAjax.post('/pm/api/getNewProjectID', {count: 1, user_id: userID}, function (IDs) {
  835. let typeInfo = {
  836. updateType: 'copy',
  837. projType: cur.data.projectType
  838. };
  839. let updateData = GetUpdateData(null, parent, next, cur.data.name, cur.data.property, IDs.lowID, typeInfo);
  840. updateData.forEach(function (data) {
  841. if (data.updateType === 'copy') {
  842. data['srcProjectId'] = cur.id();
  843. }
  844. });
  845. pre = GetNeedUpdatePreNode(parent, next);
  846. if (pre) {
  847. updateData = {};
  848. updateData['updateType'] = 'update';
  849. updateData['updateData'] = {};
  850. updateData['updateData'][projTreeObj.tree.setting.tree.id] = pre.id();
  851. updateData['updateData'][projTreeObj.tree.setting.tree.nid] = projTreeObj.tree.maxNodeId() + 1;
  852. }
  853. console.log(updateData);
  854. projTreeObj.tree.maxNodeId(IDs.lowID - 1);
  855. CommonAjax.post('/pm/api/copyProjects', {updateData: updateData, user_id: userID}, function (data) {
  856. dialog.modal('hide');
  857. data.forEach(function (nodeData) {
  858. if (nodeData.updateType === 'copy') {
  859. projTreeObj.insert(nodeData.updateData, parent, next);
  860. }
  861. });
  862. }, function () {
  863. dialog.modal('hide');
  864. });
  865. });
  866. }
  867. });
  868. // 选择工程专业后动态更改费率文件等数据
  869. $("#tender-engineering").change(function() {
  870. $('#engineering-info').hide();
  871. let engineeringList = getEngineeringList();
  872. if(engineeringList.length === 0){
  873. return false;
  874. }
  875. let selectedEngineering = $(this).val();
  876. selectedEngineering = parseInt(selectedEngineering);
  877. let currentLib = {};
  878. for(let engineering of engineeringList) {
  879. if (engineering.engineering === selectedEngineering) {
  880. currentLib = engineering.lib;
  881. }
  882. }
  883. if (Object.keys(currentLib).length <= 0) {
  884. return false;
  885. }
  886. // 输出数据到页面
  887. if (currentLib.fee_lib !== undefined && currentLib.fee_lib.length > 0) {
  888. $("#tender-fee-rate").children("option").first().val("newFeeRate-"+currentLib.fee_lib[0].id);
  889. }
  890. $(this).parent().siblings('.hidden-area').slideDown('fast');
  891. });
  892. });
  893. /**
  894. * 初始化数据
  895. *
  896. * @return {void}
  897. */
  898. function init() {
  899. billValuation = billValuation.replace(/\n/g, '\\n');
  900. rationValuation = rationValuation.replace(/\n/g, '\\n');
  901. //init spread and pmTree
  902. $.bootstrapLoading.start();
  903. GetAllProjectData(function (datas) {
  904. projTreeObj.getShowData(datas);
  905. projTreeObj.tree = pmTree.createNew(projTreeObj.setting, datas);
  906. projTreeObj.tree.selected = projTreeObj.tree.items[0];
  907. projTreeObj.buildSheet();
  908. projTreeObj.showTreeData(projTreeObj.tree.items, projTreeObj.setting.header);
  909. //初始选择
  910. projTreeObj.initSelection(0);
  911. $.bootstrapLoading.end();
  912. });
  913. engineering = engineeringList !== null && engineeringList !== undefined ? JSON.parse(engineeringList) : [];
  914. }
  915. /**
  916. * 新增建设项目
  917. *
  918. * @return {boolean}
  919. */
  920. function AddProject() {
  921. let name = $('#project-name').val().trim();
  922. if (name === '') {
  923. setDangerInfo($('#project-name-info'), '请填写建设项目名称');
  924. return false;
  925. }
  926. let existCallback = function () {
  927. setDangerInfo($('#project-name-info'), `已存在“${$("#project-name").val()}”`);
  928. };
  929. let sucCallback = function () {
  930. $('#add-project-dialog').modal('hide');
  931. $('#project-name').val('');
  932. setDangerInfo($('#project-name-info'), '', false);
  933. };
  934. let selectedItem = projTreeObj.tree.selected;
  935. /*
  936. * (1)、当前没有焦点行,新建建设项目为第一个节点。
  937. (2)、当前定位在文件夹,新建建设项目为文件夹的最后一个子节点。
  938. (3)、当前定位在建设项目,新建建设项目为其后兄弟。
  939. (4)、当前定位在单项工程或单位工程,新建项目为当前所属建设项目的后兄弟。
  940. * */
  941. if(!selectedItem){
  942. AddSiblingsItem(selectedItem, name, null, projectType.project, existCallback, sucCallback);
  943. }
  944. else {
  945. if(selectedItem.data.projType === projectType.project){
  946. AddSiblingsItem(selectedItem, name, null, projectType.project, existCallback, sucCallback);
  947. }
  948. else if(selectedItem.data.projType === projectType.engineering || selectedItem.data.projType === projectType.tender){
  949. let proj = selectedItem.parent.data.projType === projectType.project ? selectedItem.parent : selectedItem.parent.parent;
  950. AddSiblingsItem(proj, name, null, projectType.project, existCallback, sucCallback);
  951. }
  952. else if(selectedItem.data.projType === projectType.folder){
  953. AddChildrenItem(selectedItem, name, null, projectType.project, existCallback, sucCallback);
  954. }
  955. }
  956. }
  957. //新建建设项目、新建单项工程、新建文件夹、重命名弹窗隐藏事件
  958. function bindModalsHidden(projDialog, engDialog, folderDialog, renameDialog){
  959. projDialog.on('hidden.bs.modal', function () {
  960. setDangerInfo($('#project-name-info'), '', false);
  961. $('#project-name').val('');
  962. });
  963. engDialog.on('hidden.bs.modal', function () {
  964. setDangerInfo($('#engineering-name-info'), '', false);
  965. $('#engineering-name').val('');
  966. });
  967. folderDialog.on('hidden.bs.modal', function () {
  968. setDangerInfo($('#folder-name-info'), '', false);
  969. $('#folder-name').val('');
  970. });
  971. renameDialog.on('hidden.bs.modal', function () {
  972. setDangerInfo($('#rename-name-info'), '', false);
  973. $('#rename-name').val('');
  974. });
  975. }
  976. //绑定新建建设项目、新建单项工程、新建文件夹、重命名回车键功能
  977. function bindInputs(projInput, engInput, foldInput, renameInput){
  978. projInput.bind('keypress', function (event) {
  979. if(event.keyCode === 13){
  980. $('#addProjOk').click();
  981. return false;
  982. }
  983. });
  984. engInput.bind('keypress', function (event) {
  985. if(event.keyCode === 13){
  986. $('#add-engineering-confirm').click();
  987. return false;
  988. }
  989. });
  990. foldInput.bind('keypress', function (event) {
  991. if(event.keyCode === 13){
  992. $('#add-folder-confirm').click();
  993. return false;
  994. }
  995. });
  996. renameInput.bind('keypress', function (event) {
  997. if(event.keyCode === 13){
  998. $('#rename-confirm').click();
  999. return false;
  1000. }
  1001. });
  1002. }
  1003. //新建建设项目、单项工程、文件夹、重命名提示(文本改变,暂时不需要)
  1004. function getChangedFunc(input, nameInfo){
  1005. return function () {
  1006. let selected = Tree.selected();
  1007. let parent = selected ? selected.parent : Tree._root;
  1008. let name = input.val();
  1009. if(existName(name, parent.children)){
  1010. nameInfo.text(`已存在“${name}”`);
  1011. nameInfo.show();
  1012. }
  1013. else {
  1014. nameInfo.text('');
  1015. nameInfo.hide();
  1016. }
  1017. }
  1018. }
  1019. function AddTenderItems(selected, projName, engName, tenderName, property, callback){
  1020. const addPath = {p_e_t: 'p_e_t', e_t: 'e_t', t: 't'};
  1021. let path, updateDatas = [];
  1022. let tempProjs = getProjs(selected);
  1023. let tempProj = getNodeByName(projName, tempProjs);
  1024. let tempEng;
  1025. if(tempProj){
  1026. tempEng = getNodeByName(engName, tempProj.children);
  1027. if(tempEng){
  1028. path = addPath.t;
  1029. }
  1030. else {
  1031. path = addPath.e_t
  1032. }
  1033. }
  1034. else {
  1035. path = addPath.p_e_t;
  1036. }
  1037. if(path === addPath.p_e_t){
  1038. let parent, pre, next;
  1039. GetNewProjectId(3, function (IDs) {
  1040. let projID = IDs.lowID, engID = IDs.lowID + 1, tenderID = IDs.lowID + 2;
  1041. if(!selected || selected.data.projType === projectType.project){
  1042. parent = selected ? selected.parent : projTreeObj.tree._root;
  1043. pre = selected;
  1044. next = selected ? selected.nextSibling : projTreeObj.tree.firstNode();
  1045. }
  1046. else if(selected.data.projType === projectType.folder){
  1047. parent = selected ? selected : projTreeObj.tree._root;
  1048. pre = selected ? selected.lastChild() : projTreeObj.tree.firstNode();
  1049. next = null;
  1050. }
  1051. else if(selected.data.projType === projectType.engineering || selected.data.projType === projectType.tender){
  1052. let selectedProj = selected.parent.data.projType === projectType.project ? selected.parent : selected.parent.parent;
  1053. parent = selectedProj ? selectedProj.parent : projTreeObj.tree._root;
  1054. pre = selectedProj;
  1055. next = selectedProj ? selectedProj.nextSibling : projTreeObj.tree.firstNode();
  1056. }
  1057. let updateProjs = GetUpdateData(pre, parent, next, projName, null, projID, {updateType: 'new', projectType: projectType.project});
  1058. let updateEng = {updateType: 'new', updateData: {ID: engID, ParentID: projID, NextSiblingID: -1, name: engName, projType: projectType.engineering}};
  1059. property.rootProjectID = projID;
  1060. let updateTender = {updateType: 'new', updateData: {ID: tenderID, ParentID: engID, NextSiblingID: -1, name: tenderName, projType: projectType.tender, property: property}};
  1061. updateDatas = updateDatas.concat(updateProjs);
  1062. updateDatas.push(updateEng);
  1063. updateDatas.push(updateTender);
  1064. UpdateProjectData(updateDatas, function(datas){
  1065. let projData, engData, tenderData;
  1066. datas.forEach(function (data) {
  1067. if (data.updateType === 'new') {
  1068. if(data.updateData.projType === projectType.project){
  1069. projData = data.updateData;
  1070. }
  1071. else if(data.updateData.projType === projectType.engineering){
  1072. engData = data.updateData;
  1073. }
  1074. else if(data.updateData.projType === projectType.tender){
  1075. tenderData = data.updateData;
  1076. }
  1077. }
  1078. });
  1079. let pojNode = projTreeObj.insert(projData, parent, next);
  1080. let engNode = projTreeObj.insert(engData, pojNode, null);
  1081. projTreeObj.insert(tenderData, engNode, null);
  1082. callback();
  1083. });
  1084. });
  1085. }
  1086. else if(path === addPath.e_t){
  1087. GetNewProjectId(2, function (IDs) {
  1088. let engID = IDs.lowID, tenderID = IDs.lowID + 1;
  1089. let pre = tempProj.lastChild();
  1090. let next = null;
  1091. let updateEng = {updateType: 'new', updateData: {ID: engID, ParentID: tempProj.data.ID, NextSiblingID: -1, name: engName, projType: projectType.engineering}};
  1092. property.rootProjectID = tempProj.data.ID;
  1093. let updateTender = {updateType: 'new', updateData: {ID: tenderID, ParentID: engID, NextSiblingID: -1, name: tenderName, projType: projectType.tender, property: property}};
  1094. if(selected && selected.data.projType === projectType.engineering && selected.parent === tempProj){
  1095. pre = selected;
  1096. next = selected.nextSibling;
  1097. updateEng.updateData.NextSiblingID = pre.data.NextSiblingID;
  1098. }
  1099. updateDatas.push(updateEng);
  1100. updateDatas.push(updateTender);
  1101. if(pre){
  1102. updateDatas.push({updateType: 'update', updateData: {ID: pre.id(), NextSiblingID: engID}});
  1103. }
  1104. UpdateProjectData(updateDatas, function (datas) {
  1105. let engData, tenderData;
  1106. datas.forEach(function (data) {
  1107. if (data.updateType === 'new') {
  1108. if(data.updateData.projType === projectType.engineering){
  1109. engData = data.updateData;
  1110. }
  1111. else if(data.updateData.projType === projectType.tender){
  1112. tenderData = data.updateData;
  1113. }
  1114. }
  1115. });
  1116. let engNode = projTreeObj.insert(engData, tempProj, next);
  1117. projTreeObj.insert(tenderData, engNode, null);
  1118. callback();
  1119. });
  1120. });
  1121. }
  1122. else if(path === addPath.t){
  1123. GetNewProjectId(1, function (IDs) {
  1124. let tenderID = IDs.lowID;
  1125. let pre = tempEng.lastChild();
  1126. property.rootProjectID = tempProj.data.ID;
  1127. let updateTender = {updateType: 'new', updateData: {ID: tenderID, ParentID: tempEng.id(), NextSiblingID: -1, name: tenderName, projType: projectType.tender, property: property}};
  1128. updateDatas.push(updateTender);
  1129. if(pre){
  1130. updateDatas.push({updateType: 'update', updateData: {ID: pre.id(), NextSiblingID: tenderID}});
  1131. }
  1132. UpdateProjectData(updateDatas, function (datas) {
  1133. datas.forEach(function (data) {
  1134. if(data.updateType === 'new') {
  1135. projTreeObj.insert(data.updateData, tempEng, null);
  1136. }
  1137. });
  1138. callback();
  1139. })
  1140. });
  1141. }
  1142. }
  1143. /**
  1144. * 新增子元素
  1145. *
  1146. * @param {String} name
  1147. * @param {String} type
  1148. * @param {function} callback
  1149. * @return {void}
  1150. */
  1151. function AddChildrenItem(selected, name, property, type, existCallback, sucCallback) {
  1152. if(!selected){
  1153. selected = projTreeObj.tree.selected;
  1154. }
  1155. let parent = selected ? selected : projTreeObj.tree._root;
  1156. let pre = selected ? selected.lastChild() : projTreeObj.tree.firstNode();
  1157. if(existName(name, parent.children)){
  1158. //alert('同级目录已存在相同名称数据.');
  1159. existCallback();
  1160. }
  1161. else {
  1162. GetNewProjectId(1, function(IDs) {
  1163. let typeInfo = {
  1164. updateType: 'new',
  1165. projectType: type
  1166. };
  1167. let updateData = GetUpdateData(pre, parent, null, name, property, IDs.lowID, typeInfo);
  1168. projTreeObj.tree.maxNodeId(IDs.lowID - 1);
  1169. UpdateProjectData(updateData, function(datas){
  1170. datas.forEach(function (data) {
  1171. if (data.updateType === 'new') {
  1172. projTreeObj.insert(data.updateData, parent, null);
  1173. }
  1174. });
  1175. sucCallback();
  1176. });
  1177. });
  1178. }
  1179. }
  1180. /**
  1181. * 新增同级元素
  1182. *
  1183. * @param {String} name
  1184. * @param {String} type
  1185. * @param {function} callback
  1186. * @return {void}
  1187. */
  1188. function AddSiblingsItem(selected, name, property, type, existCallback, sucCallback) {
  1189. if(!selected){
  1190. selected = projTreeObj.tree.selected;
  1191. }
  1192. let parent = selected ? selected.parent : projTreeObj.tree._root;
  1193. let next = selected ? selected.nextSibling : projTreeObj.tree.firstNode();
  1194. if(existName(name, parent.children)){
  1195. //alert('同级目录已存在相同名称数据.');
  1196. existCallback();
  1197. }
  1198. else {
  1199. GetNewProjectId(1, function(IDs) {
  1200. let typeInfo = {
  1201. updateType: 'new',
  1202. projectType: type
  1203. };
  1204. let updateData = GetUpdateData(selected, parent, next, name, property, IDs.lowID, typeInfo);
  1205. projTreeObj.tree.maxNodeId(IDs.lowID - 1);
  1206. UpdateProjectData(updateData, function(datas){
  1207. datas.forEach(function (data) {
  1208. if (data.updateType === 'new') {
  1209. projTreeObj.insert(data.updateData, parent, next);
  1210. }
  1211. });
  1212. sucCallback();
  1213. });
  1214. });
  1215. }
  1216. }
  1217. function getEngineeringList(){
  1218. let valuation = $("#valuation").val();
  1219. let valuationType = $("input[name='valuation_type']:checked").val();
  1220. let valuationData = valuationType === 'bill' ? JSON.parse(billValuation) : JSON.parse(rationValuation);
  1221. let engineeringList = [];
  1222. for(let tmp of valuationData) {
  1223. if (tmp._id === valuation) {
  1224. engineeringList = tmp.engineering_list;
  1225. break;
  1226. }
  1227. }
  1228. return engineeringList;
  1229. }
  1230. function getNodeByName(name, nodes){
  1231. for(let i = 0, len = nodes.length; i < len; i++){
  1232. if(name === nodes[i].data.name){
  1233. return nodes[i];
  1234. }
  1235. }
  1236. return null;
  1237. }
  1238. //同级是否重名
  1239. function existName(name , nodes){
  1240. for(let i = 0, len = nodes.length; i < len; i++){
  1241. if(name === nodes[i].data.name){
  1242. return true;
  1243. }
  1244. }
  1245. return false;
  1246. }
  1247. //获取新建单位工程时的建设项目数据
  1248. function getProjs(selected){
  1249. let rst = [];
  1250. let temp;
  1251. let firstNode;
  1252. if(!selected){
  1253. temp = projTreeObj.tree._root;
  1254. firstNode = temp.children[0];
  1255. }
  1256. else if(selected.data.projType === projectType.folder){
  1257. temp = selected;
  1258. firstNode = temp.children[0];
  1259. }
  1260. else if(selected.data.projType === projectType.project){
  1261. temp = selected.parent;
  1262. firstNode = temp.children[0];
  1263. }
  1264. else if(selected.data.projType === projectType.engineering || selected.data.projType === projectType.tender){
  1265. let proj = selected.parent.data.projType === projectType.project ? selected.parent : selected.parent.parent;
  1266. temp = proj.parent;
  1267. firstNode = proj;
  1268. }
  1269. for(let childNode of temp.children){
  1270. if(childNode.data.projType === projectType.project){
  1271. rst.push(childNode);
  1272. }
  1273. }
  1274. if(firstNode){
  1275. //firstNode to first place
  1276. let index = null;
  1277. for(let i = 0, len = rst.length; i < len; i++){
  1278. if(rst[i].data.ID === firstNode.data.ID){
  1279. index = i;
  1280. break;
  1281. }
  1282. }
  1283. if(index){
  1284. rst.splice(index, 1);
  1285. rst.splice(0, 0, firstNode);
  1286. }
  1287. }
  1288. return rst;
  1289. }
  1290. function setFileOptions(projID){
  1291. // 获取单价文件数据
  1292. if(!projID){
  1293. $("#unit-price").children("option:not(':first')").remove();
  1294. let first = $("#tender-fee-rate").children("option").first();
  1295. $("#tender-fee-rate").empty();
  1296. $("#tender-fee-rate").append(first);
  1297. }
  1298. else {
  1299. getUnitFile(projID, function (response) {
  1300. $("#unit-price").children("option:not(':first')").remove();
  1301. if (response.data.length <= 0) {
  1302. return false;
  1303. }
  1304. let unitFileHtml = '';
  1305. for(let tmp of response.data) {
  1306. unitFileHtml += '<option value="'+ tmp.id +'">'+ tmp.name +'</option>';
  1307. }
  1308. $("#unit-price").children("option").first().after(unitFileHtml);
  1309. });
  1310. // 获取费率文件数据
  1311. getFeeRateFile(projID, function (response) {
  1312. let first = $("#tender-fee-rate").children("option").first();
  1313. $("#tender-fee-rate").empty();
  1314. $("#tender-fee-rate").append(first);
  1315. if (response.data.length <= 0) {
  1316. return false;
  1317. }
  1318. for(let tmp of response.data) {
  1319. let option = $("<option>").val(tmp.ID).text(tmp.name);
  1320. $("#tender-fee-rate").append(option);
  1321. }
  1322. });
  1323. }
  1324. }
  1325. //建设项目下拉框
  1326. function setProjOptions(projs, selected){
  1327. $("#poj-name-list").empty();
  1328. $("#poj-name").val("");
  1329. if(projs.length > 0){
  1330. let firstProj = selected && selected.data.projType === projectType.project ? selected: projs[0];
  1331. $("#poj-name").val(firstProj.data.name);
  1332. setFileOptions(firstProj.data.ID);
  1333. setEngOptions(firstProj.data.ID);
  1334. for(let i = 0, len = projs.length; i < len; i++){
  1335. let proj = $("<button>").val(projs[i].data.ID).text(projs[i].data.name);
  1336. proj.addClass("dropdown-item");
  1337. proj.attr("type", "button");
  1338. proj.click(function () {
  1339. $("#poj-name").val(projs[i].data.name);
  1340. setFileOptions(projs[i].data.ID);
  1341. setEngOptions(projs[i].data.ID);
  1342. });
  1343. $("#poj-name-list").append(proj);
  1344. }
  1345. }
  1346. else {
  1347. setFileOptions(null);
  1348. setEngOptions(null);
  1349. }
  1350. }
  1351. //单项工程下拉框
  1352. function setEngOptions(projID){
  1353. let proj = projTreeObj.tree.findNode(projID) || null;
  1354. $("#eng-name-list").empty();
  1355. $("#eng-name").val("");
  1356. if(proj){
  1357. let engineerings = [].concat(proj.children);
  1358. //set selected engineering to first place
  1359. let selected = projTreeObj.tree.selected;
  1360. let firstNode = null;
  1361. if(selected && (selected.data.projType === projectType.engineering || selected.data.projType === projectType.tender)){
  1362. firstNode = selected.data.projType === projectType.engineering ? selected : selected.parent;
  1363. }
  1364. if(firstNode){
  1365. let index = null;
  1366. for(let i = 0, len = engineerings.length; i < len; i++){
  1367. if(firstNode.data.ID === engineerings[i].data.ID){
  1368. index = i;
  1369. }
  1370. }
  1371. if(index){
  1372. engineerings.splice(index, 1);
  1373. engineerings.splice(0, 0, firstNode);
  1374. }
  1375. }
  1376. if(engineerings.length > 0){
  1377. $("#eng-name").val(engineerings[0].data.name);
  1378. for(let i = 0, len = engineerings.length; i < len; i++){
  1379. let eng = $("<button>").val(engineerings[i].data.ID).text(engineerings[i].data.name);
  1380. eng.addClass("dropdown-item");
  1381. eng.attr("type", "button");
  1382. eng.click(function () {
  1383. $("#eng-name").val(engineerings[i].data.name);
  1384. });
  1385. $("#eng-name-list").append(eng);
  1386. }
  1387. }
  1388. }
  1389. }
  1390. function hasTender(selected, pojName, engName, tenderName){
  1391. let isExist = false;
  1392. let tempProjs = getProjs(selected);
  1393. if(pojName !== ''){
  1394. let tempProj = getNodeByName(pojName, tempProjs);
  1395. if(tempProj){
  1396. if(engName !== ''){
  1397. let tempEng = getNodeByName(engName, tempProj.children);
  1398. if(tempEng){
  1399. let tempTender = getNodeByName(tenderName, tempEng.children);
  1400. if(tempTender){
  1401. isExist = true;
  1402. }
  1403. }
  1404. }
  1405. }
  1406. }
  1407. return isExist;
  1408. }
  1409. //替换class
  1410. function replaceClass(selector, orgClass, newClass){
  1411. selector.removeClass(orgClass);
  1412. selector.addClass(newClass);
  1413. }
  1414. //设置提示信息
  1415. function setDangerInfo(area, info, show = true){
  1416. area.text(info);
  1417. if(show)
  1418. area.show();
  1419. else
  1420. area.hide();
  1421. }
  1422. /**
  1423. * 新增单项工程
  1424. *
  1425. * @return {boolean}
  1426. */
  1427. function AddEngineering() {
  1428. let name = $('#engineering-name').val().trim();
  1429. if (name === '') {
  1430. setDangerInfo($('#engineering-name-info'), '请填写单项工程名称');
  1431. return false;
  1432. }
  1433. let existCallback = function () {
  1434. setDangerInfo($('#engineering-name-info'), `已存在“${$("#engineering-name").val()}”`);
  1435. };
  1436. let sucCallback = function () {
  1437. $('#add-engineering-dialog').modal('hide');
  1438. $('#engineering-name').val('');
  1439. setDangerInfo($('#engineering-name-info'), '', false);
  1440. };
  1441. let selectedItem = projTreeObj.tree.selected;
  1442. // 如果选择的是单项工程则新增同级数据
  1443. if(selectedItem){
  1444. if(selectedItem.data.projType === projectType.project){
  1445. AddChildrenItem(selectedItem, name, null, projectType.engineering, existCallback, sucCallback);
  1446. }
  1447. else if(selectedItem.data.projType === projectType.engineering){
  1448. AddSiblingsItem(selectedItem, name, null, projectType.engineering, existCallback, sucCallback);
  1449. }
  1450. else if(selectedItem.data.projType === projectType.tender){
  1451. let proj = selectedItem.parent;
  1452. AddSiblingsItem(proj, name, null, projectType.engineering, existCallback, sucCallback);
  1453. }
  1454. }
  1455. }
  1456. /**
  1457. * 新增单位工程
  1458. *
  1459. * @return {boolean}
  1460. */
  1461. function AddTender() {
  1462. try {
  1463. let projName = $("#poj-name").val().trim();
  1464. if(projName === ''){
  1465. replaceClass($('#poj-name-info'), 'text-info', 'text-danger');
  1466. setDangerInfo($('#poj-name-info'), '请填写建设项目名称');
  1467. return false;
  1468. }
  1469. let engName = $("#eng-name").val().trim();
  1470. if(engName === ''){
  1471. replaceClass($('#eng-name-info'), 'text-info', 'text-danger');
  1472. setDangerInfo($('#eng-name-info'), '请填写单项工程名称');
  1473. return false;
  1474. }
  1475. let tenderName = $('#tender-name').val();
  1476. if (tenderName === '') {
  1477. setDangerInfo($('#tender-name-info'), '请填写单位工程名称');
  1478. return false;
  1479. }
  1480. if(hasTender(projTreeObj.tree.selected, projName, engName, tenderName)){
  1481. return false;
  1482. }
  1483. let unitPriceFile = $("#unit-price").val();
  1484. let unitPriceName = unitPriceFile !== '' ? $("#unit-price").children("option:selected").text() : tenderName;
  1485. let feeFile = $("#tender-fee-rate").val();
  1486. let feeFileName = $("#tender-fee-rate").children("option:selected").text();
  1487. let valuation = $("#valuation").val();
  1488. if(valuation === ''){
  1489. setDangerInfo($('#valuation-info'), '请选择计价规则');
  1490. return false;
  1491. }
  1492. let engineering = $("#tender-engineering").val();
  1493. if (engineering === '') {
  1494. setDangerInfo($('#engineering-info'), '请选择工程专业');
  1495. return false;
  1496. }
  1497. let valuationName = $("#valuation").children("option:selected").text();
  1498. let valuationType = $("input[name='valuation_type']:checked").val();
  1499. let engineering_id = undefined;
  1500. let valuationData = valuationType === 'bill' ? JSON.parse(billValuation) : JSON.parse(rationValuation);
  1501. let engineeringList = [];
  1502. for(let tmp of valuationData) {
  1503. if (tmp._id === valuation) {
  1504. engineeringList = tmp.engineering_list;
  1505. break;
  1506. }
  1507. }
  1508. let libs = null;
  1509. for(let tmp of engineeringList) {
  1510. if (tmp.engineering == engineering) {
  1511. engineering_id = tmp.engineering_id;
  1512. libs = tmp.lib;
  1513. break;
  1514. }
  1515. }
  1516. // 一个项目里面,这两个文件必须得有,而界面又没有像费率、单价文件那样给出可选项。所以这里给出提示。
  1517. if (!libs.artificial_lib) throw '编办没有绑定人工系数标准文件';
  1518. if (!libs.program_lib) throw '编办没有绑定计算程序标准文件';
  1519. let engineeringName = $('#tender-engineering').children("option:selected").text();
  1520. let callback = function() {
  1521. $("#add-tender-dialog").modal("hide");
  1522. $('#tender-name').val('');
  1523. $("#tender-fee-rate").children("option").removeAttr("selected");
  1524. $("#tender-engineering").children("option").removeAttr("selected");
  1525. $("#poj-name").val('');
  1526. $("#poj-name-info").hide();
  1527. $("#eng-name").val('');
  1528. $("#eng-name-info").hide();
  1529. };
  1530. let selectedItem = projTreeObj.tree.selected;
  1531. let tenderInfo = {
  1532. valuation: valuation,
  1533. valuationType: valuationType,
  1534. valuationName: valuationName,
  1535. engineering: engineering,
  1536. engineering_id: engineering_id,
  1537. engineeringName: engineeringName,
  1538. unitPriceFile: {name: unitPriceName, id: unitPriceFile},
  1539. feeFile: {name: feeFileName, id: feeFile}
  1540. };
  1541. AddTenderItems(selectedItem, projName, engName, tenderName, tenderInfo, callback);
  1542. } catch (error) {
  1543. alert(error);
  1544. }
  1545. }
  1546. /**
  1547. * 新增文件夹
  1548. *
  1549. * @return {boolean}
  1550. */
  1551. function AddFolder() {
  1552. let name = $('#folder-name').val().trim();
  1553. if (name === '') {
  1554. setDangerInfo($('#folder-name-info'), '请填写文件夹名称');
  1555. return false;
  1556. }
  1557. let selectedItem = projTreeObj.tree.selected;
  1558. let existCallback = function () {
  1559. setDangerInfo($('#folder-name-info'), `已存在“${$("#folder-name").val()}”`);
  1560. };
  1561. let sucCallback = function () {
  1562. $('#add-folder-dialog').modal('hide');
  1563. $('#folder-name').val('');
  1564. setDangerInfo($('#folder-name-info'), '', false);
  1565. };
  1566. if (selectedItem !== null) {
  1567. // 判断是否超过3层
  1568. if(!withinTreble(selectedItem)){
  1569. alert("文件夹不能超过3层");
  1570. return false;
  1571. }
  1572. if(selectedItem.data.projType === projectType.folder || selectedItem.data.projType === projectType.project){
  1573. AddSiblingsItem(null, name, null, projectType.folder, existCallback, sucCallback);
  1574. }
  1575. else if(selectedItem.data.projType === projectType.engineering || selectedItem.data.projType === projectType.tender){
  1576. let proj = selectedItem.parent.data.projType === projectType.project ? selectedItem.parent : selectedItem.parent.parent;
  1577. AddSiblingsItem(proj, name, null, projectType.folder, existCallback, sucCallback);
  1578. }
  1579. } else {
  1580. AddSiblingsItem(null, name, null, projectType.folder, existCallback, sucCallback);
  1581. }
  1582. }
  1583. //判断是否是三层文件夹以内
  1584. function withinTreble(selectedItem){
  1585. let rst;
  1586. if(selectedItem.data.projType === projectType.engineering || selectedItem.data.projType === projectType.tender){
  1587. selectedItem = selectedItem.parent.data.projType === projectType.project ? selectedItem.parent : selectedItem.parent.parent;
  1588. }
  1589. if(selectedItem.parent.parent && hasFolder(selectedItem.parent.parent.children) && selectedItem.parent.parent.parent && hasFolder(selectedItem.parent.parent.parent.children)
  1590. && selectedItem.parent.parent.parent.parent && hasFolder(selectedItem.parent.parent.parent.parent.children)){
  1591. return false;
  1592. }
  1593. return true;
  1594. function hasFolder(items){
  1595. for(let i = 0, len = items.length; i < len; i++){
  1596. if(items[i].data.projType === projectType.folder){
  1597. return true;
  1598. }
  1599. }
  1600. return false;
  1601. }
  1602. }
  1603. /**
  1604. * 组织更新数据
  1605. *
  1606. * @param {Object} parent
  1607. * @param {Object} next
  1608. * @param {String} name
  1609. * @param {Object} type
  1610. * @return {Object}
  1611. */
  1612. function GetUpdateData(pre, parent, next, name, property, newId, type) {
  1613. let data = [];
  1614. let updateData = {};
  1615. let rootProjectID = -1;
  1616. if(type.projectType === projectType.tender){
  1617. let rootProject = parent ? parent.parent : projTreeObj.tree._root;
  1618. rootProjectID = rootProject ? rootProject.id() : -1;
  1619. if(property){
  1620. property.rootProjectID=rootProjectID;
  1621. }
  1622. }
  1623. updateData['updateType'] = type.updateType === undefined ? 'new' : type.updateType;
  1624. updateData['updateData'] = {};
  1625. if (newId !== '') {
  1626. updateData['updateData'][projTreeObj.tree.setting.tree.id] = newId;
  1627. }
  1628. updateData['updateData'][projTreeObj.tree.setting.tree.pid] = parent ? parent.id() : -1;
  1629. updateData['updateData'][projTreeObj.tree.setting.tree.nid] = next ? next.id() : -1;
  1630. if (name !== '') {
  1631. updateData['updateData']['name'] = name;
  1632. }
  1633. if (property !== null && property !== undefined) {
  1634. updateData['updateData']['property'] = property;
  1635. }
  1636. if (type !== null && type.projectType !== null) {
  1637. updateData['updateData']['projType'] = type.projectType !== undefined ? type.projectType : 'Tender';
  1638. }
  1639. if(pre){//维护preNode
  1640. let updateObj = Object.create(null);
  1641. updateObj.updateData = Object.create(null);
  1642. updateObj.updateType = 'update';
  1643. updateObj.updateData.ID = pre.id();
  1644. updateObj.updateData.NextSiblingID = newId;
  1645. data.push(updateObj);
  1646. }
  1647. data.push(updateData);
  1648. return data;
  1649. }
  1650. /**
  1651. * 获取删除数据
  1652. *
  1653. * @return {Object} node
  1654. * @return {Object}
  1655. */
  1656. function GetDeleteUpdateData(node) {
  1657. let datas = [], updateData,
  1658. pre = node.preSibling(),
  1659. deleteNodeData = function (node) {
  1660. var data = Object.create(null);
  1661. data['updateType'] = 'delete';
  1662. //data['NextSiblingID'] = node.data.NextSiblingID;
  1663. data['updateData'] = Object.create(null);
  1664. data['updateData'][projTreeObj.tree.setting.tree.id] = node.id();
  1665. data['updateData']['projType'] = node.data.projType;
  1666. if (node.data.projType === 'Tender') {
  1667. data['updateData']['FullFolder'] = GetFullFolder(node.parent);
  1668. }
  1669. return data;
  1670. },
  1671. addDeleteChildren = function (children) {
  1672. children.forEach(function(child){
  1673. datas.push(deleteNodeData(child));
  1674. addDeleteChildren(child.children);
  1675. });
  1676. };
  1677. if (pre && pre.id() !== -1) {
  1678. updateData = {};
  1679. updateData['updateType'] = 'update';
  1680. updateData['updateData'] = {};
  1681. updateData['updateData'][projTreeObj.tree.setting.tree.id] = pre.id();
  1682. updateData['updateData'][projTreeObj.tree.setting.tree.nid] = node ? node.nid() : -1;
  1683. datas.push(updateData);
  1684. }
  1685. datas.push(deleteNodeData(node));
  1686. addDeleteChildren(node.children);
  1687. return datas;
  1688. };
  1689. /**
  1690. * 获取父级所有名称
  1691. *
  1692. * @return {Array}
  1693. */
  1694. function GetFullFolder (node) {
  1695. let fullFolder = [];
  1696. let cur = node;
  1697. while (cur && cur.data) {
  1698. fullFolder.unshift(cur.data.name);
  1699. cur = cur.parent;
  1700. }
  1701. return fullFolder;
  1702. }
  1703. /**
  1704. * 获取需要更新的前节点
  1705. *
  1706. * @param {Object} parent
  1707. * @param {Object} next
  1708. * @return {Object}
  1709. */
  1710. function GetNeedUpdatePreNode(parent, next) {
  1711. if (next) {
  1712. return next.preSibling();
  1713. } else if (parent) {
  1714. return parent.firstChild();
  1715. } else {
  1716. return null;
  1717. }
  1718. }
  1719. /**
  1720. * 获取最新id
  1721. *
  1722. * @param {function} callback
  1723. * @return {void}
  1724. */
  1725. function GetNewProjectId(count, callback) {
  1726. CommonAjax.post('/pm/api/getNewProjectID', {count: count}, function(data) {
  1727. callback(data);
  1728. });
  1729. }
  1730. /**
  1731. * 重命名项目
  1732. *
  1733. * @param {Number} projectId
  1734. * @param {String} newName
  1735. * @param {Number} parentID
  1736. * @param {function} callback
  1737. * @return {void}
  1738. */
  1739. function RenameProject(projectId, newName, parentID, callback) {
  1740. $.ajax({
  1741. type: "POST",
  1742. url: '/pm/api/renameProject',
  1743. data: {'data': JSON.stringify({"user_id": userID, "id": projectId, "newName": newName, "parentID": parentID})},
  1744. dataType: 'json',
  1745. cache: false,
  1746. timeout: 5000,
  1747. success: function(result){
  1748. if (result.error === 0) {
  1749. callback();
  1750. } else {
  1751. if(result.message === '同级目录已存在相同名称数据'){
  1752. setDangerInfo($('#rename-name-info'), `已存在“${newName}”`);
  1753. }
  1754. }
  1755. },
  1756. error: function(iqXHR, textStatus, errorThrown){
  1757. alert('error ' + textStatus + " " + errorThrown)
  1758. }
  1759. });
  1760. }
  1761. /**
  1762. * 转换当前树结构为zTree结构
  1763. *
  1764. * @param {Object} Tree
  1765. * @param {Object} zTreeObj
  1766. * @param {Object} filterNode
  1767. * @return {Mixed}
  1768. */
  1769. function ConvertTreeToZtree(Tree, zTreeObj, filterNode) {
  1770. let setting = {
  1771. data: {
  1772. simpleData: {
  1773. enable:true,
  1774. idKey: "id",
  1775. pIdKey: "pId",
  1776. rootPId: "-1"
  1777. }
  1778. }};
  1779. let zTreeData = [],
  1780. exportNodesData = function (nodes) {
  1781. nodes.forEach(function (node) {
  1782. if (node !== filterNode) {
  1783. var data = {};
  1784. data['id'] = node.data[Tree.setting.tree.id];
  1785. data['pId'] = node.pid();
  1786. data['name'] = node.data['name'];
  1787. data['isParent'] = node.data.projType === 'Folder';//(node.data.projType === 'Folder' && node.children.length === 0);
  1788. data['open'] = node.data.projType === 'Folder';//node.children.length !== 0;
  1789. zTreeData.push(data);
  1790. exportNodesData(node.children);
  1791. }
  1792. })
  1793. };
  1794. exportNodesData(Tree._root.children);
  1795. return $.fn.zTree.init(zTreeObj, setting, zTreeData);
  1796. }
  1797. /**
  1798. * 获取指定zTree节点
  1799. *
  1800. * @param {Object} zTreeObj
  1801. * @return {object}
  1802. */
  1803. function GetTargetTreeNode(zTreeObj) {
  1804. if (!zTreeObj || !projTreeObj.tree) {
  1805. return null;
  1806. }
  1807. let ztree_selected = zTreeObj.getSelectedNodes().length === 0 ? null : zTreeObj.getSelectedNodes()[0];
  1808. return ztree_selected ? projTreeObj.tree.findNode(ztree_selected.id) : null;
  1809. }
  1810. /**
  1811. * 根据指定id获取对应的工程专业
  1812. *
  1813. * @param {Array} engineeringList
  1814. * @return {String}
  1815. */
  1816. function getEngineeringHtml(engineeringList) {
  1817. let result = '<option value="">请选择对应的工程专业</option>';
  1818. if (engineeringList.length <= 0) {
  1819. return result;
  1820. }
  1821. let engineeringObject = {};
  1822. for(let tmp of engineering) {
  1823. engineeringObject[tmp.value] = tmp.name;
  1824. }
  1825. for(let tmp of engineeringList) {
  1826. if (engineeringObject[tmp.engineering] !== undefined) {
  1827. result += '<option value="'+ tmp.engineering +'">'+ engineeringObject[tmp.engineering] +'</option>';
  1828. }
  1829. }
  1830. return result;
  1831. }
  1832. /**
  1833. * 远程获取项目属性数据
  1834. *
  1835. * @param {Object} projectInfo
  1836. * @return {void}
  1837. */
  1838. function getProperty(projectInfo) {
  1839. if (projectInfo.property === undefined) {
  1840. return;
  1841. }
  1842. projectProperty = projectInfo.property;
  1843. // 写入专业工程相关
  1844. let engineeringHtml = getEngineeringHtml(projectProperty.engineeringList);
  1845. $("#tender-engineering").html(engineeringHtml);
  1846. // 填入计价规则
  1847. let valuationHtml = '<option value="'+ projectProperty.valuation +'">'+ projectProperty.valuationName +'</option>';
  1848. $("#tender-valuation").html(valuationHtml);
  1849. // 选中计价方式
  1850. $("input[name='tender_valuation_type']").attr('disabled', 'disabled').removeAttr('checked', 'checked');
  1851. $("input[name='tender_valuation_type'][value='"+ projectProperty.valuationType +"']")
  1852. .attr("checked", "checked").removeAttr('disabled', 'disabled');
  1853. }
  1854. /**
  1855. * 获取单价文件
  1856. *
  1857. * @param {Number} parentID
  1858. * @return {void}
  1859. */
  1860. function getUnitFile(parentID, callback) {
  1861. parentID = parseInt(parentID);
  1862. if (isNaN(parentID) && parentID <= 0) {
  1863. return;
  1864. }
  1865. $.ajax({
  1866. url: '/pm/api/getUnitFile',
  1867. type: 'post',
  1868. data: {'data': JSON.stringify({"user_id": userID, "parentID": parentID})},
  1869. dataType: 'json',
  1870. error: function() {
  1871. alert('数据传输错误!');
  1872. },
  1873. beforeSend: function() {
  1874. },
  1875. success: function(response) {
  1876. if (response.error === 1) {
  1877. alert('获取失败!');
  1878. } else {
  1879. if(callback){
  1880. callback(response);
  1881. }
  1882. }
  1883. }
  1884. });
  1885. }
  1886. /**
  1887. * 获取费率文件
  1888. *
  1889. * @param {Number} parentID
  1890. * @return {void}
  1891. */
  1892. function getFeeRateFile(parentID, callback) {
  1893. parentID = parseInt(parentID);
  1894. if (isNaN(parentID) && parentID <= 0) {
  1895. return;
  1896. }
  1897. $.ajax({
  1898. url: '/pm/api/getFeeRateFile',
  1899. type: 'post',
  1900. data: {'data': JSON.stringify({"user_id": userID, "parentID": parentID})},
  1901. dataType: 'json',
  1902. error: function() {
  1903. alert('数据传输错误!');
  1904. },
  1905. beforeSend: function() {
  1906. },
  1907. success: function(response) {
  1908. if (response.error === 1) {
  1909. alert('获取失败!');
  1910. } else {
  1911. if(callback){
  1912. callback(response);
  1913. }
  1914. }
  1915. }
  1916. });
  1917. }
  1918. /**
  1919. * 加载数据到侧边栏
  1920. *
  1921. * @return {void}
  1922. */
  1923. function setDataToSideBar() {
  1924. // 获取当前点击的数据
  1925. let that = projTreeObj;
  1926. let selectedItem = that.tree.selected;
  1927. let name = selectedItem.data.name;
  1928. let target = selectedItem.data.projType === projectType.project ? '#summary-project' : '#summary-engineering';
  1929. $(".side-content .p-3").hide();
  1930. $(target).show();
  1931. // 加载单价文件与费率文件
  1932. if (selectedItem.data.projType === projectType.project) {
  1933. let engineeringData = selectedItem.children !== null && selectedItem.children.children !== null ?
  1934. selectedItem.children : [];
  1935. /*if (engineeringData.length <= 0) {
  1936. return;
  1937. }*/
  1938. let unitPriceFileList = [];
  1939. let feeFileList = [];
  1940. let poj_tenders = getProjTenders(selectedItem);
  1941. getUnitFile(selectedItem.data.ID, function (response) {
  1942. unitPriceFileList = unitPriceFileList.concat(response.data);
  1943. $(target + '-unit-price-table tbody').empty();
  1944. set_file_table(target, poj_tenders, unitPriceFileList, fileType.unitPriceFile);
  1945. });
  1946. getFeeRateFile(selectedItem.data.ID, function (response) {
  1947. feeFileList = feeFileList.concat(response.data);
  1948. $(target + '-fee-table tbody').empty();
  1949. set_file_table(target, poj_tenders, feeFileList, fileType.feeRateFile);
  1950. });
  1951. }
  1952. }
  1953. //获取建设项目的全部单位工程
  1954. function getProjTenders(proj) {
  1955. let rst = [];
  1956. let engineerings = proj.children || null;
  1957. if (engineerings) {
  1958. for (let i = 0, len = engineerings.length; i < len; i++) {
  1959. let e_tenders = engineerings[i].children || null;
  1960. if (e_tenders && e_tenders.length > 0) {
  1961. rst = rst.concat(e_tenders);
  1962. }
  1963. }
  1964. }
  1965. return rst;
  1966. }
  1967. //单价、费率文件汇总信息的使用次数、使用该文件的单位工程
  1968. function getUsedObj(tenders, fileId, type){
  1969. let rst = Object.create(null), usedCount = 0, usedInfo = '';
  1970. rst.usedCount = 0;
  1971. rst.usedInfo = null;
  1972. for(let i = 0, len = tenders.length; i < len; i++){
  1973. if(tenders[i].data.property){
  1974. let theFile = type === fileType.unitPriceFile ? tenders[i].data.property.unitPriceFile || null : tenders[i].data.property.feeFile || null;
  1975. if(theFile && theFile.id == fileId){
  1976. usedCount ++;
  1977. usedInfo += tenders[i].data.name + '<br>';
  1978. }
  1979. }
  1980. }
  1981. if(usedCount > 0){
  1982. usedInfo = usedInfo.slice(0, usedInfo.length - 4);
  1983. rst.usedCount = usedCount;
  1984. rst.usedInfo = usedInfo;
  1985. }
  1986. return rst;
  1987. }
  1988. //单价、费率文件汇总界面交互
  1989. function bindEvents_file_table(jqS, usedObj, targetBody, type){
  1990. //悬浮显示删除和重命名按钮
  1991. $(jqS).hover(function(){
  1992. $('p',this).show();
  1993. },function(){
  1994. $('p', this).hide();
  1995. });
  1996. //删除
  1997. if(usedObj.usedCount > 0){//不可删除
  1998. $(jqS + ' p a:eq(0)').addClass('disabled');
  1999. $(jqS + ' p a:eq(0)').removeAttr('data-target');
  2000. }
  2001. else {
  2002. $(jqS + ' p a:eq(0)').on('click', function () {
  2003. let dispName = $(jqS + ' div:eq(0)')[0].childNodes[0].textContent;
  2004. //刷新删除弹出框内容
  2005. let delData = '删除"' + dispName + '"?';
  2006. $('#del-wj .modal-body h5').text(delData);
  2007. let attrId = $(jqS).attr('id');
  2008. let id = attrId.slice(5, attrId.length);
  2009. if(type === fileType.unitPriceFile){
  2010. id = parseInt(id);
  2011. }
  2012. let obj = Object.create(null);
  2013. obj.fileType = type;
  2014. obj.id = id;
  2015. fileDelObj = obj;
  2016. });
  2017. }
  2018. //重命名
  2019. $(jqS + ' p a:eq(1)').on('click', function () {
  2020. let fileObjs = getFileObj(targetBody, type);
  2021. let orgDispName = $(jqS + ' div:eq(0)')[0].childNodes[0].textContent;
  2022. let postFix = orgDispName.slice(orgDispName.length - 4, orgDispName.length);
  2023. let orgName = orgDispName.slice(0, orgDispName.length - 4);
  2024. $(jqS + ' input').val(orgName);
  2025. $(jqS + ' div:eq(0)').hide();
  2026. $(jqS + ' div:eq(1)').show();
  2027. //确认重命名
  2028. $(jqS + ' .btn-success').on('click', function () {
  2029. let attrId = $(jqS).attr('id');
  2030. let id = attrId.slice(5, attrId.length);
  2031. let newName = $(jqS + ' input').val().trim();
  2032. if(newName !== orgName){
  2033. if(hasThisFileName(fileObjs, newName)){
  2034. alert('本建设项目已存在该文件名,请重新输入!');
  2035. $(jqS + ' input').val(orgName);
  2036. return;
  2037. }
  2038. if(newName.trim().length === 0){
  2039. alert('文件名不可为空!');
  2040. $(jqS + ' input').val(orgName);
  2041. return;
  2042. }
  2043. //ajax
  2044. let updateObj = Object.create(null);
  2045. updateObj.fileType = type;
  2046. updateObj.updateType = 'update';
  2047. updateObj.updateData = Object.create(null);
  2048. if(type === fileType.unitPriceFile){
  2049. updateObj.updateData.id = parseInt(id);
  2050. //updateObj.updateData.id = id;
  2051. }
  2052. else if(type === fileType.feeRateFile){
  2053. updateObj.updateData.ID = id;
  2054. }
  2055. updateObj.updateData.name = newName;
  2056. a_updateFiles([updateObj], function () {
  2057. let newDispName = newName + postFix;
  2058. $(jqS + ' div:eq(0)')[0].childNodes[0].textContent = newDispName;
  2059. $(jqS + ' div:eq(0)').show();
  2060. $(jqS + ' div:eq(1)').hide();
  2061. });
  2062. }
  2063. let newDispName = newName + postFix;
  2064. $(jqS + ' div:eq(0)')[0].childNodes[0].textContent = newDispName;
  2065. $(jqS + ' div:eq(0)').show();
  2066. $(jqS + ' div:eq(1)').hide();
  2067. });
  2068. //取消重命名
  2069. $(jqS + ' .btn-secondary').on('click', function () {
  2070. $(jqS + ' div:eq(0)').show();
  2071. $(jqS + ' div:eq(1)').hide();
  2072. });
  2073. });
  2074. //悬浮框显示使用该文件的单位工程
  2075. $($(jqS)[0].nextSibling).popover({
  2076. placement:"bottom",
  2077. html:true,
  2078. trigger:"hover", //| focus
  2079. content: usedObj.usedInfo ? usedObj.usedInfo : ''
  2080. }
  2081. );
  2082. }
  2083. //更新单价、费率文件(删除、重命名)
  2084. function a_updateFiles(updateDatas, callback){
  2085. $.ajax({
  2086. type: 'post',
  2087. url: '/pm/api/updateFiles',
  2088. data: {data: JSON.stringify({user_id: userID, updateDatas: updateDatas})},
  2089. dataType: 'json',
  2090. success: function (result){
  2091. if(!result.error && callback){
  2092. callback();
  2093. }
  2094. }
  2095. })
  2096. }
  2097. function set_file_table(target, poj_tenders, fileList, type){
  2098. let fileCounter = 1;
  2099. for(let i = 0, len = fileList.length; i < len; i++){
  2100. let fileId = type === fileType.unitPriceFile ? fileList[i].id : fileList[i].ID;
  2101. let usedObj = getUsedObj(poj_tenders, fileId, type);
  2102. let usedHtml = usedObj.usedCount > 0 ? '<td class="text-center"><a href="javascript:void(0);">' + usedObj.usedCount + '</a></td>' : '<td class="text-center">' + usedObj.usedCount + '</td>';
  2103. let hoverHtml = '<p style="display: none"><a class="btn btn-sm" href="javascript:void(0);" data-toggle="modal" data-target="#del-wj">删除</a><a class="btn btn-sm" href="javascript:void(0);">重命名</a></p></div>';
  2104. let renHtml = '<div class="input-group" style="display: none;">'
  2105. + '<input class="form-control form-control-sm" value="">'
  2106. + '<span class="input-group-btn">'
  2107. + '<button class="btn btn-success btn-sm" type="button"><i class="fa fa-check"></i></button>'
  2108. + '</span>'
  2109. + '<span class="input-group-btn">'
  2110. + '<button class="btn btn-secondary btn-sm" type="button"><i class="fa fa-remove"></i></button>'
  2111. + '</span>'
  2112. + '</div></td>';
  2113. let fileTypeStr = type === fileType.unitPriceFile ? '单价文件' : '费率文件';
  2114. let fileHtml = '<tr><td>' + fileCounter + '</td><td id="file_' + fileId + '"><div>' + fileList[i].name + hoverHtml + renHtml + usedHtml + '</tr>';
  2115. fileCounter++;
  2116. let targetBody = type === fileType.unitPriceFile ? target + '-unit-price-table tbody' : target + '-fee-table tbody';
  2117. $(targetBody).append(fileHtml);
  2118. let jqS = '#file_' + fileId;
  2119. bindEvents_file_table(jqS, usedObj, targetBody, type);
  2120. }
  2121. }
  2122. function getFileObj(jqS, type){
  2123. let rst = [];
  2124. let trs = $('tr', jqS);
  2125. for(let i = 0, len = trs.length; i < len; i++){
  2126. let td = $('td:eq(1)', trs[i])[0];
  2127. let dispName = td.childNodes[0].childNodes[0].textContent;
  2128. let name = dispName.slice(0, dispName.length - 4);
  2129. let attrId = $(td).attr('id');
  2130. let id = attrId.slice(5, attrId.length);
  2131. if(type === fileType.unitPriceFile){
  2132. id = parseInt(id);
  2133. }
  2134. let obj = Object.create(null);
  2135. obj.id = id;
  2136. obj.name = name;
  2137. rst.push(obj);
  2138. }
  2139. return rst;
  2140. //let orgDispName = $(jqS + ' div:eq(0)')[0].childNodes[0].textContent;
  2141. }
  2142. function hasThisFileName(fileObjs, name){
  2143. for(let i = 0, len = fileObjs.length; i < len; i++){
  2144. if(fileObjs[i].name === name){
  2145. return true;
  2146. }
  2147. }
  2148. return false;
  2149. }