| New file |
| | |
| | |  |
| | | <!DOCTYPE html> |
| | | <html> |
| | | <head> |
| | | <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> |
| | | <title>è®¾å¤æ¯æ¥è¿è¡ç¶ææ¥è¡¨</title> |
| | | <meta name="renderer" content="webkit"> |
| | | <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> |
| | | <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"> |
| | | <link rel="stylesheet" href="../../../layuiadmin/layui/css/layui.css" media="all"> |
| | | <link rel="stylesheet" href="../../../layuiadmin/style/admin.css" media="all"> |
| | | <script src="../../../layuiadmin/layui/layui.js"></script> |
| | | <script src="../../../layuiadmin/Scripts/json2.js"></script> |
| | | <script src="../../../layuiadmin/Scripts/jquery-1.4.1.js"></script> |
| | | <script src="../../../layuiadmin/Scripts/webConfig.js"></script> |
| | | <script src="../../../layuiadmin/PubCustom.js"></script> |
| | | <script src="../../../layuiadmin/zgqCustom/zgqCustom.js"></script> |
| | | <script src="../../../layuiadmin/HideButton.js"></script> |
| | | <script src='../../../layuiadmin/lib/extend/echarts.min.js'></script> |
| | | <style type="text/css"> |
| | | * { |
| | | margin: 0; |
| | | padding: 0; |
| | | box-sizing: border-box; |
| | | } |
| | | |
| | | html, body { |
| | | height: 100%; |
| | | } |
| | | |
| | | .page-container { |
| | | height: 100%; |
| | | padding: 10px; |
| | | display: flex; |
| | | flex-direction: column; |
| | | } |
| | | |
| | | .query-bar { |
| | | background: #fff; |
| | | padding: 10px 15px; |
| | | border-radius: 6px; |
| | | margin-bottom: 10px; |
| | | flex-shrink: 0; |
| | | } |
| | | |
| | | .summary-row { |
| | | display: flex; |
| | | flex-wrap: wrap; |
| | | margin-bottom: 10px; |
| | | flex-shrink: 0; |
| | | } |
| | | |
| | | .chart-container { |
| | | background: #fff; |
| | | border-radius: 6px; |
| | | padding: 8px; |
| | | flex: 1; |
| | | overflow: auto; |
| | | min-height: 0; |
| | | display: grid; |
| | | grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); |
| | | gap: 8px; |
| | | } |
| | | |
| | | .chart-box { |
| | | margin: 4px; |
| | | border: 1px solid #eee; |
| | | border-radius: 4px; |
| | | background: #fafbfc; |
| | | position: relative; |
| | | min-height: 260px; |
| | | display: flex; |
| | | align-items: stretch; |
| | | justify-content: stretch; |
| | | } |
| | | |
| | | .empty-tip { |
| | | position: absolute; |
| | | left: 0; |
| | | top: 0; |
| | | width: 100%; |
| | | height: 100%; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | color: #999; |
| | | font-size: 12px; |
| | | } |
| | | |
| | | .summary-card { |
| | | margin: 4px; |
| | | border: 1px solid #eee; |
| | | border-radius: 4px; |
| | | background: #fafbfc; |
| | | text-align: center; |
| | | padding: 8px 4px; |
| | | min-width: 200px; |
| | | } |
| | | |
| | | .summary-card.total-card { |
| | | background: linear-gradient(135deg, #1e9fff 0%, #5fb3ff 100%); |
| | | border-color: #1e9fff; |
| | | } |
| | | |
| | | .summary-card.total-card .summary-number, |
| | | .summary-card.total-card .summary-label { |
| | | color: #fff; |
| | | } |
| | | |
| | | .summary-number { |
| | | font-size: 16px; |
| | | font-weight: bold; |
| | | color: #1e9fff; |
| | | } |
| | | |
| | | .summary-label { |
| | | font-size: 11px; |
| | | color: #888; |
| | | margin-top: 2px; |
| | | } |
| | | </style> |
| | | </head> |
| | | <body> |
| | | <div class="page-container"> |
| | | <div class="query-bar"> |
| | | <form class="layui-form" action="" lay-filter="component-form-group"> |
| | | <div class="layui-collapse"> |
| | | <div class="layui-colla-item"> |
| | | <div class="layui-colla-title layui-inline"> |
| | | <div class="layui-inline"><span>æ´å¤</span></div> |
| | | </div> |
| | | <div class="layui-inline"> |
| | | <label class="layui-form-label" style="width:100px;">æ¥æé´é</label> |
| | | <div class="layui-input-block"> |
| | | <select name="HInitTimeCycle" id="HInitTimeCycle" class="ForFilteringSchemes" lay-filter="HInitTimeCycle" style="width:190px;"> |
| | | </select> |
| | | </div> |
| | | </div> |
| | | <div class="layui-inline"> |
| | | <label class="layui-form-label" style="width:100px;">å¼å§æ¥æ</label> |
| | | <div class="layui-input-block"> |
| | | <input type="date" class="layui-input ForFilteringSchemes" id="HBeginDate" style="width:160px;"> |
| | | </div> |
| | | </div> |
| | | <div class="layui-inline"> |
| | | <label class="layui-form-label" style="width:100px;">ç»ææ¥æ</label> |
| | | <div class="layui-input-block"> |
| | | <input type="date" class="layui-input ForFilteringSchemes" id="HEndDate" style="width:160px;"> |
| | | </div> |
| | | </div> |
| | | <button class="layui-btn layuiadmin-btn-order" type="button" lay-submit="" lay-filter="btnSearch" id="btnSearch"> |
| | | <i class="layui-icon layui-icon-search layuiadmin-button-btn"></i> |
| | | </button> |
| | | <button class="layui-btn layuiadmin-btn-order" type="button" lay-submit="" lay-filter="btnReSearch" id="btnReSearch" style="padding:0 5px">éç½®</button> |
| | | </div> |
| | | <div class="layui-colla-content"> |
| | | </div> |
| | | </div> |
| | | </form> |
| | | </div> |
| | | |
| | | <div class="summary-row" id="summaryRow"></div> |
| | | <div class="chart-container" id="chartContainer"></div> |
| | | </div> |
| | | |
| | | <script> |
| | | layui.config({ |
| | | base: '../../../layuiadmin/' |
| | | }).extend({ |
| | | index: 'lib/index', |
| | | }).use(['index', 'form', 'element'], function () { |
| | | |
| | | var $ = layui.$, layer = layui.layer, form = layui.form; |
| | | var chartInstances = {}; |
| | | var chartConfigKeys = []; |
| | | |
| | | // å¾è¡¨é
ç½® |
| | | var ChartConfig = { |
| | | kaiban: { chartTitle: 'å¼çåç»è®¡', chartType: 'bar', dataTableIndex: 0 }, |
| | | tinggong: { chartTitle: 'åå·¥æèµ·åç»è®¡', chartType: 'bar', dataTableIndex: 1 }, |
| | | jieban: { chartTitle: 'ç»çåç»è®¡', chartType: 'pie', dataTableIndex: 2 }, |
| | | gongxuliuzhuan: { chartTitle: 'å·¥åºæµè½¬å¡ç»è®¡', chartType: 'pie', dataTableIndex: 3 }, |
| | | gongxuliuzhuanpaigong: { chartTitle: 'å·¥åºæµè½¬å¡æ´¾å·¥ç»è®¡', chartType: 'bar', dataTableIndex: 4 }, |
| | | gongxujinzhan: { chartTitle: 'å·¥åºè¿ç«æ¥æ¶ç»è®¡', chartType: 'bar', dataTableIndex: 5 }, |
| | | gongxuchuzhanhuibao: { chartTitle: 'å·¥åºåºç«æ±æ¥ç»è®¡', chartType: 'pie', dataTableIndex: 6 }, |
| | | shangliaofangcuo: { chartTitle: '䏿é²é', chartType: 'pie', dataTableIndex: 7 }, |
| | | shengchanhuibao: { chartTitle: 'çäº§æ±æ¥', chartType: 'bar', dataTableIndex: 8 }, |
| | | chanlianghuibao: { chartTitle: 'äº§éæ±æ¥', chartType: 'bar', dataTableIndex: 9 }, |
| | | shengchanzhilianghuibao: { chartTitle: 'çäº§è´¨éæ±æ¥', chartType: 'bar', dataTableIndex: 10 } |
| | | }; |
| | | |
| | | // çæé¡µé¢ç»æ |
| | | function generatePageStructure() { |
| | | chartConfigKeys = []; |
| | | for (var key in ChartConfig) { chartConfigKeys.push(key); } |
| | | generateSummaryCards(); |
| | | generateChartBoxes(); |
| | | } |
| | | function generateSummaryCards() { |
| | | var $summaryRow = $('#summaryRow'); $summaryRow.empty(); |
| | | $summaryRow.append('<div class="summary-card total-card" id="card-total"><div class="summary-number">0</div><div class="summary-label">æ»è®¡</div></div>'); |
| | | chartConfigKeys.forEach(key => { |
| | | var config = ChartConfig[key]; |
| | | var label = config.chartTitle.replace('ç»è®¡', ''); |
| | | $summaryRow.append(`<div class="summary-card" id="card-${key}"><div class="summary-number">0</div><div class="summary-label">${label}</div></div>`); |
| | | }); |
| | | } |
| | | function generateChartBoxes() { |
| | | var $c = $('#chartContainer'); $c.empty(); |
| | | chartConfigKeys.forEach(key => { |
| | | $c.append(`<div class="chart-box" id="chart-${key}"><div class="empty-tip">ææ æ°æ®</div></div>`); |
| | | }); |
| | | } |
| | | |
| | | //æ¥è¯¢ |
| | | form.on('submit(btnReSearch)', function (data) { |
| | | set_ClearQuery(); |
| | | }); |
| | | //éç½® |
| | | form.on('submit(btnSearch)', function (data) { |
| | | get_FastQuery(); |
| | | }); |
| | | //æ¥æé´é䏿å表çå¬ |
| | | form.on('select(HInitTimeCycle)', function (data) { |
| | | var HInitTimeCycle = $("#HInitTimeCycle").val() * 1; |
| | | if (HInitTimeCycle != -1) { |
| | | $('#HBeginDate').prop('disabled', true); |
| | | $('#HEndDate').prop('disabled', true); |
| | | $("#HBeginDate").val(Format(new Date(new Date() - 1000 * 60 * 60 * 24 * HInitTimeCycle), "yyyy-MM-dd")); |
| | | $("#HEndDate").val(Format(new Date(), "yyyy-MM-dd")); |
| | | get_FastQuery(); |
| | | } else { |
| | | $('#HBeginDate').prop('disabled', false); |
| | | $('#HEndDate').prop('disabled', false); |
| | | } |
| | | }); |
| | | |
| | | //åå§å |
| | | function set_ClearBill() { |
| | | generatePageStructure(); |
| | | setSelect_HInitTimeCycle(); |
| | | var HInitTimeCycle = $("#HInitTimeCycle").val() * 1; |
| | | if (HInitTimeCycle != -1) { |
| | | $('#HBeginDate').prop('disabled', true); |
| | | $('#HEndDate').prop('disabled', true); |
| | | } else { |
| | | $('#HBeginDate').prop('disabled', false); |
| | | $('#HEndDate').prop('disabled', false); |
| | | } |
| | | $("#HBeginDate").val(Format(new Date(new Date() - 1000 * 60 * 60 * 24 * HInitTimeCycle), "yyyy-MM-dd")); |
| | | $("#HEndDate").val(Format(new Date(), "yyyy-MM-dd")); |
| | | get_FastQuery(); |
| | | } |
| | | |
| | | //éç½® |
| | | function set_ClearQuery() { |
| | | var today = Format(new Date(), "yyyy-MM-dd"); |
| | | $("#HBeginDate").val(today); |
| | | $("#HEndDate").val(today); |
| | | get_FastQuery(); |
| | | } |
| | | |
| | | //åå§æ¥æé´é 䏿å表 |
| | | function setSelect_HInitTimeCycle() { |
| | | var valueList = [0, 1, 2, 3, 4, 5, 6, 29]; |
| | | var titleList = ["ä»å¤©", "è¿ä¸¤å¤©", "è¿ä¸å¤©", "è¿å天", "è¿äºå¤©", "è¿å
天", "è¿ä¸å¤©", "è¿30天"]; |
| | | var HInitTimeCycle_ArrayList = '<option value="-1" selected="selected" >ä»»æé´é</option>'; |
| | | for (var i = 0; i < valueList.length; i++) { |
| | | HInitTimeCycle_ArrayList += '<option style="color:blue;" value="' + valueList[i] + '">' + titleList[i] + '</option>'; |
| | | } |
| | | $("#HInitTimeCycle").empty().append(HInitTimeCycle_ArrayList); |
| | | $("#HInitTimeCycle").val("0"); |
| | | form.render('select'); |
| | | } |
| | | // ============================================== |
| | | // æ¥è¯¢ èªå¨è¡¥é½æææ¥æï¼ç©ºæ°æ®=0ï¼ |
| | | // ============================================== |
| | | function get_FastQuery() { |
| | | var wait = layer.load(); |
| | | var beginDate = $("#HBeginDate").val(); |
| | | var endDate = $("#HEndDate").val(); |
| | | |
| | | var sWhere = JSON.stringify({ HBeginDate: beginDate, HEndDate: endDate }); |
| | | var params = { sWhere: sWhere, user: sessionStorage["HUserName"] || '' }; |
| | | |
| | | $.ajax({ |
| | | url: GetWEBURL() + 'Sc_ProcessExchangeBill/DailyRunStateList', |
| | | type: 'GET', |
| | | data: params, |
| | | success: function (result) { |
| | | var data = {}; |
| | | var fullDateList = getDateRange(beginDate, endDate); |
| | | |
| | | if (result && result.code == "1" && result.data) { |
| | | chartConfigKeys.forEach(key => { |
| | | var cfg = ChartConfig[key]; |
| | | var tb = "h_p_Cs_ProcDailyRunStateReport" + (cfg.dataTableIndex > 0 ? cfg.dataTableIndex : ""); |
| | | var list = (result.data[tb] && Array.isArray(result.data[tb])) ? result.data[tb] : []; |
| | | |
| | | // 转 mapï¼æ¥æç»ä¸æ ¼å¼åï¼ |
| | | var dataMap = {}; |
| | | list.forEach(x => { |
| | | var date = x.æ¥æ || ""; |
| | | try { |
| | | date = Format(new Date(date), "yyyy-MM-dd"); |
| | | } catch (e) { |
| | | date = ""; |
| | | } |
| | | var num = parseInt(x.æ°é) || 0; |
| | | if (date) dataMap[date] = num; |
| | | }); |
| | | |
| | | // è¡¥é½æææ¥æ |
| | | data[key] = fullDateList.map(date => ({ |
| | | name: date, |
| | | value: dataMap[date] || 0 |
| | | })); |
| | | }); |
| | | } else { |
| | | // åç«¯æ æææ°æ®ï¼å
¨é¨åå§å为 0 |
| | | chartConfigKeys.forEach(key => { |
| | | data[key] = fullDateList.map(date => ({ name: date, value: 0 })); |
| | | }); |
| | | } |
| | | |
| | | renderAll(data); |
| | | layer.close(wait); |
| | | }, |
| | | error: function () { |
| | | var fullDateList = getDateRange(beginDate, endDate); |
| | | var data = {}; |
| | | chartConfigKeys.forEach(key => { |
| | | data[key] = fullDateList.map(date => ({ name: date, value: 0 })); |
| | | }); |
| | | renderAll(data); |
| | | layer.close(wait); |
| | | } |
| | | }); |
| | | } |
| | | |
| | | // ============================================== |
| | | // çæå¼å§~ç»æçæææ¥æï¼èªå¨è·¨æ/è·¨å¹´ï¼ |
| | | // ============================================== |
| | | function getDateRange(startDate, endDate) { |
| | | var arr = []; |
| | | var start = new Date(startDate); |
| | | var end = new Date(endDate); |
| | | while (start <= end) { |
| | | arr.push(Format(start, "yyyy-MM-dd")); |
| | | start.setDate(start.getDate() + 1); |
| | | } |
| | | return arr; |
| | | } |
| | | |
| | | // ============================================== |
| | | // æ¸²æææå¾è¡¨åå¡çï¼åæ¶âå
¨0è·³è¿âï¼å§ç»ç»å¾ï¼ |
| | | // ============================================== |
| | | function renderAll(data) { |
| | | chartConfigKeys.forEach(key => { |
| | | var cfg = ChartConfig[key]; |
| | | var d = data[key] || []; |
| | | var $chartBox = $('#chart-' + key); |
| | | var dom = $chartBox[0]; |
| | | var chartKey = 'chart-' + key; |
| | | |
| | | // 1. 鿝æ§å®ä¾ï¼æå¼ ResizeObserver å¹¶æ¸
ç©ºå®¹å¨ |
| | | if (chartInstances[chartKey]) { |
| | | try { |
| | | if (chartInstances[chartKey]._resizeObserver) chartInstances[chartKey]._resizeObserver.disconnect(); |
| | | } catch (e) { } |
| | | chartInstances[chartKey].dispose(); |
| | | delete chartInstances[chartKey]; |
| | | } |
| | | $chartBox.empty(); |
| | | |
| | | // 2. æ´æ°å¡çæ»æ° |
| | | var total = d.reduce((a, b) => a + b.value, 0); |
| | | $('#card-' + key + ' .summary-number').text(total); |
| | | |
| | | // 3. å§ç»ç»å¶å¾è¡¨ï¼æ±ç¶å¾ä¼æ¾ç¤º0弿±åï¼é¥¼å¾å
¨0æ¶ç¹æ®å¤çï¼ |
| | | if (cfg.chartType === 'pie') { |
| | | // 饼徿 论æ¯å¦æ0é½ç»å¶ |
| | | renderPie(key, cfg.chartTitle, d); |
| | | } else if (cfg.chartType === 'bar') { |
| | | // æ±ç¶å¾æ 论æ¯å¦æ0é½ç»å¶ï¼è®©æ¨ªè½´æ¥æå®æ´å±ç¤º |
| | | renderBar(key, cfg.chartTitle, d); |
| | | } |
| | | }); |
| | | |
| | | // æ´æ°æ»è®¡å¡ç |
| | | var totalAll = 0; |
| | | chartConfigKeys.forEach(key => { |
| | | var d = data[key] || []; |
| | | totalAll += d.reduce((a, b) => a + b.value, 0); |
| | | }); |
| | | $("#card-total .summary-number").text(totalAll); |
| | | } |
| | | |
| | | function renderPie(key, title, data) { |
| | | var dom = document.getElementById('chart-' + key); |
| | | var $chartBox = $('#chart-' + key); |
| | | $chartBox.empty(); |
| | | |
| | | var chart = echarts.init(dom); |
| | | chartInstances['chart-' + key] = chart; |
| | | // èªå¨ååºå®¹å¨å°ºå¯¸ååï¼ä¼å
ä½¿ç¨ ResizeObserverï¼ |
| | | if (window.ResizeObserver) { |
| | | try { |
| | | var ro = new ResizeObserver(function () { try { chart.resize(); } catch (e) { } }); |
| | | ro.observe(dom); |
| | | chart._resizeObserver = ro; |
| | | } catch (e) { } |
| | | } |
| | | |
| | | // è®¡ç®æ»å |
| | | var total = data.reduce((s, x) => s + x.value, 0); |
| | | var isAllZero = total === 0; |
| | | |
| | | // ç»å¶æ°æ®ï¼å
¨0æ¶ç¨æå°å¼å ä½ï¼ |
| | | var pieData = data.map(x => ({ |
| | | name: x.name, |
| | | value: isAllZero ? 0.0001 : x.value, |
| | | originalValue: x.value |
| | | })); |
| | | |
| | | // åºç¡ç³»åé
ç½® |
| | | var seriesConfig = { |
| | | type: 'pie', |
| | | radius: ['30%', '50%'], |
| | | data: pieData, |
| | | label: { |
| | | show: true, |
| | | fontSize: 11, |
| | | // å¼ºå¶æ¾ç¤ºæ ç¾ï¼é²æ¢è¢«éè |
| | | overflow: 'none', |
| | | hideOverlap: false |
| | | }, |
| | | labelLine: { |
| | | show: true, |
| | | length: 10, |
| | | length2: 8 |
| | | }, |
| | | avoidLabelOverlap: false // å
许æ ç¾éå ï¼ç¡®ä¿é½æ¾ç¤º |
| | | }; |
| | | |
| | | chart.setOption({ |
| | | title: { text: title, left: 'center', textStyle: { fontSize: 12 } }, |
| | | tooltip: { |
| | | trigger: 'item', |
| | | formatter: function (params) { |
| | | return `${params.name}: ${params.data.originalValue}`; |
| | | } |
| | | }, |
| | | series: [ |
| | | // 第ä¸å±ï¼å¤é¨æ¾ç¤ºæ¥æ |
| | | { |
| | | ...seriesConfig, |
| | | label: { |
| | | ...seriesConfig.label, |
| | | position: 'outside', |
| | | formatter: function (params) { |
| | | // å¤é¨å§ç»æ¾ç¤ºæ¥æï¼åç§°ï¼ |
| | | return params.name; |
| | | } |
| | | } |
| | | }, |
| | | // 第äºå±ï¼å
鍿¾ç¤ºæ°éï¼å
¨0æ¶ä¹æ¾ç¤º0ï¼ |
| | | { |
| | | ...seriesConfig, |
| | | label: { |
| | | ...seriesConfig.label, |
| | | position: 'inside', |
| | | formatter: function (params) { |
| | | // å
鍿¾ç¤ºåå§æ°éï¼å
¨0æ¶æ¾ç¤º '0' |
| | | return params.data.originalValue; |
| | | } |
| | | }, |
| | | labelLine: { show: false } // å
é¨ä¸éè¦å¼å¯¼çº¿ |
| | | } |
| | | ] |
| | | }); |
| | | } |
| | | |
| | | // ============================================== |
| | | // æ±ç¶å¾æ¸²æï¼æ¯æå
¨0æ°æ®ï¼æ¾ç¤ºæ¨ªè½´æ ç¾å0å¼ï¼ |
| | | // ============================================== |
| | | function renderBar(key, title, data) { |
| | | var dom = document.getElementById('chart-' + key); |
| | | var chart = echarts.init(dom); |
| | | chartInstances['chart-' + key] = chart; |
| | | if (window.ResizeObserver) { |
| | | try { |
| | | var ro = new ResizeObserver(function () { try { chart.resize(); } catch (e) { } }); |
| | | ro.observe(dom); |
| | | chart._resizeObserver = ro; |
| | | } catch (e) { } |
| | | } |
| | | var colorList = ['#5470c6', '#91cc75', '#fac858', '#ee6666', '#73c0de', '#3ba272', '#fc8452', '#9a60b4', '#ea7ccc']; |
| | | |
| | | chart.setOption({ |
| | | title: { text: title, left: 'center', textStyle: { fontSize: 12 } }, |
| | | tooltip: { trigger: 'axis' }, |
| | | xAxis: { type: 'category', data: data.map(x => x.name) }, |
| | | yAxis: { type: 'value' }, |
| | | series: [{ |
| | | type: 'bar', |
| | | data: data.map(x => x.value), |
| | | barWidth: '40%', |
| | | itemStyle: { |
| | | color: function (params) { |
| | | return colorList[params.dataIndex % colorList.length]; |
| | | }, |
| | | borderRadius: [4, 4, 0, 0] |
| | | }, |
| | | label: { |
| | | show: true, |
| | | position: 'top', |
| | | fontSize: 11, |
| | | formatter: '{c}' |
| | | } |
| | | }] |
| | | }); |
| | | } |
| | | // åå§å |
| | | set_ClearBill(); |
| | | |
| | | window.onresize = function () { |
| | | for (var k in chartInstances) { |
| | | if (chartInstances[k]) chartInstances[k].resize(); |
| | | } |
| | | }; |
| | | }); |
| | | </script> |
| | | </body> |
| | | </html> |