From b7ed9ae49ba158fe981a4719c3a85d630795a877 Mon Sep 17 00:00:00 2001 From: wikiboss Date: Mon, 2 Nov 2026 16:19:39 +0800 Subject: [PATCH] =?UTF-8?q?feat(dashboard):=20=E6=8E=A7=E5=88=B6=E5=8F=B0?= =?UTF-8?q?=E5=89=96=E6=9E=90=E5=9B=BE=E8=A1=A8=E6=94=AF=E6=8C=81=E6=8C=87?= =?UTF-8?q?=E6=A0=87=E5=9B=BD=E6=A0=87=E7=BB=B4=E5=BA=A6=E5=88=86=E7=B1=BB?= =?UTF-8?q?=E5=88=87=E6=8D=A2=E3=80=81=E5=8E=BB=E9=99=A4=E5=8E=9A=E9=87=8D?= =?UTF-8?q?=E5=A4=A7=E8=89=B2=E5=9D=97=E5=B9=B6=E5=90=AF=E7=94=A8=E5=8A=A8?= =?UTF-8?q?=E6=80=81=E8=87=AA=E9=80=82=E5=BA=94=E5=88=BB=E5=BA=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- application/admin/view/dashboard/index.html | 73 ++++++++--- application/extra/site.php | 2 +- public/assets/js/backend/dashboard.js | 127 ++++++++++++++++++-- 3 files changed, 170 insertions(+), 32 deletions(-) diff --git a/application/admin/view/dashboard/index.html b/application/admin/view/dashboard/index.html index bdfcec0..c141469 100644 --- a/application/admin/view/dashboard/index.html +++ b/application/admin/view/dashboard/index.html @@ -77,27 +77,48 @@ - - -
-
+ + + +
+
+
- 刷新图表 + 刷新图表
-
+
-
- +
+
-
-
- - {{item.name}} - - -
+
+ + {{item.name}} + +
查询
- -
+
+ +
+
+ + 指标维度: + + + ⭐ 核心品质 + 🌾 物理与杂质 + 🧪 储存品质 + 🛡️ 卫生安全 + 📊 全部指标 + +
+
+ 已按国标体系分类,Y轴动态自适应放大微量指标 +
+
+
diff --git a/application/extra/site.php b/application/extra/site.php index 40f1959..01e9806 100644 --- a/application/extra/site.php +++ b/application/extra/site.php @@ -4,7 +4,7 @@ return array ( 'name' => '中央储备粮遵义直属库有限公司', 'beian' => '', 'cdnurl' => '', - 'version' => '20261102_v3', + 'version' => '20261102_v6', 'timezone' => 'Asia/Shanghai', 'forbiddenip' => '', 'languages' => diff --git a/public/assets/js/backend/dashboard.js b/public/assets/js/backend/dashboard.js index be24455..79bc791 100644 --- a/public/assets/js/backend/dashboard.js +++ b/public/assets/js/backend/dashboard.js @@ -1,5 +1,38 @@ define(['jquery', 'bootstrap', 'backend', 'addtabs', 'table', 'echarts', 'echarts-theme', 'template'], function ($, undefined, Backend, Datatable, Table, Echarts, undefined, Template) { +var CATEGORY_DEFS = { + core: { + name: '核心品质', + keywords: ['水分', '整精米率', '容重', '出糙率', '色泽', '气味', '纯粮率'] + }, + impurity: { + name: '物理与杂质', + keywords: ['杂质', '黄粒米', '谷外糙米', '互混', '不完善粒', '生霉粒', '加热损伤粒'] + }, + storage: { + name: '储存品质', + keywords: ['脂肪酸值', '面筋吸水量', '品尝评分', '酸价', '过氧化值', '发芽率', '还原糖'] + }, + safety: { + name: '卫生安全', + keywords: ['铅', '镉', '总汞', '汞', '无机砷', '砷', '黄曲霉毒素', '黄曲霉毒素B1', '马拉硫磷', '农药'] + } +}; + +function filterSeriesByCategory(seriesData, categoryKey) { + if (!seriesData || !Array.isArray(seriesData)) return []; + if (!categoryKey || categoryKey === 'all') return seriesData; + var cat = CATEGORY_DEFS[categoryKey]; + if (!cat) return seriesData; + return seriesData.filter(function (item) { + var name = item.name || ''; + return cat.keywords.some(function (kw) { + return name.indexOf(kw) !== -1; + }); + }); +} + + var Controller = { index: function () { var vue = new Vue({ @@ -8,6 +41,7 @@ define(['jquery', 'bootstrap', 'backend', 'addtabs', 'table', 'echarts', 'echart lineCharts: [], granaryList: [], typeList: [], + selectedCategory: 'core', search: { gid: '', year: '', @@ -18,6 +52,9 @@ define(['jquery', 'bootstrap', 'backend', 'addtabs', 'table', 'echarts', 'echart this.getInitData(); }, methods: { + categoryChange(cat) { + this.paramsLineCharts(); + }, // 仓库切换智能联动其品种并刷新折线图 granaryChange(gid) { let cur = this.granaryList.find(function (item) { return item.id === gid; }); @@ -96,19 +133,38 @@ define(['jquery', 'bootstrap', 'backend', 'addtabs', 'table', 'echarts', 'echart } }) }, - // 折线图 + // 折线图 (平滑无遮挡 + 指标分类过滤 + 自适应刻度) paramsLineCharts() { let series = this.lineCharts || {}; let lineChart = Echarts.init(document.getElementById('main-chart')); let legendData = []; let hasData = false; - if (series.seriesData && series.seriesData.length) { - for (let i = 0; i < series.seriesData.length; i++) { - let item = series.seriesData[i]; + let rawSeriesData = (series.seriesData && Array.isArray(series.seriesData)) ? series.seriesData : []; + let displaySeries = filterSeriesByCategory(rawSeriesData, this.selectedCategory); + if (!displaySeries.length && this.selectedCategory !== 'all' && rawSeriesData.length) { + displaySeries = []; + } + + if (displaySeries && displaySeries.length) { + for (let i = 0; i < displaySeries.length; i++) { + let item = displaySeries[i]; item.type = 'line'; - item.areaStyle = { - focus: 'series' + item.smooth = true; + item.symbol = 'circle'; + item.symbolSize = 7; + delete item.areaStyle; + item.lineStyle = { + width: 2.5 + }; + item.label = { + show: true, + position: 'top', + fontSize: 11, + color: '#4b5563', + formatter: function (p) { + return (p.value !== 0 && p.value !== '0' && p.value !== null && p.value !== undefined) ? p.value : ''; + } }; legendData.push(item.name); if (item.data && item.data.length && item.data.some(function (v) { return v !== null && v !== undefined && v !== ''; })) { @@ -122,11 +178,19 @@ define(['jquery', 'bootstrap', 'backend', 'addtabs', 'table', 'echarts', 'echart let granaryName = curGranary ? curGranary.name : '所选仓库'; let typeName = this.typeList && this.typeList[this.search.type] ? this.typeList[this.search.type].name : this.search.type; let yearText = this.search.year || ''; + let currentCatName = (CATEGORY_DEFS[this.selectedCategory] ? CATEGORY_DEFS[this.selectedCategory].name : '指标'); + + let emptySubtext = ''; + if (!rawSeriesData.length) { + emptySubtext = (yearText ? yearText + '年 ' : '') + granaryName + ' 暂无【' + typeName + '】检测报告,可切换年份或对应品种查看'; + } else { + emptySubtext = (yearText ? yearText + '年 ' : '') + granaryName + '【' + typeName + '】暂无【' + currentCatName + '】项检测数据,可切换其他分类或全部指标查看'; + } let option = { title: !hasData ? { text: '暂无检测数据', - subtext: (yearText ? yearText + '年 ' : '') + granaryName + ' 暂无【' + typeName + '】检测报告,可切换年份或对应品种查看', + subtext: emptySubtext, left: 'center', top: 'middle', textStyle: { @@ -143,6 +207,13 @@ define(['jquery', 'bootstrap', 'backend', 'addtabs', 'table', 'echarts', 'echart }, tooltip: { trigger: 'axis', + backgroundColor: 'rgba(255, 255, 255, 0.96)', + borderColor: '#e4e7ed', + borderWidth: 1, + textStyle: { + color: '#303133', + fontSize: 12 + }, axisPointer: { type: 'cross', label: { @@ -151,7 +222,12 @@ define(['jquery', 'bootstrap', 'backend', 'addtabs', 'table', 'echarts', 'echart } }, legend: { - data: hasData ? legendData : [] + data: hasData ? legendData : [], + top: 5, + textStyle: { + fontSize: 12, + color: '#606266' + } }, toolbox: { feature: { @@ -159,24 +235,49 @@ define(['jquery', 'bootstrap', 'backend', 'addtabs', 'table', 'echarts', 'echart } }, grid: { - left: '3%', + left: '4%', right: '4%', - bottom: 0, + top: 50, + bottom: 20, containLabel: true }, xAxis: [ { type: 'category', boundaryGap: false, - data: hasData ? (series.list || []) : [] + data: hasData ? (series.list || []) : [], + axisLine: { + lineStyle: { + color: '#dcdfe6' + } + }, + axisLabel: { + color: '#606266' + } } ], yAxis: [ { - type: 'value' + type: 'value', + scale: true, + axisLine: { + show: true, + lineStyle: { + color: '#dcdfe6' + } + }, + axisLabel: { + color: '#606266' + }, + splitLine: { + lineStyle: { + type: 'dashed', + color: '#f2f3f5' + } + } } ], - series: hasData ? series.seriesData : [] + series: hasData ? displaySeries : [] }; lineChart.setOption(option, true);