天气预报模块

This commit is contained in:
冯少康 2026-07-29 17:47:52 +08:00
parent 33859185ff
commit c31bb50108
5 changed files with 501 additions and 453 deletions

View File

@ -274,6 +274,7 @@
"monitoringData": "监测数据",
"ImportMonitoringData": "导入监测数据",
"pinToTop": "置顶",
"unpin": "取消置顶"
"unpin": "取消置顶",
"executeAssociation":"执行关联"
}

View File

@ -5,7 +5,7 @@ import { gisImgOpt, tqycAnimationType, weathFlag } from '@/gis/ol/index';
import { playbackSearchData, weatherDataLine, weatherPreview } from '@/utils/axios/tqyb/data/index';
import tab1 from './tab-1/index.vue';
import tab2 from './tab-2/index.vue';
// import tab3 from './tab-3/index.vue';
import tab3 from './tab-3/index.vue';
import WindRose from './WindRose.vue';
const { t } = useI18n();
@ -50,6 +50,7 @@ function handleSendData(params: any) {
console.log('选中的回放数据,需要传至gis --->', params);
delete params.key
delete params.endTime
params.hour+=6;
playbackSearchData(params, false, (res) => {
console.log(res);
//
@ -239,7 +240,7 @@ onMounted(() => {
<tab2 v-if="tabActive === '公开气象数据'" type="gkqx" @playback="handleSendData" @preview="weatherPreviewHandle" />
</el-tab-pane>
<el-tab-pane :label="t('associateMeteorologicalData')" name="关联气象数据">
<!-- //<tab3 /> -->
<tab3 />
</el-tab-pane>
</el-tabs>
</Dialog>

View File

@ -1,16 +1,33 @@
<script setup lang="ts">
import type { TableInstance, UploadInstance, UploadProps, UploadRawFile } from 'element-plus';
import dayjs from 'dayjs';
import { ElLoading, ElMessage, ElMessageBox, ElNotification, genFileId } from 'element-plus';
import SparkMD5 from 'spark-md5';
import { useI18n } from 'vue-i18n';
import { gisImgOpt, weathFlag } from '@/gis/ol/index';
import { deleteData, getData, getTimeBatch, importFile } from '@/utils/axios/tqyb/data';
import type {
TableInstance,
UploadInstance,
UploadProps,
UploadRawFile,
} from "element-plus";
import dayjs from "dayjs";
import {
ElLoading,
ElMessage,
ElMessageBox,
ElNotification,
genFileId,
} from "element-plus";
import SparkMD5 from "spark-md5";
import { useI18n } from "vue-i18n";
import { gisImgOpt, weathFlag } from "@/gis/ol/index";
import {
deleteData,
getData,
getTimeBatch,
importFile,
getPcValueBySjlx,
} from "@/utils/axios/tqyb/data";
const propsWithDefaults = withDefaults(defineProps<Props>(), {
type: '',
type: "",
});
const emit = defineEmits(['playback', 'preview']);
const emit = defineEmits(["playback", "preview"]);
const { t } = useI18n();
const chunks = ref([]);
@ -37,7 +54,7 @@ const searchForm = reactive({});
const fileInput: Ref<HTMLInputElement | null> = ref(null);
function search() {
console.log('搜索条件:', searchForm);
console.log("搜索条件:", searchForm);
getList();
}
@ -45,13 +62,17 @@ function search() {
const timeBatchList = ref<any>([]);
const timeBatch = ref<any>(null);
const dataSourceList = ref([
{ label: 'T1H', value: 6 },
{ label: 'GFS', value: 7 },
{ label: "T1H", value: 6 },
{ label: "GFS", value: 7 },
]);
const xxxxxxxxxxxxx = ref('');
const xxxxxxxxxxxxx = ref("");
//
const searchSelectValue = ref<any>(null);
//
const searchPcSelectValue = ref<any>(null);
//
const fileDatasource = ref<any>(null);
@ -59,13 +80,17 @@ const fileDatasource = ref<any>(null);
const selectValue = ref<any>(null);
//
const selectOption = ref<any>([]);
const pcSelectOption = ref<any>([]);
//
const pickerValue = ref([]);
const hfSelectSjy = ref<any>(null);
getTimeBatchList();
function getTimeBatchList() {
getTimeBatch({
}, (res) => {
getTimeBatch({}, (res) => {
timeBatchList.value = res;
});
}
@ -75,49 +100,65 @@ function getList() {
startTime = searchForm.createTime[0];
endTime = searchForm.createTime[1];
}
if (propsWithDefaults.type === 'sjyc') {
dataS = '1,2';
selectOption.value = [{
value: '1',
label: '盘古模型',
}, {
value: '2',
label: 'graphcast',
}];
if (propsWithDefaults.type === "sjyc") {
dataS = "1,2";
selectOption.value = [
{
value: "1",
label: "盘古模型",
},
{
value: "2",
label: "graphcast",
},
];
}
if (propsWithDefaults.type === 'zfx') {
dataS = '3,4,5';
selectOption.value = [{
value: '3',
label: 'cra40',
}, {
value: '4',
label: 'ncep',
}, {
value: '5',
label: 'fnl',
}];
if (propsWithDefaults.type === "zfx") {
dataS = "3,4,5";
selectOption.value = [
{
value: "3",
label: "cra40",
},
{
value: "4",
label: "ncep",
},
{
value: "5",
label: "fnl",
},
];
}
if (propsWithDefaults.type === 'gkqx') {
dataS = '';
selectOption.value = [{
value: '6',
label: 't1h',
}];
selectValue.value = '6';
if (propsWithDefaults.type === "gkqx") {
dataS = "6,7";
selectOption.value = [
{
value: "6",
label: "T1H",
},
{
value: "7",
label: "GFS",
},
];
selectValue.value = "6";
}
dataSource.value = dataS;
getData({
...searchForm,
startTime,
endTime,
dataSource: searchSelectValue.value || dataS,
pageSize: pageSize.value,
pageNum: currentPage.value,
}, (res) => {
taskList.value = res.rows;
total.value = res.total;
});
getData(
{
...searchForm,
startTime,
endTime,
dataSource: searchSelectValue.value || dataS,
pageSize: pageSize.value,
pageNum: currentPage.value,
},
(res) => {
taskList.value = res.rows;
total.value = res.total;
}
);
}
function handleSizeChange(val: number) {
@ -132,16 +173,12 @@ function handleCurrentChange(val: number) {
}
function deleteTask(task: any) {
console.log('删除任务', task);
ElMessageBox.confirm(
t('isSureDelete'),
'Warning',
{
confirmButtonText: t('sure'),
cancelButtonText: t('cancel'),
type: 'warning',
},
)
console.log("删除任务", task);
ElMessageBox.confirm(t("isSureDelete"), "Warning", {
confirmButtonText: t("sure"),
cancelButtonText: t("cancel"),
type: "warning",
})
.then(() => {
let arr = [];
arr.push(task.id);
@ -165,29 +202,28 @@ function handleSelectionChange(selection: any[]) {
multipleTableRef.value?.clearSelection(); //
multipleTableRef.value?.toggleRowSelection(latestSelection, true); //
currentSelection.value = [latestSelection];
}
else {
} else {
//
currentSelection.value = selection;
}
console.log('当前选中项:', currentSelection.value);
console.log("当前选中项:", currentSelection.value);
}
function playback() {
if (!selectValue.value) {
ElMessage({
type: 'warning',
type: "warning",
message: t(`selectTqybTableDataType`),
});
}
if (!pickerValue.value.length) {
ElMessage({
type: 'warning',
type: "warning",
message: t(`selectStartAndEndTime`),
});
}
const startTime = dayjs(pickerValue.value[0]).format('YYYY-MM-DD HH:mm:ss');
const endTime = dayjs(pickerValue.value[1]).format('YYYY-MM-DD HH:mm:ss');
const startTime = dayjs(pickerValue.value[0]).format("YYYY-MM-DD HH:mm:ss");
const endTime = dayjs(pickerValue.value[1]).format("YYYY-MM-DD HH:mm:ss");
const params = {
dataType: selectValue.value,
@ -197,8 +233,8 @@ function playback() {
timeBatch: timeBatch.value,
};
EventBusTool.getEventBus().publish('playData', {
key: 'setTaishiParam',
EventBusTool.getEventBus().publish("playData", {
key: "setTaishiParam",
dataType: selectValue.value,
weatherType: 3,
startTime,
@ -208,74 +244,76 @@ function playback() {
});
//
weathFlag[gisImgOpt.weatherType] = true;
emit('playback', params);
emit("playback", params);
}
function disabledHour() {
return [1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 13, 14, 15, 16, 17, 19, 20, 21, 22, 23];
return [
1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 13, 14, 15, 16, 17, 19, 20, 21, 22, 23,
];
}
function handleClick(): void {
if (!fileDatasource.value) {
return ElMessage({
type: 'warning',
message: '请先选择数据来源',
type: "warning",
message: "请先选择数据来源",
});
}
if (fileInput.value) {
fileInput.value.value = '';
fileInput.value.value = "";
fileInput.value.click();
}
}
//
const uploadData = ref({
md5Value: '',
fileName: '',
fileExt: 'grib2',
dataSource: '',
shareTotal: '1',
shareIndex: '', //
fileShare: 'false',
md5Value: "",
fileName: "",
fileExt: "grib2",
dataSource: "",
shareTotal: "1",
shareIndex: "", //
fileShare: "false",
});
//
function handleFileChange(event: Event): void {
const target = event.target as HTMLInputElement;
const file = target.files?.[0];
if (!file) {
console.warn('未选择文件');
console.warn("未选择文件");
return;
}
console.log('file', file, dataSource.value, dataSource);
console.log("file", file, dataSource.value, dataSource);
let md5;
// MD5
const fileReader = new FileReader();
const spark = new SparkMD5.ArrayBuffer();
//
const getFileExtension = (filename: any) => {
const lastDotIndex = filename.lastIndexOf('.');
const lastDotIndex = filename.lastIndexOf(".");
return lastDotIndex !== -1 && lastDotIndex < filename.length - 1
? filename.slice(lastDotIndex + 1)
: '';
: "";
};
const formData = new FormData();
formData.append('fileExt', getFileExtension(file.name));
formData.append("fileExt", getFileExtension(file.name));
fileReader.onload = (e) => {
spark.append(e.target.result);
md5 = spark.end();
// FormData
formData.append('md5Value', md5);
formData.append('fileName', file.name);
formData.append('file', file);
formData.append('shareTotal', '1');
formData.append('fileShare', 'false');
formData.append('dataSource', fileDatasource.value);
formData.append("md5Value", md5);
formData.append("fileName", file.name);
formData.append("file", file);
formData.append("shareTotal", "1");
formData.append("fileShare", "false");
formData.append("dataSource", fileDatasource.value);
// importTaskformDatacallback
importFile(formData, (res: any) => {
console.log('接口响应:', res);
console.log("接口响应:", res);
getList();
});
};
@ -286,14 +324,14 @@ function handleFileChange(event: Event): void {
function getDataSource(code: any) {
//
const dataSourceMap: any = {
1: '盘古模型',
2: 'graphcast',
3: 'cra40',
4: 'ncep',
5: 'fnl',
6: 't1h',
1: "盘古模型",
2: "graphcast",
3: "cra40",
4: "ncep",
5: "fnl",
6: "t1h",
};
//
//
return dataSourceMap[code] || code;
}
@ -306,16 +344,53 @@ function previewTask(row: any) {
weatherType: 3,
timeBatch: row.timeBatch,
};
EventBusTool.getEventBus().publish('playData', {
key: 'setTaishiParam',
EventBusTool.getEventBus().publish("playData", {
key: "setTaishiParam",
dataType: row.dataSource,
weatherType: 3,
startTime: row.dataStartTime,
endTime: row.dataStartTime,
hour: 0,
});
emit('preview', params);
emit("preview", params);
}
const changeSjyValue = (val) => {
pcSelectOption.value = [];
//
if (val) {
//
getPcValueBySjlx(
{
dataType: val,
},
(res) => {
pcSelectOption.value = res.result.map((element) => {
return {
value: element,
label: element,
};
});
}
);
}
};
const changeSjyValue1 = (val) => {
timeBatchList.value = [];
//
if (val) {
//
getPcValueBySjlx(
{
dataType: val,
},
(res) => {
timeBatchList.value = res.result;
}
);
}
};
getList();
</script>
@ -323,20 +398,50 @@ getList();
<div class="tab2">
<ElForm :inline="true" :model="searchForm" class="custom-form">
<ElFormItem label="">
<ElInput v-model="searchForm.fileName" :placeholder="`${t('keyword')}...`" class="custom-input" />
<ElInput
v-model="searchForm.fileName"
:placeholder="`${t('keyword')}...`"
class="custom-input"
/>
</ElFormItem>
<ElFormItem v-if="type !== 'gkqx'" :label="t('tqybTableDataType')">
<el-select-v2 v-model="searchSelectValue" clearable :options="selectOption" placeholder="选择数据源"
style="width: 240px;margin-right: 10px;" />
<ElFormItem :label="t('tqybTableDataType')">
<el-select-v2
v-model="searchSelectValue"
clearable
:options="selectOption"
placeholder="选择数据源"
style="width: 240px; margin-right: 10px"
@change="changeSjyValue"
/>
</ElFormItem>
<ElFormItem :label="t('timeBatch')">
<el-select-v2
v-model="searchPcSelectValue"
clearable
:options="pcSelectOption"
placeholder="选择批次"
style="width: 240px; margin-right: 10px"
/>
</ElFormItem>
<ElFormItem>
<ElButton type="primary" class="custom-btn" icon="Search" @click="search">
{{ t('search') }}
<ElButton
type="primary"
class="custom-btn"
icon="Search"
@click="search"
>
{{ t("search") }}
</ElButton>
</ElFormItem>
</ElForm>
<ElTable ref="multipleTableRef" :data="taskList" width="100%" max-height="60vh" class="custom-table"
@selection-change="handleSelectionChange">
<ElTable
ref="multipleTableRef"
:data="taskList"
width="100%"
max-height="60vh"
class="custom-table"
@selection-change="handleSelectionChange"
>
<ElTableColumn type="index" :label="t('serialNumber')" width="80" />
<ElTableColumn prop="fileName" :label="t('fileName')" width="250" />
<ElTableColumn prop="dataSource" :label="t('tqybTableDataType')">
@ -361,7 +466,12 @@ getList();
</div>
</template>
</ElTableColumn>
<ElTableColumn v-if="type === 'gkqx'" prop="timeBatch" :label="t('timeBatch')" width="180">
<ElTableColumn
v-if="type === 'gkqx'"
prop="timeBatch"
:label="t('timeBatch')"
width="180"
>
<template #default="scope">
<div>
{{ scope.row?.timeBatch }}
@ -377,46 +487,90 @@ getList();
</ElTableColumn>
<ElTableColumn :label="t('operation')" width="120">
<template #default="scope">
<ElButton type="text" class="custom-text-btn" @click="previewTask(scope.row)">
{{ t('preview') }}
<ElButton
type="text"
class="custom-text-btn"
@click="previewTask(scope.row)"
>
{{ t("preview") }}
</ElButton>
<ElButton type="text" class="custom-text-btn" style="color:red" @click="deleteTask(scope.row)">
{{ t('delete') }}
<ElButton
type="text"
class="custom-text-btn"
style="color: red"
@click="deleteTask(scope.row)"
>
{{ t("delete") }}
</ElButton>
</template>
</ElTableColumn>
</ElTable>
<div class="pagination">
<el-pagination v-model:current-page="currentPage" v-model:page-size="pageSize" :page-sizes="[10, 20, 50, 100, 200]"
size="small" :background="true" layout="total, sizes, prev, pager, next, jumper" :total="total"
@size-change="handleSizeChange" @current-change="handleCurrentChange" />
<el-pagination
v-model:current-page="currentPage"
v-model:page-size="pageSize"
:page-sizes="[10, 20, 50, 100, 200]"
size="small"
:background="true"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
<div class="dialog-footer">
<!-- 下拉菜单 -->
<el-select-v2 v-if="type !== 'gkqx'" v-model="selectValue" :options="selectOption" placeholder="选择数据源"
style="width: 240px;margin-right: 10px;" />
<el-select-v2
v-if="type !== 'gkqx'"
v-model="selectValue"
:options="selectOption"
placeholder="选择数据源"
style="width: 240px; margin-right: 10px"
/>
<!-- 时间选择 -->
<div style="width: 760px;display: flex;margin-right: 10px">
<ElSelect v-if="type === 'gkqx'" v-model="xxxxxxxxxxxxx" placeholder="选择数据源" filterable
style="width: 160px;margin-right: 10px">
<ElOption v-for="v in dataSourceList" :label="v.label" :value="v.value" />
<div style="display: flex; margin-right: 10px" class="bottomBox">
<ElSelect
v-if="type === 'gkqx'"
v-model="hfSelectSjy"
placeholder="选择数据源"
filterable
style="width: 160px; margin-right: 10px"
@change="changeSjyValue1"
>
<ElOption
v-for="v in dataSourceList"
:label="v.label"
:value="v.value"
/>
</ElSelect>
<ElSelect v-if="type === 'gkqx'" v-model="timeBatch" placeholder="请选择批次" filterable
style="width: 200px;margin-right: 10px">
<ElSelect
v-if="type === 'gkqx'"
v-model="timeBatch"
placeholder="请选择批次"
filterable
style="width: 200px; margin-right: 10px"
>
<ElOption v-for="v in timeBatchList" :label="v" :value="v" />
</ElSelect>
<el-date-picker v-model="pickerValue" unlink-panels type="datetimerange" :default-time="new Date()"
range-separator="至" :start-placeholder="t('startDate')" :end-placeholder="t('endDate')"
<el-date-picker
v-model="pickerValue"
unlink-panels
type="datetimerange"
:default-time="new Date()"
range-separator="至"
:start-placeholder="t('startDate')"
:end-placeholder="t('endDate')"
:disabled-minutes="() => Array.from({ length: 60 }, (_, i) => i)"
:disabled-seconds="() => Array.from({ length: 60 }, (_, i) => i)"
value-format="YYYY-MM-DD HH:00:00"
:disabled-hours="disabledHour" />
:disabled-hours="disabledHour"
/>
</div>
<!-- 回放 -->
<el-button class="custom-btn" icon="VideoPlay" @click="playback">
{{ t('playback') }}
{{ t("playback") }}
</el-button>
<!-- <el-upload v-if="type !== 'sjyc'" ref="upload" class="upload-file" -->
@ -436,8 +590,12 @@ getList();
</div>
</template>
<style lang="less">
<style scoped lang="less">
.tab2 {
:deep(.el-date-editor .el-range-separator) {
color: #fff !important;
}
.config-dialog {
margin-top: 35vh;
@ -485,7 +643,6 @@ getList();
}
.config-custom-date {
.el-date-editor.el-input,
.el-date-editor.el-input__wrapper {
width: calc(20vw - 80px) !important;
@ -503,4 +660,10 @@ getList();
margin-top: 10px;
}
}
.bottomBox {
:deep(.el-date-range-picker__separator) {
color: #fff !important;
}
}
</style>

View File

@ -1,343 +1,173 @@
<script setup lang="ts">
import { ElButton, ElOption, TableInstance, UploadInstance } from 'element-plus';
import dayjs from 'dayjs';
import { ElMessage } from 'element-plus';
import { ref, reactive } from 'vue'; // Vue set
import { useI18n } from 'vue-i18n';
import { getData, getTaskLog } from '@/utils/axios/tqyb/task';
import log from '../log/index.vue';
const emit = defineEmits(['playback']);
import { useI18n } from "vue-i18n";
import dayjs from "dayjs";
import { getZxglData, getGlqxsjRzData } from "@/utils/axios/tqyb/data";
const { t } = useI18n();
const configVisible = ref(false);
const configType = ref('');
/* 新增、编辑表单 */
const configForm = ref<any>({});
// ref
const fileInput: Ref<HTMLInputElement | null> = ref(null);
const taskList = ref<any[]>([]);
const logData = ref<any>([]);
const currentPage = ref(1);
const pageSize = ref(20);
const total = ref(0);
//
const currentSelection = ref<any>([]);
const multipleTableRef = ref<TableInstance>();
const logVisible = ref(false);
/* drawer侧边栏表单 */
const form = ref<any>({});
/* 任务列表搜索表单 */
const searchForm = reactive({});
interface OptionItem {
label: string;
value: number;
const searchForm = ref({});
//
const searchSelectValue = ref<any>(null);
//
const selectOption = ref<any>([]);
//
const pickerValue = ref([]);
function disabledHour() {
return [
1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 13, 14, 15, 16, 17, 19, 20, 21, 22, 23,
];
}
const taskStatusList = ref<OptionItem[]>([
// -101234
{ label: '执行失败', value: -1 },
{ label: '未开始', value: 0 },
{ label: '等待中', value: 1 },
{ label: '运行中', value: 2 },
{ label: '已完成', value: 3 },
{ label: '检查未通过', value: 4 },
//
let pollTimer = null;
//
const isPolling = ref(false);
// loading
const pollLoading = ref(false);
//
const pollResult = ref(null);
//
const emptyCount = ref(0);
/**
* 轮询请求接口方法
*/
const fetchData = () => {
getGlqxsjRzData(
{
lastId: "",
},
(res) => {
console.log(222222, res);
//
const isEmpty = !res.result || res.result.length === 0;
if (isEmpty) {
emptyCount.value += 1;
// 2
if (emptyCount.value >= 2) {
stopPoll();
console.log("连续2次无数据终止轮询");
}
} else {
//
emptyCount.value = 0;
console.log("获取到数据,继续轮询");
}
}
);
};
//
const startPoll = () => {
if (isPolling.value) return;
//
emptyCount.value = 0;
isPolling.value = true;
pollLoading.value = true;
//
fetchData();
// 3
pollTimer = setInterval(fetchData, 3000);
};
//
const stopPoll = () => {
if (pollTimer) {
clearInterval(pollTimer);
pollTimer = null;
}
isPolling.value = false;
pollLoading.value = false;
};
const dataSourceList = ref([
{ label: "cra40", value: 3 },
{ label: "ncep", value: 4 },
{ label: "fnl", value: 5 },
]);
function search() {
console.log('搜索条件:', searchForm);
getList();
}
function getList() {
let startDate, endDate;
if (searchForm.createTime && searchForm.createTime.length) {
startDate = searchForm.createTime[0];
endDate = searchForm.createTime[1];
}
getData({
...searchForm,
startDate,
endDate,
pageSize: pageSize.value,
pageNum: currentPage.value,
}, (res) => {
taskList.value = res.rows;
total.value = res.total;
});
}
function refresh() {
console.log('刷新任务列表');
getList();
}
function showLog(task: any) {
console.log('显示运行日志');
getTaskLog({ taskId: task.id }, (res) => {
console.log('res', res);
logData.value = res;
logVisible.value = true;
});
}
function handleSelectionChange(selection: any[]) {
// multipleTableRef.value!.clearSelection()
// multipleSelection.value = val
// 1
if (selection.length > 1) {
//
const latestSelection = selection[selection.length - 1];
multipleTableRef.value?.clearSelection(); //
multipleTableRef.value?.toggleRowSelection(latestSelection, true); //
currentSelection.value = [latestSelection];
}
else {
//
currentSelection.value = selection;
}
console.log('当前选中项:', currentSelection.value);
}
function playback() {
console.log('当前选中项:', currentSelection.value);
if (Object.keys(currentSelection.value).length === 0) {
ElMessage({
type: 'warning',
message: t(`isSelect`),
});
}
else {
const startTime = dayjs(currentSelection.value[0].startDate).add(0, 'hour').format('YYYY-MM-DD HH:mm:ss');
const params = {
dataType: currentSelection.value[0].predictionModel,
weatherType: 3,
startTime,
endTime: dayjs(startTime).add(currentSelection.value[0].leadTime, 'hour').format('YYYY-MM-DD HH:mm:ss'),
// hour: currentSelection.value[0].leadTime,
hour: 0,
};
emit('playback', params);
EventBusTool.getEventBus().publish('playData', {
key: 'setTaishiParam',
dataType: currentSelection.value[0].predictionModel,
weatherType: 3,
startTime,
// hour: currentSelection.value[0].leadTime,
hour: 0,
endTime: dayjs(startTime).add(currentSelection.value[0].leadTime, 'hour').format('YYYY-MM-DD HH:mm:ss'),
});
}
}
function handleClick(): void {
if (fileInput.value) {
fileInput.value.value = '';
fileInput.value.click();
}
}
//
function handleFileChange(event: Event): void {
const target = event.target as HTMLInputElement;
const file = target.files?.[0];
if (!file) {
console.warn('未选择文件');
return;
}
configForm.value.file = file;
configForm.value.inputFile = file.name;
// const formData = new FormData();
// // FormData
// formData.append('inputFile', file.name);
// formData.append('file', file);
// importTaskformDatacallback
// importFile(formData, (res:any) => {
// console.log(':', res);
// getList();
// });
}
function handleSizeChange(val: number) {
console.log(`${val} items per page`);
pageSize.value = val;
getList();
}
function handleCurrentChange(val: number) {
console.log(`current page: ${val}`);
currentPage.value = val;
getList();
}
getList();
const zxglClick = () => {
startPoll();
// const startTime = dayjs(pickerValue.value[0]).format("YYYY-MM-DD");
// const endTime = dayjs(pickerValue.value[1]).format("YYYY-MM-DD");
// getZxglData(
// {
// dataType: searchSelectValue.value,
// startDate: startTime,
// endDate: endTime,
// },
// (res) => {
// if(res.code==200){
// startPoll();
// }
// }
// );
};
//
</script>
<template>
<div class="ycrw">
<!-- 主表 -->
<ElForm :inline="true" :model="searchForm" class="custom-form">
<ElFormItem label="">
<ElInput v-model="searchForm.taskName" :placeholder="`${t('keyword')}...`" class="custom-input" />
</ElFormItem>
<ElFormItem :label="t('taskStatus')">
<ElSelect v-model="searchForm.taskStatus" :placeholder="t('pleaseSelect')" clearable class="custom-select">
<ElOption v-for="item in taskStatusList" :key="item.value" :label="item.label" :value="item.value" />
<ElFormItem :label="t('tqybTableDataType')">
<ElSelect
v-model="searchSelectValue"
placeholder="选择数据源"
filterable
style="width: 160px; margin-right: 10px"
>
<ElOption
v-for="v in dataSourceList"
:label="v.label"
:value="v.value"
/>
</ElSelect>
</ElFormItem>
<ElFormItem :label="t('predictionDate')">
<ElDatePicker v-model="searchForm.createTime" value-format="YYYY-MM-DD" type="daterange" range-separator="--"
:start-placeholder="t('startDate')" :end-placeholder="t('endDate')" class="custom-date-picker" />
<ElFormItem :label="t('timeRange')">
<el-date-picker
v-model="pickerValue"
unlink-panels
type="datetimerange"
:default-time="new Date()"
range-separator="至"
:start-placeholder="t('startDate')"
:end-placeholder="t('endDate')"
:disabled-minutes="() => Array.from({ length: 60 }, (_, i) => i)"
:disabled-seconds="() => Array.from({ length: 60 }, (_, i) => i)"
value-format="YYYY-MM-DD HH:00:00"
:disabled-hours="disabledHour"
/>
</ElFormItem>
<ElFormItem>
<ElButton type="primary" class="custom-btn" icon="Search" @click="search">
{{ t('search') }}
<ElButton type="primary" class="custom-btn" @click="zxglClick">
{{ t("executeAssociation") }}
</ElButton>
</ElFormItem>
</ElForm>
<ElTable ref="multipleTableRef" :data="taskList" width="100%" max-height="60vh" class="custom-table"
@selection-change="handleSelectionChange">
<ElTableColumn type="selection" width="55" />
<ElTableColumn type="index" :label="t('serialNumber')" width="80" />
<ElTableColumn prop="taskName" :label="t('taskName')" />
<ElTableColumn :label="t('taskStatus')">
<template #default="scope">
<div v-if="scope.row.taskStatus === -1" style="color:#f42a2a;">执行失败</div>
<div v-if="scope.row.taskStatus === 0" style="color:#f42a2a;">未开始</div>
<div v-if="scope.row.taskStatus === 1" style="color:#ffcb40;">等待中</div>
<div v-if="scope.row.taskStatus === 2" style="color:#ffcb40;">运行中</div>
<div v-if="scope.row.taskStatus === 3" style="color:#2af442;">已完成</div>
<div v-if="scope.row.taskStatus === 4" style="color:#f42a2a;">检查未通过</div>
</template>
</ElTableColumn>
<ElTableColumn prop="model" :label="t('predictionModel')">
<template #default="scope">
<div v-if="scope.row.predictionModel === 1">
{{ '盘古' }}
</div>
<div v-if="scope.row.predictionModel === 2">
{{ 'Graphcast' }}
</div>
</template>
</ElTableColumn>
<ElTableColumn prop="time" :label="t('predictionDate')">
<!-- 预测日期 -->
<template #default="scope">
<div>
{{ scope.row.startDate }}
</div>
</template>
</ElTableColumn>
<ElTableColumn prop="startTime" :label="t('predictionStartTime')">
<!-- 预测时间 -->
<template #default="scope">
<div>
{{ scope.row.startTime }}
</div>
</template>
</ElTableColumn>
<ElTableColumn prop="leadTime" :label="t('predictionDuration')">
<!-- 预测时长 -->
<template #default="scope">
<div>
{{ scope.row.leadTime }}小时
</div>
</template>
</ElTableColumn>
<ElTableColumn prop="hours" :label="t('timeConsuming')">
<!-- 耗时 -->
<template #default="scope">
<div>
{{ (scope.row.timeConsuming) }}分钟
</div>
</template>
</ElTableColumn>
<!--<ElTableColumn prop="creator" :label="t('creator')">
<template #default="scope">
{{ scope.row.createBy || '暂无信息' }}
</template>
</ElTableColumn>-->
<ElTableColumn prop="createTime" :label="t('creationTime')" width="220" />
</ElTable>
<div class="pagination">
<el-pagination v-model:current-page="currentPage" v-model:page-size="pageSize" :page-sizes="[10, 20, 50, 100, 200]"
size="small" :background="true" layout="total, sizes, prev, pager, next, jumper" :total="total"
@size-change="handleSizeChange" @current-change="handleCurrentChange" />
</div>
<div class="dialog-footer">
<el-button type="primary" class="custom-btn" icon="Refresh" @click="refresh">
{{ t('refresh') }}
</el-button>
<div class="gltext-content">
{{ pollResult }}
</div>
</div>
</template>
<style lang="less">
<style scoped lang="less">
.ycrw {
.config-dialog {
margin-top: 35vh;
.config-custom-form {
padding: 20px;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
.config-custom-select,
.config-custom-input {
width: calc(20vw - 80px) !important;
}
.custom-select-dropdown {
max-width: 200px;
/* 根据实际需求调整 */
}
}
.config-custom-btn {
.el-button {
width: 92px;
height: 32px;
background-color: #08a7cf;
border-radius: 0;
border: 0;
color: #fff;
&:hover {
filter: brightness(1.3);
}
&:last-child {
background-color: #b98326;
}
}
:deep(.el-date-editor) {
.el-date-editor {
color: #fff !important;
}
}
.el-table__header-wrapper {
.el-checkbox {
display: none;
}
}
.config-custom-date {
.el-date-editor.el-input,
.el-date-editor.el-input__wrapper {
width: calc(20vw - 80px) !important;
}
}
.pagination {
.gltext-content {
width: 100%;
display: flex;
justify-content: left;
margin-top: 10px;
height: 400px;
border: solid 1px #064048;
border-radius: 5px;
color: #fff;
}
:deep(.el-date-editor .el-range-separator) {
color: #fff !important;
}
}
</style>

View File

@ -235,3 +235,56 @@ export async function importFile(
}
// 127.0.0.1:9999/weatherData/getDataLine?startTime=2025-07-31 00:00:00&endTime=2025-07-31 18:00:00&longitude=1&latitude=1&dataType=1
/**
*
*/
export async function getPcValueBySjlx(
params: any,
callback?: (data: any) => void,
): Promise<any> {
const response = await request({
url: `${serverIp}${baseURL}/weatherData/getTimeBatch`,
method: 'GET',
params,
});
if (response.success && response.code === 200) {
callback?.(response);
}
}
/**
*
*/
export async function getZxglData(
params: any,
callback?: (data: any) => void,
): Promise<any> {
const response = await request({
url: `${serverIp}${baseURL}/weatherData/linkedData`,
method: 'PUT',
params,
});
if (response.success && response.code === 200) {
callback?.(response);
}
}
/**
*
*/
export async function getGlqxsjRzData(
params: any,
callback?: (data: any) => void,
): Promise<any> {
const response = await request({
url: `${serverIp}${baseURL}/weatherData/getLinkedDataLog`,
method: 'GET',
params,
});
if (response.success && response.code === 200) {
callback?.(response);
}
}