cs_tools.js 99 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098
  1. 'use strict';
  2. /**
  3. * cs_errorList:错误列表
  4. * 使用范围:
  5. * 台账分解(原报)、台账修订(原报)、计量台账(所有角色)
  6. *
  7. * posSearch & billsSearch:台账搜索相关
  8. * 使用范围:
  9. * 0号台账:台账分解、台账审批、台账修订、部位台账;
  10. * 期计量:计量台账、部位台账
  11. *
  12. * 所有工具均基于spreadjs,请放在gc.spread.sheets.all.10.0.1.min.js/spreadjs_zh.js之后
  13. *
  14. * @author Mai
  15. * @date
  16. * @version
  17. */
  18. const showSideTools = function (show) {
  19. const left = $('#left-view'), right = $('#right-view'), parent = left.parent();
  20. if (show) {
  21. right.show();
  22. autoFlashHeight();
  23. /**
  24. * right.show()后, parent被撑开成2倍left.height, 导致parent.width减少了10px
  25. * 第一次left.width调整后,parent的缩回left.height, 此时parent.width又增加了10px
  26. * 故需要通过最终的parent.width再计算一次left.width
  27. *
  28. * Q: 为什么不通过先计算left.width的宽度,以避免计算两次left.width?
  29. * A: 右侧工具栏不一定显示,当右侧工具栏显示过一次后,就必须使用parent和right来计算left.width
  30. *
  31. */
  32. //left.css('width', parent.width() - right.outerWidth());
  33. //left.css('width', parent.width() - right.outerWidth());
  34. const percent = 100 - right.outerWidth() /parent.width() * 100;
  35. left.css('width', percent + '%');
  36. } else {
  37. left.width(parent.width());
  38. right.hide();
  39. }
  40. };
  41. const showSelectTab = function(select, spread, afterShow) {
  42. const tab = $(select), tabPanel = $(tab.attr('content'));
  43. $('a', '.side-menu').removeClass('active');
  44. tab.addClass('active');
  45. $('.tab-content .tab-pane').removeClass('active');
  46. tabPanel.addClass('active');
  47. showSideTools(true);
  48. spread && spread.refresh();
  49. if (afterShow) afterShow();
  50. };
  51. (function($){
  52. /**
  53. * 错误列表
  54. * @param setting
  55. * {
  56. * tabSelector: 'a[content=#error-list]',
  57. * selector: '#error-list',
  58. * relaSpread: ledgerSpread,
  59. * storeKey: 'ledger-error-' + tenderId,
  60. * }
  61. * @returns {{spread: *}}
  62. */
  63. $.cs_errorList = function (setting) {
  64. if (!setting.spreadSetting) {
  65. setting.spreadSetting = {
  66. cols: [
  67. {title: '行号', field: 'serialNo', width: 50, formatter: '@', hAlign: 1},
  68. {
  69. title: '错误类型', field: 'errorType', width: 85, formatter: '@',
  70. getValue: function (x) {
  71. switch (x.errorType) {
  72. case 'gather': return '汇总错误';
  73. case 'qty': return '数量';
  74. case 'tp': return '金额';
  75. case 'over': return '超计';
  76. case 'sibling': return '项目节清单同层';
  77. case 'same_code': return '重复项目节编号';
  78. case 's2b_over_gxby': return '违规计量(工序报验)';
  79. case 's2b_over_dagl': return '违规计量(档案管理)';
  80. case 's2b_lost_gxby': return '遗漏计量(工序报验)';
  81. case 's2b_lost_dagl': return '遗漏计量(档案管理)';
  82. case 's2b_multi': return x.memo || '联动计量超限';
  83. case 'minus_cb': return '负变更清单漏计';
  84. case 'change_over': return '变更令超计';
  85. case 'settle': return '结算清单';
  86. default: return '';
  87. }
  88. }
  89. },
  90. {title: '清单编号', field: 'b_code', width: 85, formatter: '@'},
  91. {title: '清单名称', field: 'name', width: 165, formatter: '@'},
  92. {title: '备注', field: 'memo', width: 100, formatter: '@'},
  93. ],
  94. emptyRows: 0,
  95. headRows: 1,
  96. headRowHeight: [32],
  97. defaultRowHeight: 21,
  98. headerFont: '12px 微软雅黑',
  99. font: '12px 微软雅黑',
  100. selectedBackColor: '#fffacd',
  101. readOnly: true,
  102. };
  103. }
  104. const clearErrorData = function () {
  105. if (setting.storeKey) removeLocalCache(setting.storeKey);
  106. };
  107. const autoShowHistory = function (show) {
  108. if (setting.storeKey) {
  109. setLocalCache(setting.storeKey + '-showHis', show.toString());
  110. }
  111. };
  112. if (setting.selector && setting.relaSpread) {
  113. const resultId = setting.id + '-spread';
  114. const obj = $(setting.selector);
  115. obj.html(
  116. ' <div id="' + resultId + '" class="sjs-sh">\n' +
  117. ' </div>'
  118. );
  119. autoFlashHeight();
  120. const spread = SpreadJsObj.createNewSpread($('#' + resultId)[0]);
  121. const sheet = spread.getActiveSheet();
  122. SpreadJsObj.initSheet(sheet, setting.spreadSetting);
  123. spread.getActiveSheet().bind(spreadNS.Events.CellDoubleClick, function (e, info) {
  124. const sheet = info.sheet;
  125. const data = sheet.zh_data;
  126. if (!data) { return }
  127. const curBills = data[info.row];
  128. if (!curBills) { return }
  129. SpreadJsObj.locateTreeNode(setting.relaSpread.getActiveSheet(), curBills.ledger_id, true);
  130. if (setting.afterLocated) {
  131. setting.afterLocated();
  132. }
  133. });
  134. const loadErrorData = function (data, his = false) {
  135. const sourceTree = setting.relaSpread.getActiveSheet().zh_tree;
  136. if (!sourceTree) return;
  137. for (const d of data) {
  138. if (d.ledger_id) {
  139. d.serialNo = sourceTree.getNodeIndex(sourceTree.getItems(d.ledger_id)) + 1;
  140. } else if (d.lid) {
  141. const nodeIndex = sourceTree.nodes.findIndex(x => { return x.id === d.lid });
  142. if (nodeIndex >= 0) {
  143. d.serialNo = nodeIndex + 1;
  144. d.ledger_id = sourceTree.nodes[nodeIndex].ledger_id;
  145. }
  146. }
  147. }
  148. data.sort(function (a, b) {
  149. return a.serialNo ? (b.serialNo ? a.serialNo - b.serialNo : 1) : 1;
  150. });
  151. SpreadJsObj.loadSheetData(sheet, SpreadJsObj.DataType.Data, data);
  152. if (!his && setting.storeKey) {
  153. setLocalCache(setting.storeKey, JSON.stringify(data));
  154. }
  155. $(setting.tabSelector).show();
  156. };
  157. const showErrorList = function () {
  158. const tab = $(setting.tabSelector), tabPanel = $(tab.attr('content'));
  159. $('a', '.side-menu').removeClass('active');
  160. tab.addClass('active');
  161. $('.tab-content .tab-pane').removeClass('active');
  162. tabPanel.addClass('active');
  163. showSideTools(true);
  164. spread.refresh();
  165. if (setting.afterShow) setting.afterShow();
  166. };
  167. const loadHisErrorData = function () {
  168. if (setting.storeKey) {
  169. const storeStr = getLocalCache(setting.storeKey);
  170. const storeData = storeStr ? JSON.parse(storeStr) : [];
  171. if (storeData.length > 0) {
  172. loadErrorData(storeData, true);
  173. const showHis = getLocalCache(setting.storeKey + '-showHis');
  174. if (showHis === 'true') {
  175. showErrorList();
  176. removeLocalCache(setting.storeKey + '-showHis');
  177. }
  178. }
  179. }
  180. };
  181. return {
  182. spread: spread,
  183. loadErrorData: loadErrorData,
  184. clearErrorData: clearErrorData,
  185. loadHisErrorData: loadHisErrorData,
  186. show: showErrorList,
  187. autoShowHistory: autoShowHistory,
  188. };
  189. } else {
  190. const loadErrorData = function (data) {
  191. if (setting.storeKey) {
  192. setLocalCache(setting.storeKey, JSON.stringify(data));
  193. }
  194. };
  195. return {
  196. loadErrorData: loadErrorData,
  197. clearErrorData: clearErrorData,
  198. autoShowHistory: autoShowHistory,
  199. };
  200. }
  201. };
  202. $.ledger_checkList = function (setting) {
  203. const checkTypeText = [];
  204. for (const ct in setting.checkType) {
  205. checkTypeText[setting.checkType[ct].value] = setting.checkType[ct].text;
  206. }
  207. if (!setting.spreadSetting) {
  208. setting.spreadSetting = {
  209. cols: [
  210. {
  211. title: '类型', field: 'type', width: 150, formatter: '@',
  212. getValue: function (data){
  213. if (setting.checkType) {
  214. return data.memo || checkTypeText[data.type] || '';
  215. } else {
  216. return '';
  217. }
  218. }
  219. },
  220. {title: '行号', field: 'serialNo', hAlign: 1, width: 40, formatter: '@'},
  221. {title: '项目节编号\n(变更令号)', field: 'code', width: 80, formatter: '@'},
  222. {title: '清单编号', field: 'b_code', width: 80, formatter: '@'},
  223. {title: '名称', field: 'name', width: 150, formatter: '@'},
  224. ],
  225. emptyRows: 0,
  226. headRows: 1,
  227. headRowHeight: [32],
  228. defaultRowHeight: 21,
  229. headerFont: '12px 微软雅黑',
  230. font: '12px 微软雅黑',
  231. selectedBackColor: '#fffacd',
  232. readOnly: true,
  233. };
  234. }
  235. const clearCheckData = function () {
  236. if (setting.storeKey) removeLocalCache(setting.storeKey);
  237. };
  238. const autoShowHistory = function (show) {
  239. if (setting.storeKey) {
  240. setLocalCache(setting.storeKey + '-showHis', show.toString());
  241. }
  242. };
  243. if (setting.selector && setting.relaSpread) {
  244. const resultId = setting.id + '-spread';
  245. const obj = $(setting.selector);
  246. const dropdown = [];
  247. if (setting.checkType) {
  248. dropdown.push('<div class="dropdown">');
  249. dropdown.push('<button class="btn btn-sm btn-outline-primary dropdown-toggle" type="button" id="'+ setting.id + 'drop" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">所有类型</button>');
  250. dropdown.push('<div class="dropdown-menu" aria-labelledby="'+ setting.id + 'drop">');
  251. dropdown.push('<a class="dropdown-item" href="javascript: void(0);" check-type="all">所有类型</a>');
  252. for (const ct in setting.checkType) {
  253. dropdown.push('<a class="dropdown-item" href="javascript: void(0);" check-type="' + setting.checkType[ct].value +'">' + setting.checkType[ct].text + '</a>');
  254. }
  255. dropdown.push('</div>');
  256. dropdown.push('</div>');
  257. }
  258. obj.html(
  259. '<div class="sjs-bar">\n' +
  260. ' <div class="pb-1 d-flex">\n' + dropdown.join('') +
  261. ' <span class="ml-auto pr-2" id="' + setting.id + '-time">检查时间:2020-08-01 13:20:25</span>\n' +
  262. ' </div>\n' +
  263. '</div>' +
  264. '<div id="' + resultId + '" class="sjs-sh">\n' +
  265. '</div>'
  266. );
  267. autoFlashHeight();
  268. const spread = SpreadJsObj.createNewSpread($('#' + resultId)[0]);
  269. const sheet = spread.getActiveSheet();
  270. SpreadJsObj.initSheet(sheet, setting.spreadSetting);
  271. spread.getActiveSheet().bind(spreadNS.Events.CellDoubleClick, function (e, info) {
  272. const sheet = info.sheet;
  273. const data = sheet.zh_data;
  274. if (!data) { return }
  275. const curBills = data[info.row];
  276. if (!curBills) { return }
  277. SpreadJsObj.locateTreeNode(setting.relaSpread.getActiveSheet(), curBills.ledger_id, true);
  278. if (setting.afterLocated) {
  279. setting.afterLocated();
  280. }
  281. });
  282. const filterCheckData = function () {
  283. const filter = $(this).attr('check-type');
  284. $('#' + setting.id + 'drop').html(this.innerHTML);
  285. for (const d of sheet.zh_data) {
  286. if (filter === 'all') {
  287. d.visible = true;
  288. } else {
  289. d.visible = d.type == filter;
  290. }
  291. }
  292. SpreadJsObj.refreshTreeRowVisible(sheet);
  293. };
  294. $('a[check-type]').bind('click', filterCheckData);
  295. const hideCheckData = function () {
  296. const tab = $(setting.tabSelector), tabPanel = $(tab.attr('content'));
  297. if (tab.hasClass('active')) {
  298. $('a', '.side-menu').removeClass('active');
  299. tab.addClass('active');
  300. $('.tab-content .tab-pane').removeClass('active');
  301. tabPanel.addClass('active');
  302. showSideTools(false);
  303. if (spread) spread.refresh();
  304. if (setting.afterShow) setting.afterShow();
  305. tab.hide();
  306. }
  307. };
  308. const loadCheckData = function (data, his = false) {
  309. const sourceTree = setting.relaSpread.getActiveSheet().zh_tree;
  310. if (!sourceTree) return;
  311. for (const d of data.warning_data) {
  312. if (d.ledger_id) {
  313. d.serialNo = sourceTree.getNodeIndex(sourceTree.getItems(d.ledger_id)) + 1;
  314. } else if (d.lid) {
  315. const nodeIndex = sourceTree.nodes.findIndex(x => { return x.id === d.lid });
  316. if (nodeIndex >= 0) {
  317. d.serialNo = nodeIndex + 1;
  318. d.ledger_id = sourceTree.nodes[nodeIndex].ledger_id;
  319. }
  320. }
  321. }
  322. $('#' + setting.id + '-time').html('检查时间:' + moment(data.check_time).format('YYYY-MM-DD HH:mm:ss'));
  323. SpreadJsObj.loadSheetData(sheet, SpreadJsObj.DataType.Data, data.warning_data);
  324. if (!his && setting.storeKey) {
  325. setLocalCache(setting.storeKey, JSON.stringify(data));
  326. }
  327. $(setting.tabSelector).show();
  328. };
  329. const showCheckList = function () {
  330. const tab = $(setting.tabSelector), tabPanel = $(tab.attr('content'));
  331. $('a', '.side-menu').removeClass('active');
  332. tab.addClass('active');
  333. $('.tab-content .tab-pane').removeClass('active');
  334. tabPanel.addClass('active');
  335. showSideTools(true);
  336. spread.refresh();
  337. if (setting.afterShow) setting.afterShow();
  338. };
  339. const loadHisCheckData = function () {
  340. if (setting.storeKey) {
  341. const storeStr = getLocalCache(setting.storeKey);
  342. const storeData = storeStr ? JSON.parse(storeStr) : null;
  343. if (storeData) {
  344. loadCheckData(storeData, true);
  345. const showHis = getLocalCache(setting.storeKey + '-showHis');
  346. if (showHis === 'true') {
  347. showCheckList();
  348. removeLocalCache(setting.storeKey + '-showHis');
  349. }
  350. }
  351. }
  352. };
  353. return {
  354. spread: spread,
  355. loadCheckData: loadCheckData,
  356. clearCheckData: clearCheckData,
  357. loadHisCheckData: loadHisCheckData,
  358. show: showCheckList,
  359. hide: hideCheckData,
  360. autoShowHistory: autoShowHistory,
  361. };
  362. } else {
  363. const loadCheckData = function (data) {
  364. if (setting.storeKey) {
  365. setLocalCache(setting.storeKey, JSON.stringify(data));
  366. }
  367. };
  368. return {
  369. loadCheckData: loadCheckData,
  370. clearCheckData: clearCheckData,
  371. autoShowHistory: autoShowHistory,
  372. };
  373. }
  374. };
  375. $.posSearch = function (setting) {
  376. if (!setting.selector || !setting.searchSpread) return;
  377. const searchHtml =
  378. ' <div class="ml-2">\n' +
  379. ' <div class="input-group input-group-sm">\n' +
  380. ' <input type="text" class="form-control" placeholder="输入名称查找" id="pos-keyword">\n' +
  381. ' <div class="input-group-append">\n' +
  382. ' <span class="input-group-text" id="pos-search-hint">结果:0</span>\n' +
  383. ' </div>\n' +
  384. ' <div class="input-group-append" >\n' +
  385. ' <button class="btn btn-outline-secondary" type="button" title="上一个" id="search-pre-pos"><i class="fa fa-angle-double-left"></i></button>\n' +
  386. ' <button class="btn btn-outline-secondary" type="button" title="下一个" id="search-next-pos"><i class="fa fa-angle-double-right"></i></button>\n' +
  387. ' </div>\n' +
  388. ' </div>\n' +
  389. ' </div>\n';
  390. $(setting.selector).html(searchHtml);
  391. const sheet = setting.searchSpread.getActiveSheet();
  392. const searchObj = (function () {
  393. let resultArr = [];
  394. const search = function (keyword) {
  395. if (keyword && keyword !== '') {
  396. resultArr = [];
  397. const sortData = sheet.zh_data;
  398. if (sortData) {
  399. for (let i = 0, iLength = sortData.length; i < iLength; i++) {
  400. const sd = sortData[i];
  401. if (sd.name && sd.name.indexOf(keyword) > -1) {
  402. resultArr.push({index: i, data: sd});
  403. }
  404. }
  405. }
  406. } else {
  407. resultArr = [];
  408. }
  409. $('#pos-search-hint').html('结果:' + resultArr.length);
  410. };
  411. const searchAndLocate = function (keyword) {
  412. search(keyword);
  413. if (resultArr.length > 0) {
  414. const sel = sheet.getSelections()[0];
  415. const curRow = sel ? sel.row : 0;
  416. const pos = resultArr[0];
  417. if (pos.index !== curRow) {
  418. sheet.setSelection(pos.index, sel ? sel.col : 0, 1, 1);
  419. sheet.getParent().focus();
  420. sheet.showRow(pos.index, spreadNS.VerticalPosition.center);
  421. SpreadJsObj.reloadRowsBackColor(sheet, [pos.index, curRow]);
  422. }
  423. }
  424. };
  425. const locateNext = function () {
  426. if (resultArr.length > 0) {
  427. const sel = sheet.getSelections()[0];
  428. const curRow = sel ? sel.row : 0;
  429. let next = _.find(resultArr, function (d) {
  430. return d.index > curRow;
  431. });
  432. if (!next) next = resultArr[0];
  433. if (next.index !== curRow) {
  434. sheet.setSelection(next.index, sel ? sel.col : 0, 1, 1);
  435. sheet.getParent().focus();
  436. sheet.showRow(next.index, spreadNS.VerticalPosition.center);
  437. SpreadJsObj.reloadRowsBackColor(sheet, [next.index, curRow]);
  438. }
  439. }
  440. };
  441. const locatePre = function () {
  442. if (resultArr.length > 0) {
  443. const sel = sheet.getSelections()[0];
  444. const curRow = sel ? sel.row : 0;
  445. let next = _.findLast(resultArr, function (d) {
  446. return d.index < curRow;
  447. });
  448. if (!next) next = resultArr[resultArr.length - 1];
  449. if (next.index !== curRow) {
  450. sheet.setSelection(next.index, sel ? sel.col : 0, 1, 1);
  451. sheet.getParent().focus();
  452. sheet.showRow(next.index, spreadNS.VerticalPosition.center);
  453. SpreadJsObj.reloadRowsBackColor(sheet, [next.index, curRow]);
  454. }
  455. }
  456. };
  457. return {search, searchAndLocate, locateNext, locatePre};
  458. })();
  459. // $('#pos-keyword').bind('input propertychange', function () {
  460. // posSearch.search(this.value);
  461. // });
  462. $('#pos-keyword').bind('keydown', function(e){
  463. if (e.keyCode == 13) searchObj.searchAndLocate(this.value);
  464. });
  465. $('#search-pre-pos').click(function () {
  466. searchObj.locatePre();
  467. });
  468. $('#search-next-pos').click(function () {
  469. searchObj.locateNext();
  470. });
  471. return searchObj;
  472. };
  473. $.billsSearch = function (setting) {
  474. if (!setting.selector || !setting.searchSpread || !setting.resultSpreadSetting) return;
  475. if (!setting.searchRangeStr) setting.searchRangeStr = '项目节编号/清单编号/名称/台账数量';
  476. if (!setting.keyId) setting.keyId = 'ledger_id';
  477. const resultId = setting.id + '-search-result';
  478. const obj = $(setting.selector);
  479. let filter = [];
  480. if (setting.searchOver || setting.searchEmpty) {
  481. filter.push('<select class="input-group-text" id="search-filter">');
  482. filter.push('<option value="">台账</option>');
  483. if (setting.customSearch) {
  484. for (const cs of setting.customSearch) {
  485. if (cs.valid) filter.push('<option value="' + cs.key + '">' + cs.title + '</option>');
  486. }
  487. }
  488. filter.push('</select>');
  489. }
  490. obj.html(
  491. ' <div class="sjs-bar">\n' +
  492. ' <div class="input-group input-group-sm pb-1">\n' +
  493. ' <div class="input-group-prepend">\n' +
  494. filter.join('') +
  495. ' </div>' +
  496. ' <input id="searchKeyword" type="text" class="form-control" autocomplete="off" placeholder="可查找 ' + setting.searchRangeStr + '" aria-label="Recipient\'s username" aria-describedby="button-addon2">\n' +
  497. ' <div class="input-group-append">\n' +
  498. ' <button class="btn btn-outline-secondary" type="button"">搜索</button>\n' +
  499. ' </div>\n' +
  500. ' </div>\n' +
  501. ' </div>\n' +
  502. ' <div id="' + resultId + '" class="sjs-sh">\n' +
  503. ' </div>'
  504. );
  505. autoFlashHeight();
  506. const resultSpread = SpreadJsObj.createNewSpread($('#' + resultId)[0]);
  507. SpreadJsObj.initSheet(resultSpread.getActiveSheet(), setting.resultSpreadSetting);
  508. const searchSheet = setting.searchSpread.getActiveSheet();
  509. let searchResult = [];
  510. const search = function () {
  511. const filter = $('#search-filter').val();
  512. if (filter) {
  513. searchCustom(filter);
  514. } else {
  515. searchBills();
  516. }
  517. };
  518. const get18Bw = function(tree, data) {
  519. let parent = tree.getParent(data);
  520. while (parent && (!parent.code || /^[a-zA-Z]/.test(parent.code || ''))) {
  521. parent = tree.getParent(parent);
  522. }
  523. return parent ? parent.name : '';
  524. };
  525. const get08Bw = function(tree, data) {
  526. let parent = tree.getParent(data);
  527. let lastXmj = '', level4Xmj = '';
  528. while (parent) {
  529. if (parent.code && !lastXmj) lastXmj = parent.name;
  530. if (parent.code && parent.level === 4) level4Xmj = parent.name;
  531. parent = tree.getParent(parent);
  532. }
  533. return level4Xmj || lastXmj;
  534. };
  535. const getBw = function (data) {
  536. if (!data.b_code) return '';
  537. if (searchSheet.zh_dataType !== SpreadJsObj.DataType.Tree) return '';
  538. const sortTree = searchSheet.zh_tree;
  539. if (!sortTree.checkCodeType) return '';
  540. if (sortTree.checkCodeType() === '18') {
  541. return get18Bw(sortTree, data)
  542. } else {
  543. return get08Bw(sortTree, data);
  544. }
  545. };
  546. const searchBills = function () {
  547. const keyword = $('#searchKeyword', obj).val();
  548. const keyNum = _.toNumber(keyword);
  549. searchResult = [];
  550. const sortData = SpreadJsObj.getSortData(searchSheet);
  551. for (const node of sortData) {
  552. if (node.filter) continue;
  553. if ((node.code && node.code.indexOf(keyword) > -1) ||
  554. (node.b_code && node.b_code.indexOf(keyword) > -1) ||
  555. (node.name && node.name.indexOf(keyword) > -1) ||
  556. (!_.isNaN(keyNum) && checkZero(ZhCalc.sub(keyNum, node.quantity)))
  557. ) {
  558. const data = JSON.parse(JSON.stringify(node));
  559. data.visible = true;
  560. data.bw = getBw(data);
  561. searchResult.push(data);
  562. }
  563. }
  564. calculateCompletePercent(searchResult);
  565. calculateSum();
  566. SpreadJsObj.loadSheetData(resultSpread.getActiveSheet(), 'data', searchResult);
  567. };
  568. const getCheckFun = function (key) {
  569. const cs = setting.customSearch.find(function (x) {return x.key === key});
  570. return cs ? cs.check : null;
  571. };
  572. const getParentFun = function (key) {
  573. const cs = setting.customSearch.find(function (x) {return x.key === key});
  574. return cs && cs.parent !== undefined ? cs.parent : false;
  575. };
  576. const searchCustom = function (key) {
  577. const keyword = $('#searchKeyword', obj).val();
  578. const keyNum = _.toNumber(keyword);
  579. const checkFun = getCheckFun(key);
  580. searchResult = [];
  581. const sortData = SpreadJsObj.getSortData(searchSheet);
  582. const parentFun = getParentFun(key);
  583. for (const node of sortData) {
  584. if (node.children && node.children.length > 0 && !parentFun) continue;
  585. if (checkFun && checkFun(node)) {
  586. if (!keyword ||
  587. (node.code && node.code.indexOf(keyword) > -1) ||
  588. (node.b_code && node.b_code.indexOf(keyword) > -1) ||
  589. (node.name && node.name.indexOf(keyword) > -1) ||
  590. (!_.isNaN(keyNum) && checkZero(ZhCalc.sub(keyNum, node.quantity)))
  591. ) {
  592. const data = JSON.parse(JSON.stringify(node));
  593. data.visible = true;
  594. searchResult.push(data);
  595. }
  596. }
  597. }
  598. calculateCompletePercent(searchResult);
  599. calculateSum();
  600. SpreadJsObj.loadSheetData(resultSpread.getActiveSheet(), 'data', searchResult);
  601. };
  602. const calculateSum = function () {
  603. if (!searchResult || searchResult.length === 0 || !setting.calcSum) return;
  604. const sum = setting.calcSum(searchResult);
  605. if (sum) searchResult.unshift(sum);
  606. };
  607. const calculateCompletePercent = function (searchResult) {
  608. if (!searchResult) return;
  609. for (const sr of searchResult) {
  610. const base = ZhCalc.add(sr.total_price, sr.end_qc_tp);
  611. sr.complete_percent = base !== 0 ? ZhCalc.mul(ZhCalc.div(sr.end_gather_tp, base), 100, 2) : 0;
  612. }
  613. };
  614. $('input', obj).bind('keydown', function (e) {
  615. if (e.keyCode == 13) search();
  616. });
  617. $('button', obj).bind('click', () => {search()});
  618. resultSpread.getActiveSheet().bind(spreadNS.Events.CellDoubleClick, function (e, info) {
  619. const sheet = info.sheet;
  620. const data = sheet.zh_data;
  621. if (!data) { return }
  622. const curBills = data[info.row];
  623. if (!curBills || curBills[setting.keyId] === undefined) { return }
  624. SpreadJsObj.locateTreeNode(searchSheet, curBills[setting.keyId], true);
  625. if (setting.afterLocated) {
  626. setting.afterLocated();
  627. }
  628. });
  629. return {spread: resultSpread};
  630. };
  631. $.listSearch = function (setting) {
  632. if (!setting.selector || !setting.searchSpread || !setting.resultSpreadSetting) return;
  633. if (!setting.searchRangeStr) setting.searchRangeStr = '清单编号/名称';
  634. const resultId = setting.id + '-search-result';
  635. const obj = $(setting.selector);
  636. let filter = [];
  637. if (setting.searchOver || setting.searchEmpty) {
  638. filter.push('<select class="input-group-text" id="search-filter">');
  639. filter.push('<option value="">台账</option>');
  640. if (setting.customSearch) {
  641. for (const cs of setting.customSearch) {
  642. if (cs.valid) filter.push('<option value="' + cs.key + '">' + cs.title + '</option>');
  643. }
  644. }
  645. filter.push('</select>');
  646. }
  647. obj.html(
  648. ' <div class="sjs-bar">\n' +
  649. ' <div class="input-group input-group-sm pb-1">\n' +
  650. ' <div class="input-group-prepend">\n' +
  651. filter.join('') +
  652. ' </div>' +
  653. ' <input id="searchKeyword" type="text" class="form-control" autocomplete="off" placeholder="可查找 ' + setting.searchRangeStr + '" aria-label="Recipient\'s username" aria-describedby="button-addon2">\n' +
  654. ' <div class="input-group-append">\n' +
  655. ' <button class="btn btn-outline-secondary" type="button"">搜索</button>\n' +
  656. ' </div>\n' +
  657. ' </div>\n' +
  658. ' </div>\n' +
  659. ' <div id="' + resultId + '" class="sjs-sh">\n' +
  660. ' </div>'
  661. );
  662. autoFlashHeight();
  663. const resultSpread = SpreadJsObj.createNewSpread($('#' + resultId)[0]);
  664. SpreadJsObj.initSheet(resultSpread.getActiveSheet(), setting.resultSpreadSetting);
  665. const searchSheet = setting.searchSpread.getActiveSheet();
  666. let searchResult = [];
  667. const search = function () {
  668. const filter = $('#search-filter').val();
  669. if (filter) {
  670. searchCustom(filter);
  671. } else {
  672. searchList();
  673. }
  674. };
  675. const calulateSum = function () {
  676. if (searchResult.length === 0 || !setting.calcSum) return;
  677. searchResult.unshift(setting.calcSum(searchResult));
  678. };
  679. const searchList = function () {
  680. const keyword = $('#searchKeyword', obj).val();
  681. searchResult = [];
  682. const sortData = SpreadJsObj.getSortData(searchSheet);
  683. for (const [i, node] of sortData.entries()) {
  684. if (setting.check(node, keyword)) {
  685. const data = JSON.parse(JSON.stringify(node));
  686. data.searchIndex = i;
  687. data.visible = true;
  688. searchResult.push(data);
  689. }
  690. }
  691. calulateSum();
  692. SpreadJsObj.loadSheetData(resultSpread.getActiveSheet(), 'data', searchResult);
  693. };
  694. const getCheckFun = function (key) {
  695. const cs = setting.customSearch.find(function (x) {return x.key === key});
  696. return cs ? cs.check : null;
  697. };
  698. const searchCustom = function (key) {
  699. const keyword = $('#searchKeyword', obj).val();
  700. const checkFun = getCheckFun(key);
  701. searchResult = [];
  702. const sortData = SpreadJsObj.getSortData(searchSheet);
  703. for (const [i, node] of sortData.entries()) {
  704. if (checkFun && checkFun(node)) {
  705. if (setting.check(node, keyword)) {
  706. const data = JSON.parse(JSON.stringify(node));
  707. data.searchIndex = i;
  708. data.visible = true;
  709. searchResult.push(data);
  710. }
  711. }
  712. }
  713. calulateSum();
  714. SpreadJsObj.loadSheetData(resultSpread.getActiveSheet(), 'data', searchResult);
  715. };
  716. $('input', obj).bind('keydown', function (e) {
  717. if (e.keyCode == 13) search();
  718. });
  719. $('button', obj).bind('click', () => {search()});
  720. resultSpread.getActiveSheet().bind(spreadNS.Events.CellDoubleClick, function (e, info) {
  721. const cur = SpreadJsObj.getSelectObject(info.sheet);
  722. if (!cur || cur.searchIndex < 0) return;
  723. SpreadJsObj.locateRow(searchSheet, cur.searchIndex);
  724. if (setting.afterLocated) {
  725. setting.afterLocated();
  726. }
  727. });
  728. return {spread: resultSpread};
  729. };
  730. $.ledgerSearch = function (setting) {
  731. if (!setting.selector || !setting.ledger || !setting.resultSpreadSetting) return;
  732. if (!setting.ledger.billsTree) return;
  733. if (!setting.ledger.pos && !setting.ledger.getLedgerPos) return;
  734. if (!setting.searchRangeStr) setting.searchRangeStr = '项目节编号/清单编号/名称/台账数量';
  735. if (!setting.keyId) setting.keyId = 'ledger_id';
  736. const ledger = setting.ledger;
  737. const resultId = setting.id + '-search-result';
  738. const obj = $(setting.selector);
  739. let filter = [];
  740. if (setting.searchOver || setting.searchEmpty) {
  741. filter.push('<select class="input-group-text" id="search-filter">');
  742. filter.push('<option value="">台账</option>');
  743. if (setting.customSearch) {
  744. for (const cs of setting.customSearch) {
  745. if (cs.valid) filter.push('<option value="' + cs.key + '">' + cs.title + '</option>');
  746. }
  747. }
  748. filter.push('</select>');
  749. }
  750. obj.html(
  751. ' <div class="sjs-bar">\n' +
  752. ' <div class="input-group input-group-sm pb-1">\n' +
  753. ' <div class="input-group-prepend">\n' +
  754. filter.join('') +
  755. ' </div>' +
  756. ' <input id="searchKeyword" type="text" class="form-control" autocomplete="off" placeholder="可查找 ' + setting.searchRangeStr + '" aria-label="Recipient\'s username" aria-describedby="button-addon2">\n' +
  757. ' <div class="input-group-append">\n' +
  758. ' <button class="btn btn-outline-secondary" type="button"">搜索</button>\n' +
  759. ' </div>\n' +
  760. ' </div>\n' +
  761. ' </div>\n' +
  762. ' <div id="' + resultId + '" class="sjs-sh">\n' +
  763. ' </div>'
  764. );
  765. autoFlashHeight();
  766. const resultSpread = SpreadJsObj.createNewSpread($('#' + resultId)[0]);
  767. SpreadJsObj.initSheet(resultSpread.getActiveSheet(), setting.resultSpreadSetting);
  768. let searchResult = [];
  769. const defaultCheck = function(node, keyword) {
  770. const keyNum = _.toNumber(keyword);
  771. return (node.code && node.code.indexOf(keyword) > -1) ||
  772. (node.b_code && node.b_code.indexOf(keyword) > -1) ||
  773. (node.name && node.name.indexOf(keyword) > -1) ||
  774. (!_.isNaN(keyNum) && checkZero(ZhCalc.sub(keyNum, node.quantity)));
  775. };
  776. const getCheckFun = function (key) {
  777. const cs = setting.customSearch.find(function (x) {return x.key === key});
  778. return cs ? [cs.billsCheck || cs.check, cs.posCheck] : [null, null];
  779. };
  780. const search = function () {
  781. const filter = $('#search-filter').val();
  782. const [billsCheck, posCheck] = filter ? getCheckFun(filter) : [null, null];
  783. searchCustom(billsCheck || defaultCheck, posCheck || defaultCheck);
  784. };
  785. const get18Bw = function(tree, data) {
  786. let parent = tree.getParent(data);
  787. while (parent && (!parent.code || /^[a-zA-Z]/.test(parent.code || ''))) {
  788. parent = tree.getParent(parent);
  789. }
  790. return parent ? parent.name : '';
  791. };
  792. const get08Bw = function(tree, data) {
  793. let parent = tree.getParent(data);
  794. let lastXmj = '', level4Xmj = '';
  795. while (parent) {
  796. if (parent.code && !lastXmj) lastXmj = parent.name;
  797. if (parent.code && parent.level === 4) level4Xmj = parent.name;
  798. parent = tree.getParent(parent);
  799. }
  800. return level4Xmj || lastXmj;
  801. };
  802. const getBw = function (data) {
  803. if (!data.b_code) return '';
  804. const sortTree = ledger.billsTree;
  805. if (!sortTree.checkCodeType) return '';
  806. if (sortTree.checkCodeType() === '18') {
  807. return get18Bw(sortTree, data)
  808. } else {
  809. return get08Bw(sortTree, data);
  810. }
  811. };
  812. const searchCustom = function (billsCheckFun, posCheckFun) {
  813. const keyword = $('#searchKeyword', obj).val();
  814. searchResult = [];
  815. for (const node of ledger.billsTree.nodes) {
  816. if (billsCheckFun(node, keyword)) {
  817. const convertData = { lid: node[ledger.billsTree.setting.id], pid: -1 };
  818. for (const col of setting.resultSpreadSetting.cols) {
  819. if (col.field === 'bw') {
  820. convertData.bw = getBw(node);
  821. } else {
  822. convertData[col.field] = node[col.field];
  823. }
  824. }
  825. searchResult.push(convertData);
  826. }
  827. const posRange = ledger.pos ? ledger.pos.getLedgerPos(node.id) : ledger.getLedgerPos(node);
  828. if (!posRange || posRange.length === 0) continue;
  829. for (const p of posRange) {
  830. if (posCheckFun(p, keyword)) {
  831. const convertData = { lid: node[ledger.billsTree.setting.id], pid: p[ledger.pos ? ledger.pos.setting.id : ledger.posId] };
  832. for (const col of setting.resultSpreadSetting.cols) {
  833. convertData[col.field] = p[col.field];
  834. }
  835. searchResult.push(convertData);
  836. }
  837. }
  838. }
  839. calculateCompletePercent(searchResult);
  840. calculateSum();
  841. SpreadJsObj.loadSheetData(resultSpread.getActiveSheet(), 'data', searchResult);
  842. };
  843. const calculateSum = function () {
  844. if (!searchResult || searchResult.length === 0 || !setting.calcSum) return;
  845. const sum = setting.calcSum(searchResult);
  846. if (sum) searchResult.unshift(sum);
  847. };
  848. const calculateCompletePercent = function (searchResult) {
  849. if (!searchResult) return;
  850. for (const sr of searchResult) {
  851. const base = ZhCalc.add(sr.total_price, sr.end_qc_tp);
  852. sr.complete_percent = base !== 0 ? ZhCalc.mul(ZhCalc.div(sr.end_gather_tp, base), 100, 2) : 0;
  853. }
  854. };
  855. $('input', obj).bind('keydown', function (e) {
  856. if (e.keyCode == 13) search();
  857. });
  858. $('button', obj).bind('click', () => {search()});
  859. resultSpread.getActiveSheet().bind(spreadNS.Events.CellDoubleClick, function (e, info) {
  860. const sheet = info.sheet;
  861. const data = sheet.zh_data;
  862. if (!data) { return }
  863. const curBills = data[info.row];
  864. if (!curBills) return;
  865. setting.locate(curBills);
  866. });
  867. return {spread: resultSpread};
  868. };
  869. $.gclSearch = function(setting) {
  870. if (!setting.selector || !setting.gcl || !setting.resultSpreadSetting) return;
  871. if (!setting.gcl.bills) return;
  872. if (!setting.gcl.xmj && !setting.gcl.getBillsXmj) return;
  873. if (!setting.searchRangeStr) setting.searchRangeStr = '清单编号/名称/项目节编号/单位/分部/分项工程/细目/计量单元';
  874. if (!setting.keyId) setting.keyId = 'ledger_id';
  875. const gcl = setting.gcl;
  876. const resultId = setting.id + '-search-result';
  877. const obj = $(setting.selector);
  878. let filter = [];
  879. if (setting.searchOver || setting.searchEmpty) {
  880. filter.push('<select class="input-group-text" id="search-filter">');
  881. filter.push('<option value="">清单</option>');
  882. if (setting.customSearch) {
  883. for (const cs of setting.customSearch) {
  884. if (cs.valid) filter.push('<option value="' + cs.key + '">' + cs.title + '</option>');
  885. }
  886. }
  887. filter.push('</select>');
  888. }
  889. obj.html(
  890. ' <div class="sjs-bar">\n' +
  891. ' <div class="input-group input-group-sm pb-1">\n' +
  892. ' <div class="input-group-prepend">\n' +
  893. filter.join('') +
  894. ' </div>' +
  895. ' <input id="searchKeyword" type="text" class="form-control" autocomplete="off" placeholder="可查找 ' + setting.searchRangeStr + '" aria-label="Recipient\'s username" aria-describedby="button-addon2">\n' +
  896. ' <div class="input-group-append">\n' +
  897. ' <button class="btn btn-outline-secondary" type="button"">搜索</button>\n' +
  898. ' </div>\n' +
  899. ' </div>\n' +
  900. ' </div>\n' +
  901. ' <div id="' + resultId + '" class="sjs-sh">\n' +
  902. ' </div>'
  903. );
  904. autoFlashHeight();
  905. const resultSpread = SpreadJsObj.createNewSpread($('#' + resultId)[0]);
  906. SpreadJsObj.initSheet(resultSpread.getActiveSheet(), setting.resultSpreadSetting);
  907. let searchResult = [];
  908. const defaultCheck = function(node, keyword, fields) {
  909. for (const f of fields) {
  910. if (node[f] && node[f].indexOf(keyword) > -1) return true;
  911. }
  912. return false;
  913. };
  914. const getCheckFun = function (key) {
  915. const cs = setting.customSearch.find(function (x) {return x.key === key});
  916. return cs ? [cs.billsCheck, cs.xmjCheck] : [null, null];
  917. };
  918. const search = function () {
  919. const filter = $('#search-filter').val();
  920. const [billsCheck, xmjCheck] = filter ? getCheckFun(filter) : [null, null];
  921. searchCustom(billsCheck || defaultCheck, xmjCheck || defaultCheck);
  922. };
  923. const searchCustom = function (billsCheckFun, xmjCheckFun) {
  924. const keyword = $('#searchKeyword', obj).val();
  925. searchResult = [];
  926. for (const node of gcl.bills) {
  927. if (billsCheckFun(node, keyword, setting.searchField.bills)) {
  928. const convertData = { bid: node.id, xid: -1 };
  929. for (const col of setting.resultSpreadSetting.cols) {
  930. convertData[col.field] = node[col.field];
  931. }
  932. searchResult.push(convertData);
  933. }
  934. const xmjRange = gcl.xmj ? gcl.xmj.getBillsXmj(node.id) : gcl.getBillsXmj(node);
  935. if (!xmjRange || xmjRange.length === 0) continue;
  936. for (const x of xmjRange) {
  937. if (xmjCheckFun(x, keyword, setting.searchField.xmj)) {
  938. const convertData = { bid: node.id, xid: x.mx_id };
  939. for (const col of setting.resultSpreadSetting.cols) {
  940. convertData[col.field] = x[col.field];
  941. }
  942. searchResult.push(convertData);
  943. }
  944. }
  945. }
  946. // calculateSum();
  947. SpreadJsObj.loadSheetData(resultSpread.getActiveSheet(), 'data', searchResult);
  948. };
  949. const calculateSum = function () {
  950. if (!searchResult || searchResult.length === 0 || !setting.calcSum) return;
  951. const sum = setting.calcSum(searchResult);
  952. if (sum) searchResult.unshift(sum);
  953. };
  954. $('input', obj).bind('keydown', function (e) {
  955. if (e.keyCode == 13) search();
  956. });
  957. $('button', obj).bind('click', () => {search()});
  958. resultSpread.getActiveSheet().bind(spreadNS.Events.CellDoubleClick, function (e, info) {
  959. const sheet = info.sheet;
  960. const data = sheet.zh_data;
  961. if (!data) { return }
  962. const curBills = data[info.row];
  963. if (!curBills) return;
  964. setting.locate(curBills);
  965. });
  966. return {spread: resultSpread};
  967. };
  968. $.xmjSearch = function (setting) {
  969. if (!setting.selector || !setting.searchSpread) return;
  970. if (!setting.searchRangeStr) setting.searchRangeStr = '输入项目节编号、细目、计量单元查找';
  971. const searchHtml =
  972. ' <div class="ml-2">\n' +
  973. ' <div class="input-group input-group-sm">\n' +
  974. ' <input type="text" class="form-control" placeholder="'+ setting.searchRangeStr +'" id="xmj-keyword">\n' +
  975. ' <div class="input-group-append">\n' +
  976. ' <span class="input-group-text" id="xmj-search-hint">结果:0</span>\n' +
  977. ' </div>\n' +
  978. ' <div class="input-group-append" >\n' +
  979. ' <button class="btn btn-outline-secondary" type="button" title="上一个" id="search-pre-xmj"><i class="fa fa-angle-double-left"></i></button>\n' +
  980. ' <button class="btn btn-outline-secondary" type="button" title="下一个" id="search-next-xmj"><i class="fa fa-angle-double-right"></i></button>\n' +
  981. ' </div>\n' +
  982. ' </div>\n' +
  983. ' </div>\n';
  984. $(setting.selector).html(searchHtml);
  985. const sheet = setting.searchSpread.getActiveSheet();
  986. const searchObj = (function () {
  987. let resultArr = [];
  988. const search = function (keyword) {
  989. if (keyword && keyword !== '') {
  990. resultArr = [];
  991. const sortData = sheet.zh_data;
  992. if (sortData) {
  993. for (let i = 0, iLength = sortData.length; i < iLength; i++) {
  994. const sd = sortData[i];
  995. if ((sd.jldy && sd.jldy.indexOf(keyword) > -1) || (sd.code && sd.code.indexOf(keyword) > -1) || (sd.bwmx && sd.bwmx.indexOf(keyword) > -1)) {
  996. resultArr.push({index: i, data: sd});
  997. }
  998. }
  999. }
  1000. } else {
  1001. resultArr = [];
  1002. }
  1003. $('#xmj-search-hint').html('结果:' + resultArr.length);
  1004. };
  1005. const searchAndLocate = function (keyword) {
  1006. search(keyword);
  1007. const sel = sheet.getSelections()[0];
  1008. const curRow = sel ? sel.row : 0;
  1009. sheet.setSelection(0, sel ? sel.col : 0, 1, 1);
  1010. SpreadJsObj.reloadRowsBackColor(sheet, [0, curRow]);
  1011. if (resultArr.length > 0) {
  1012. const pos = resultArr[0];
  1013. if (pos.index !== curRow) {
  1014. sheet.setSelection(pos.index, sel ? sel.col : 0, 1, 1);
  1015. sheet.getParent().focus();
  1016. sheet.showRow(pos.index, spreadNS.VerticalPosition.center);
  1017. SpreadJsObj.reloadRowsBackColor(sheet, [pos.index, curRow]);
  1018. }
  1019. }
  1020. };
  1021. const locateNext = function () {
  1022. if (resultArr.length > 0) {
  1023. const sel = sheet.getSelections()[0];
  1024. const curRow = sel ? sel.row : 0;
  1025. let next = _.find(resultArr, function (d) {
  1026. return d.index > curRow;
  1027. });
  1028. if (!next) next = resultArr[0];
  1029. if (next.index !== curRow) {
  1030. sheet.setSelection(next.index, sel ? sel.col : 0, 1, 1);
  1031. sheet.getParent().focus();
  1032. sheet.showRow(next.index, spreadNS.VerticalPosition.center);
  1033. SpreadJsObj.reloadRowsBackColor(sheet, [next.index, curRow]);
  1034. }
  1035. }
  1036. };
  1037. const locatePre = function () {
  1038. if (resultArr.length > 0) {
  1039. const sel = sheet.getSelections()[0];
  1040. const curRow = sel ? sel.row : 0;
  1041. let next = _.findLast(resultArr, function (d) {
  1042. return d.index < curRow;
  1043. });
  1044. if (!next) next = resultArr[resultArr.length - 1];
  1045. if (next.index !== curRow) {
  1046. sheet.setSelection(next.index, sel ? sel.col : 0, 1, 1);
  1047. sheet.getParent().focus();
  1048. sheet.showRow(next.index, spreadNS.VerticalPosition.center);
  1049. SpreadJsObj.reloadRowsBackColor(sheet, [next.index, curRow]);
  1050. }
  1051. }
  1052. };
  1053. return {search, searchAndLocate, locateNext, locatePre};
  1054. })();
  1055. // $('#pos-keyword').bind('input propertychange', function () {
  1056. // posSearch.search(this.value);
  1057. // });
  1058. $('#xmj-keyword').bind('keydown', function(e){
  1059. if (e.keyCode == 13) searchObj.searchAndLocate(this.value);
  1060. });
  1061. $('#search-pre-xmj').click(function () {
  1062. searchObj.locatePre();
  1063. });
  1064. $('#search-next-xmj').click(function () {
  1065. searchObj.locateNext();
  1066. });
  1067. return searchObj;
  1068. };
  1069. $.billsTag = function (setting) {
  1070. if (!setting.selector || !setting.relaSpread) return;
  1071. if (!setting.tagType) setting.tagType = [
  1072. {tagClass: 'text-primary', color: '#007bff'},
  1073. {tagClass: 'text-success', color: '#28a745'},
  1074. {tagClass: 'text-danger', color: '#dc3545'},
  1075. {tagClass: 'text-warning', color: '#da9500'},
  1076. {tagClass: 'text-info', color: '#17a2b8'},
  1077. ];
  1078. if (!setting.key) setting.key = 'id';
  1079. if (!setting.treeId) setting.treeId = 'ledger_id';
  1080. const obj = $(setting.selector);
  1081. const relaTree = setting.relaTree;
  1082. const html = [], pageLength = 15;
  1083. let billsTags = [], classIndexes = [], billsIndexes = {}, curShow = [];
  1084. html.push('<div class="sjs-bar d-flex justify-content-between">');
  1085. // 下拉过滤
  1086. html.push('<div class="dropdown mr-2">');
  1087. html.push('<a class="btn btn-sm btn-outline-secondary" id="dmb-bills-tag" data-toggle="dropdown" title="优先显示" aria-expanded="false"><i class="fa fa-list-ol" id="bills-tag-filter"></i></a>');
  1088. html.push('<div class="dropdown-menu" aria-labelledby="dmb-bills-tag" style="min-width: 60px; position: absolute; transform: translate3d(0px, 22px, 0px); top: 0px; left: 0px; will-change: transform;" x-placement="bottom-start">');
  1089. html.push('<a class="dropdown-item" href="javascript: void(0);" tagType="all" ><i class="fa fa-list-ol"></i></a>');
  1090. for (const t of setting.tagType) {
  1091. html.push(`<a class="dropdown-item ${t.tagClass}" href="javascript: void(0);" tagType="${t.tagClass}" ><i class="fa fa-tag"></i></a>`);
  1092. t.tags = [];
  1093. classIndexes.push(t);
  1094. }
  1095. html.push('</div>', '</div>');
  1096. // 搜索框
  1097. html.push('<div class="input-group input-group-sm">');
  1098. html.push('<input type="text" class="form-control" placeholder="可查找 项目节编号 / 清单编号 /名称" id="bills-tag-keyword" autocomplete="off">');
  1099. html.push('<div class="input-group-append">', '<div class="input-group-cancel">',
  1100. '<a href="javascript: void(0);" id="bills-tag-clear" class="text-danger"><i class="fa fa-times-circle" title="移除搜索结果"></i></a>', '</div>',
  1101. '<button class="btn btn-outline-secondary" type="button" id="bills-tag-search">搜索</button>', '</div>');
  1102. html.push('</div>');
  1103. html.push('</div>');
  1104. // 书签列表
  1105. html.push('<div class="sjs-sh" style="overflow: auto;" id="bills-tag-list"></div>');
  1106. obj.html(html.join(''));
  1107. const clearViewTags = function () {
  1108. const viewTags = $('.tag-item', obj);
  1109. if (viewTags && viewTags.length > 0) viewTags.remove();
  1110. billsTags.forEach(x => {x.display = false});
  1111. };
  1112. const getTagEditHtml = function(tag) {
  1113. const tagClass = classIndexes.find(x => {return x.color === tag.color}) || {};
  1114. const tagHtml = [];
  1115. tagHtml.push('<div name="tag-edit">');
  1116. tagHtml.push('<div class="card-header p-2"><div class="dropdown">');
  1117. tagHtml.push(`<a class="pull-left mr-2" href="javascript: void(0);" id="tag-change-color" tag-color="${tag.color}" data-toggle="dropdown" aria-expanded="false"><i class="fa fa-tag ${tagClass.tagClass}" title="修改书签颜色"></i></a>`);
  1118. // 下拉选择颜色
  1119. tagHtml.push('<div class="dropdown-menu" aria-labelledby="tag-change-color" style="min-width:60px">',
  1120. '<a class="dropdown-item text-primary" href="javascript: void(0);" name="tag-color"><i class="fa fa-tint"></i></a>',
  1121. '<a class="dropdown-item text-success " href="javascript: void(0);" name="tag-color"><i class="fa fa-tint"></i></a>',
  1122. '<a class="dropdown-item text-danger " href="javascript: void(0);" name="tag-color"><i class="fa fa-tint"></i></a>',
  1123. '<a class="dropdown-item text-warning " href="javascript: void(0);" name="tag-color"><i class="fa fa-tint"></i></a>',
  1124. '<a class="dropdown-item text-info " href="javascript: void(0);" name="tag-color"><i class="fa fa-tint"></i></a>', '</div>');
  1125. tagHtml.push('</div>');
  1126. if (tag.node) {
  1127. const posHint = tag.pos ? ' - ' + tag.pos.name : '';
  1128. tagHtml.push((tag.node.code || '') + (tag.node.b_code || ''), ' / ', tag.node.name || '', posHint);
  1129. }
  1130. tagHtml.push('</div>');
  1131. tagHtml.push('<div class="card-body p-2">');
  1132. tagHtml.push('<p class="card-text">', '<textarea class="form-control form-control-sm p-1" id="tag-comment">', tag.comment, '</textarea>', '</p>');
  1133. tagHtml.push('<div class="d-flex justify-content-between">');
  1134. // 参与人可见
  1135. tagHtml.push('<div class="custom-control custom-switch mr-2">');
  1136. tagHtml.push('<input type="checkbox" class="custom-control-input custom-control-warning-input" id="tag-share"', tag.share ? 'checked' : '', '>');
  1137. tagHtml.push('<label class="custom-control-label custom-control-warning-label" for="tag-share" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="所有参与台账审批管理的用户都可以看到这条书签"><i class="fa fa-users"></i> 参与者可见</label>');
  1138. tagHtml.push('</div>');
  1139. // 编辑按钮
  1140. tagHtml.push('<div>', '<button type="button" class="btn btn-sm btn-outline-danger mr-3" id="tag-del"><i class="fa fa-close"></i> 删除书签</button>',
  1141. '<button type="button" class="btn btn-sm btn-outline-success mr-1" id="tag-edit-ok"><i class="fa fa-check"></i> 确定</button>',
  1142. '<button type="button" class="btn btn-sm btn-outline-secondary" id="tag-edit-cancel">取消</button>', '</div>');
  1143. tagHtml.push('</div>');
  1144. tagHtml.push('</div>');
  1145. tagHtml.push('</div>');
  1146. return tagHtml.join('');
  1147. };
  1148. const getTagDisplayHtml = function (tag) {
  1149. const tagClass = classIndexes.find(x => {return x.color === tag.color}) || {};
  1150. const tagHtml = [];
  1151. const hidden = tag.node.filter ? 'style="display: none;"' : '';
  1152. tagHtml.push(`<div name="tag-view" ${hidden}>`);
  1153. tagHtml.push('<div class="card-header p-2"><div class="dropdown">');
  1154. tagHtml.push(`<div class="pull-left mr-2"><i class="fa fa-tag ${tagClass.tagClass}"></i></div>`);
  1155. tagHtml.push('</div>');
  1156. if (tag.node) {
  1157. const posHint = tag.pos ? ' - ' + tag.pos.name : '';
  1158. tagHtml.push((tag.node.code || '') + (tag.node.b_code || ''), ' / ', tag.node.name || '', posHint);
  1159. }
  1160. if (tag.share) {
  1161. tagHtml.push(`<div class="pull-right"><i class="fa fa-users text-warning" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="所有参与台账审批管理的用户都可以看到这条书签"></i> <span>${tag.u_name}</span></div>`);
  1162. }
  1163. tagHtml.push('<div class="pull-right edit-tag-btn">');
  1164. const lid = tag.node ? tag.node[setting.treeId] : -1;
  1165. tagHtml.push(`<a class="mr-1" name="bills-tag-locate" href="javascript: void(0);" lid="${lid}" pos_id="${tag.pos_id}"><i class="fa fa-crosshairs"></i> 定位</a>`);
  1166. if (tag.uid === userID && !setting.readOnly) tagHtml.push(`<a href="javascript: void(0);" name="bills-tag-edit" tag-id="${tag.id}"><i class="fa fa-edit"></i> 编辑</a>`);
  1167. tagHtml.push('</div>');
  1168. if (tag.node && relaTree) {
  1169. const parents = relaTree.getAllParents(tag.node);
  1170. const parentName = [];
  1171. parents.forEach(p => { if (p.code && p.level > 1) parentName.push(p.name); });
  1172. if(parentName.length > 0) tagHtml.push(`<div>所属部位:${parentName.join('/')}</div>`);
  1173. }
  1174. tagHtml.push('<div class="card-body p-2">', '<p class="card-text">', tag.comment, '</p>', '</div>');
  1175. tagHtml.push('</div>');
  1176. return tagHtml.join('');
  1177. };
  1178. const searchTagsAndShow = function () {
  1179. const keyword = $('#bills-tag-keyword').val();
  1180. const filterClass = $('#bills-tag-filter')[0].classList;
  1181. const tagClass = filterClass.length > 2 ? filterClass[2] : null;
  1182. const ci = tagClass ? classIndexes.find(x => {return x.tagClass === tagClass}) : null;
  1183. curShow = billsTags.filter(x => {
  1184. if (ci && ci.color !== x.color) return false;
  1185. if (!keyword) return true;
  1186. if (x.node.code && x.node.code.indexOf(keyword) >= 0) return true;
  1187. if (x.node.b_code && x.node.b_code.indexOf(keyword) >= 0) return true;
  1188. if (x.node.name && x.node.name.indexOf(keyword) >= 0) return true;
  1189. return false;
  1190. });
  1191. reloadViewTags();
  1192. };
  1193. const refreshTagView = function (tag) {
  1194. const obj = $('#bills-tag-' + tag.id);
  1195. if (obj && obj.length > 0) {
  1196. obj.html(getTagDisplayHtml(tag));
  1197. }
  1198. };
  1199. const refreshBillsTagView = function (bills) {
  1200. const bi = billsIndexes[bills.id] || [];
  1201. for (const tag of bi) {
  1202. refreshTagView(tag);
  1203. }
  1204. };
  1205. const refreshPosTagView = function(pos) {
  1206. const posRange = pos instanceof Array ? pos : [pos];
  1207. for (const p of posRange) {
  1208. const bi = billsIndexes[p.lid] || [];
  1209. const pi = bi.filter(x => { return x.pos_id === p.id; });
  1210. for (const tag of pi) {
  1211. refreshTagView(tag);
  1212. }
  1213. }
  1214. };
  1215. const reviewTag = function (tag, isTop = false) {
  1216. const obj = $('#bills-tag-' + tag.id);
  1217. if (obj && obj.length > 0) {
  1218. obj.html(getTagDisplayHtml(tag));
  1219. } else {
  1220. const objHtml = [];
  1221. objHtml.push(`<div class="card border-primary my-2 tag-item" id="bills-tag-${tag.id}" tag-id="${tag.id}">`);
  1222. objHtml.push(getTagDisplayHtml(tag));
  1223. objHtml.push('</div>');
  1224. if (isTop) {
  1225. $('#bills-tag-list').prepend(objHtml.join(''));
  1226. } else {
  1227. $('#bills-tag-list').append(objHtml.join(''));
  1228. }
  1229. }
  1230. tag.display = true;
  1231. };
  1232. const loadViewTags = function () {
  1233. let showCount = 0;
  1234. for (const t of curShow) {
  1235. if (showCount >= pageLength) continue;
  1236. if (t.display) continue;
  1237. reviewTag(t);
  1238. showCount++;
  1239. }
  1240. };
  1241. const reloadViewTags = function () {
  1242. clearViewTags();
  1243. $("#bills-tag-lis").scrollTop(0);
  1244. loadViewTags();
  1245. };
  1246. const _addToBillsIndex = function(data, isTop = false) {
  1247. let bi = billsIndexes[data.lid];
  1248. if (!bi) {
  1249. bi = [];
  1250. billsIndexes[data.lid] = bi;
  1251. }
  1252. isTop ? bi.unshift(data) : bi.push(data);
  1253. };
  1254. const loadDatas = function (datas) {
  1255. billsTags = [];
  1256. billsIndexes = {};
  1257. for (const d of datas) {
  1258. if (!d.node) continue;
  1259. billsTags.push(d);
  1260. _addToBillsIndex(d);
  1261. }
  1262. curShow = billsTags;
  1263. reloadViewTags();
  1264. };
  1265. const updateDatas = function (data) {
  1266. const refresh = {};
  1267. if (data.add) {
  1268. billsTags.push(data.add);
  1269. _addToBillsIndex(data.add, true);
  1270. refresh.add = data.add;
  1271. }
  1272. if (data.del) {
  1273. const delTag = billsTags.find(x => {return x.id === data.del});
  1274. billsTags.splice(billsTags.indexOf(delTag), 1);
  1275. if (delTag.node) {
  1276. const bi = billsIndexes[delTag.node.id];
  1277. bi.splice(bi.indexOf(delTag), 1);
  1278. }
  1279. refresh.del = delTag;
  1280. }
  1281. if (data.update) {
  1282. const updateTag = billsTags.find(x => {return x.id === data.update.id});
  1283. for (const prop in data.update) {
  1284. updateTag[prop] = data.update[prop];
  1285. }
  1286. refresh.update = updateTag;
  1287. }
  1288. return refresh;
  1289. };
  1290. const updateDatasAndShow = function (data) {
  1291. const relaBills = [];
  1292. const refresh = updateDatas(data);
  1293. if (refresh.add) {
  1294. reviewTag(refresh.add, true);
  1295. relaBills.push(refresh.add.node);
  1296. }
  1297. if (refresh.del) {
  1298. $('#bills-tag-' + refresh.del.id).remove();
  1299. relaBills.push(refresh.del.node);
  1300. }
  1301. if (refresh.update) {
  1302. refreshTagView(refresh.update);
  1303. relaBills.push(refresh.update.node);
  1304. }
  1305. return relaBills;
  1306. };
  1307. const show = function () {
  1308. showSelectTab(setting.selector, null, setting.afterShow);
  1309. };
  1310. const getBillsTagsColor = function (id) {
  1311. const billsTags = billsIndexes[id] || [];
  1312. return billsTags.length > 0 ? billsTags.map(x => {return x.color}) : undefined;
  1313. };
  1314. const getBillsTagsInfo = function (id) {
  1315. const billsTags = billsIndexes[id] || [];
  1316. return billsTags.length > 0 ? billsTags.map(x => {
  1317. const tagClass = classIndexes.find(tc => {return tc.color === x.color}) || {};
  1318. return {color: x.color, comment: x.comment, tagClass: tagClass.tagClass};
  1319. }) : undefined;
  1320. };
  1321. const getPosTagsColor = function (lid, pos_id) {
  1322. const billsTags = billsIndexes[lid] || [];
  1323. const posTags = billsTags.filter(x => { return x.pos_id === pos_id; });
  1324. return posTags.length > 0 ? posTags.map(x => {return x.color}) : undefined;
  1325. };
  1326. const getPosTagsInfo = function(lid, pos_id) {
  1327. const billsTags = billsIndexes[lid] || [];
  1328. const posTags = billsTags.filter(x => { return x.pos_id === pos_id; });
  1329. return posTags.length > 0 ? posTags.map(x => {
  1330. const tagClass = classIndexes.find(tc => {return tc.color === x.color}) || {};
  1331. return {color: x.color, comment: x.comment, tagClass: tagClass.tagClass};
  1332. }) : undefined;
  1333. };
  1334. const afterDeleteBills = function (nodes) {
  1335. for (const node of nodes) {
  1336. const bi = billsIndexes[node.id];
  1337. if (!bi) continue;
  1338. delete billsIndexes[node.id];
  1339. for (const biTag of bi) {
  1340. const delTag = billsTags.find(x => {return x.id === biTag.id});
  1341. billsTags.splice(billsTags.indexOf(delTag), 1);
  1342. $('#bills-tag-' + delTag.id).remove();
  1343. }
  1344. }
  1345. };
  1346. const afterDeletePos = function (pos) {
  1347. for (const p of pos) {
  1348. const bi = billsIndexes[p.lid];
  1349. if (!bi) continue;
  1350. const pi = bi.filter(x => { return x.pos_id === p.id; });
  1351. for (const piTag of pi) {
  1352. const delTag = billsTags.find(x => {return x.id === piTag.id});
  1353. billsTags.splice(billsTags.indexOf(delTag), 1);
  1354. $('#bills-tag-' + delTag.id).remove();
  1355. bi.splice(pi.indexOf(piTag), 1);
  1356. }
  1357. }
  1358. };
  1359. $('body').on('click', '[name=bills-tag-locate]', function () {
  1360. const lid = parseInt(this.getAttribute('lid'));
  1361. const pos_id = this.getAttribute('pos_id');
  1362. SpreadJsObj.locateTreeNode(setting.relaSpread.getActiveSheet(), lid, true);
  1363. setting.afterLocated && setting.afterLocated(lid, pos_id);
  1364. });
  1365. $('body').on('click', '[name=bills-tag-edit]', function () {
  1366. const tagId = this.getAttribute('tag-id');
  1367. const tag = billsTags.find(x => {return x.id == tagId});
  1368. if (tag) {
  1369. const obj = $('#bills-tag-' + tag.id);
  1370. $('[name=tag-view]', obj).hide();
  1371. obj.append(getTagEditHtml(tag));
  1372. }
  1373. });
  1374. $('body').on('click', '#tag-edit-cancel', function () {
  1375. const obj = $('[name=tag-edit]').parent();
  1376. $('[name=tag-edit]').remove();
  1377. $('[name=tag-view]', obj).show();
  1378. });
  1379. $('body').on('click', '#tag-del', function () {
  1380. const obj = $('[name=tag-edit]').parent();
  1381. postData(setting.updateUrl, {del: parseInt(obj.attr('tag-id'))}, function (result) {
  1382. if (!result.del) return;
  1383. const bills = updateDatasAndShow(result);
  1384. setting.afterModify && setting.afterModify(bills);
  1385. });
  1386. });
  1387. $('body').on('click', '#tag-edit-ok', function () {
  1388. const obj = $('[name=tag-edit]').parent();
  1389. const data = {
  1390. id: parseInt(obj.attr('tag-id')),
  1391. share: $('#tag-share')[0].checked,
  1392. comment: $('#tag-comment').val(),
  1393. color: $('#tag-change-color').attr('tag-color'),
  1394. };
  1395. postData(setting.updateUrl, {update: data}, function (result) {
  1396. if (!result.update) return;
  1397. const bills = updateDatasAndShow(result);
  1398. setting.afterModify && setting.afterModify(bills);
  1399. });
  1400. });
  1401. $('body').on('click', '[name=tag-color]', function () {
  1402. const tagClass = this.classList[1];
  1403. const ci = classIndexes.find(tc => {return tc.tagClass === tagClass});
  1404. const tcc = $('#tag-change-color');
  1405. tcc.attr('tag-color', ci.color);
  1406. tcc.find('i').attr('class', 'fa fa-tag ' + tagClass);
  1407. });
  1408. $('body').on('click', '[tagType]', function () {
  1409. const tagClass = this.getAttribute('tagType');
  1410. if (tagClass === 'all') {
  1411. $('#bills-tag-filter').attr('class', 'fa fa-list-ol');
  1412. } else {
  1413. $('#bills-tag-filter').attr('class', 'fa fa-tag ' + tagClass);
  1414. }
  1415. searchTagsAndShow();
  1416. });
  1417. // 防抖
  1418. function debounce(fun, delay) {
  1419. let timer = null;
  1420. return function () {
  1421. if (timer) {
  1422. clearTimeout(timer);
  1423. }
  1424. timer = setTimeout(fun, delay);
  1425. }
  1426. }
  1427. $('#bills-tag-list').bind('scroll', debounce(function (e) {
  1428. const obj = $('#bills-tag-list');
  1429. var sum = obj[0].scrollHeight;
  1430. if (sum <= obj.scrollTop() + obj.height()) {
  1431. loadViewTags();
  1432. }
  1433. }, 300));
  1434. $('#bills-tag-clear').bind('click', () => {
  1435. if (!$('#bills-tag-keyword').val()) return;
  1436. $('#bills-tag-keyword').val('');
  1437. searchTagsAndShow();
  1438. });
  1439. $('#bills-tag-search').bind('click', () => {searchTagsAndShow();});
  1440. $('#bills-tag-keyword').bind('keydown', e => {if (e.keyCode === 13) searchTagsAndShow();});
  1441. return { loadDatas, updateDatasAndShow, show,
  1442. getBillsTagsColor, getBillsTagsInfo, getPosTagsColor, getPosTagsInfo,
  1443. refreshBillsTagView, refreshPosTagView,
  1444. afterDeleteBills, afterDeletePos }
  1445. };
  1446. $.sumLoadMiss = function (setting) {
  1447. if (!setting.spreadSetting) {
  1448. setting.spreadSetting = {
  1449. cols: [
  1450. { title: '清单编号', field: 'b_code', width: 80, formatter: '@' },
  1451. { title: '清单名称', field: 'name', width: 120, formatter: '@' },
  1452. { title: '单位', field: 'unit', width: 50, formatter: '@' },
  1453. { title: setting.type === 'stage' ? '合同数量' : '数量', field: 'qty', width: 60 },
  1454. { title: '变更数量', field: 'qc_qty', width: 60, visible: setting.type === 'stage' },
  1455. {
  1456. title: '类型', field: 'type', width: 100, getValue: function (x) {
  1457. switch (x.type) {
  1458. case 'less': return '数量变少';
  1459. case 'miss': return '找不到清单';
  1460. case 'qc-conflict': return '变更冲突(已调用变更令)';
  1461. default: return '';
  1462. }
  1463. }
  1464. }
  1465. ],
  1466. emptyRows: 0,
  1467. headRows: 1,
  1468. headRowHeight: [32],
  1469. defaultRowHeight: 21,
  1470. headerFont: '12px 微软雅黑',
  1471. font: '12px 微软雅黑',
  1472. selectedBackColor: '#fffacd',
  1473. readOnly: true,
  1474. };
  1475. }
  1476. const clearMissData = function () {
  1477. if (setting.storeKey) removeLocalCache(setting.storeKey);
  1478. };
  1479. const autoShowHistory = function (show) {
  1480. if (setting.storeKey) {
  1481. setLocalCache(setting.storeKey + '-showHis', show.toString());
  1482. }
  1483. };
  1484. if (setting.selector && setting.relaSpread) {
  1485. const resultId = setting.id + '-spread';
  1486. const obj = $(setting.selector);
  1487. obj.html(
  1488. ' <div id="' + resultId + '" class="sjs-sh">\n' +
  1489. ' </div>'
  1490. );
  1491. autoFlashHeight();
  1492. const spread = SpreadJsObj.createNewSpread($('#' + resultId)[0]);
  1493. const sheet = spread.getActiveSheet();
  1494. SpreadJsObj.initSheet(sheet, setting.spreadSetting);
  1495. spread.getActiveSheet().bind(spreadNS.Events.CellDoubleClick, function (e, info) {
  1496. if (!setting.relaSpread) return;
  1497. const sheet = info.sheet;
  1498. const data = sheet.zh_data;
  1499. if (!data) { return }
  1500. const curBills = data[info.row];
  1501. if (!curBills) { return }
  1502. if (curBills.ledger_id) {
  1503. SpreadJsObj.locateTreeNode(setting.relaSpread.getActiveSheet(), curBills.ledger_id, true);
  1504. if (setting.afterLocated) {
  1505. setting.afterLocated();
  1506. }
  1507. } else {
  1508. toastr.warning('找不到该清单');
  1509. }
  1510. });
  1511. const loadMissData = function (data, his = false) {
  1512. const sourceTree = setting.relaSpread.getActiveSheet().zh_tree;
  1513. if (!sourceTree) return;
  1514. for (const d of data) {
  1515. d.serialNo = sourceTree.getNodeIndex(sourceTree.getItems(d.ledger_id)) + 1;
  1516. }
  1517. data.sort(function (a, b) {
  1518. return a.serialNo - b.serialNo;
  1519. });
  1520. SpreadJsObj.loadSheetData(sheet, SpreadJsObj.DataType.Data, data);
  1521. if (!his && setting.storeKey) {
  1522. setLocalCache(setting.storeKey, JSON.stringify(data));
  1523. }
  1524. $(setting.tabSelector).show();
  1525. };
  1526. const showMissList = function () {
  1527. const tab = $(setting.tabSelector), tabPanel = $(tab.attr('content'));
  1528. $('a', '.side-menu').removeClass('active');
  1529. tab.addClass('active');
  1530. $('.tab-content .tab-pane').removeClass('active');
  1531. tabPanel.addClass('active');
  1532. showSideTools(true);
  1533. spread.refresh();
  1534. if (setting.afterShow) setting.afterShow();
  1535. };
  1536. const loadHisMissData = function () {
  1537. if (setting.storeKey) {
  1538. const storeStr = getLocalCache(setting.storeKey);
  1539. const storeData = storeStr ? JSON.parse(storeStr) : [];
  1540. if (storeData.length > 0) {
  1541. loadMissData(storeData, true);
  1542. const showHis = getLocalCache(setting.storeKey + '-showHis');
  1543. if (showHis === 'true') {
  1544. showMissList();
  1545. removeLocalCache(setting.storeKey + '-showHis');
  1546. }
  1547. }
  1548. }
  1549. };
  1550. return {
  1551. spread: spread,
  1552. loadMissData: loadMissData,
  1553. clearMissData: clearMissData,
  1554. loadHisMissData: loadHisMissData,
  1555. show: showMissList,
  1556. autoShowHistory: autoShowHistory,
  1557. };
  1558. } else {
  1559. const loadMissData = function (data) {
  1560. if (setting.storeKey) {
  1561. setLocalCache(setting.storeKey, JSON.stringify(data));
  1562. }
  1563. };
  1564. return {
  1565. loadErrorData: loadMissData,
  1566. clearErrorData: clearMissData,
  1567. autoShowHistory: autoShowHistory,
  1568. };
  1569. }
  1570. };
  1571. $.stdLib = function (setting) {
  1572. if (!setting.selector) return;
  1573. const obj = $(setting.selector);
  1574. const stdLibHtml = setting.libs.map(l => {
  1575. return `<option value="${l.id}" >${l.name}</option>`;
  1576. });
  1577. const relaSelect = {
  1578. showLevel: `std-${setting.stdType}-sl`,
  1579. searchText: `std-${setting.stdType}-st`,
  1580. searchResult: `std-${setting.stdType}-sr`,
  1581. searchPre: `std-${setting.stdType}-sp`,
  1582. searchNext: `std-${setting.stdType}-sn`,
  1583. searchClose: `std-${setting.stdType}-sc`,
  1584. addParent: `std-${setting.stdType}-wp`
  1585. };
  1586. const hiddenOption = setting.showAddType ? '' : 'style="display: none;"';
  1587. obj.html(
  1588. '<div class="sjs-bar d-flex">\n' +
  1589. ' <div class="dropdown mr-1">\n' +
  1590. ' <button class="btn btn-sm btn-light dropdown-toggle text-primary" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">\n' +
  1591. ' <i class="fa fa-list-ol"></i> 显示层级\n' +
  1592. ' </button>\n' +
  1593. ' <div class="dropdown-menu" aria-labelledby="dropdownMenuButton">\n' +
  1594. ` <a class="dropdown-item" href="javascript: void(0);" tag="1" name="${relaSelect.showLevel}">第一层</a>\n` +
  1595. ` <a class="dropdown-item" href="javascript: void(0);" tag="2" name="${relaSelect.showLevel}">第二层</a>\n` +
  1596. ` <a class="dropdown-item" href="javascript: void(0);" tag="3" name="${relaSelect.showLevel}">第三层</a>\n` +
  1597. ` <a class="dropdown-item" href="javascript: void(0);" tag="4" name="${relaSelect.showLevel}">第四层</a>\n` +
  1598. ` <a class="dropdown-item" href="javascript: void(0);" tag="5" name="${relaSelect.showLevel}">第五层</a>\n` +
  1599. ` <a class="dropdown-item" href="javascript: void(0);" tag="last" name="${relaSelect.showLevel}">最底层</a>\n` +
  1600. ' </div>\n' +
  1601. ' </div>' +
  1602. ` <div class="input-group input-group-sm pr-1"><select class="form-control form-control-sm col-auto">${stdLibHtml.join('')}</select></div>\n` +
  1603. ' <div class="ml-1">\n' +
  1604. ' <div class="dropdown">\n' +
  1605. ' <button class="btn btn-sm btn-outline-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">\n' +
  1606. ' <i class="fa fa-search"></i>\n' +
  1607. ' </button>\n' +
  1608. ' <div class="dropdown-menu dropdown-menu-right">\n' +
  1609. ' <div class="px-2 border-primary border-1 d-flex" style="width: 300px">\n' +
  1610. ' <div class="d-inline-block">\n' +
  1611. ' <div class="input-group input-group-sm mr-1">' +
  1612. ` <input type="text" class="form-control" placeholder="输入编号/名称查找" id="${relaSelect.searchText}">\n` +
  1613. ` <div class="input-group-append" ><span class="input-group-text" id="${relaSelect.searchResult}">结果:0</span></div>\n` +
  1614. ' <div class="input-group-append" >\n' +
  1615. ` <button class="btn btn-outline-secondary" type="button" title="上一个" id="${relaSelect.searchPre}"><i class="fa fa-angle-double-left"></i></button>\n` +
  1616. ` <button class="btn btn-outline-secondary" type="button" title="下一个" id="${relaSelect.searchNext}"><i class="fa fa-angle-double-right"></i></button>\n` +
  1617. ' </div>\n' +
  1618. ' </div>\n' +
  1619. ' </div>\n' +
  1620. ` <div class="d-inline-block"><button class="btn btn-light text-danger btn-sm ml-1" type="button" id="${relaSelect.searchClose}"><i class="fa fa-remove"></i></button></div>\n` +
  1621. ' </div>\n' +
  1622. ' </div>\n' +
  1623. ' </div>\n' +
  1624. ' </div>' +
  1625. ` <div class="ml-1" ${hiddenOption}>\n` +
  1626. ' <div class="dropdown">\n' +
  1627. ' <button class="btn btn-sm btn-outline-secondary dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">\n' +
  1628. ' <i class="fa fa-cog"></i>\n' +
  1629. ' </button>\n' +
  1630. ' <div class="dropdown-menu dropdown-menu-right">\n' +
  1631. ' <div class="px-2 border-primary border-1 d-flex" style="width: 100px">\n' +
  1632. ' <div class="form-check form-check-inline">\n' +
  1633. ` <input class="form-check-input pt-1" type="checkbox" id="${relaSelect.addParent}">\n` +
  1634. ` <label class="form-check-label" for="${relaSelect.addParent}">添加父项</label>\n` +
  1635. ' </div>' +
  1636. ' </div>\n' +
  1637. ' </div>\n' +
  1638. ' </div>\n' +
  1639. ' </div>' +
  1640. '</div>\n' +
  1641. `<div id="std-${setting.stdType}-spread" class="sjs-sh"></div>\n`
  1642. );
  1643. autoFlashHeight();
  1644. const pathTree = createNewPathTree('base', setting.treeSetting);
  1645. const spreadSetting = {
  1646. cols: [
  1647. {title: '名称', field: 'name', hAlign: 0, width: 180, formatter: '@'},
  1648. {title: '单位', field: 'unit', hAlign: 1, width: 60, formatter: '@'},
  1649. ],
  1650. treeCol: 0,
  1651. emptyRows: 0,
  1652. headRows: 1,
  1653. headRowHeight: [32],
  1654. defaultRowHeight: 21,
  1655. headerFont: '12px 微软雅黑',
  1656. font: '12px 微软雅黑',
  1657. headColWidth: [30],
  1658. selectedBackColor: '#fffacd',
  1659. readOnly: true,
  1660. stdType: setting.stdType,
  1661. };
  1662. spreadSetting.cols.unshift(setting.stdType === 'xmj'
  1663. ? {title: '项目节编号', field: 'code', hAlign: 0, width: 150, formatter: '@', cellType: 'tree'}
  1664. : {title: '清单编号', field: 'b_code', hAlign: 0, width: 150, formatter: '@', cellType: 'tree'});
  1665. const spread = SpreadJsObj.createNewSpread($(`#std-${setting.stdType}-spread`)[0]);
  1666. const sheet = spread.getActiveSheet();
  1667. if (setting.spreadSetting) setting.spreadSetting.stdType = setting.stdType;
  1668. SpreadJsObj.initSheet(sheet, setting.spreadSetting || spreadSetting);
  1669. if (setting.cellDoubleClick) sheet.bind(spreadNS.Events.CellDoubleClick, function(e, info) {
  1670. const stdSheet = info.sheet;
  1671. if (!stdSheet.zh_setting || !stdSheet.zh_tree) return;
  1672. const stdTree = stdSheet.zh_tree;
  1673. const stdNode = stdTree.nodes[info.row];
  1674. if (!stdNode) { return; }
  1675. const updateData = { postType: 'add-std', postData: { stdType: stdSheet.zh_setting.stdType, withParent: $(`#${relaSelect.addParent}`)[0].checked } };
  1676. const fullPath = stdTree.getAllParents(stdNode);
  1677. fullPath.push(stdNode);
  1678. fullPath.sort((x, y) => { return x.level - y.level; });
  1679. updateData.postData.stdData = fullPath.map(x => {
  1680. return { code: x.code || '', b_code: x.b_code || '', name: x.name, unit: x.unit, source: x.source, node_type: x.node_type }
  1681. });
  1682. updateData.postData.stdNode = stdNode;
  1683. setting.cellDoubleClick(updateData, stdNode, stdTree);
  1684. });
  1685. sheet.bind(spreadNS.Events.SelectionChanged, function (e, info) {
  1686. if (!info.oldSelections || !info.oldSelections[0] || info.newSelections[0].row !== info.oldSelections[0].row) {
  1687. SpreadJsObj.saveTopAndSelect(info.sheet, cacheKey.node);
  1688. console.log(SpreadJsObj.getSelectObject(info.sheet));
  1689. }
  1690. });
  1691. sheet.bind(spreadNS.Events.TopRowChanged, function (e, info) {
  1692. SpreadJsObj.saveTopAndSelect(info.sheet, cacheKey.node);
  1693. });
  1694. const cacheLib = [];
  1695. const cacheKey = {
  1696. lib: setting.page + '-' + setting.tid + '-' + setting.stdType,
  1697. };
  1698. $('select', setting.selector).change(function () {
  1699. loadLib(parseInt(this.value), true);
  1700. });
  1701. (function (select, sheet) {
  1702. $(select).click(function () {
  1703. if (!sheet.zh_tree) return;
  1704. const tag = $(this).attr('tag');
  1705. const tree = sheet.zh_tree;
  1706. setTimeout(() => {
  1707. switch (tag) {
  1708. case "1":
  1709. case "2":
  1710. case "3":
  1711. case "4":
  1712. case "5":
  1713. tree.expandByLevel(parseInt(tag));
  1714. SpreadJsObj.refreshTreeRowVisible(sheet);
  1715. break;
  1716. case "last":
  1717. tree.expandByCustom(() => { return true; });
  1718. SpreadJsObj.refreshTreeRowVisible(sheet);
  1719. break;
  1720. }
  1721. }, 100);
  1722. });
  1723. })(`a[name=${relaSelect.showLevel}]`, sheet);
  1724. const loadLib = function(listId, reload = false) {
  1725. cacheKey.node = cacheLib.lib + '-' + listId;
  1726. const locateMemory = function () {
  1727. if (!reload) {
  1728. SpreadJsObj.loadTopAndSelect(sheet, cacheKey.node);
  1729. } else {
  1730. removeLocalCache(cacheKey.node);
  1731. }
  1732. };
  1733. const cacheData = cacheLib.find(function (lib) {
  1734. return lib.id === listId;
  1735. });
  1736. if (cacheData) {
  1737. pathTree.loadDatas(cacheData.data);
  1738. SpreadJsObj.loadSheetData(sheet, 'tree', pathTree);
  1739. locateMemory();
  1740. setLocalCache(cacheKey.lib, listId);
  1741. } else {
  1742. postData(`/std-lib/get-data`, {stdType: setting.stdType, list_id: listId}, function (data) {
  1743. cacheLib.push({id: listId, data: data});
  1744. pathTree.loadDatas(data);
  1745. SpreadJsObj.loadSheetData(sheet, 'tree', pathTree);
  1746. locateMemory();
  1747. setLocalCache(cacheKey.lib, listId);
  1748. });
  1749. }
  1750. };
  1751. const _loadCacheLib = function() {
  1752. let libId = getLocalCache(cacheKey.lib);
  1753. if (libId) {
  1754. $('select', setting.selector).val(libId);
  1755. loadLib(parseInt(libId));
  1756. } else {
  1757. loadLib(parseInt($('select', setting.selector).val()));
  1758. }
  1759. };
  1760. _loadCacheLib();
  1761. const searchObj = {
  1762. result: [],
  1763. cur: 0,
  1764. searchStdNode: function() {
  1765. const keyword = $(`#${relaSelect.searchText}`).val();
  1766. searchObj.result = keyword ? pathTree.nodes.filter(x => {
  1767. return x.code.indexOf(keyword) >= 0 || x.b_code.indexOf(keyword) >= 0 || x.name.indexOf(keyword) >= 0;
  1768. }) : [];
  1769. // searchObj.result = [];
  1770. // for (const x of pathTree.nodes) {
  1771. // if (x.code.indexOf(keyword) >= 0 || x.b_code.indexOf(keyword) >= 0 || x.name.indexOf(keyword) >= 0) {
  1772. // searchObj.result.push(x);
  1773. // }
  1774. // }
  1775. $(`#${relaSelect.searchResult}`)[0].innerText = `结果:${searchObj.result.length}`;
  1776. searchObj.cur = 0;
  1777. if (searchObj.result.length > 0) {
  1778. SpreadJsObj.locateTreeNode(sheet, pathTree.getNodeKey(searchObj.result[searchObj.cur]));
  1779. }
  1780. },
  1781. searchPre: function () {
  1782. if (searchObj.result.length === 0) return;
  1783. searchObj.cur = searchObj.cur === 0 ? searchObj.result.length - 1 : this.cur - 1;
  1784. SpreadJsObj.locateTreeNode(sheet, pathTree.getNodeKey(searchObj.result[searchObj.cur]), true);
  1785. },
  1786. searchNext: function () {
  1787. if (searchObj.result.length === 0) return;
  1788. searchObj.cur = searchObj.cur === searchObj.result.length - 1 ? 0 : searchObj.cur + 1;
  1789. SpreadJsObj.locateTreeNode(sheet, pathTree.getNodeKey(searchObj.result[searchObj.cur]), true);
  1790. },
  1791. clear: function () {
  1792. $(`#${relaSelect.searchText}`).val('');
  1793. $(`#${relaSelect.searchResult}`)[0].innerText = `结果:${0}`;
  1794. searchObj.result = [];
  1795. searchObj.cur = 0;
  1796. }
  1797. };
  1798. $(`#${relaSelect.searchText}`).change(searchObj.searchStdNode);
  1799. $(`#${relaSelect.searchPre}`).click(function (e) {
  1800. searchObj.searchPre();
  1801. e.stopPropagation();
  1802. });
  1803. $(`#${relaSelect.searchNext}`).click(function (e) {
  1804. searchObj.searchNext();
  1805. e.stopPropagation();
  1806. });
  1807. $(`#${relaSelect.searchClose}`).click(function (e) {
  1808. searchObj.clear();
  1809. e.stopPropagation();
  1810. });
  1811. return { spread }
  1812. };
  1813. $.gljLib = function (setting) {
  1814. if (!setting.selector) return;
  1815. const obj = $(setting.selector);
  1816. const stdLibHtml = setting.libs.map(l => {
  1817. return `<option value="${l.id}" >${l.name}</option>`;
  1818. });
  1819. const relaSelect = {
  1820. showLevel: `std-${setting.stdType}-sl`,
  1821. searchText: `std-${setting.stdType}-st`,
  1822. searchResult: `std-${setting.stdType}-sr`,
  1823. searchPre: `std-${setting.stdType}-sp`,
  1824. searchNext: `std-${setting.stdType}-sn`,
  1825. searchClose: `std-${setting.stdType}-sc`,
  1826. };
  1827. obj.html(
  1828. '<div class="sjs-bar d-flex">\n' +
  1829. ` <div class="input-group input-group-sm pr-1"><select class="form-control form-control-sm col-auto">${stdLibHtml.join('')}</select></div>\n` +
  1830. ' <div class="ml-1">\n' +
  1831. ' <div class="dropdown">\n' +
  1832. ' <button class="btn btn-sm btn-outline-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">\n' +
  1833. ' <i class="fa fa-search"></i>\n' +
  1834. ' </button>\n' +
  1835. ' <div class="dropdown-menu dropdown-menu-right">\n' +
  1836. ' <div class="px-2 border-primary border-1 d-flex" style="width: 300px">\n' +
  1837. ' <div class="d-inline-block">\n' +
  1838. ' <div class="input-group input-group-sm mr-1">' +
  1839. ` <input type="text" class="form-control" placeholder="输入编号/名称查找" id="${relaSelect.searchText}">\n` +
  1840. ` <div class="input-group-append" ><span class="input-group-text" id="${relaSelect.searchResult}">结果:0</span></div>\n` +
  1841. ' <div class="input-group-append" >\n' +
  1842. ` <button class="btn btn-outline-secondary" type="button" title="上一个" id="${relaSelect.searchPre}"><i class="fa fa-angle-double-left"></i></button>\n` +
  1843. ` <button class="btn btn-outline-secondary" type="button" title="下一个" id="${relaSelect.searchNext}"><i class="fa fa-angle-double-right"></i></button>\n` +
  1844. ' </div>\n' +
  1845. ' </div>\n' +
  1846. ' </div>\n' +
  1847. ` <div class="d-inline-block"><button class="btn btn-light text-danger btn-sm ml-1" type="button" id="${relaSelect.searchClose}"><i class="fa fa-remove"></i></button></div>\n` +
  1848. ' </div>\n' +
  1849. ' </div>\n' +
  1850. ' </div>\n' +
  1851. ' </div>' +
  1852. '</div>\n' +
  1853. `<div id="std-${setting.stdType}-spread" class="${setting.spreadClassCss ? setting.spreadClassCss : 'sjs-sh'}"></div>\n`
  1854. );
  1855. autoFlashHeight();
  1856. const pathTree = createNewPathTree('base', setting.treeSetting);
  1857. const spreadSetting = {
  1858. cols: [
  1859. {title: '名称', field: 'name', hAlign: 0, width: 180, formatter: '@'},
  1860. {title: '单位', field: 'unit', hAlign: 1, width: 60, formatter: '@'},
  1861. ],
  1862. treeCol: 0,
  1863. emptyRows: 0,
  1864. headRows: 1,
  1865. headRowHeight: [32],
  1866. defaultRowHeight: 21,
  1867. headerFont: '12px 微软雅黑',
  1868. font: '12px 微软雅黑',
  1869. headColWidth: [30],
  1870. selectedBackColor: '#fffacd',
  1871. readOnly: true,
  1872. stdType: setting.stdType,
  1873. };
  1874. spreadSetting.cols.unshift(setting.stdType === 'xmj'
  1875. ? {title: '项目节编号', field: 'code', hAlign: 0, width: 150, formatter: '@', cellType: 'tree'}
  1876. : {title: '清单编号', field: 'b_code', hAlign: 0, width: 150, formatter: '@', cellType: 'tree'});
  1877. const spread = SpreadJsObj.createNewSpread($(`#std-${setting.stdType}-spread`)[0]);
  1878. const sheet = spread.getActiveSheet();
  1879. SpreadJsObj.initSheet(sheet, setting.spreadSetting ? setting.spreadSetting : spreadSetting);
  1880. if (setting.cellDoubleClick) sheet.bind(spreadNS.Events.CellDoubleClick, setting.cellDoubleClick);
  1881. sheet.bind(spreadNS.Events.SelectionChanged, function (e, info) {
  1882. if (!info.oldSelections || !info.oldSelections[0] || info.newSelections[0].row !== info.oldSelections[0].row) {
  1883. SpreadJsObj.saveTopAndSelect(info.sheet, cacheKey.node);
  1884. }
  1885. });
  1886. sheet.bind(spreadNS.Events.TopRowChanged, function (e, info) {
  1887. SpreadJsObj.saveTopAndSelect(info.sheet, cacheKey.node);
  1888. });
  1889. const cacheLib = [];
  1890. const cacheKey = {
  1891. lib: setting.page + '-' + setting.tid + '-' + setting.stdType,
  1892. };
  1893. $('select', setting.selector).change(function () {
  1894. loadLib(parseInt(this.value), true);
  1895. });
  1896. const loadLib = function(listId, reload = false) {
  1897. cacheKey.node = cacheLib.lib + '-' + listId;
  1898. const locateMemory = function () {
  1899. if (!reload) {
  1900. SpreadJsObj.loadTopAndSelect(sheet, cacheKey.node);
  1901. } else {
  1902. removeLocalCache(cacheKey.node);
  1903. }
  1904. };
  1905. const cacheData = cacheLib.find(function (lib) {
  1906. return lib.id === listId;
  1907. });
  1908. if (cacheData) {
  1909. pathTree.loadDatas(cacheData.data);
  1910. SpreadJsObj.loadSheetData(sheet, 'tree', pathTree);
  1911. locateMemory();
  1912. setLocalCache(cacheKey.lib, listId);
  1913. } else {
  1914. postData(`/std-lib/get-data`, {stdType: setting.stdType, list_id: listId}, function (data) {
  1915. cacheLib.push({id: listId, data: data});
  1916. pathTree.loadDatas(data);
  1917. SpreadJsObj.loadSheetData(sheet, 'tree', pathTree);
  1918. locateMemory();
  1919. setLocalCache(cacheKey.lib, listId);
  1920. });
  1921. }
  1922. };
  1923. const _loadCacheLib = function() {
  1924. let libId = getLocalCache(cacheKey.lib);
  1925. if (libId) {
  1926. $('select', setting.selector).val(libId);
  1927. loadLib(parseInt(libId));
  1928. } else {
  1929. loadLib(parseInt($('select', setting.selector).val()));
  1930. }
  1931. };
  1932. _loadCacheLib();
  1933. const searchObj = {
  1934. result: [],
  1935. cur: 0,
  1936. searchStdNode: function() {
  1937. const keyword = $(`#${relaSelect.searchText}`).val();
  1938. searchObj.result = keyword ? pathTree.nodes.filter(x => {
  1939. return x.code.indexOf(keyword) >= 0 || x.name.indexOf(keyword) >= 0;
  1940. }) : [];
  1941. // searchObj.result = [];
  1942. // for (const x of pathTree.nodes) {
  1943. // if (x.code.indexOf(keyword) >= 0 || x.b_code.indexOf(keyword) >= 0 || x.name.indexOf(keyword) >= 0) {
  1944. // searchObj.result.push(x);
  1945. // }
  1946. // }
  1947. $(`#${relaSelect.searchResult}`)[0].innerText = `结果:${searchObj.result.length}`;
  1948. searchObj.cur = 0;
  1949. if (searchObj.result.length > 0) {
  1950. SpreadJsObj.locateTreeNode(sheet, pathTree.getNodeKey(searchObj.result[searchObj.cur]));
  1951. }
  1952. },
  1953. searchPre: function () {
  1954. if (searchObj.result.length === 0) return;
  1955. searchObj.cur = searchObj.cur === 0 ? searchObj.result.length - 1 : this.cur - 1;
  1956. SpreadJsObj.locateTreeNode(sheet, pathTree.getNodeKey(searchObj.result[searchObj.cur]), true);
  1957. },
  1958. searchNext: function () {
  1959. if (searchObj.result.length === 0) return;
  1960. searchObj.cur = searchObj.cur === searchObj.result.length - 1 ? 0 : searchObj.cur + 1;
  1961. SpreadJsObj.locateTreeNode(sheet, pathTree.getNodeKey(searchObj.result[searchObj.cur]), true);
  1962. },
  1963. clear: function () {
  1964. $(`#${relaSelect.searchText}`).val('');
  1965. $(`#${relaSelect.searchResult}`)[0].innerText = `结果:${0}`;
  1966. searchObj.result = [];
  1967. searchObj.cur = 0;
  1968. }
  1969. };
  1970. $(`#${relaSelect.searchText}`).change(searchObj.searchStdNode);
  1971. $(`#${relaSelect.searchPre}`).click(function (e) {
  1972. searchObj.searchPre();
  1973. e.stopPropagation();
  1974. });
  1975. $(`#${relaSelect.searchNext}`).click(function (e) {
  1976. searchObj.searchNext();
  1977. e.stopPropagation();
  1978. });
  1979. $(`#${relaSelect.searchClose}`).click(function (e) {
  1980. searchObj.clear();
  1981. e.stopPropagation();
  1982. });
  1983. return { spread }
  1984. };
  1985. })(jQuery);