Browse Source

docs:统计分析-水位统计

master
waibao2 1 month ago
parent
commit
8480734384
  1. 4
      package.json
  2. 9
      src/api/system/dept.js
  3. 497
      src/assets/file/kriging.js
  4. 321
      src/components/HistoryData/index.vue
  5. 345
      src/components/HistoryYOY/index.vue
  6. 173
      src/components/TimeCount/index.vue
  7. 245
      src/components/TimeProcess/index.vue
  8. 283
      src/components/YearEigenvalue/index.vue
  9. 1
      src/router/index.js
  10. 86
      src/views/statistic/rsvr/rsvr_main.vue
  11. 10
      src/views/statistic/rsvr/rsvrls.vue
  12. 10
      src/views/statistic/rsvr/rsvrsd.vue
  13. 307
      src/views/statistic/rsvr/rsvrtzz copy.vue
  14. 11
      src/views/statistic/rsvr/rsvrtzz.vue
  15. 11
      src/views/statistic/rsvr/sdrsvr.vue
  16. 4
      vite.config.js

4
package.json

@ -17,6 +17,7 @@ @@ -17,6 +17,7 @@
},
"dependencies": {
"@element-plus/icons-vue": "2.3.1",
"@turf/turf": "^7.2.0",
"@vueup/vue-quill": "1.2.0",
"@vueuse/core": "10.6.1",
"axios": "0.27.2",
@ -25,13 +26,16 @@ @@ -25,13 +26,16 @@
"element-plus": "2.4.3",
"file-saver": "2.0.5",
"fuse.js": "6.6.2",
"html2pdf.js": "^0.12.1",
"js-cookie": "3.0.5",
"jsencrypt": "3.3.2",
"leaflet": "^1.9.4",
"leaflet.sidepanel": "^1.2.3",
"lodash": "^4.17.21",
"nprogress": "0.2.0",
"ol": "^10.6.1",
"pinia": "2.1.7",
"proj4": "^2.19.10",
"splitpanes": "^4.0.4",
"vue": "3.3.9",
"vue-cropper": "1.1.1",

9
src/api/system/dept.js

@ -1,3 +1,4 @@ @@ -1,3 +1,4 @@
import request from '@/utils/request'
// 查询部门列表
@ -24,7 +25,13 @@ export function getDept(deptId) { @@ -24,7 +25,13 @@ export function getDept(deptId) {
method: 'get'
})
}
// 查询部门下拉树结构
export function treeselect() {
return request({
url: '/system/dept/treeselect',
method: 'get'
})
}
// 新增部门
export function addDept(data) {
return request({

497
src/assets/file/kriging.js

@ -0,0 +1,497 @@ @@ -0,0 +1,497 @@
// Extend the Array class
Array.prototype.max = function () {
return Math.max.apply(null, this);
};
Array.prototype.min = function () {
return Math.min.apply(null, this);
};
Array.prototype.mean = function () {
var i, sum;
for (i = 0, sum = 0; i < this.length; i++)
sum += this[i];
return sum / this.length;
};
Array.prototype.pip = function (x, y) {
var i, j, c = false;
for (i = 0, j = this.length - 1; i < this.length; j = i++) {
if (((this[i][1] > y) != (this[j][1] > y)) &&
(x < (this[j][0] - this[i][0]) * (y - this[i][1]) / (this[j][1] - this[i][1]) + this[i][0])) {
c = !c;
}
}
return c;
}
var kriging = function () {
var kriging = {};
var createArrayWithValues = function (value, n) {
var array = [];
for (var i = 0; i < n; i++) {
array.push(value);
}
return array;
};
// Matrix algebra
var kriging_matrix_diag = function (c, n) {
var Z = createArrayWithValues(0, n * n);
for (i = 0; i < n; i++) Z[i * n + i] = c;
return Z;
};
var kriging_matrix_transpose = function (X, n, m) {
var i, j, Z = Array(m * n);
for (i = 0; i < n; i++)
for (j = 0; j < m; j++)
Z[j * n + i] = X[i * m + j];
return Z;
};
var kriging_matrix_scale = function (X, c, n, m) {
var i, j;
for (i = 0; i < n; i++)
for (j = 0; j < m; j++)
X[i * m + j] *= c;
};
var kriging_matrix_add = function (X, Y, n, m) {
var i, j, Z = Array(n * m);
for (i = 0; i < n; i++)
for (j = 0; j < m; j++)
Z[i * m + j] = X[i * m + j] + Y[i * m + j];
return Z;
};
// Naive matrix multiplication
var kriging_matrix_chol = function (X, n) {
var i, j, k, sum, p = Array(n);
for (i = 0; i < n; i++) p[i] = X[i * n + i];
for (i = 0; i < n; i++) {
for (j = 0; j < i; j++)
p[i] -= X[i * n + j] * X[i * n + j];
if (p[i] <= 0) return false;
p[i] = Math.sqrt(p[i]);
for (j = i + 1; j < n; j++) {
for (k = 0; k < i; k++)
X[j * n + i] -= X[j * n + k] * X[i * n + k];
X[j * n + i] /= p[i];
}
}
for (i = 0; i < n; i++) X[i * n + i] = p[i];
return true;
};
// Cholesky decomposition
kriging_matrix_chol = function (X, n) {
var i, j, k, sum, p = Array(n);
for (i = 0; i < n; i++) p[i] = X[i * n + i];
for (i = 0; i < n; i++) {
for (j = 0; j < i; j++)
p[i] -= X[i * n + j] * X[i * n + j];
if (p[i] <= 0) return false;
p[i] = Math.sqrt(p[i]);
for (j = i + 1; j < n; j++) {
for (k = 0; k < i; k++)
X[j * n + i] -= X[j * n + k] * X[i * n + k];
X[j * n + i] /= p[i];
}
}
for (i = 0; i < n; i++) X[i * n + i] = p[i];
return true;
};
// Inversion of cholesky decomposition
var kriging_matrix_chol2inv = function (X, n) {
var i, j, k, sum;
for (i = 0; i < n; i++) {
X[i * n + i] = 1 / X[i * n + i];
for (j = i + 1; j < n; j++) {
sum = 0;
for (k = i; k < j; k++)
sum -= X[j * n + k] * X[k * n + i];
X[j * n + i] = sum / X[j * n + j];
}
}
for (i = 0; i < n; i++)
for (j = i + 1; j < n; j++)
X[i * n + j] = 0;
for (i = 0; i < n; i++) {
X[i * n + i] *= X[i * n + i];
for (k = i + 1; k < n; k++)
X[i * n + i] += X[k * n + i] * X[k * n + i];
for (j = i + 1; j < n; j++)
for (k = j; k < n; k++)
X[i * n + j] += X[k * n + i] * X[k * n + j];
}
for (i = 0; i < n; i++)
for (j = 0; j < i; j++)
X[i * n + j] = X[j * n + i];
};
// Inversion via gauss-jordan elimination
var kriging_matrix_solve = function (X, n) {
var m = n;
var b = Array(n * n);
var indxc = Array(n);
var indxr = Array(n);
var ipiv = Array(n);
var i, icol, irow, j, k, l, ll;
var big, dum, pivinv, temp;
for (i = 0; i < n; i++)
for (j = 0; j < n; j++) {
if (i == j) b[i * n + j] = 1;
else b[i * n + j] = 0;
}
for (j = 0; j < n; j++) ipiv[j] = 0;
for (i = 0; i < n; i++) {
big = 0;
for (j = 0; j < n; j++) {
if (ipiv[j] != 1) {
for (k = 0; k < n; k++) {
if (ipiv[k] == 0) {
if (Math.abs(X[j * n + k]) >= big) {
big = Math.abs(X[j * n + k]);
irow = j;
icol = k;
}
}
}
}
}
++(ipiv[icol]);
if (irow != icol) {
for (l = 0; l < n; l++) {
temp = X[irow * n + l];
X[irow * n + l] = X[icol * n + l];
X[icol * n + l] = temp;
}
for (l = 0; l < m; l++) {
temp = b[irow * n + l];
b[irow * n + l] = b[icol * n + l];
b[icol * n + l] = temp;
}
}
indxr[i] = irow;
indxc[i] = icol;
if (X[icol * n + icol] == 0) return false; // Singular
pivinv = 1 / X[icol * n + icol];
X[icol * n + icol] = 1;
for (l = 0; l < n; l++) X[icol * n + l] *= pivinv;
for (l = 0; l < m; l++) b[icol * n + l] *= pivinv;
for (ll = 0; ll < n; ll++) {
if (ll != icol) {
dum = X[ll * n + icol];
X[ll * n + icol] = 0;
for (l = 0; l < n; l++) X[ll * n + l] -= X[icol * n + l] * dum;
for (l = 0; l < m; l++) b[ll * n + l] -= b[icol * n + l] * dum;
}
}
}
for (l = (n - 1); l >= 0; l--)
if (indxr[l] != indxc[l]) {
for (k = 0; k < n; k++) {
temp = X[k * n + indxr[l]];
X[k * n + indxr[l]] = X[k * n + indxc[l]];
X[k * n + indxc[l]] = temp;
}
}
return true;
}
// Variogram models
var kriging_variogram_gaussian = function (h, nugget, range, sill, A) {
return nugget + ((sill - nugget) / range) *
(1.0 - Math.exp(-(1.0 / A) * Math.pow(h / range, 2)));
};
var kriging_variogram_exponential = function (h, nugget, range, sill, A) {
return nugget + ((sill - nugget) / range) *
(1.0 - Math.exp(-(1.0 / A) * (h / range)));
};
var kriging_variogram_spherical = function (h, nugget, range, sill, A) {
if (h > range) return nugget + (sill - nugget) / range;
return nugget + ((sill - nugget) / range) *
(1.5 * (h / range) - 0.5 * Math.pow(h / range, 3));
};
// Train using gaussian processes with bayesian priors
kriging.train = function (t, x, y, model, sigma2, alpha) {
var variogram = {
t: t,
x: x,
y: y,
nugget: 0.0,
range: 0.0,
sill: 0.0,
A: 1 / 3,
n: 0
};
switch (model) {
case "gaussian":
variogram.model = kriging_variogram_gaussian;
break;
case "exponential":
variogram.model = kriging_variogram_exponential;
break;
case "spherical":
variogram.model = kriging_variogram_spherical;
break;
};
// Lag distance/semivariance
var i, j, k, l, n = t.length;
var distance = Array((n * n - n) / 2);
for (i = 0, k = 0; i < n; i++)
for (j = 0; j < i; j++, k++) {
distance[k] = Array(2);
distance[k][0] = Math.pow(
Math.pow(x[i] - x[j], 2) +
Math.pow(y[i] - y[j], 2), 0.5);
distance[k][1] = Math.abs(t[i] - t[j]);
}
distance.sort(function (a, b) { return a[0] - b[0]; });
variogram.range = distance[(n * n - n) / 2 - 1][0];
// Bin lag distance
var lags = ((n * n - n) / 2) > 30 ? 30 : (n * n - n) / 2;
var tolerance = variogram.range / lags;
var lag = createArrayWithValues(0, lags);
var semi = createArrayWithValues(0, lags);
if (lags < 30) {
for (l = 0; l < lags; l++) {
lag[l] = distance[l][0];
semi[l] = distance[l][1];
}
}
else {
for (i = 0, j = 0, k = 0, l = 0; i < lags && j < ((n * n - n) / 2); i++, k = 0) {
while (distance[j][0] <= ((i + 1) * tolerance)) {
lag[l] += distance[j][0];
semi[l] += distance[j][1];
j++; k++;
if (j >= ((n * n - n) / 2)) break;
}
if (k > 0) {
lag[l] /= k;
semi[l] /= k;
l++;
}
}
if (l < 2) return variogram; // Error: Not enough points
}
// Feature transformation
n = l;
variogram.range = lag[n - 1] - lag[0];
var X = createArrayWithValues(1, 2 * n);
var Y = Array(n);
var A = variogram.A;
for (i = 0; i < n; i++) {
switch (model) {
case "gaussian":
X[i * 2 + 1] = 1.0 - Math.exp(-(1.0 / A) * Math.pow(lag[i] / variogram.range, 2));
break;
case "exponential":
X[i * 2 + 1] = 1.0 - Math.exp(-(1.0 / A) * lag[i] / variogram.range);
break;
case "spherical":
X[i * 2 + 1] = 1.5 * (lag[i] / variogram.range) -
0.5 * Math.pow(lag[i] / variogram.range, 3);
break;
};
Y[i] = semi[i];
}
// Least squares
var Xt = kriging_matrix_transpose(X, n, 2);
var Z = kriging_matrix_multiply(Xt, X, 2, n, 2);
Z = kriging_matrix_add(Z, kriging_matrix_diag(1 / alpha, 2), 2, 2);
var cloneZ = Z.slice(0);
if (kriging_matrix_chol(Z, 2))
kriging_matrix_chol2inv(Z, 2);
else {
kriging_matrix_solve(cloneZ, 2);
Z = cloneZ;
}
var W = kriging_matrix_multiply(kriging_matrix_multiply(Z, Xt, 2, 2, n), Y, 2, n, 1);
// Variogram parameters
variogram.nugget = W[0];
variogram.sill = W[1] * variogram.range + variogram.nugget;
variogram.n = x.length;
// Gram matrix with prior
n = x.length;
var K = Array(n * n);
for (i = 0; i < n; i++) {
for (j = 0; j < i; j++) {
K[i * n + j] = variogram.model(Math.pow(Math.pow(x[i] - x[j], 2) +
Math.pow(y[i] - y[j], 2), 0.5),
variogram.nugget,
variogram.range,
variogram.sill,
variogram.A);
K[j * n + i] = K[i * n + j];
}
K[i * n + i] = variogram.model(0, variogram.nugget,
variogram.range,
variogram.sill,
variogram.A);
}
// Inverse penalized Gram matrix projected to target vector
var C = kriging_matrix_add(K, kriging_matrix_diag(sigma2, n), n, n);
var cloneC = C.slice(0);
if (kriging_matrix_chol(C, n))
kriging_matrix_chol2inv(C, n);
else {
kriging_matrix_solve(cloneC, n);
C = cloneC;
}
// Copy unprojected inverted matrix as K
var K = C.slice(0);
var M = kriging_matrix_multiply(C, t, n, n, 1);
variogram.K = K;
variogram.M = M;
return variogram;
};
// Model prediction
kriging.predict = function (x, y, variogram) {
var i, k = Array(variogram.n);
for (i = 0; i < variogram.n; i++)
k[i] = variogram.model(Math.pow(Math.pow(x - variogram.x[i], 2) +
Math.pow(y - variogram.y[i], 2), 0.5),
variogram.nugget, variogram.range,
variogram.sill, variogram.A);
return kriging_matrix_multiply(k, variogram.M, 1, variogram.n, 1)[0];
};
kriging.variance = function (x, y, variogram) {
var i, k = Array(variogram.n);
for (i = 0; i < variogram.n; i++)
k[i] = variogram.model(Math.pow(Math.pow(x - variogram.x[i], 2) +
Math.pow(y - variogram.y[i], 2), 0.5),
variogram.nugget, variogram.range,
variogram.sill, variogram.A);
return variogram.model(0, variogram.nugget, variogram.range,
variogram.sill, variogram.A) +
kriging_matrix_multiply(kriging_matrix_multiply(k, variogram.K,
1, variogram.n, variogram.n),
k, 1, variogram.n, 1)[0];
};
// Gridded matrices or contour paths
kriging.grid = function (polygons, variogram, width) {
var i, j, k, n = polygons.length;
if (n == 0) return;
// Boundaries of polygons space
var xlim = [polygons[0][0][0], polygons[0][0][0]];
var ylim = [polygons[0][0][1], polygons[0][0][1]];
for (i = 0; i < n; i++) // Polygons
for (j = 0; j < polygons[i].length; j++) { // Vertices
if (polygons[i][j][0] < xlim[0])
xlim[0] = polygons[i][j][0];
if (polygons[i][j][0] > xlim[1])
xlim[1] = polygons[i][j][0];
if (polygons[i][j][1] < ylim[0])
ylim[0] = polygons[i][j][1];
if (polygons[i][j][1] > ylim[1])
ylim[1] = polygons[i][j][1];
}
// Alloc for O(n^2) space
var xtarget, ytarget;
var a = Array(2), b = Array(2);
var lxlim = Array(2); // Local dimensions
var lylim = Array(2); // Local dimensions
var x = Math.ceil((xlim[1] - xlim[0]) / width);
var y = Math.ceil((ylim[1] - ylim[0]) / width);
var A = Array(x + 1);
for (i = 0; i <= x; i++) A[i] = Array(y + 1);
for (i = 0; i < n; i++) {
// Range for polygons[i]
lxlim[0] = polygons[i][0][0];
lxlim[1] = lxlim[0];
lylim[0] = polygons[i][0][1];
lylim[1] = lylim[0];
for (j = 1; j < polygons[i].length; j++) { // Vertices
if (polygons[i][j][0] < lxlim[0])
lxlim[0] = polygons[i][j][0];
if (polygons[i][j][0] > lxlim[1])
lxlim[1] = polygons[i][j][0];
if (polygons[i][j][1] < lylim[0])
lylim[0] = polygons[i][j][1];
if (polygons[i][j][1] > lylim[1])
lylim[1] = polygons[i][j][1];
}
// Loop through polygon subspace
a[0] = Math.floor(((lxlim[0] - ((lxlim[0] - xlim[0]) % width)) - xlim[0]) / width);
a[1] = Math.ceil(((lxlim[1] - ((lxlim[1] - xlim[1]) % width)) - xlim[0]) / width);
b[0] = Math.floor(((lylim[0] - ((lylim[0] - ylim[0]) % width)) - ylim[0]) / width);
b[1] = Math.ceil(((lylim[1] - ((lylim[1] - ylim[1]) % width)) - ylim[0]) / width);
for (j = a[0]; j <= a[1]; j++)
for (k = b[0]; k <= b[1]; k++) {
xtarget = xlim[0] + j * width;
ytarget = ylim[0] + k * width;
if (polygons[i].pip(xtarget, ytarget))
A[j][k] = kriging.predict(xtarget,
ytarget,
variogram);
}
}
A.xlim = xlim;
A.ylim = ylim;
A.zlim = [variogram.t.min(), variogram.t.max()];
A.width = width;
return A;
};
kriging.contour = function (value, polygons, variogram) {
};
// Plotting on the DOM
kriging.plot = function (canvas, grid, xlim, ylim, colors) {
// Clear screen
var ctx = canvas.getContext("2d");
ctx.clearRect(0, 0, canvas.width, canvas.height);
// Starting boundaries
var range = [xlim[1] - xlim[0], ylim[1] - ylim[0], grid.zlim[1] - grid.zlim[0]];
var i, j, x, y, z;
var n = grid.length;
var m = grid[0].length;
var wx = Math.ceil(grid.width * canvas.width / (xlim[1] - xlim[0]));
var wy = Math.ceil(grid.width * canvas.height / (ylim[1] - ylim[0]));
for (i = 0; i < n; i++)
for (j = 0; j < m; j++) {
if (grid[i][j] == undefined) continue;
x = canvas.width * (i * grid.width + grid.xlim[0] - xlim[0]) / range[0];
y = canvas.height * (1 - (j * grid.width + grid.ylim[0] - ylim[0]) / range[1]);
z = (grid[i][j] - grid.zlim[0]) / range[2];
if (z < 0.0) z = 0.0;
if (z > 1.0) z = 1.0;
ctx.fillStyle = colors[Math.floor((colors.length - 1) * z)];
ctx.fillRect(Math.round(x - wx / 2), Math.round(y - wy / 2), wx, wy);
}
};
return kriging;
}();
// 修改为支持两种模块系统的写法
if (typeof module !== 'undefined' && module.exports) {
module.exports = kriging;
} else if (typeof define === 'function' && define.amd) {
define(function () { return kriging; });
}
// 添加 ES6 默认导出
export default kriging;

321
src/components/HistoryData/index.vue

@ -0,0 +1,321 @@ @@ -0,0 +1,321 @@
<template>
<div class="app-container app-container-bg">
<el-card class="first-card" ref='firstCard' shadow="always">
<el-form :model="queryParams" ref="queryForm" :inline="true" @submit.native.prevent>
<el-form-item label="测站名称" prop="stnmId">
<ESelectSingle ref="eSelectSingle" :stationType="stationType" @stationChange="handleStationChange" @loadingChange="handleStationLoading" />
</el-form-item>
<el-form-item label="开始时间">
<el-date-picker v-model="queryParams.startTime" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" format="YYYY-MM-DD HH:mm:ss" placeholder="选择开始时间" :disabled-date="disabledStartDate">
</el-date-picker>
</el-form-item>
<el-form-item label="结束时间">
<el-date-picker v-model="queryParams.endTime" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="选择结束时间" :disabled-date="disabledEndDate">
</el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">查询</el-button>
</el-form-item>
<el-form-item class="classification">
<div style="margin: -6px 0 0 0">设备故障: <span class="red">{{gzCount}}</span></div>
<div style="margin: -5px 0 0 0">数据异常: <span class="red">{{ycCount}}</span></div>
</el-form-item>
</el-form>
</el-card>
<splitpanes horizontal class="el-card-p card-shadow carder-border mt10 pad10 default-theme container-box" :push-other-panes="false">
<pane size="70" ref="firstPane" class="mr10">
<splitpanes :horizontal="device === 'mobile'" class=" default-theme" :push-other-panes="false">
<pane :size="100 - firstSize" class="mr10">
<div v-table-height='{bottom:0}' style="width:100%;">
<TimeBarChart v-loading="echartsLoading" :legendData='legendData' :xAxisData="xAxisData" :seriesData="seriesData" :textTitle="textTitle" :unit="unit" :echartType="echartType" />
</div>
</pane>
<pane :size="firstSize" :min-size="SPLITPANES_CONFIG.MIN_SIZE" :max-size="SPLITPANES_CONFIG.MAX_SIZE" ref="firstPane">
<div style="display:flex;align-items: center;" class="mb20">
<div class="ml10">主设备<span>{{zsbStcd}}</span></div>
</div>
<el-table min-height="500" v-loading="rightLoading" :data="tableData1" border style="height:88%;overflow: auto;">
<el-table-column prop="tm" label="时间" width="180" :align="alignment">
</el-table-column>
<el-table-column prop="value" label="数值" :align="alignment"></el-table-column>
</el-table>
</pane>
</splitpanes>
</pane>
<pane size="30">
<el-table v-table-height v-loading="loading" :data="alarmList" border>
<el-table-column label="测站类型" :align="alignment" prop="type" />
<el-table-column label="预警类型" :align="alignment" prop="alarmType" />
<el-table-column label="预警级别" :align="alignment" prop="alarmLevel" />
<el-table-column label="预警内容" :align="alignment" prop="alarmContent" width="600" />
<el-table-column label="预警时间" :align="alignment" prop="alarmTime" />
<el-table-column label="预警时长(时)" :align="alignment" prop="alarmTotalLength" />
<el-table-column label="预警状态" :align="alignment" prop="flag">
<template #default="scope">
<span v-if="scope.row.flag == 0 " class="red">预警中</span>
<span v-if="scope.row.flag == 1 " class="green">预警结束</span>
</template>
</el-table-column>
<el-table-column label="是否处理" :align="alignment" prop="isDeal">
<template #default="scope">
<span v-if="scope.row.isDeal == 'n' " class="red"></span>
<span v-if="scope.row.isDeal == 'y' " class="green"></span>
</template>
</el-table-column>
</el-table>
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
</pane>
</splitpanes>
</div>
</template>
<script setup>
import { ref, reactive, watch, toRaw, computed, onMounted } from 'vue'
import dayjs from 'dayjs';
import ESelectSingle from '@/components/ESelectSingle/index.vue'
import TimeBarChart from '@/components/ChartsTimeBar/index.vue'
import {
Splitpanes,
Pane
} from 'splitpanes'
import 'splitpanes/dist/splitpanes.css'
import useAppStore from '@/store/modules/app'
const device = computed(() => useAppStore().device);
const props = defineProps({
stationType: {
type: String,
default: 'A'
},
requestSuffix: {
type: String,
default: '/historydata'
},
fixed: {
type: Number,
default: 1
}
})
const {
proxy
} = getCurrentInstance()
const requestPrefix = '/history/data'
const alignment = 'center'
const textTitle = computed(() => {
switch (props.stationType) {
case 'A':
return '雨量过程线';
case 'B':
return '水位过程线';
case 'C':
return '水位过程线';
case 'D':
return '潮位过程线';
case 'E':
return '流量过程线';
}
});
const unit = computed(() => {
switch (props.stationType) {
case 'A':
return 'mm';
case 'B':
return 'm';
case 'C':
return 'm';
case 'D':
return 'm';
case 'E':
return 'm³/s';
}
});
const echartType = computed(() => {
switch (props.stationType) {
case 'A':
return 'bar';
case 'B':
return 'line';
case 'C':
return 'line';
case 'D':
return 'line';
case 'E':
return 'line';
}
});
const firstSize = ref(proxy.SPLITPANES_CONFIG.DEFAULT_SIZE)
const eSelectSingle = ref(null)
const handleStationLoading = (loadingState) => {
loading.value = loadingState;
}
//
const handleStationChange = async (stnmId) => {
queryParams.stnmId = stnmId
if (stnmId == undefined) {
proxy.$modal.msgWarning("请选择站点后查询");
return
} else {
try {
await Promise.all([
getList(),
drawTable1(),
getEchartsData()
]);
} catch (error) {
console.error('请求执行出错:', error);
}
}
}
const loading = ref(false);
const tableData = ref([]);
const queryParams = reactive({
stnmId: "",
startTime: dayjs().subtract(1, 'day').format('YYYY-MM-DD HH:mm:ss'),
endTime: dayjs().format('YYYY-MM-DD HH:mm:ss'),
pageNum: 1,
pageSize: 10,
stationType: props.stationType
})
const gzCount = ref(0)
const ycCount = ref(0)
const total = ref(0)
const alarmList = ref([])
const getList = async () => {
loading.value = true;
try {
const res = await proxy.axiosGet('/alarm/alarm/queryByStnmIdAndTm', queryParams)
if (res.code == 0) {
let data = res.data
total.value = res.count
gzCount.value = res.gzCount
ycCount.value = res.ycCount
for (var i = 0; i < data.length; i++) {
data[i].value = data[i].value.toFixed(proxy.fixed)
}
alarmList.value = data
}
} catch (error) {
} finally {
loading.value = false
}
};
const tableData1 = ref([]);
const rightLoading = ref(false);
// drawTable1
const drawTable1 = async () => {
let params = getParams();
rightLoading.value = true;
try {
let url = requestPrefix + '/originaldata';
let res = await proxy.axiosPost2(url, params);
if (res.code === 0) {
let data = res.data;
tableData1.value = data;
//
originalTableData1.value = JSON.parse(JSON.stringify(data));
isDataModified.value = false; //
}
} catch (error) {
console.error(error);
} finally {
rightLoading.value = false;
}
};
// echarts
const zsbStcd = ref('')
const legendData = ref([])
const xAxisData = ref([])
const seriesData = ref([])
const echartsLoading = ref(false)
const getEchartsData = async () => {
let params = getParams()
echartsLoading.value = true
let url = requestPrefix + props.requestSuffix
try {
let res = await proxy.axiosPost2(url, params);
if (res.code === 0) {
zsbStcd.value = res.data.zstcd
legendData.value = res.data.legend
// seriesdata
if (res.data.series && res.data.series.length > 0) {
// seriesdata
xAxisData.value = res.data.series[0].data.map(item => {
// item
if (typeof item === 'object' && item !== null) {
// tm, time, or the first element
const timeValue = item.tm || item.time || item[0];
return dayjs(timeValue).format('YYYY-MM-DD HH:mm');
} else {
// item
return dayjs(item).format('YYYY-MM-DD HH:mm');
}
});
}
seriesData.value = res.data.series
console.log(res, '======获取echarts数据', res.data, xAxisData)
}
} catch (error) {
} finally {
echartsLoading.value = false
}
};
//
const handleQuery = async () => {
try {
await Promise.all([
getList(),
drawTable1(),
getEchartsData()
]);
} catch (error) {
console.error('请求执行出错:', error);
}
}
onMounted(() => {
})
const getParams = () => {
let params = {
stnmId: queryParams.stnmId,
startTime: queryParams.startTime,
endTime: queryParams.endTime,
stationType: props.stationType
}
return params
}
//
const disabledStartDate = (time) => {
const endTime = queryParams.endTime ? dayjs(queryParams.endTime) : null;
return dayjs(time).isAfter(dayjs()) ||
(endTime && dayjs(time).isAfter(endTime));
};
//
const disabledEndDate = (time) => {
const startTime = queryParams.startTime ? dayjs(queryParams.startTime) : null;
return dayjs(time).isAfter(dayjs()) ||
(startTime && dayjs(time).isBefore(startTime));
};
</script>
<style scoped lang="scss">
.classification :deep(.el-form-item__content) {
flex-direction: column;
}
.splitpanes__splitter {
margin-bottom: 20px
}
</style>

345
src/components/HistoryYOY/index.vue

@ -0,0 +1,345 @@ @@ -0,0 +1,345 @@
<template>
<div class="app-container app-container-bg">
<el-card class="first-card" ref='firstCard' shadow="always">
<el-form :model="queryParams" ref="queryForm" :inline="true" @submit.native.prevent>
<el-form-item label="选择站点">
<el-tree-select filterable :props="{ value: 'stnmId', label: 'name' }" v-model="queryParams.stnmId" style="width: 240px" :data="treeSelectOptions" node-key="id" />
</el-form-item>
<el-form-item label="开始时间">
<el-date-picker :clearable="false" v-model="queryParams.startTime" type="datetime" value-format="MM-DD HH:mm" format="YYYY-MM-DD HH:mm:ss" placeholder="选择开始时间" :disabled-date="disabledStartDate">
</el-date-picker>
</el-form-item>
<el-form-item label="结束时间">
<el-date-picker :clearable="false" v-model="queryParams.endTime" type="datetime" value-format="MM-DD HH:mm" format="YYYY-MM-DD HH:mm:ss" placeholder="选择结束时间" :disabled-date="disabledEndDate">
</el-date-picker>
</el-form-item>
<br />
<el-form-item label="年份区间">
<el-date-picker :clearable="false" class="picker-year" style="width:180px" v-model="yearstart" type="year" value-format="YYYY" placeholder="选择开始年" @change="changeYearStart">
</el-date-picker>
<span class="pr10 pl10"> -</span>
<el-date-picker :clearable="false" class="picker-year" style="width:180px" v-model="yearend" type="year" value-format="YYYY" placeholder="选择结束年" @change="changeYearEnd">
</el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">查询</el-button>
<!-- <el-button type="warning" icon="Download" @click="handleExport">下载</el-button> -->
</el-form-item>
</el-form>
</el-card>
<div class="el-card-p card-shadow carder-border mt10 pad10" style="max-width: 100%; overflow-x: hidden;padding-top:0" v-loading="loading">
<div class="main-table-header sticky-header">
<div class="table-title">
<span class="pr10" v-if="stnm!==''">{{stnm}}</span>
<span v-else>{{tableTitle}}</span>
</div>
<div class="table-time mb5">
<div>
<span>年份: </span><span id="title1">{{queryParams.years }}</span>
</div>
<div>
<span>单位: </span><span id="title2">{{stationType=='E'?'m³/s':'m'}}</span>
</div>
</div>
</div>
<el-table v-table-height border :data="tableData" :span-method="arraySpanMethod" style="width: 100%;">
<el-table-column prop="year" label="年份" :align="alignment">
</el-table-column>
<el-table-column v-if="stationType == 'D'" prop="nvalue" label="当前潮位" :align="alignment">
</el-table-column>
<el-table-column v-if="stationType != 'D' && stationType != 'E'" prop="nvalue" label="当前水位" :align="alignment">
</el-table-column>
<el-table-column v-if="stationType == 'E'" prop="nvalue" label="当前流量" :align="alignment">
</el-table-column>
<el-table-column v-if="stationType == 'D'" prop="value" label="平均潮位" :align="alignment">
</el-table-column>
<el-table-column v-if="stationType != 'D' && stationType != 'E'" prop="value" label="平均水位" :align="alignment">
</el-table-column>
<el-table-column v-if="stationType == 'E'" prop="value" label="平均流量" :align="alignment">
</el-table-column>
<el-table-column label="最高潮位" :align="alignment" v-if="stationType == 'D'">
<el-table-column prop="maxvalue" label="潮位" :align="alignment">
</el-table-column>
<el-table-column label="时间" :align="alignment" width="180">
<template #default="scope">
<span>{{ parseTime(scope.row.maxtm) }}</span>
</template>
</el-table-column>
</el-table-column>
<el-table-column label="最高水位" :align="alignment" v-if="stationType != 'D' && stationType != 'E'">
<el-table-column prop="maxvalue" label="水位" :align="alignment">
</el-table-column>
<el-table-column label="时间" :align="alignment" width="180">
<template #default="scope">
<span>{{ parseTime(scope.row.maxtm) }}</span>
</template>
</el-table-column>
</el-table-column>
<el-table-column label="最高流量" :align="alignment" v-if="stationType == 'E'">
<el-table-column prop="maxvalue" label="流量" :align="alignment">
</el-table-column>
<el-table-column label="时间" :align="alignment" width="180">
<template #default="scope">
<span>{{ parseTime(scope.row.maxtm) }}</span>
</template>
</el-table-column>
</el-table-column>
<el-table-column label="最低潮位" :align="alignment" v-if="stationType == 'D'">
<el-table-column prop="minvalue" label="潮位" :align="alignment">
</el-table-column>
<el-table-column label="时间" :align="alignment" width="180">
<template #default="scope">
<span>{{ parseTime(scope.row.mintm) }}</span>
</template>
</el-table-column>
</el-table-column>
<el-table-column label="最低水位" :align="alignment" v-if="stationType != 'D' && stationType != 'E'">
<el-table-column prop="minvalue" label="水位" :align="alignment">
</el-table-column>
<el-table-column label="时间" :align="alignment" width="180">
<template #default="scope">
<span>{{ parseTime(scope.row.mintm) }}</span>
</template>
</el-table-column>
</el-table-column>
<el-table-column label="最低流量" :align="alignment" v-if="stationType == 'E'">
<el-table-column prop="minvalue" label="流量" :align="alignment">
</el-table-column>
<el-table-column label="时间" :align="alignment" width="180">
<template #default="scope">
<span>{{ parseTime(scope.row.mintm) }}</span>
</template>
</el-table-column>
</el-table-column>
</el-table>
</div>
</div>
</template>
<script setup>
import dayjs from 'dayjs';
import singleStation from '@/components/SingleStation/index.vue'
import { ref, reactive, onMounted } from 'vue';
const props = defineProps({
tableTitle: {
type: String,
default: '表格标题'
},
stationType: {
type: String,
default: 'A'
},
requestPrefix: {
type: String,
default: ""
}
})
const { proxy } = getCurrentInstance()
const alignment = 'center'
const type = computed(() => {
switch (props.stationType) {
case 'A':
return 'rain';
case 'B':
return 'river';
case 'C':
return 'rsvr';
case 'D':
return 'tide';
case 'E':
return 'q_qflow';
}
});
const tablename = computed(() => {
switch (props.stationType) {
case 'D':
return '潮位过程表';
case 'E':
return '流量过程表';
default:
return '水位过程表';
}
});
const loading = ref(false);
const tableData = ref([]);
const yearstart = ref(dayjs().subtract(1, 'year').format('YYYY'))
const yearend = ref(dayjs().format('YYYY'))
const queryParams = reactive({
startTime: dayjs().subtract(30, 'day').format('MM-DD 08:00'),
endTime: dayjs().format('MM-DD 08:00'),
years: `${yearstart.value}-${yearend.value}`,
stnmIds: '',
type: type.value
});
let total = ref(0)
let dataCount = ref(0)
const stnm = ref('')
const getList = async () => {
loading.value = true;
let url = `/report/${props.requestPrefix}`
try {
const res = await proxy.axiosGet(url, queryParams)
if (res.code == 0) {
let data = res.data.list
let { avg, max, min, list } = res.data
tableData.value = data;
if (data && data.length > 0) {
stnm.value = `${data[0].stnm}${queryParams.startTime} ~ ${queryParams.endTime}${tablename.value}`
}
console.log(avg[0], avg[1], avg[2], avg[3])
tableData.value.push({
year: "平均",
nvalue: (avg[0] == 0 ? "" : avg[0]),
value: (avg[1] == 0 ? "" : avg[1]),
maxvalue: (avg[2] == 0 ? "" : avg[2]),
minvalue: (avg[3] == 0 ? "" : avg[3]),
});
tableData.value.push({
year: "最高",
nvalue: (typeof (max[0].nvalue) == "undefined" ? "" : max[0].nvalue),
value: (typeof (max[1].value) == "undefined" ? "" : max[1].value),
maxvalue: (typeof (max[3].maxvalue) == "undefined" ? "" : max[3].maxvalue),
minvalue: (typeof (max[4].minvalue) == "undefined" ? "" : max[4].minvalue),
});
tableData.value.push({
year: "时间",
nvalue: (typeof (max[0].year) == "undefined" ? "" : max[0].year),
value: (typeof (max[1].year) == "undefined" ? "" : max[1].year),
maxvalue: (proxy.parseTime(typeof (max[3].maxtm)) == "undefined" ? "" : proxy.parseTime(max[3].maxtm)),
minvalue: (proxy.parseTime(typeof (max[4].mintm)) == "undefined" ? "" : proxy.parseTime(max[4].mintm)),
});
tableData.value.push({
year: "最低",
nvalue: (typeof (min[0].nvalue) == "undefined" ? "" : min[0].nvalue),
value: (typeof (min[1].value) == "undefined" ? "" : min[1].value),
maxvalue: (typeof (min[2].maxvalue) == "undefined" ? "" : min[2].maxvalue),
minvalue: (typeof (min[3].minvalue) == "undefined" ? "" : min[3].minvalue),
});
tableData.value.push({
year: "时间",
nvalue: (typeof (min[0].year) == "undefined" ? "" : min[0].year),
value: (typeof (min[1].year) == "undefined" ? "" : min[1].year),
maxvalue: (proxy.parseTime(typeof (min[2].maxtm)) == "undefined" ? "" : proxy.parseTime(min[2].maxtm)),
minvalue: (proxy.parseTime(typeof (min[3].mintm)) == "undefined" ? "" : proxy.parseTime(min[3].mintm)),
});
dataCount.value = tableData.value.length;
}
} catch (error) {
console.error(error)
} finally {
// loading
loading.value = false
}
}
const changeYearStart = (val) => {
yearstart.value = val
queryParams.years = `${yearstart.value}-${yearend.value}`
getList()
}
const changeYearEnd = (val) => {
yearend.value = val
queryParams.years = `${yearstart.value}-${yearend.value}`
getList()
}
//
const getPrevRow = (scope, field, type) => {
const rowIndex = scope.$index;
const data = scope.store.states.data;
// null
if (rowIndex === 0) return null;
//
let prevRowIndex = rowIndex - 1;
while (prevRowIndex >= 0 && (!data.value[prevRowIndex][field] || data.value[prevRowIndex][field] === '')) {
prevRowIndex--;
}
if (type == '1') {
field = 'month'
}
let result = prevRowIndex >= 0 ? data.value[prevRowIndex][field] : null;
// null
return result
};
const treeSelectOptions = ref([])
const getTreeStation = async () => {
loading.value = true;
try {
let res = await proxy.axiosGet('/basic/stype/getTreeStation2/' + proxy.stationType);
if (res.code == 0) {
treeSelectOptions.value = res.data
// stnmId
if (treeSelectOptions.value.length > 0) {
const firstLeafNode = findFirstLeafNode(treeSelectOptions.value);
if (firstLeafNode) {
queryParams.stnmId = firstLeafNode.stnmId;
nextTick(() => {
getList()
})
}
}
}
} catch (error) {
}
}
//
const findFirstLeafNode = (nodes) => {
for (let node of nodes) {
//
if (node.children && node.children.length > 0) {
const leaf = findFirstLeafNode(node.children);
if (leaf) {
return leaf;
}
}
//
else if (node.stnmId) {
return node;
}
}
return null;
}
//
const handleQuery = () => {
getList()
}
//
const handleExport = () => { }
onMounted(() => {
getTreeStation()
})
const arraySpanMethod = ({ row, column, rowIndex, columnIndex }) => {
if (dataCount.value > 4) {
if (rowIndex > dataCount.value - 6) {
if (columnIndex === 3 || columnIndex === 5) {
return [1, 2];
} else if (columnIndex === 4 || columnIndex === 6) {
return [0, 0];
}
}
}
}
</script>
<style scoped lang="scss">
.no-border-table :deep(.el-table__body-wrapper .el-table__cell) {
border-bottom: 0 !important;
}
.no-border-table :deep(.el-table__body-wrapper .el-table__cell) {
padding: 2px 0 !important;
}
.no-border-table :deep(.el-table__body-wrapper .el-table__row:nth-child(6n) .el-table__cell) {
padding: 10px 0 !important;
background-color: #f9f9f9;
}
</style>

173
src/components/TimeCount/index.vue

@ -0,0 +1,173 @@ @@ -0,0 +1,173 @@
<template>
<div class="app-container app-container-bg">
<el-card class="first-card" ref='firstCard' shadow="always">
<el-form :model="queryParams" ref="queryForm" :inline="true" @submit.native.prevent>
<el-form-item label="开始时间">
<el-date-picker v-model="queryParams.startTime" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" format="YYYY-MM-DD HH:mm:ss" placeholder="选择开始时间" :disabled-date="disabledStartDate">
</el-date-picker>
</el-form-item>
<el-form-item label="结束时间">
<el-date-picker v-model="queryParams.endTime" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" format="YYYY-MM-DD HH:mm:ss" placeholder="选择结束时间" :disabled-date="disabledEndDate">
</el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">查询</el-button>
</el-form-item>
</el-form>
</el-card>
<splitpanes :horizontal="device === 'mobile'" class="el-card-p card-shadow carder-border mt10 pad10 default-theme container-box" :push-other-panes="false">
<pane :size="firstSize" :min-size="SPLITPANES_CONFIG.MIN_SIZE" :max-size="SPLITPANES_CONFIG.MAX_SIZE" ref="firstPane" class="mr10">
<e-tree ref="eTreeRef" :stationType="stationType" @stationChange="handleStationChange" @loadingChange="handleStationLoading"></e-tree>
</pane>
<pane :size="100 - firstSize" style="height: 100%;">
<div class="main-table-header">
<div class="table-title">{{tableTitle}}</div>
</div>
<el-table v-table-height v-loading="loading" :data="tableData" border>
<el-table-column v-if="rsvrsdFlag" prop="typename" label="类型" :align="alignment">
</el-table-column>
<el-table-column v-if="!rsvrsdFlag" prop="area" label="区域" :align="alignment">
</el-table-column>
<el-table-column prop="stnm" label="站名" :align="alignment" width="200">
</el-table-column>
<el-table-column prop="minvalue" label="当前水位" :align="alignment">
</el-table-column>
<el-table-column prop="value" label="平均水位" :align="alignment">
</el-table-column>
<el-table-column label="最高水位" :align="alignment">
<el-table-column prop="maxvalue" label="水位" :align="alignment" width="80">
</el-table-column>
<el-table-column label="时间" :align="alignment" width="180" prop="maxtm"></el-table-column>
</el-table-column>
<el-table-column label="最低水位" :align="alignment">
<el-table-column prop="minvalue" label="水位" :align="alignment" width="80">
</el-table-column>
<el-table-column label="时间" :align="alignment" width="180" prop="mintm"></el-table-column>
</el-table-column>
<el-table-column prop="lsmaxvalue" label="历史最高" :align="alignment">
</el-table-column>
</el-table>
</pane>
</splitpanes>
</div>
</template>
<script setup>
import dayjs from 'dayjs';
import {
Splitpanes,
Pane
} from 'splitpanes'
import 'splitpanes/dist/splitpanes.css'
import ETree from '@/components/ETree/index.vue'
import useAppStore from '@/store/modules/app'
const device = computed(() => useAppStore().device);
const props = defineProps({
stationType: {
type: String,
default: 'A'
},
requestPrefix: {
type: String,
default: ""
}
})
const {
proxy
} = getCurrentInstance()
const type = computed(() => {
switch (props.stationType) {
case 'A':
return 'rain';
case 'B':
return 'river';
case 'C':
return 'rsvr';
case 'D':
return 'tide';
case 'E':
return 'q_qflow';
}
});
const alignment = 'center'
const firstSize = ref(proxy.SPLITPANES_CONFIG.DEFAULT_SIZE)
const eTreeRef = ref(null)
let stnmIdsList = []
const handleStationLoading = (loadingState) => {
loading.value = loadingState;
}
//
const handleStationChange = (stnmIds) => {
stnmIdsList = stnmIds
queryParams.stnmIds = stnmIds.join(',')
if (stnmIdsList.length == 0) {
proxy.$modal.msgWarning("请选择站点后查询");
return
} else if (stnmIdsList.length > 50) {
proxy.$modal.msg("站点最多可选择50个");
return
} else {
getList()
}
}
const queryParams = reactive({
startTime: dayjs().subtract(30, 'day').format('YYYY-MM-DD 08:00:00'),
endTime: dayjs().format('YYYY-MM-DD 08:00:00'),
type: type.value,
stnmIds: '',
});
//
const disabledStartDate = (time) => {
const endTime = queryParams.endTime ? dayjs(queryParams.endTime) : null;
return dayjs(time).isAfter(dayjs()) ||
(endTime && dayjs(time).isAfter(endTime));
};
//
const disabledEndDate = (time) => {
const startTime = queryParams.startTime ? dayjs(queryParams.startTime) : null;
return dayjs(time).isAfter(dayjs()) ||
(startTime && dayjs(time).isBefore(startTime));
};
const tableTitle = '水位时段统计(m)'
// stationType
const rsvrsdFlag = computed(() => {
return props.stationType == 'C'
})
const tableData = ref([])
const loading = ref(false)
// getList
const getList = async () => {
loading.value = true;
let url = `/report/${props.requestPrefix}`
try {
let res = await proxy.axiosPost2(url, queryParams)
if (res.code == 0) {
let data = res.data
data.map(item => {
item.maxtm = dayjs(item.maxtm).format('YYYY-MM-DD HH:mm:ss')
item.mintm = dayjs(item.mintm).format('YYYY-MM-DD HH:mm:ss')
return item
})
tableData.value = data
}
} catch (error) {
tableData.value = [];
} finally {
loading.value = false
}
}
//
const handleQuery = async () => {
getList()
}
</script>
<style lang="scss" scoped>
</style>

245
src/components/TimeProcess/index.vue

@ -0,0 +1,245 @@ @@ -0,0 +1,245 @@
<template>
<div class="app-container app-container-bg">
<el-card class="first-card" ref='firstCard' shadow="always">
<el-form :model="queryParams" ref="queryForm" :inline="true" @submit.native.prevent>
<el-form-item label="时间维度">
<el-select v-model="queryParams.dataType" placeholder="请选择时间维度" class="w150" @change="changeDataType">
<el-option v-for="item in dataTypes" :key="item.value" :label="item.label" :value="item.value">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="开始时间">
<el-date-picker v-model="queryParams.startTime" type="datetime" format="YYYY-MM-DD HH:mm:ss" placeholder="选择开始时间" :disabled-date="disabledStartDate" @change="(val)=>changeTime(val,'start')">
</el-date-picker>
</el-form-item>
<el-form-item label="结束时间">
<el-date-picker v-model="queryParams.endTime" type="datetime" format="YYYY-MM-DD HH:mm:ss" placeholder="选择结束时间" :disabled-date="disabledEndDate" @change="(val)=>changeTime(val,'end')">
</el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">查询</el-button>
</el-form-item>
</el-form>
</el-card>
<splitpanes :horizontal="device === 'mobile'" class="el-card-p card-shadow carder-border mt10 pad10 default-theme container-box" :push-other-panes="false">
<pane :size="firstSize" :min-size="SPLITPANES_CONFIG.MIN_SIZE" :max-size="SPLITPANES_CONFIG.MAX_SIZE" ref="firstPane" class="mr10">
<e-tree ref="eTreeRef" :stationType="stationType" @stationChange="handleStationChange"></e-tree>
</pane>
<pane :size="100 - firstSize">
<splitpanes horizontal class="default-theme" :push-other-panes="false">
<pane size="50">
<TimeBarChart v-loading="echartsLoading" :legendData='legendData' :xAxisData="xAxisData" :seriesData="seriesData" :echartType="echartType" :grid="grid" :BarFormatter="false" :unit="unit" />
</pane>
<pane size="50" class="mr10">
<div class="main-table-header">
<div class="table-title">{{tableTitle}}</div>
<div class="table-time mb5">
<div>
<span>时间: </span><span id="title1">{{ tableTime}}</span>
</div>
<div>
<span>单位: </span><span id="title2">mm</span>
</div>
</div>
</div>
<el-table v-loading="loading" ref="myTable" :data="tableData" v-table-height="{bottom:90}" border>
<el-table-column :align="alignment" :width="item.label == '时间' ? '180': '' " :prop="item.prop" :label="item.label" v-for="(item, index) in tableHead" :key="index"></el-table-column>
</el-table>
</pane>
</splitpanes>
</pane>
</splitpanes>
</div>
</template>
<script setup>
import dayjs from 'dayjs';
import {
Splitpanes,
Pane
} from 'splitpanes'
import 'splitpanes/dist/splitpanes.css'
import BarChart from '@/components/ChartsBar/index.vue'
import TimeBarChart from '@/components/ChartsTimeBar/index.vue'
import ETree from '@/components/ETree/index.vue'
import useAppStore from '@/store/modules/app'
const device = computed(() => useAppStore().device);
const props = defineProps({
stationType: {
type: String,
default: 'A'
},
tableTitle: {
type: String,
default: '表格标题'
},
requestPrefix: {
type: String,
default: ''
},
requestPrefixTable: {
type: String,
default: ''
}
})
const { proxy } = getCurrentInstance()
const alignment = 'center'
let unit = ref('m')
const eTreeRef = ref(null)
let stnmIdsList = []
//
const handleStationChange = (stnmIds) => {
stnmIdsList = stnmIds
queryParams.stnmIds = stnmIds.join(',')
if (stnmIdsList.length == 0) {
proxy.$modal.msgWarning("请选择站点后查询");
return
} else if (stnmIdsList.length > 50) {
proxy.$modal.msg("站点最多可选择50个");
return
} else {
getList()
getEchartsData()
}
}
const queryParams = reactive({
startTime: dayjs().subtract(7, 'day').format('YYYY-MM-DD 08:00:00'),
endTime: dayjs().format('YYYY-MM-DD 08:00:00'),
dataType: '0',
});
//
const disabledStartDate = (time) => {
const endTime = queryParams.endTime ? dayjs(queryParams.endTime) : null;
return dayjs(time).isAfter(dayjs()) ||
(endTime && dayjs(time).isAfter(endTime));
};
//
const disabledEndDate = (time) => {
const startTime = queryParams.startTime ? dayjs(queryParams.startTime) : null;
return dayjs(time).isAfter(dayjs()) ||
(startTime && dayjs(time).isBefore(startTime));
};
const tableTime = ref(queryParams.startTime.substring(0, 16) + " 至 " + queryParams.endTime.substring(0, 16))
const timeType = ref('day')
//
const changeDataType = (val) => {
queryParams.dataType = val
if (val == 0) {
tableTime.value = queryParams.startTime.substring(0, 16) + " 至 " + queryParams.endTime.substring(0, 16);
} else {
tableTime.value = queryParams.startTime.substring(0, 10) + " 至 " + queryParams.endTime.substring(0, 10);
}
getList()
getEchartsData()
}
//
const changeTime = (val, type = 'start') => {
if (type == 'start') {
queryParams.startTime = dayjs(val).format('YYYY-MM-DD HH:mm:ss')
} else {
queryParams.endTime = dayjs(val).format('YYYY-MM-DD HH:mm:ss')
}
}
const firstSize = ref(proxy.SPLITPANES_CONFIG.DEFAULT_SIZE)
const loading = ref(false)
const tableData = ref([])
const tableHead = ref([])
const getList = async () => {
loading.value = true;
try {
let res = await proxy.axiosPost2(props.requestPrefixTable, queryParams)
if (res.code == 0) {
tableHead.value = handleTableHead(res.data)
let data = res.data.slice(1)
if (queryParams.dataType == 1) {
data.map(item => { item.tm = item.tm.slice(0, 10) })
} else {
data.map(item => { item.tm = item.tm.slice(0, 16) })
}
tableData.value = data
}
} catch (error) {
tableHead.value = [];
tableData.value = [];
} finally {
loading.value = false
}
}
// res.data
const handleTableHead = (data) => {
if (!data || data.length === 0) return [];
const firstRow = data[0]; //
const head = [];
// ""
head.push({ prop: 'tm', label: '时间' });
// firstRow key-value
Object.keys(firstRow).forEach(key => {
if (key !== 'avg' && key !== 'tm') {
head.push({ prop: key, label: firstRow[key] });
}
});
return head;
};
const legendData = ref([])
const xAxisData = ref([])
const seriesData = ref([])
const echartsLoading = ref(false)
const getEchartsData = async () => {
echartsLoading.value = true
try {
let res = await proxy.axiosPost2(props.requestPrefix, queryParams);
if (res.code === 0) {
legendData.value = res.data.legend
// seriesdata
if (res.data.series && res.data.series.length > 0) {
// seriesdata
xAxisData.value = res.data.series[0].data.map(item => {
// item
if (typeof item === 'object' && item !== null) {
// tm, time, or the first element
const timeValue = item.tm || item.time || item[0];
return dayjs(timeValue).format('YYYY-MM-DD HH:mm');
} else {
// item
return dayjs(item).format('YYYY-MM-DD HH:mm');
}
});
}
seriesData.value = res.data.series
}
} catch (error) {
} finally {
echartsLoading.value = false
}
};
const echartType = ref('line')
const handleQuery = () => {
getList()
getEchartsData()
}
const dataTypes = ref([
{ label: '5分钟', value: '-1' },
{ label: '小时', value: '0' },
{ label: '日', value: '1' }
])
const grid = {
left: "5%",
right: "5%",
bottom: "10%",
top: "10%",
containLabel: true,
}
</script>
<style lang="scss" scoped>
:deep(.el-tabs),
:deep(.el-tabs .el-tabs__content) {
height: 100%;
}
</style>

283
src/components/YearEigenvalue/index.vue

@ -0,0 +1,283 @@ @@ -0,0 +1,283 @@
<template>
<div class="app-container app-container-bg">
<el-card class="first-card" ref='firstCard' shadow="always">
<el-form :model="queryParams" ref="queryForm" :inline="true" @submit.native.prevent>
<el-form-item label="年份区间">
<el-date-picker class="picker-year" style="width:180px" v-model="queryParams.startTime" type="year" value-format="YYYY" placeholder="选择开始年" @change="handleQuery">
</el-date-picker>
<span class="pr10 pl10"> - </span>
<el-date-picker class="picker-year" style="width:180px" v-model="queryParams.endTime" type="year" value-format="YYYY" placeholder="选择结束年" @change="handleQuery">
</el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">查询</el-button>
</el-form-item>
<br />
<el-form-item label="报表排列方式(按站点)">
<el-radio-group v-model="direction" @change="getList">
<el-radio label="zx">纵向</el-radio>
<el-radio label="hx">横向</el-radio>
</el-radio-group>
</el-form-item>
</el-form>
</el-card>
<splitpanes :horizontal="device === 'mobile'" class="el-card-p card-shadow carder-border mt10 pad10 default-theme container-box" :push-other-panes="false">
<pane :size="firstSize" :min-size="SPLITPANES_CONFIG.MIN_SIZE" :max-size="SPLITPANES_CONFIG.MAX_SIZE" ref="firstPane" class="mr10">
<e-tree ref="eTreeRef" :stationType="stationType" @stationChange="handleStationChange"></e-tree>
</pane>
<pane :size="100 - firstSize">
<div class="main-table-header">
<div class="table-title">{{tableTitle}}</div>
</div>
<el-table v-if="direction=='zx'" v-loading="loading" ref="myTable" :data="tableData" v-table-height="{bottom:90}" border :span-method="arraySpanMethod">
<el-table-column prop="station" label="站点" :align="alignment" :rowspan="getRowspan"></el-table-column>
<el-table-column prop="type" label="" :align="alignment"></el-table-column>
<el-table-column :align="alignment" :prop="item.prop" :label="item.label" v-for="(item, index) in tableColumns.filter(col => col.prop !== 'station' && col.prop !== 'type')" :key="index"></el-table-column>
</el-table>
<el-table v-if="direction=='hx'" v-table-height v-loading="loading" :data="tableData" border :span-method="arraySpanMethod">
<el-table-column label="年份" prop="time" :align="alignment"></el-table-column>
<el-table-column :align="alignment" v-for="(column, index) in tableColumns" :key="column.prop" :prop="column.prop" :label="column.label" :min-width="120">
<el-table-column label="平均水位" :prop="'avg'+index" :align="alignment"></el-table-column>
<el-table-column label="最高水位" :prop="'maxValue'+index" :align="alignment"></el-table-column>
<el-table-column label="时间" :prop="'maxtm'+index" :align="alignment"></el-table-column>
<el-table-column label="最低水位" :prop="'minValue'+index" :align="alignment"></el-table-column>
<el-table-column label="时间" :prop="'mintm'+index" :align="alignment"></el-table-column>
</el-table-column>
</el-table>
</pane>
</splitpanes>
</div>
</template>
<script setup>
import dayjs from 'dayjs';
import {
Splitpanes,
Pane
} from 'splitpanes'
import 'splitpanes/dist/splitpanes.css'
import ETree from '@/components/ETree/index.vue'
import useAppStore from '@/store/modules/app'
const device = computed(() => useAppStore().device);
const props = defineProps({
//
stationType: {
type: String,
default: 'A'
},
//
requestPrefix: {
type: String,
default: ''
},
//
tableName: {
type: String,
default: ""
},
})
const { proxy } = getCurrentInstance()
const alignment = 'center'
let direction = ref('zx')
const eTreeRef = ref(null)
const tableTitle = '水位年特征值表(m)'
let stnmIdsList = []
//
const handleStationChange = (stnmIds) => {
stnmIdsList = stnmIds
queryParams.stnmIds = stnmIds.join(',')
if (stnmIdsList.length == 0) {
proxy.$modal.msgWarning("请选择站点后查询");
return
} else if (stnmIdsList.length > 50) {
proxy.$modal.msg("站点最多可选择50个");
return
} else {
getList()
}
}
const queryParams = reactive({
startTime: dayjs().subtract(1, 'year').format('YYYY'),
endTime: dayjs().format('YYYY'),
tableName: props.tableName,
valueType: "all"
});
const firstSize = ref(proxy.SPLITPANES_CONFIG.DEFAULT_SIZE)
const loading = ref(false)
const tableColumns = ref([])
const tableData = ref([])
const getList = async () => {
loading.value = true;
let url = `/report/${props.requestPrefix}`
try {
let res = await proxy.axiosPost2(url, queryParams)
if (res.code == 0) {
if (direction.value == 'zx') {
getZXTableData(res)
} else {
getHXTableData(res)
}
}
} catch (error) {
tableColumns.value = [];
tableData.value = [];
} finally {
loading.value = false
}
}
// getZXTableData
const getZXTableData = (res) => {
let { year, list, name } = res.data;
let columns = [
{
prop: "station",
label: "站点"
},
{
prop: "type",
label: ""
}
]
//
year.forEach(item => {
columns.push({
prop: item,
label: item
});
});
tableColumns.value = columns
//
let processedData = [];
list.forEach((item, index) => {
//
const row1 = {
station: name[index],
type: "平均水位"
};
year.forEach((y, yIndex) => {
row1[y] = item[yIndex] && item[yIndex].value !== undefined ? item[yIndex].value : '-';
});
//
const row2 = {
station: name[index],
type: "最高水位"
};
year.forEach((y, yIndex) => {
row2[y] = item[yIndex] && item[yIndex].maxValue !== undefined ? item[yIndex].maxValue : '-';
});
//
const row3 = {
station: name[index],
type: "时间"
};
year.forEach((y, yIndex) => {
row3[y] = item[yIndex] && item[yIndex].maxtm !== undefined ?
proxy.parseTime(item[yIndex].maxtm, '{y}-{m}-{d}') : '-';
});
//
const row4 = {
station: name[index],
type: "最低水位"
};
year.forEach((y, yIndex) => {
row4[y] = item[yIndex] && item[yIndex].minValue !== undefined ? item[yIndex].minValue : '-';
});
//
const row5 = {
station: name[index],
type: "时间"
};
year.forEach((y, yIndex) => {
row5[y] = item[yIndex] && item[yIndex].mintm !== undefined ?
proxy.parseTime(item[yIndex].mintm, '{y}-{m}-{d}') : '-';
});
processedData.push(row1);
processedData.push(row2);
processedData.push(row3);
processedData.push(row4);
processedData.push(row5);
});
// tableData
tableData.value = processedData;
}
const getHXTableData = (res) => {
const { year, list, name, } = res.data;
if (!year || !list || !name) {
tableData.value = [];
return;
}
const columns = name.map(stationName => ({
prop: stationName,
label: stationName
}));
tableColumns.value = columns;
const processedData = [];
//
year.forEach(y => {
const row = { time: y };
name.forEach((stationName, idx) => {
const stationIndex = name.indexOf(stationName);
const stationList = list[stationIndex];
if (!stationList || stationList.length === 0) {
row[stationName] = { avg: "-", maxValue: '-', maxtm: '-', minValue: '-', mintm: '-' };
return;
}
const valueItem = stationList[0]; //
row['avg' + idx] = valueItem.value ? valueItem.value : '-'
row['maxValue' + idx] = valueItem.maxValue ? valueItem.maxValue : '-'
row['maxtm' + idx] = valueItem.maxtm ? valueItem.maxtm : '-'
row['minValue' + idx] = valueItem.minValue ? valueItem.minValue : '-'
row['mintm' + idx] = valueItem.mintm ? valueItem.mintm : '-'
});
processedData.push(row);
});
tableData.value = processedData;
};
//
const arraySpanMethod = ({ row, column, rowIndex, columnIndex }) => {
if (direction.value == 'zx') {
if (columnIndex === 0) {
//
if (rowIndex % 5 === 0) {
//
return [5, 1];
} else {
//
return [0, 0];
}
}
}
return [1, 1];
}
const handleQuery = () => {
getList()
}
</script>

1
src/router/index.js

@ -184,6 +184,7 @@ const router = createRouter({ @@ -184,6 +184,7 @@ const router = createRouter({
return { top: 0 }
}
},
strict: process.env.NODE_ENV === 'development'
});

86
src/views/statistic/rsvr/rsvr_main.vue

@ -0,0 +1,86 @@ @@ -0,0 +1,86 @@
<template>
<div class="report-rain">
<div class="tjfx-menu">
<el-select v-model="menu" placeholder="请选择">
<el-option v-for="dict in tjfxMenus" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</div>
<!-- 添加加载状态和错误提示 -->
<el-empty v-if="componentError" class="error-message" description="组件加载失败,请刷新页面重试" />
<component :is="currentComponent" :tableTitle="tableTitle"></component>
</div>
</template>
<script setup>
import { ref, computed, defineAsyncComponent } from 'vue'
//
const tjfxMenus = [
{
value: '1',
label: '时段过程'
},
{
value: '2',
label: '年特征值'
}, {
value: '3',
label: '时段统计'
}, {
value: '4',
label: '历史同期对比'
}
]
//
const menu = ref(tjfxMenus.length > 0 ? tjfxMenus[0].value : '')
//
const componentMap = {
'1': defineAsyncComponent(() => import('@/views/statistic/rsvr/sdrsvr.vue')),
'2': defineAsyncComponent(() => import('@/views/statistic/rsvr/rsvrtzz.vue')),
'3': defineAsyncComponent(() => import('@/views/statistic/rsvr/rsvrsd.vue')),
'4': defineAsyncComponent(() => import('@/views/statistic/rsvr/rsvrls.vue'))
}
//
const componentError = ref(false)
onErrorCaptured((error) => {
componentError.value = true
return true
})
//
const currentComponent = computed(() => {
return componentMap[menu.value]
})
// tjfxMenus name
const tableTitle = computed(() => {
const currentItem = tjfxMenus.find(item => item.value === menu.value);
return currentItem ? currentItem.label : '';
})
</script>
<style lang="scss">
.tjfx-menu {
position: absolute;
right: 25px;
top: 30px;
z-index: 999999;
.el-input__wrapper {
background: #10163A;
}
.el-input__inner {
background: #10163A;
color: #fff;
border-color: #10163A;
}
.el-select .el-input .el-select__caret {
color: #fff !important;
}
}
</style>

10
src/views/statistic/rsvr/rsvrls.vue

@ -0,0 +1,10 @@ @@ -0,0 +1,10 @@
<template>
<history-yoy :stationType="stationType" :fixed="fixed" :requestPrefix="requestPrefix" :tableTitle="title"></history-yoy>
</template>
<script setup>
import HistoryYoy from '@/components/HistoryYOY/index.vue'
const stationType = ref('C')
const fixed = ref(1)
const requestPrefix = ref('history')
const title = '水库水位历史同期对比'
</script>

10
src/views/statistic/rsvr/rsvrsd.vue

@ -0,0 +1,10 @@ @@ -0,0 +1,10 @@
<template>
<time-count :stationType="stationType" :fixed="fixed" :requestPrefix="requestPrefix" :tableTitle="title"></time-count>
</template>
<script setup>
import TimeCount from '@/components/TimeCount/index.vue'
const stationType = ref('C')
const fixed = ref(1)
const requestPrefix = ref('sddata')
const title = '水库水位时段统计(m)'
</script>

307
src/views/statistic/rsvr/rsvrtzz copy.vue

@ -0,0 +1,307 @@ @@ -0,0 +1,307 @@
<template>
<div class="app-container app-container-bg">
<el-card class="first-card" ref='firstCard' shadow="always">
<el-form :model="queryParams" ref="queryForm" :inline="true" @submit.native.prevent>
<el-form-item label="开始时间">
<el-date-picker v-model="queryParams.startTime" type="datetime" value-format="MM-DD" format="YYYY-MM-DD HH:mm:ss" placeholder="选择开始时间" :disabled-date="disabledStartDate">
</el-date-picker>
</el-form-item>
<el-form-item label="结束时间">
<el-date-picker v-model="queryParams.endTime" type="datetime" value-format="MM-DD" format="YYYY-MM-DD HH:mm:ss" placeholder="选择结束时间" :disabled-date="disabledEndDate">
</el-date-picker>
</el-form-item>
<el-form-item label="年份区间">
<el-date-picker class="picker-year" style="width:120px" v-model="yearstart" type="year" value-format="YYYY" placeholder="选择开始年">
</el-date-picker>
<span class="pr10 pl10"> - </span>
<el-date-picker class="picker-year" style="width:120px" v-model="yearend" type="year" value-format="YYYY" placeholder="选择结束年">
</el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">查询</el-button>
</el-form-item>
<br />
<el-form-item label="报表排列方式(按站点)">
<el-radio-group v-model="direction" @change="getList">
<el-radio label="zx">纵向</el-radio>
<el-radio label="hx">横向</el-radio>
</el-radio-group>
</el-form-item>
</el-form>
</el-card>
<splitpanes :horizontal="device === 'mobile'" class="el-card-p card-shadow carder-border mt10 pad10 default-theme container-box" :push-other-panes="false">
<pane :size="firstSize" :min-size="SPLITPANES_CONFIG.MIN_SIZE" :max-size="SPLITPANES_CONFIG.MAX_SIZE" ref="firstPane" class="mr10">
<e-tree ref="eTreeRef" :stationType="stationType" @stationChange="handleStationChange" @loadingChange="handleStationLoading"></e-tree>
</pane>
<pane :size="100 - firstSize" style="height: 100%;">
<div class="main-table-header">
<div class="table-title">{{tableTitle}}</div>
</div>
<el-table v-table-height v-loading="loading" :data="tableData" border :span-method="arraySpanMethod">
<el-table-column :align="alignment" v-for="column in tableColumns" :key="column.prop" :prop="column.prop" :label="column.label" :min-width="column.width || 120">
</el-table-column>
</el-table>
</pane>
</splitpanes>
</div>
</template>
<script setup>
import dayjs from 'dayjs';
import {
Splitpanes,
Pane
} from 'splitpanes'
import 'splitpanes/dist/splitpanes.css'
import ETree from '@/components/ETree/index.vue'
import useAppStore from '@/store/modules/app'
const device = computed(() => useAppStore().device);
const props = defineProps({
})
const {
proxy
} = getCurrentInstance()
const { update_type_options } = proxy.useDict("update_type_options")
const stationType = 'A'
const alignment = 'center'
const firstSize = ref(proxy.SPLITPANES_CONFIG.DEFAULT_SIZE)
const direction = ref('zx')
const eTreeRef = ref(null)
let stnmIdsList = []
const handleStationLoading = (loadingState) => {
loading.value = loadingState;
}
//
const handleStationChange = (stnmIds) => {
stnmIdsList = stnmIds
queryParams.stnmIds = stnmIds.join(',')
if (stnmIdsList.length == 0) {
proxy.$modal.msgWarning("请选择站点后查询");
return
} else if (stnmIdsList.length > 50) {
proxy.$modal.msg("站点最多可选择50个");
return
} else {
getList()
}
}
const yearstart = ref(dayjs().subtract(1, 'year').format('YYYY'))
const yearend = ref(dayjs().format('YYYY'))
const queryParams = reactive({
startTime: dayjs().subtract(7, 'day').format('MM-DD'),
endTime: dayjs().format('MM-DD'),
years: `${yearstart.value}-${yearend.value}`,
stnmIds: '',
});
//
const disabledStartDate = (time) => {
const endTime = queryParams.endTime ? dayjs(queryParams.endTime) : null;
return dayjs(time).isAfter(dayjs()) ||
(endTime && dayjs(time).isAfter(endTime));
};
//
const disabledEndDate = (time) => {
const startTime = queryParams.startTime ? dayjs(queryParams.startTime) : null;
return dayjs(time).isAfter(dayjs()) ||
(startTime && dayjs(time).isBefore(startTime));
};
const tableTitle = computed(() => {
const startFormatted = dayjs(queryParams.startTime, 'MM-DD').format('MM月DD日');
const endFormatted = dayjs(queryParams.endTime, 'MM-DD').format('MM月DD日');
return `${startFormatted}~${endFormatted}历史同期降水量表(mm)`;
});
const tableColumns = ref([])
const tableData = ref([])
const loading = ref(false)
// getList
const getList = async () => {
loading.value = true;
try {
let res = await proxy.axiosPost2('/report/rainhistorycount', queryParams)
if (res.code == 0) {
if (direction.value == 'zx') {
getZXTableData(res)
} else {
getHXTableData(res)
}
}
} catch (error) {
tableColumns.value = [];
tableData.value = [];
} finally {
loading.value = false
}
}
const getZXTableData = (res) => {
let { year, list, name, max, min } = res.data;
let columns = [
{
prop: "station",
label: "站点"
},
{
prop: "type",
label: ""
}
]
//
year.forEach(item => {
columns.push({
prop: item,
label: item
});
});
tableColumns.value = columns
// -
const processedData = [];
list.forEach((item, index) => {
// ""
const row1 = {
station: name[index],
type: "平均水位"
};
year.forEach(y => {
row1[y] = item[0].value ? item[0].value.toFixed(1) : '-';
});
// const row2 = {
// station: name[index],
// type: ""
// };
// year.forEach(y => {
// row2[y] = item[0].value ? item[0].value.toFixed(1) : '-';
// });
// const row3 = {
// station: name[index],
// type: ""
// };
// year.forEach(y => {
// row3[y] = item[0].tm ? item[0].tm : '-';
// });
// const row4 = {
// station: name[index],
// type: ""
// };
// year.forEach(y => {
// row4[y] = item[0].value ? item[0].value.toFixed(1) : '-';
// });
// const row5 = {
// station: name[index],
// type: ""
// };
// year.forEach(y => {
// row5[y] = item[0].tm ? item[0].tm : '-';
// });
processedData.push(row1);
// processedData.push(row2);
// processedData.push(row3);
// processedData.push(row4);
// processedData.push(row5);
});
console.log(processedData, 'processedData')
tableData.value = processedData;
}
const getHXTableData = (res) => {
const { year, list, name, max, min } = res.data;
if (!year || !list || !name || !max || !min) {
console.error('数据缺失:', { year, list, name, max, min });
tableData.value = [];
return;
}
const columns = name.map(stationName => ({
prop: stationName,
label: stationName
}));
tableColumns.value = columns;
console.log(columns, 'tableColumns')
const processedData = [];
//
year.forEach(y => {
const row = { time: y };
name.forEach((stationName, idx) => {
const stationIndex = name.indexOf(stationName);
const stationList = list[stationIndex];
if (!stationList || stationList.length === 0) {
row[stationName] = { rain: '-', tm: '-' };
return;
}
const valueItem = stationList[0]; //
row['rain' + idx] = valueItem.value ? valueItem.value.toFixed(1) : '-'
row['tm' + idx] = valueItem.tm ? valueItem.tm.slice(5) : '-'
});
processedData.push(row);
});
//
processedData.push({
time: '最大值',
...name.reduce((acc, stationName, index) => {
acc['rain' + index] = max[index]?.value ? max[index]?.value.toFixed(1) : '-';
acc['tm' + index] = max[index]?.tm ? max[index].tm : '-';
return acc;
}, {})
});
//
processedData.push({
time: '最小值',
...name.reduce((acc, stationName, index) => {
acc['rain' + index] = min[index]?.value ? min[index]?.value.toFixed(1) : '-';
acc['tm' + index] = min[index]?.tm ? min[index].tm : '-';
return acc;
}, {})
});
tableData.value = processedData;
};
//
const handleQuery = async () => {
getList()
}
//
const arraySpanMethod = ({ row, column, rowIndex, columnIndex }) => {
//
const columnCount = tableColumns.value.length;
// /
if (columnIndex === columnCount - 1 || columnIndex === columnCount - 2) {
return [1, 1];
}
//
if (columnIndex === 0) {
//
if (rowIndex % 2 === 0) {
//
return [2, 1];
} else {
//
return [0, 0];
}
}
//
if (rowIndex % 2 === 0) {
//
return [2, 1];
} else {
//
return [0, 0];
}
}
</script>
<style lang="scss" scoped>
</style>

11
src/views/statistic/rsvr/rsvrtzz.vue

@ -0,0 +1,11 @@ @@ -0,0 +1,11 @@
<template>
<year-eigenvalue :stationType="stationType" :fixed="fixed" :requestPrefix="requestPrefix" :tableTitle="title" :tableName="tableName"></year-eigenvalue>
</template>
<script setup>
import YearEigenvalue from '@/components/YearEigenvalue/index.vue'
const stationType = ref('C')
const fixed = ref(1)
const requestPrefix = ref('tzzdatahistory')
let title = '水位年特征值表(m)'
let tableName=ref('arch_char_rsvr')
</script>

11
src/views/statistic/rsvr/sdrsvr.vue

@ -0,0 +1,11 @@ @@ -0,0 +1,11 @@
<template>
<time-process :stationType="stationType" :fixed="fixed" :requestPrefix="requestPrefix" :requestPrefixTable="requestPrefixTable" :tableTitle="title"></time-process>
</template>
<script setup>
import TimeProcess from '@/components/TimeProcess/index.vue'
const stationType = ref('C')
const fixed = ref(1)
const requestPrefix = ref('/ycrsvrdata/chartdata')
const requestPrefixTable = ref('/ycrsvrdata/gettabledataopen')
const title = '水位时段过程'
</script>

4
vite.config.js

@ -10,7 +10,7 @@ export default defineConfig(({ mode, command }) => { @@ -10,7 +10,7 @@ export default defineConfig(({ mode, command }) => {
// 部署生产环境和开发环境下的URL。
// 默认情况下,vite 会假设你的应用是被部署在一个域名的根路径上
// 例如 https://www.ruoyi.vip/。如果应用被部署在一个子路径上,你就需要用这个选项指定这个子路径。例如,如果你的应用被部署在 https://www.ruoyi.vip/admin/,则设置 baseUrl 为 /admin/。
base: VITE_APP_ENV === 'production' ? '/' : '/',
base: VITE_APP_ENV === 'production' ? '/' : '/report/',
plugins: createVitePlugins(env, command === 'build'),
resolve: {
// https://cn.vitejs.dev/config/#resolve-alias
@ -31,7 +31,7 @@ export default defineConfig(({ mode, command }) => { @@ -31,7 +31,7 @@ export default defineConfig(({ mode, command }) => {
proxy: {
// https://cn.vitejs.dev/config/#server-proxy
'/dev-api': {
target: 'http://localhost:8080',
target: 'http://localhost:8080/report',
changeOrigin: true,
rewrite: (p) => p.replace(/^\/dev-api/, '')
}

Loading…
Cancel
Save