输运模拟

This commit is contained in:
冯少康 2026-07-30 18:06:40 +08:00
parent c549f4e01e
commit 209f9fe151
5 changed files with 386 additions and 97 deletions

View File

@ -1,10 +1,16 @@
<!-- gis地图右侧侧边栏icon文件 -->
<script setup lang="ts">
// Icon
import type { LocateParams, MapControlItem } from '@/gis/ol/interface/common';
import { domFullscreenStatus } from '@/gis/common/domHandle';
import { mapRightMenuEvent } from '@/gis/ol/olRightMenu';
import type { LocateParams, MapControlItem } from "@/gis/ol/interface/common";
import { domFullscreenStatus } from "@/gis/common/domHandle";
import { mapRightMenuEvent } from "@/gis/ol/olRightMenu";
import { getGif } from "@/utils/axios/symn";
import { useI18n } from "vue-i18n";
import { ElMessage } from "element-plus";
import { getrwssGifFileData, downGifSsFile,getRwscGifFileGcrz } from "@/utils/axios/fskjk";
const { t } = useI18n();
//
const isShowLocate = ref(false);
@ -15,31 +21,33 @@ const locate = ref<LocateParams>({
// gif
const isShowGif = ref(false);
const gifSrc = ref('');
const gifParams = ref({ taskId: '', speciesId: '' });
const viewLogsDialog = ref(false);
const gifSrc = ref("");
const gifParams = ref({ taskId: "", speciesId: "" });
//
const baseList = ref<MapControlItem[]>([
{
name: 'fullScreen',
name: "fullScreen",
isMargin: true,
tooltip: '全屏',
tooltip: "全屏",
isActive: false,
activeName: 'fullScreen_active',
activeName: "fullScreen_active",
},
{
name: 'digitalMap',
name: "digitalMap",
isMargin: false,
tooltip: '数字地图',
tooltip: "数字地图",
isActive: false, // ,
activeName: 'digitalMap_active',
activeName: "digitalMap_active",
},
{
name: 'satelliteMap',
name: "satelliteMap",
isMargin: true,
tooltip: '卫星地图',
tooltip: "卫星地图",
isActive: true,
activeName: 'satelliteMap_active',
activeName: "satelliteMap_active",
},
// {
@ -50,18 +58,18 @@ const baseList = ref<MapControlItem[]>([
// activeName: 'mark_active',
// },
{
name: 'distance',
name: "distance",
isMargin: false,
tooltip: '距离',
tooltip: "距离",
isActive: false,
activeName: 'distance_active',
activeName: "distance_active",
},
{
name: 'area',
name: "area",
isMargin: false,
tooltip: '面积',
tooltip: "面积",
isActive: false,
activeName: 'area_active',
activeName: "area_active",
},
// {
// name: 'space',
@ -71,32 +79,32 @@ const baseList = ref<MapControlItem[]>([
// activeName: 'space_active',
// },
{
name: 'deleteDraw',
name: "deleteDraw",
isMargin: true,
tooltip: '删除绘制',
tooltip: "删除绘制",
isActive: false,
activeName: 'deleteDraw',
activeName: "deleteDraw",
},
{
name: 'locate',
name: "locate",
isMargin: false,
tooltip: '定位',
tooltip: "定位",
isActive: false,
activeName: 'locate_active',
activeName: "locate_active",
},
{
name: 'zoomIn',
name: "zoomIn",
isMargin: false,
tooltip: '放大',
tooltip: "放大",
isActive: false,
activeName: 'zoomIn',
activeName: "zoomIn",
},
{
name: 'zoomOut',
name: "zoomOut",
isMargin: false,
tooltip: '缩小',
tooltip: "缩小",
isActive: false,
activeName: 'zoomOut',
activeName: "zoomOut",
},
// {
// name: 'addTarget',
@ -117,49 +125,69 @@ const baseList = ref<MapControlItem[]>([
//
const yxcjTool = ref<MapControlItem[]>([
{
name: 'dataExport',
name: "dataExport",
isMargin: false,
tooltip: '数据导入',
tooltip: "数据导入",
isActive: false,
activeName: 'dataExport_active',
activeName: "dataExport_active",
},
{
name: 'dataStatistics',
name: "dataStatistics",
isMargin: false,
tooltip: '数据统计',
tooltip: "数据统计",
isActive: false,
activeName: 'dataStatistics_active',
activeName: "dataStatistics_active",
},
]);
//
const symnTool = ref<MapControlItem[]>([
{
name: 'gif',
name: "gif",
isMargin: false,
tooltip: 'GIF',
tooltip: "GIF",
isActive: false,
activeName: 'gif',
}
activeName: "gif",
},
]);
const gifFormData = reactive({
minLon: "",
maxLon: "",
minLat: "",
maxLat: "",
});
const downTypeValue = ref("");
const downTypeOptions = ref([
{
value: "global",
label: "全球",
},
{
value: "region",
label: "区域",
},
]);
const gifRzGroupValue = ref([]);
//
const svgList = ref<MapControlItem[]>([...baseList.value]);
//
function handleIconClick(item: MapControlItem) {
if (item.name === 'locate') {
if (item.name === "locate") {
item.isActive = !item.isActive;
isShowLocate.value = item.isActive;
return;
}
//
const exclusiveGroup = ['mark', 'distance', 'area', 'space', 'deleteDraw'];
const exclusiveGroup = ["mark", "distance", "area", "space", "deleteDraw"];
//
const isInExclusiveGroup = exclusiveGroup.includes(item.name);
//
if (item.isActive && ['digitalMap', 'satelliteMap'].includes(item.name)) {
if (item.isActive && ["digitalMap", "satelliteMap"].includes(item.name)) {
return;
}
@ -172,15 +200,15 @@ function handleIconClick(item: MapControlItem) {
}
});
//
if (item.name !== 'deleteDraw') {
if (item.name !== "deleteDraw") {
item.isActive = !item.isActive;
}
}
//
else if (['digitalMap', 'satelliteMap'].includes(item.name)) {
else if (["digitalMap", "satelliteMap"].includes(item.name)) {
//
svgList.value.forEach((icon) => {
if (['digitalMap', 'satelliteMap'].includes(icon.name)) {
if (["digitalMap", "satelliteMap"].includes(icon.name)) {
icon.isActive = false;
}
});
@ -188,41 +216,49 @@ function handleIconClick(item: MapControlItem) {
item.isActive = true;
}
//
else if (['dataExport', 'dataStatistics'].includes(item.name)) {
else if (["dataExport", "dataStatistics"].includes(item.name)) {
// UI
// eslint-disable-next-line prefer-const
let falg: any = !item.isActive;
switchIconActive(item.name, falg);
//
EventBusTool.getEventBus().publish('yxcjGisUiEvent', {
EventBusTool.getEventBus().publish("yxcjGisUiEvent", {
key: item.name,
falg,
});
}
// gif
else if (item.name === 'gif') {
getGif(gifParams.value,(res: any) => {
gifSrc.value = window.FSXConfig.VUE_APP_SERVER_IP + res;
isShowGif.value = true;
});
else if (item.name === "gif") {
let taskId = JSON.parse(sessionStorage.getItem("ssmnDataItem")).id;
getGif(
{
taskId,
genGifType: "global",
},
(res: any) => {
gifSrc.value = window.FSXConfig.VUE_APP_SERVER_IP + res;
isShowGif.value = true;
}
);
}
//
else {
//
if (!['zoomIn', 'zoomOut'].includes(item.name)) {
if (!["zoomIn", "zoomOut"].includes(item.name)) {
item.isActive = !item.isActive;
}
}
// 使
(mapRightMenuEvent[item.name] as any) && (mapRightMenuEvent[item.name] as any)();
(mapRightMenuEvent[item.name] as any) &&
(mapRightMenuEvent[item.name] as any)();
}
// dialog
function dialogClose() {
isShowLocate.value = false;
const locate = svgList.value.find((item) => {
return item.name === 'locate';
return item.name === "locate";
});
// 1: 使iflocate
@ -248,52 +284,113 @@ function switchIconActive(key: string, falg: boolean) {
});
}
// GIF
const generateGif = () => {
let taskId = JSON.parse(sessionStorage.getItem("ssmnDataItem")).id;
getrwssGifFileData(
{
taskId,
lonmin: gifFormData.minLon,
latmin: gifFormData.minLat,
lonmax: gifFormData.maxLon,
latmax: gifFormData.maxLat,
speciesId: "",
},
(res: any) => {
console.log(res, "2222222222222");
}
);
};
// GIF
const downGifFile = () => {
let taskId = JSON.parse(sessionStorage.getItem("ssmnDataItem")).id;
downGifSsFile(
{
taskId,
speciesId: "",
genGifType: downTypeValue.value,
},
(res: Blob) => {
console.log(res, "2222222222222");
// res Blobheaders
const fileName = "JPX38_region.gif";
const url = URL.createObjectURL(res);
const a = document.createElement("a");
a.href = url;
a.download = fileName;
document.body.appendChild(a);
a.click();
URL.revokeObjectURL(url);
document.body.removeChild(a);
ElMessage.success("文件下载成功");
}
);
};
//
const viewLogs = ()=>{
viewLogsDialog.value = true;
let taskId = JSON.parse(sessionStorage.getItem("ssmnDataItem")).id;
getRwscGifFileGcrz(
{
taskId,
speciesId: "",
},
(res: any) => {
console.log(res,222222222);
gifRzGroupValue.value = res.result;
}
);
}
onMounted(() => {
//
svgList.value[0].isActive = domFullscreenStatus();
// UI
EventBusTool.getEventBus().subscribe('mapRightMenuUIEvent', (res: any) => {
EventBusTool.getEventBus().subscribe("mapRightMenuUIEvent", (res: any) => {
// icon
if (res.key === 'enterFullscreen' && !svgList.value[0].isActive) {
if (res.key === "enterFullscreen" && !svgList.value[0].isActive) {
svgList.value[0].isActive = true;
}
// 退icon
else if (res.key === 'exitFullscreen' && svgList.value[0].isActive) {
else if (res.key === "exitFullscreen" && svgList.value[0].isActive) {
svgList.value[0].isActive = false;
}
// 退icon
else if (res.key === 'f11KeyPressed') {
else if (res.key === "f11KeyPressed") {
if (!svgList.value[0].isActive) {
svgList.value[0].isActive = true;
}
else {
} else {
svgList.value[0].isActive = false;
}
}
// 退icon
else if (res.key === 'switchLocalLayer') {
else if (res.key === "switchLocalLayer") {
svgList.value[1].isActive = false;
svgList.value[2].isActive = true;
}
//
if (res.key === 'baseList') {
if (res.key === "baseList") {
svgList.value = [...baseList.value];
} else if (res.key === 'allList') {
} else if (res.key === "allList") {
svgList.value = [...baseList.value, ...yxcjTool.value];
} else if (res.key === 'gifIcon') {
} else if (res.key === "gifIcon") {
svgList.value = [...baseList.value, ...symnTool.value];
}
//
if (res.key === 'dataExport') { //
if (res.key === "dataExport") {
//
switchIconActive(res.key, res.falg);
}
if (res.key === 'dataStatistics') { //
if (res.key === "dataStatistics") {
//
switchIconActive(res.key, res.falg);
}
});
EventBusTool.getEventBus().subscribe('speciesChange', (res: any) => {
if (res.key === 'speciesId') {
EventBusTool.getEventBus().subscribe("speciesChange", (res: any) => {
if (res.key === "speciesId") {
gifParams.value = res.data;
}
});
@ -303,40 +400,143 @@ onMounted(() => {
<template>
<div class="icon_container">
<div
v-for="(item, index) in svgList" :key="index" class="icon"
:class="{ 'has-margin': item.isMargin, 'has-active': item.isActive }" @click.stop="handleIconClick(item)"
v-for="(item, index) in svgList"
:key="index"
class="icon"
:class="{ 'has-margin': item.isMargin, 'has-active': item.isActive }"
@click.stop="handleIconClick(item)"
>
<el-tooltip class="box-item" effect="dark" :content="item.tooltip" placement="left">
<SvgIcon :name="item.isActive ? item.activeName : item.name" width="20" height="20" />
<el-tooltip
class="box-item"
effect="dark"
:content="item.tooltip"
placement="left"
>
<SvgIcon
:name="item.isActive ? item.activeName : item.name"
width="20"
height="20"
/>
</el-tooltip>
</div>
</div>
<Dialog v-model="isShowLocate" title="地图定位" width="400" class="config-dialog" @close="dialogClose">
<el-row style="display: flex;justify-content: space-between;">
<Dialog
v-model="isShowLocate"
title="地图定位"
width="400"
class="config-dialog"
@close="dialogClose"
>
<el-row style="display: flex; justify-content: space-between">
<el-col :span="9">
<el-input-number
v-model="locate.lon" style="width: auto;" placeholder="请输入经度" :min="-180" :max="180"
v-model="locate.lon"
style="width: auto"
placeholder="请输入经度"
:min="-180"
:max="180"
controls-position="right"
/>
</el-col>
<el-col :span="9">
<el-input-number
v-model="locate.lat" style="width: auto;" placeholder="请输入纬度" :min="-90" :max="90"
v-model="locate.lat"
style="width: auto"
placeholder="请输入纬度"
:min="-90"
:max="90"
controls-position="right"
/>
</el-col>
<el-col :span="4">
<el-button type="primary" @click="locateHandle">
定位
</el-button>
<el-button type="primary" @click="locateHandle"> 定位 </el-button>
</el-col>
</el-row>
</Dialog>
<Dialog v-model="isShowGif" title="GIF" width="1340" class="config-dialog" style="min-height: 120px" @close="isShowGif=false">
<img v-if="isShowGif" :src="gifSrc" alt="GIF" style="width: 100%">
<a v-if="gifSrc" :href="gifSrc" download="gif" class="download-icon">
<Dialog
v-model="isShowGif"
title="GIF"
width="1340"
class="config-dialog"
style="min-height: 120px"
@close="isShowGif = false"
>
<el-form :model="form" label-width="auto" style="max-width: 100%">
<el-row :gutter="12">
<el-col :span="5">
<el-form-item :label="t('lonmin')">
<el-input v-model="gifFormData.minLon" />
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item :label="t('lonmax')">
<el-input v-model="gifFormData.maxLon" />
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item :label="t('latmin')">
<el-input v-model="gifFormData.minLat" />
</el-form-item>
</el-col>
<el-col :span="5">
<el-form-item :label="t('latmax')">
<el-input v-model="gifFormData.maxLat" />
</el-form-item>
</el-col>
<el-col :span="2"
>
<el-button @click="generateGif" type="primary" class="custom-btn" >生成GIF</el-button></el-col
>
<el-col :span="2"><el-button @click="viewLogs" type="primary" class="custom-btn" >查看日志</el-button></el-col>
</el-row>
</el-form>
<img
v-if="isShowGif"
:src="gifSrc"
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
v-model="downTypeValue"
:options="downTypeOptions"
:props="props"
placeholder="选择类型"
/>
</el-col>
<el-col :span="2">
<el-button :disabled="!downTypeValue" @click="downGifFile"
type="primary" class="custom-btn" >下载</el-button
>
</el-col>
</el-row>
<!-- <a v-if="gifSrc" :href="gifSrc" download="gif" class="download-icon">
<el-icon size="20"><Download /></el-icon>
</a>
</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>
</Dialog>
</template>
@ -398,14 +598,29 @@ onMounted(() => {
align-items: center;
justify-content: center;
border-radius: 50%;
background-color: rgba(0,0,0,0.2);
background-color: rgba(0, 0, 0, 0.2);
cursor: pointer;
color: black;
&:hover {
background-color: rgba(0,0,0,0.3);
background-color: rgba(0, 0, 0, 0.3);
}
&:active {
background-color: rgba(0,0,0,0.4);
background-color: rgba(0, 0, 0, 0.4);
}
}
.gif-rztext{
max-height: 400px;
overflow: auto;
}
.custom-btn {
background-color: #1397a3;
border-color: #1397a3;
color: #fff;
&:hover {
background-color: #185c5c;
border-color: #4ac1c1;
}
}
</style>

View File

@ -378,7 +378,7 @@ onMounted(() => {
<SvgIcon name="stop" title="停止" width="34" height="34" />
</div>
<div class="slider">
<div style="color: white">value:{{ value }} ----- totalHours:{{ totalHours }}</div>
<!-- <div style="color: white">value:{{ value }} ----- totalHours:{{ totalHours }}</div> -->
<el-slider v-model="value" :disabled="isDisabledSlider"
:style="{ width: isShowTabs ? (props.sliderWidth ?? '58vw') : '62vw' }" :max="totalHours"
:format-tooltip="slodtooltip" :marks="marks" @input="handleChange" />

View File

@ -276,6 +276,7 @@ const pinToTopTask = (row: any, isPin: boolean) => {
};
function viewTask(task: any) {
console.log('查看任务:', task);
sessionStorage.setItem("ssmnDataItem",JSON.stringify(task))
handleClose();
form.value = {
...task,

View File

@ -87,7 +87,6 @@ const pickerValue = ref([]);
const hfSelectSjy = ref<any>(null);
getTimeBatchList();
function getTimeBatchList() {
getTimeBatch({}, (res) => {
@ -142,7 +141,7 @@ function getList() {
label: "GFS",
},
];
selectValue.value = "6";
// selectValue.value = "6";
}
dataSource.value = dataS;
getData(
@ -153,7 +152,7 @@ function getList() {
dataSource: searchSelectValue.value || dataS,
pageSize: pageSize.value,
pageNum: currentPage.value,
batchTime:searchPcSelectValue.value,
batchTime: searchPcSelectValue.value,
},
(res) => {
taskList.value = res.rows;
@ -358,6 +357,8 @@ function previewTask(row: any) {
const changeSjyValue = (val) => {
pcSelectOption.value = [];
searchPcSelectValue.value = "";
//
if (val) {
//
@ -379,6 +380,7 @@ const changeSjyValue = (val) => {
const changeSjyValue1 = (val) => {
timeBatchList.value = [];
timeBatch.value = "";
//
if (val) {
//
@ -405,7 +407,16 @@ getList();
class="custom-input"
/>
</ElFormItem>
<ElFormItem :label="t('tqybTableDataType')">
<ElFormItem :label="t('tqybTableDataType')" v-if="type != 'gkqx'">
<el-select-v2
v-model="searchSelectValue"
clearable
:options="selectOption"
placeholder="选择数据源"
style="width: 240px; margin-right: 10px"
/>
</ElFormItem>
<ElFormItem :label="t('tqybTableDataType')" v-if="type === 'gkqx'">
<el-select-v2
v-model="searchSelectValue"
clearable
@ -533,7 +544,7 @@ getList();
<div style="display: flex; margin-right: 10px" class="bottomBox">
<ElSelect
v-if="type === 'gkqx'"
v-model="hfSelectSjy"
v-model="selectValue"
placeholder="选择数据源"
filterable
style="width: 160px; margin-right: 10px"

View File

@ -0,0 +1,62 @@
import { baseURL, serverIp } from "@/gis/common/config";
import { ElMessage } from "element-plus";
import request from "@/utils/request"; // 复用已有的Axios请求实例
/**
* GIF文件
*/
export async function getrwssGifFileData(
params: any,
callback?: (data: any) => void,
): Promise<any> {
const response = await request({
url: `${serverIp}${baseURL}/transportResult/genGif`,
method: "POST",
params,
});
if (response.success && response.code === 200) {
ElMessage({
type: "success",
message: response.message,
});
callback?.(response);
}
}
/**
* GIF文件
*/
export async function downGifSsFile(
params: any,
callback?: (data: any) => void,
): Promise<any> {
const response = await request({
url: `${serverIp}${baseURL}/transportResult/downloadGif`,
method: "GET",
params,
responseType: "blob",
});
console.log(response, "22222222222222");
// HTTP 200 = 文件流正常返回,直接执行下载回调
callback?.(response);
}
/**
* GIF文件过程日志
*/
export async function getRwscGifFileGcrz(
params: any,
callback?: (data: any) => void,
): Promise<any> {
const response = await request({
url: `${serverIp}${baseURL}/transportResult/getGenGiflog`,
method: "GET",
params,
});
if (response.success && response.code === 200) {
callback?.(response);
}
}