输运模拟、天气预报、源项重建运行日志,以及输运模拟生成GIF日志统一样式

This commit is contained in:
冯少康 2026-07-31 17:53:47 +08:00
parent b1444157ac
commit af3ac25fef
11 changed files with 1229 additions and 771 deletions

View File

@ -8,7 +8,7 @@
z-index: 1; z-index: 1;
color: #fff; color: #fff;
pointer-events: none; pointer-events: none;
user-select: none; /* user-select: none; */
* { * {
pointer-events: auto; pointer-events: auto;

View File

@ -154,7 +154,7 @@
background: red !important; background: red !important;
} }
:deep(.el-popper.is-dark > :first-child) { :deep(.el-popper.is-dark > :first-child) {
user-select: none !important; /* user-select: none !important; */
} }
.my-loading { .my-loading {

View File

@ -7,8 +7,13 @@ import { mapRightMenuEvent } from "@/gis/ol/olRightMenu";
import { getGif } from "@/utils/axios/symn"; import { getGif } from "@/utils/axios/symn";
import { useI18n } from "vue-i18n"; import { useI18n } from "vue-i18n";
import { ElMessage } from "element-plus"; import { ElMessage } from "element-plus";
import log from '@/pages/symn/log/index.vue';
import { getrwssGifFileData, downGifSsFile,getRwscGifFileGcrz } from "@/utils/axios/fskjk"; import {
getrwssGifFileData,
downGifSsFile,
getRwscGifFileGcrz,
} from "@/utils/axios/fskjk";
const { t } = useI18n(); const { t } = useI18n();
@ -231,12 +236,12 @@ function handleIconClick(item: MapControlItem) {
// gif // gif
else if (item.name === "gif") { else if (item.name === "gif") {
let taskId = JSON.parse(sessionStorage.getItem("ssmnDataItem")).id; let taskId = JSON.parse(sessionStorage.getItem("ssmnDataItem")).id;
let speciesId = JSON.parse(sessionStorage.getItem("symnZxHsId"))||""; let speciesId = JSON.parse(sessionStorage.getItem("symnZxHsId")) || "";
getGif( getGif(
{ {
taskId, taskId,
genGifType: "global", genGifType: "global",
speciesId speciesId,
}, },
(res: any) => { (res: any) => {
gifSrc.value = window.FSXConfig.VUE_APP_SERVER_IP + res; gifSrc.value = window.FSXConfig.VUE_APP_SERVER_IP + res;
@ -289,7 +294,7 @@ function switchIconActive(key: string, falg: boolean) {
// GIF // GIF
const generateGif = () => { const generateGif = () => {
let taskId = JSON.parse(sessionStorage.getItem("ssmnDataItem")).id; let taskId = JSON.parse(sessionStorage.getItem("ssmnDataItem")).id;
let speciesId = JSON.parse(sessionStorage.getItem("symnZxHsId"))||""; let speciesId = JSON.parse(sessionStorage.getItem("symnZxHsId")) || "";
getrwssGifFileData( getrwssGifFileData(
{ {
taskId, taskId,
@ -308,7 +313,7 @@ const generateGif = () => {
// GIF // GIF
const downGifFile = () => { const downGifFile = () => {
let taskId = JSON.parse(sessionStorage.getItem("ssmnDataItem")).id; let taskId = JSON.parse(sessionStorage.getItem("ssmnDataItem")).id;
let speciesId = JSON.parse(sessionStorage.getItem("symnZxHsId"))||""; let speciesId = JSON.parse(sessionStorage.getItem("symnZxHsId")) || "";
downGifSsFile( downGifSsFile(
{ {
taskId, taskId,
@ -333,22 +338,22 @@ const downGifFile = () => {
}; };
// //
const viewLogs = ()=>{ const viewLogs = () => {
viewLogsDialog.value = true; viewLogsDialog.value = true;
let taskId = JSON.parse(sessionStorage.getItem("ssmnDataItem")).id; let taskId = JSON.parse(sessionStorage.getItem("ssmnDataItem")).id;
let speciesId = JSON.parse(sessionStorage.getItem("symnZxHsId"))||""; let speciesId = JSON.parse(sessionStorage.getItem("symnZxHsId")) || "";
getRwscGifFileGcrz( getRwscGifFileGcrz(
{ {
taskId, taskId,
speciesId, speciesId,
}, },
(res: any) => { (res: any) => {
console.log(res,222222222); console.log(res, 222222222);
gifRzGroupValue.value = res.result; gifRzGroupValue.value = res.result;
} }
); );
} };
onMounted(() => { onMounted(() => {
// //
svgList.value[0].isActive = domFullscreenStatus(); svgList.value[0].isActive = domFullscreenStatus();
@ -489,60 +494,44 @@ onMounted(() => {
<el-input v-model="gifFormData.maxLat" /> <el-input v-model="gifFormData.maxLat" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="2" <el-col :span="2">
> <el-button @click="generateGif" type="primary" class="custom-btn"
<el-button @click="generateGif" type="primary" class="custom-btn" >生成GIF</el-button></el-col >生成GIF</el-button
></el-col
>
<el-col :span="2"
><el-button @click="viewLogs" type="primary" class="custom-btn"
>查看日志</el-button
></el-col
> >
<el-col :span="2"><el-button @click="viewLogs" type="primary" class="custom-btn" >查看日志</el-button></el-col>
</el-row> </el-row>
</el-form> </el-form>
<img <img v-if="isShowGif" :src="gifSrc" alt="GIF" style="width: 100%" />
v-if="isShowGif" <div style="width: 100%; display: flex; justify-content: flex-end;margin-top: 15px;">
:src="gifSrc" <div style="width: 25%;display: flex;padding-right: 10px;">
alt="GIF"
style="width: 100%"
/>
<el-row
:gutter="12"
style="margin-top: 10px; display: flex; justify-content: flex-end"
>
<el-col :span="16"></el-col>
<el-col :span="4" style="display: flex; align-items: center">
<span style="width: 35px; margin-right: 5px; color: #ade6ee">类型</span>
<el-select <el-select
v-model="downTypeValue" v-model="downTypeValue"
:options="downTypeOptions" :options="downTypeOptions"
:props="props" :props="props"
placeholder="选择类型" placeholder="选择类型"
/> />
</el-col> <el-button
<el-col :span="2"> :disabled="!downTypeValue"
<el-button :disabled="!downTypeValue" @click="downGifFile" @click="downGifFile"
type="primary" class="custom-btn" >下载</el-button type="primary"
class="custom-btn"
style="margin-left: 10px;"
>下载</el-button
> >
</el-col> </div>
</el-row>
<!-- <a v-if="gifSrc" :href="gifSrc" download="gif" class="download-icon">
<el-icon size="20"><Download /></el-icon>
</a> -->
</Dialog>
<Dialog
v-model="viewLogsDialog"
title="GIF日志"
width="1340"
class="config-dialog"
style="min-height: 120px"
@close="viewLogsDialog = false"
>
<div class="gif-rztext">
<li v-for="(item,index) in gifRzGroupValue" :key="index">{{item.createTime}}&nbsp;&nbsp;&nbsp;&nbsp;{{item.logContent}}</li>
<li v-for="(item,index) in gifRzGroupValue" :key="index">{{item.createTime}}&nbsp;&nbsp;&nbsp;&nbsp;{{item.logContent}}</li>
<li v-for="(item,index) in gifRzGroupValue" :key="index">{{item.createTime}}&nbsp;&nbsp;&nbsp;&nbsp;{{item.logContent}}</li>
</div> </div>
</Dialog> </Dialog>
<!-- 运行日志弹窗 -->
<Dialog v-model="viewLogsDialog" :title="t('operationLog')" width="56vw">
<log :data="gifRzGroupValue" />
</Dialog>
</template> </template>
<style lang="less" scoped> <style lang="less" scoped>
@ -614,18 +603,18 @@ onMounted(() => {
} }
} }
.gif-rztext{ .gif-rztext {
max-height: 400px; max-height: 400px;
overflow: auto; overflow: auto;
} }
.custom-btn { .custom-btn {
background-color: #1397a3; background-color: #1397a3;
border-color: #1397a3; border-color: #1397a3;
color: #fff; color: #fff;
&:hover { &:hover {
background-color: #185c5c; background-color: #185c5c;
border-color: #4ac1c1; border-color: #4ac1c1;
}
} }
}
</style> </style>

View File

@ -275,6 +275,7 @@
"ImportMonitoringData": "导入监测数据", "ImportMonitoringData": "导入监测数据",
"pinToTop": "置顶", "pinToTop": "置顶",
"unpin": "取消置顶", "unpin": "取消置顶",
"executeAssociation":"执行关联" "executeAssociation":"执行关联",
"sampleLevel":"样品级别"
} }

View File

@ -205,7 +205,7 @@ defineExpose({
z-index: 10; z-index: 10;
background: rgb(7, 39, 43); background: rgb(7, 39, 43);
border: 1px solid #0b8c82; border: 1px solid #0b8c82;
user-select: none; /* user-select: none; */
} }
.tab-bar span { .tab-bar span {

View File

@ -231,7 +231,7 @@ defineExpose({
z-index: 10; z-index: 10;
background: rgb(7, 39, 43); background: rgb(7, 39, 43);
border: 1px solid #0b8c82; border: 1px solid #0b8c82;
user-select: none; /* user-select: none; */
} }
.tab-bar span { .tab-bar span {

View File

@ -662,7 +662,7 @@ onUnmounted(() => {
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
user-select: none; // user-select: none;
} }
.runBtn { .runBtn {

View File

@ -36,7 +36,6 @@ function getStation() {
value: item.stationId, value: item.stationId,
}; };
}); });
console.log(res, 'res');
}); });
} }
const barData = ref<any>({ const barData = ref<any>({
@ -72,7 +71,6 @@ const rules = {
function setTime(val: any[]) { function setTime(val: any[]) {
form.value.startDate = val[0]; form.value.startDate = val[0];
form.value.endDate = val[1]; form.value.endDate = val[1];
console.log(val);
} }
function handleSearch() { function handleSearch() {
getList(); getList();
@ -83,9 +81,8 @@ function getList() {
return; return;
formEl.validate((valid, fields) => { formEl.validate((valid, fields) => {
if (valid) { if (valid) {
form.value.stationIds = [form.value.station] form.value.stationIds = [...form.value.station]
getSampleGrade(form.value, (res) => { getSampleGrade(form.value, (res) => {
console.log(res, 'res');
const list = res.result?.sampleDataList; const list = res.result?.sampleDataList;
if (!list || list.length === 0) { if (!list || list.length === 0) {
barData.value = { barData.value = {
@ -106,7 +103,8 @@ function getList() {
default: '#c2c2c2', default: '#c2c2c2',
}; };
// 1. category null // 1. category null
// X // X ,
// Array.from
const allTimes = Array.from(new Set(list.map((item: { collectStop: any }) => item.collectStop))) const allTimes = Array.from(new Set(list.map((item: { collectStop: any }) => item.collectStop)))
.sort((a, b) => new Date(a) - new Date(b)); .sort((a, b) => new Date(a) - new Date(b));
@ -116,11 +114,15 @@ function getList() {
.map((item: { category: any }) => item.category), .map((item: { category: any }) => item.category),
)).sort((a, b) => a - b); )).sort((a, b) => a - b);
// 3. // 3. Map
const groupMap = new Map(); const groupMap = new Map();
// list
list.forEach((item: { collectStop: any }) => { list.forEach((item: { collectStop: any }) => {
// Mapkey
if (!groupMap.has(item.collectStop)) if (!groupMap.has(item.collectStop))
// key
groupMap.set(item.collectStop, []); groupMap.set(item.collectStop, []);
// key
groupMap.get(item.collectStop).push(item); groupMap.get(item.collectStop).push(item);
}); });
@ -161,19 +163,16 @@ function getList() {
barData.value.xAxisData = allTimes; barData.value.xAxisData = allTimes;
barData.value.seriesData = seriesList; barData.value.seriesData = seriesList;
barData.value.legendData = validCategories.map(cat => `等级 ${cat}`); barData.value.legendData = validCategories.map(cat => `等级 ${cat}`);
console.log('处理后的数据:', barData.value);
renderChart(); renderChart();
}); });
} }
// else { // else {
// console.log(':', fields);
// ElMessage.error(''); // ElMessage.error('');
// } // }
}); });
} }
function renderChart() { function renderChart() {
if (!barData.value || !barData.value.seriesData || barData.value.seriesData.length === 0) { if (!barData.value || !barData.value.seriesData || barData.value.seriesData.length === 0) {
console.warn('数据异常');
return; return;
} }
const option = { const option = {
@ -384,18 +383,18 @@ onMounted(async () => {
<div class="sjfx-two-content"> <div class="sjfx-two-content">
<div class="head"> <div class="head">
<el-form ref="formRef" :model="form" label-width="80px" class="queryForm" :rules="rules"> <el-form ref="formRef" :model="form" label-width="80px" class="queryForm" :rules="rules">
<el-row :gutter="10"> <!-- <el-row :gutter="10"> -->
<el-col :span="4"> <!-- <el-col :span="5"> -->
<el-form-item :label="t('dataSource')" prop="dataSource"> <el-form-item :label="t('dataSource')" prop="dataSource" style="width: 270px;">
<el-select v-model="form.dataSource" :placeholder="t('pleaseSelect')" style="width: 300px;"> <el-select v-model="form.dataSource" :placeholder="t('pleaseSelect')" style="width: 300px;">
<el-option v-for="item in dataSourceList" :key="item.value" <el-option v-for="item in dataSourceList" :key="item.value"
style="background-color: transparent; height: 30px;color: #fff;" :label="item.label" style="background-color: transparent; height: 30px;color: #fff;" :label="item.label"
:value="item.value" /> :value="item.value" />
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> <!-- </el-col> -->
<el-col :span="4"> <!-- <el-col :span="4"> -->
<el-form-item :label="t('sampleType')" prop="sampleType"> <el-form-item :label="t('sampleType')" prop="sampleType" style="width: 250px;">
<el-select v-model="form.sampleType" :placeholder="t('pleaseSelect')" style="width: 100%;" <el-select v-model="form.sampleType" :placeholder="t('pleaseSelect')" style="width: 100%;"
popper-style="background-color: transparent;border: solid 1px #0da397;width:100px;overflow: hidden;border-radius: 0;" popper-style="background-color: transparent;border: solid 1px #0da397;width:100px;overflow: hidden;border-radius: 0;"
@change="handleSampleTypeChange"> @change="handleSampleTypeChange">
@ -404,13 +403,13 @@ onMounted(async () => {
:value="item.value" /> :value="item.value" />
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> <!-- </el-col> -->
<el-col :span="4"> <!-- <el-col :span="5"> -->
<el-form-item :label="t('stationName')" prop="station"> <el-form-item :label="t('stationName')" prop="station" style="width: 250px;">
<el-select-v2 v-model="form.station" :placeholder="t('pleaseSelect')" style="width: 160px;" filterable <el-select-v2 v-model="form.station" :placeholder="t('pleaseSelect')" filterable multiple collapse-tags collapse-tags-tooltip
:options="stationList" clearable /> :options="stationList" clearable />
</el-form-item> </el-form-item>
</el-col> <!-- </el-col> -->
<!-- <el-col :span="3"> <!-- <el-col :span="3">
<el-form-item :label="t('nuclideName')"> <el-form-item :label="t('nuclideName')">
<el-input v-model="form.nuclideName" style="width: 100%;" /> <el-input v-model="form.nuclideName" style="width: 100%;" />
@ -418,21 +417,21 @@ onMounted(async () => {
</el-col> --> </el-col> -->
<el-col :span="7"> <!-- <el-col :span="6"> -->
<el-form-item :label="t('createTime')" prop="createTime"> <el-form-item :label="t('createTime')" prop="createTime">
<el-date-picker v-model="form.createTime" type="daterange" :default-time="new Date()" style="width: 100%;" <el-date-picker v-model="form.createTime" type="daterange" :default-time="new Date()" style="width: 100%;"
range-separator="--" :start-placeholder="t('startDate')" :end-placeholder="t('endDate')" range-separator="--" :start-placeholder="t('startDate')" :end-placeholder="t('endDate')"
value-format="YYYY-MM-DD" @change="setTime" /> value-format="YYYY-MM-DD" @change="setTime" />
</el-form-item> </el-form-item>
</el-col> <!-- </el-col> -->
<el-col :span="2"> <!-- <el-col :span="2"> -->
<el-form-item> <el-form-item>
<el-button :icon="Search" @click="handleSearch"> <el-button :icon="Search" @click="handleSearch">
{{ t('refresh') }} {{ t('refresh') }}
</el-button> </el-button>
</el-form-item> </el-form-item>
</el-col> <!-- </el-col> -->
</el-row> <!-- </el-row> -->
</el-form> </el-form>
</div> </div>
<div class="echars"> <div class="echars">
@ -556,7 +555,7 @@ onMounted(async () => {
.chart-container { .chart-container {
width: 100%; width: 100%;
height: 800px; height: 780px;
} }
} }
</style> </style>

File diff suppressed because it is too large Load Diff

View File

@ -6,8 +6,7 @@ import SparkMD5 from 'spark-md5';
import { set } from 'vue'; // Vue set import { set } from 'vue'; // Vue set
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { add, deleteData, edit, getData, getTaskLog, resume, pinToTopOrUnpin } from '@/utils/axios/tqyb/task'; import { add, deleteData, edit, getData, getTaskLog, resume, pinToTopOrUnpin } from '@/utils/axios/tqyb/task';
import log from '../log/index.vue'; import log from '@/pages/symn/log/index.vue';
const emit = defineEmits(['playback']); const emit = defineEmits(['playback']);
const { t } = useI18n(); const { t } = useI18n();
const upload = ref<UploadInstance>(); const upload = ref<UploadInstance>();
@ -278,9 +277,7 @@ function refresh() {
} }
function showLog(task: any) { function showLog(task: any) {
console.log('显示运行日志');
getTaskLog({ taskId: task.id }, (res) => { getTaskLog({ taskId: task.id }, (res) => {
console.log('res', res);
logData.value = res; logData.value = res;
logVisible.value = true; logVisible.value = true;
}); });
@ -406,7 +403,7 @@ getList();
<template> <template>
<div class="ycrw"> <div class="ycrw">
<Dialog v-model="logVisible" :title="t('operationLog')" width="56vw" class="child-custom" style="top:230px;left:22vw"> <Dialog v-model="logVisible" :title="t('operationLog')" width="56vw" class="child-custom" style="top:50%;left:50%;transform: translate(-50%, -50%);">
<log :data="logData" /> <log :data="logData" />
</Dialog> </Dialog>

View File

@ -9,7 +9,7 @@ import { createTask, deleteTask as deleteData, exportAcTimeSeriesTxt, exportBaye
import { transformLogData } from '@/utils/index'; import { transformLogData } from '@/utils/index';
import { exportCharts } from '@/utils/index'; // import { exportCharts } from '@/utils/index'; //
import scatter from './dbvarScatter/index.vue'; import scatter from './dbvarScatter/index.vue';
import log from './log/index.vue'; import log from '@/pages/symn/log/index.vue';
import monOrAna from './monitOrAnalog/index.vue'; import monOrAna from './monitOrAnalog/index.vue';
import varBan from './univarBan/index.vue'; import varBan from './univarBan/index.vue';