financial_summary.js 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. $(document).ready(function() {
  2. autoFlashHeight();
  3. postData('/financial/' + spid + '/summary/load', {}, function (result) {
  4. console.log(result);
  5. tenders = result.tenders;
  6. transferList = result.transferList;
  7. transferTenderList = result.transferTenderList;
  8. payList = result.payList;
  9. summaryObj.setTenderSelect(result.tenders);
  10. summaryObj.changeHtmlAndCharts(result.tenders, result.transferList, result.transferTenderList, result.payList);
  11. });
  12. $('#tender-select').on('changed.bs.select', function (e, clickedIndex, isSelected, previousValue) {
  13. const vals = $(this).val();
  14. if (vals.length === 0) {
  15. $('#tender-select').selectpicker('val', '0');
  16. } else if (clickedIndex !== 0 && vals.length > 1 && _.includes(vals, '0')) {
  17. $('#tender-select').selectpicker('val', _.without(vals, '0'));
  18. } else if (clickedIndex === 0 && isSelected) {
  19. $('#tender-select').selectpicker('val', '0');
  20. }
  21. });
  22. $('#search-btn').click(function () {
  23. const tenderSelects = $('#tender-select').val().map(function (item, index) {
  24. return parseInt(item);
  25. });
  26. // 判断是单还是多个标段
  27. const is_single = tenderSelects.length === 1 && tenderSelects[0] !== 0;
  28. const is_all = tenderSelects.length === 1 && tenderSelects[0] === 0;
  29. const startMonth = $('#start-month').val();
  30. const endMonth = $('#end-month').val();
  31. const condition = {};
  32. let newTransferList = _.cloneDeep(transferList);
  33. let newTransferTenderList = _.cloneDeep(transferTenderList);
  34. let newPayList = _.cloneDeep(payList);
  35. if (startMonth !== '' && endMonth !== '') {
  36. // 判断输入合法和endMonth大于startMonth
  37. if (!/^\d{4}-\d{2}$/.test(startMonth) || !/^\d{4}-\d{2}$/.test(endMonth)) {
  38. toastr.warning('请输入正确的日期格式');
  39. return;
  40. }
  41. if (startMonth > endMonth) {
  42. toastr.warning('结束日期不能小于开始日期');
  43. return;
  44. }
  45. newTransferList = _.filter(newTransferList, function (item) {
  46. return item.t_time >= startMonth && item.t_time <= endMonth;
  47. });
  48. newTransferTenderList = _.filter(newTransferTenderList, function (item) {
  49. return _.includes(_.map(newTransferList, 'id'), item.trid);
  50. });
  51. newPayList = _.filter(newPayList, function (item) {
  52. const thisMonth = moment(item.create_time).format('YYYY-MM');
  53. return thisMonth >= startMonth && thisMonth <= endMonth;
  54. });
  55. } else if (startMonth !== '' || endMonth !== '') {
  56. toastr.warning('请选择开始和结束日期查询');
  57. return;
  58. }
  59. newTransferTenderList = !is_all ? _.filter(newTransferTenderList, function (item) { return _.includes(tenderSelects, item.tid); }) : newTransferTenderList;
  60. newPayList = !is_all ? _.filter(newPayList, function (item) { return _.includes(tenderSelects, item.tid); }) : newPayList;
  61. const newTenders = !is_all ? _.filter(tenders, function (item) { return _.includes(tenderSelects, item.id); }) : tenders;
  62. summaryObj.changeHtmlAndCharts(newTenders, newTransferList, newTransferTenderList, newPayList, tenderSelects);
  63. });
  64. const summaryObj = {
  65. setTenderSelect: function (tenders) {
  66. let tenderSelectHtml = '<option value="0" selected>全部</option>';
  67. for (const tender of tenders) {
  68. tenderSelectHtml += `<option value="${tender.id}">${tender.name}</option>`;
  69. }
  70. $('#tender-select').html(tenderSelectHtml);
  71. $('#tender-select').selectpicker();
  72. },
  73. changeHtmlAndCharts: function (tenders, transferList, transferTenderList, payList, tenderSelects = [0]) {
  74. const transfer_price = tenderSelects !== [0] ? _.map(transferTenderList, 'hb_tp') : _.map(transferList, 'total_price');
  75. const transfer_sum_price = ZhCalc.sum(transfer_price);
  76. const pay_price = _.map(payList, 'total_price');
  77. const pay_sum_price = ZhCalc.sum(pay_price);
  78. const pend_sum_price = ZhCalc.sub(transfer_sum_price, pay_sum_price);
  79. const small_expenses_tp = _.map(payList, 'small_expenses_tp');
  80. const small_expenses_sum_price = ZhCalc.sum(small_expenses_tp);
  81. // 金额概况
  82. $('#transfer_price').text(transfer_sum_price.format2Str('#,##0.######'));
  83. $('#pay_price').text(pay_sum_price.format2Str('#,##0.######'));
  84. $('#pend_price').text(pend_sum_price.format2Str('#,##0.######'));
  85. // 支付进度
  86. const pay_progress = (ZhCalc.div(pay_sum_price, ZhCalc.add(pay_sum_price, pend_sum_price)) * 100).toFixed(0);
  87. const pend_progress = 100 - pay_progress;
  88. $('#pay_progress').html(`
  89. <div class="progress-bar bg-success" style="width: ${pay_progress}%;" data-placement="bottom" data-toggle="tooltip" data-original-title="累计支付:¥${pay_sum_price.format2Str('#,##0.######')}">${pay_progress}%</div>
  90. <div class="progress-bar bg-gray" style="width: ${pend_progress}%;" data-placement="bottom" data-toggle="tooltip" data-original-title="待支付:¥${pend_sum_price.format2Str('#,##0.######')}">${pend_progress}%</div>`);
  91. $('[data-toggle="tooltip"]').tooltip();
  92. // 资金支出明细
  93. let pay_used_html = '';
  94. payUsedOption.series[0].data = [];
  95. for (const used of usedList) {
  96. const usedPays = _.filter(payList, { used: used });
  97. if (usedPays.length > 0) {
  98. const used_price = _.map(usedPays, 'total_price');
  99. const used_sum_price = ZhCalc.sum(used_price)
  100. pay_used_html += `<tr class="text-center"><td>${used}</td><td>${used_sum_price.format2Str('#,##0.######')}</td> <td>${(pay_sum_price ? ZhCalc.div(used_sum_price, pay_sum_price) * 100 : 0).toFixed(2)}%</td></tr>`;
  101. payUsedOption.series[0].data.push({ value: used_sum_price, name: used });
  102. }
  103. }
  104. pay_used_html += `<tr class="text-center"><td><strong>合计</strong></td><td>${pay_sum_price.format2Str('#,##0.######')}</td> <td></td></tr>`;
  105. pay_used_html += `<tr class="text-center"><td>其中:小额支出</td><td>${small_expenses_sum_price.format2Str('#,##0.######')}</td><td>${(pay_sum_price ? ZhCalc.div(small_expenses_sum_price, pay_sum_price) * 100 : 0).toFixed(2)}%</td></tr>`;
  106. $('#pay_used_table').html(pay_used_html);
  107. // 标段支出概况图表
  108. tenderOption.xAxis[0].data = _.map(tenders, 'name');
  109. tenderOption.dataZoom[0].start = 0;
  110. tenderOption.dataZoom[0].end = computedPosition(tenders.length);
  111. tenderOption.series[0].data = [];
  112. tenderOption.series[1].data = [];
  113. for (const t of tenders) {
  114. const transferTenders = _.filter(transferTenderList, { tid: t.id });
  115. const transfer_tender_price = ZhCalc.sum(_.map(transferTenders, 'hb_tp'));
  116. const payTenders = _.filter(payList, { tid: t.id });
  117. const pay_tender_price = ZhCalc.sum(_.map(payTenders, 'total_price'));
  118. tenderOption.series[0].data.push(transfer_tender_price);
  119. tenderOption.series[1].data.push(pay_tender_price);
  120. }
  121. tenderChart.setOption(tenderOption);
  122. // 支出明细占比图表
  123. payUsedChart.setOption(payUsedOption);
  124. // 小额支出占比
  125. paySeOption.series[0].data = [
  126. { value: small_expenses_sum_price, name: '小额支出' },
  127. { value: ZhCalc.sub(pay_sum_price, small_expenses_sum_price), name: '其他' },
  128. ];
  129. paySeChart.setOption(paySeOption);
  130. },
  131. }
  132. let resizeTimer = null;
  133. $(window).bind('resize', function () {
  134. if (resizeTimer) clearTimeout(resizeTimer);
  135. resizeTimer = setTimeout(function () {
  136. echartsReset();
  137. }, 500);
  138. })
  139. function echartsReset() {
  140. tenderChart.resize();
  141. payUsedChart.resize();
  142. paySeChart.resize();
  143. }
  144. // 计算显示滚动条长度
  145. function computedPosition(xArrayLength) {
  146. if (xArrayLength >= 8) {
  147. return Math.floor(8 / xArrayLength * 100) > 100 ? 100 : Math.floor(8 / xArrayLength * 100);
  148. // return length <= 10 ? 35 : 100 - Math.floor(35 / length * 100);
  149. } else {
  150. return 100;
  151. }
  152. }
  153. //标段占比
  154. const tenderChart = echarts.init(document.getElementById('jlchart3'));
  155. const tenderOption = {
  156. tooltip: {
  157. trigger: 'axis',
  158. axisPointer: {
  159. type: 'shadow'
  160. }
  161. },
  162. dataZoom: [
  163. {
  164. // brushSelect:false,
  165. // zoomLock: false,
  166. type: 'slider',
  167. // show: true,
  168. // realtime: true,
  169. showdetail: false,
  170. showDataShadow: false,
  171. // // dataZoomIndex: 10,
  172. start: 0,
  173. end: 10,
  174. height: 10,
  175. bottom: '5%',
  176. },
  177. ],
  178. legend: {},
  179. grid: {
  180. left: '3%',
  181. right: '4%',
  182. bottom: '10%',
  183. containLabel: true
  184. },
  185. xAxis: [
  186. {
  187. type: 'category',
  188. data: [],
  189. axisLabel: {
  190. show: true,
  191. interval: 0,
  192. formatter: function(value) {
  193. var res = value;
  194. if(res.length > 8) {
  195. res = res.substring(0, 7) + "..";
  196. }
  197. return res;
  198. }
  199. }
  200. }
  201. ],
  202. yAxis: [
  203. {
  204. type: 'value'
  205. }
  206. ],
  207. series: [
  208. {
  209. name: '累计划拨',
  210. type: 'bar',
  211. emphasis: {
  212. focus: 'series'
  213. },
  214. data: []
  215. },
  216. {
  217. name: '累计支付',
  218. type: 'bar',
  219. stack: 'Ad',
  220. emphasis: {
  221. focus: 'series'
  222. },
  223. data: []
  224. }
  225. ]
  226. };
  227. // tenderChart.setOption(tenderOption);
  228. //费用明细占比//
  229. const payUsedChart = echarts.init(document.getElementById('jlchart1'));
  230. const payUsedOption = {
  231. color: ['#9489fa', '#f06464', '#f7af59', '#f0da49', '#71c16f', '#2aaaef', '#5690dd', '#bd88f5', '#009db2', '#0780cf'],
  232. //backgroundColor: '#343a40 ',
  233. tooltip: {
  234. trigger: 'item'
  235. },
  236. legend: {
  237. orient: 'vertical',
  238. left:'60%',
  239. right:'20%',
  240. top: 'middle'
  241. },
  242. series: [
  243. {
  244. name: '金额',
  245. type: 'pie',
  246. top:'20',
  247. bottom:'20',
  248. right:'40%',
  249. radius: ['80%'],
  250. avoidLabelOverlap: false,
  251. label: {
  252. show: false,
  253. position: 'right'
  254. },
  255. emphasis: {
  256. label: {
  257. show: true,
  258. fontSize: '40',
  259. fontWeight: 'bold'
  260. }
  261. },
  262. labelLine: {
  263. show: false
  264. },
  265. data: [],
  266. }
  267. ]
  268. };
  269. // 为echarts对象加载数据
  270. // myChart1.setOption(option1);
  271. //小额支出概况//
  272. var paySeChart = echarts.init(document.getElementById('jlchart2'));
  273. var paySeOption = {
  274. color: [ '#71c16f', '#2aaaef'],
  275. //backgroundColor: '#343a40 ',
  276. tooltip: {
  277. trigger: 'item'
  278. },
  279. legend: {
  280. orient: 'vertical',
  281. left:'60%',
  282. right: '20%',
  283. top: 'middle'
  284. },
  285. series: [
  286. {
  287. name: '金额',
  288. type: 'pie',
  289. top:'20',
  290. bottom:'20',
  291. right:'40%',
  292. radius: ['80%'],
  293. avoidLabelOverlap: false,
  294. label: {
  295. show: false,
  296. position: 'right'
  297. },
  298. emphasis: {
  299. label: {
  300. show: true,
  301. fontSize: '40',
  302. fontWeight: 'bold'
  303. }
  304. },
  305. labelLine: {
  306. show: false
  307. },
  308. data: []
  309. }
  310. ]
  311. };
  312. // 为echarts对象加载数据
  313. // myChart2.setOption(option2);
  314. $.subMenu({
  315. menu: '#sub-menu', miniMenu: '#sub-mini-menu', miniMenuList: '#mini-menu-list',
  316. toMenu: '#to-menu', toMiniMenu: '#to-mini-menu',
  317. key: 'menu.1.0.0',
  318. miniHint: '#sub-mini-hint', hintKey: 'menu.hint.1.0.1',
  319. callback: function (info) {
  320. if (info.mini) {
  321. $('.panel-title').addClass('fluid');
  322. $('#sub-menu').removeClass('panel-sidebar');
  323. } else {
  324. $('.panel-title').removeClass('fluid');
  325. $('#sub-menu').addClass('panel-sidebar');
  326. }
  327. autoFlashHeight();
  328. echartsReset();
  329. }
  330. });
  331. });