修改热力图播放
This commit is contained in:
parent
aaab4fc984
commit
324e6302a7
|
|
@ -7,7 +7,7 @@ import { mapRightMenuEvent } from "@/gis/ol/olRightMenu";
|
|||
import { getGif } from "@/utils/axios/symn";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { ElMessage } from "element-plus";
|
||||
import log from '@/pages/symn/log/index.vue';
|
||||
import log from "@/pages/symn/log/index.vue";
|
||||
|
||||
import {
|
||||
getrwssGifFileData,
|
||||
|
|
@ -259,7 +259,7 @@ function handleIconClick(item: MapControlItem) {
|
|||
isShowGif.value = true;
|
||||
}
|
||||
);
|
||||
}else if(item.name=='calendar'){
|
||||
} else if (item.name == "calendar") {
|
||||
let falg: any = !item.isActive;
|
||||
switchIconActive(item.name, falg);
|
||||
EventBusTool.getEventBus().publish("sjfxCalendarEvent", {
|
||||
|
|
@ -328,6 +328,23 @@ const generateGif = () => {
|
|||
);
|
||||
};
|
||||
|
||||
// 提取文件名工具
|
||||
const getFileNameFromDisposition = (
|
||||
disposition?: string,
|
||||
defaultName = "download.gif"
|
||||
) => {
|
||||
if (!disposition) return defaultName;
|
||||
const match = disposition.match(/filename=([^;]+)/);
|
||||
if (match?.[1]) {
|
||||
try {
|
||||
return decodeURIComponent(match[1]);
|
||||
} catch {
|
||||
return match[1];
|
||||
}
|
||||
}
|
||||
return defaultName;
|
||||
};
|
||||
|
||||
// 下载任务所属GIF文件
|
||||
const downGifFile = () => {
|
||||
let taskId = JSON.parse(sessionStorage.getItem("ssmnDataItem")).id;
|
||||
|
|
@ -338,11 +355,16 @@ const downGifFile = () => {
|
|||
speciesId,
|
||||
genGifType: downTypeValue.value,
|
||||
},
|
||||
(res: Blob) => {
|
||||
console.log(res, "2222222222222");
|
||||
// res 直接是Blob,没有headers,直接写死文件名
|
||||
const fileName = "JPX38_region.gif";
|
||||
const url = URL.createObjectURL(res);
|
||||
(response) => {
|
||||
console.log(response, "2222222222222");
|
||||
const blob = response.data;
|
||||
const disposition = response.headers["content-disposition"];
|
||||
const fileName = getFileNameFromDisposition(
|
||||
disposition,
|
||||
"JPX38_global.gif"
|
||||
);
|
||||
|
||||
const url = URL.createObjectURL(blob);
|
||||
const a = document.createElement("a");
|
||||
a.href = url;
|
||||
a.download = fileName;
|
||||
|
|
@ -405,7 +427,7 @@ onMounted(() => {
|
|||
svgList.value = [...baseList.value, ...yxcjTool.value];
|
||||
} else if (res.key === "gifIcon") {
|
||||
svgList.value = [...baseList.value, ...symnTool.value];
|
||||
}else if(res.key=="sjfxList"){
|
||||
} else if (res.key == "sjfxList") {
|
||||
svgList.value = [...baseList.value, ...sjfxTool.value];
|
||||
}
|
||||
// 按钮菜单触发状态
|
||||
|
|
@ -418,7 +440,7 @@ onMounted(() => {
|
|||
switchIconActive(res.key, res.falg);
|
||||
}
|
||||
|
||||
if(res.key == "calendar"){
|
||||
if (res.key == "calendar") {
|
||||
switchIconActive(res.key, res.falg);
|
||||
}
|
||||
});
|
||||
|
|
@ -495,45 +517,47 @@ onMounted(() => {
|
|||
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-form
|
||||
:model="form"
|
||||
label-width="auto"
|
||||
style="max-width: 100%; justify-content: space-between;display: flex;"
|
||||
>
|
||||
<el-form-item :label="t('lonmin')">
|
||||
<el-input v-model="gifFormData.minLon" />
|
||||
</el-form-item>
|
||||
|
||||
<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-item :label="t('lonmax')">
|
||||
<el-input v-model="gifFormData.maxLon" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('latmin')">
|
||||
<el-input v-model="gifFormData.minLat" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="t('latmax')">
|
||||
<el-input v-model="gifFormData.maxLat" />
|
||||
</el-form-item>
|
||||
|
||||
<el-button @click="generateGif" type="primary" class="custom-btn"
|
||||
>生成GIF</el-button
|
||||
>
|
||||
|
||||
<el-button @click="viewLogs" type="primary" class="custom-btn"
|
||||
>查看日志</el-button
|
||||
>
|
||||
</el-form>
|
||||
|
||||
<img v-if="isShowGif" :src="gifSrc" alt="GIF" style="width: 100%" />
|
||||
<div style="width: 100%; display: flex; justify-content: flex-end;margin-top: 15px;">
|
||||
<div style="width: 25%;display: flex;padding-right: 10px;">
|
||||
<div
|
||||
style="
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
border-top: 1px solid #0c6a66;
|
||||
margin-top: 10px;
|
||||
"
|
||||
>
|
||||
<div
|
||||
style="width: 25%; display: flex; margin-top: 15px"
|
||||
>
|
||||
<el-select
|
||||
v-model="downTypeValue"
|
||||
:options="downTypeOptions"
|
||||
|
|
@ -545,7 +569,7 @@ onMounted(() => {
|
|||
@click="downGifFile"
|
||||
type="primary"
|
||||
class="custom-btn"
|
||||
style="margin-left: 10px;"
|
||||
style="margin-left: 10px"
|
||||
>下载</el-button
|
||||
>
|
||||
</div>
|
||||
|
|
@ -553,9 +577,9 @@ onMounted(() => {
|
|||
</Dialog>
|
||||
|
||||
<!-- 运行日志弹窗 -->
|
||||
<Dialog v-model="viewLogsDialog" :title="t('operationLog')" width="56vw">
|
||||
<log :data="gifRzGroupValue" />
|
||||
</Dialog>
|
||||
<Dialog v-model="viewLogsDialog" :title="t('operationLog')" width="56vw">
|
||||
<log :data="gifRzGroupValue" />
|
||||
</Dialog>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
|
|
|||
|
|
@ -1,20 +1,33 @@
|
|||
<script lang="ts" setup>
|
||||
import dayjs from 'dayjs';
|
||||
import { activeMoudleInf, gisImgOpt, setWeathRequesTime, weathFlag } from '@/gis/ol/index';
|
||||
import { getClockTimeRange, setcurrentTime, setShouldAnimate, stopPlay } from '@/gis/ol/olClock';
|
||||
import { clearGridFeatures } from '@/gis/ol/olGirdHeatmap';
|
||||
import { clearHeatmapLayer } from '@/gis/ol/olHeatmap';
|
||||
import { playback_EventBusCallback, sendPlaybackPostMassage } from '@/gis/worker/playbackWorkerMa';
|
||||
import { playbackSearchData } from '@/utils/axios/tqyb/data/index';
|
||||
import dayjs from "dayjs";
|
||||
import {
|
||||
activeMoudleInf,
|
||||
gisImgOpt,
|
||||
setWeathRequesTime,
|
||||
weathFlag,
|
||||
} from "@/gis/ol/index";
|
||||
import {
|
||||
getClockTimeRange,
|
||||
setcurrentTime,
|
||||
setShouldAnimate,
|
||||
stopPlay,
|
||||
} from "@/gis/ol/olClock";
|
||||
import { clearGridFeatures } from "@/gis/ol/olGirdHeatmap";
|
||||
import { clearHeatmapLayer } from "@/gis/ol/olHeatmap";
|
||||
import {
|
||||
playback_EventBusCallback,
|
||||
sendPlaybackPostMassage,
|
||||
} from "@/gis/worker/playbackWorkerMa";
|
||||
import { playbackSearchData } from "@/utils/axios/tqyb/data/index";
|
||||
|
||||
const props = defineProps({
|
||||
activeMenu: {
|
||||
type: String,
|
||||
default: '',
|
||||
default: "",
|
||||
},
|
||||
taskId: {
|
||||
type: String,
|
||||
default: '',
|
||||
default: "",
|
||||
},
|
||||
globalAttr: {
|
||||
type: Object,
|
||||
|
|
@ -55,10 +68,13 @@ interface TabItem {
|
|||
isActive: boolean;
|
||||
}
|
||||
const tabsList = ref<TabItem[]>([
|
||||
{ label: '小时', value: 'hour', isActive: true },
|
||||
{ label: '天', value: 'day', isActive: false },
|
||||
{ label: "小时", value: "hour", isActive: true },
|
||||
{ label: "天", value: "day", isActive: false },
|
||||
]);
|
||||
|
||||
const labelLeft = ref(0)
|
||||
const labelText = ref('')
|
||||
|
||||
// 下拉菜单台站选中项(输运模拟业务使用)
|
||||
const stationValue = ref<any>(null);
|
||||
|
||||
|
|
@ -73,30 +89,34 @@ const isDisabledSlider = ref<boolean>(false);
|
|||
// 是否可以查询数据
|
||||
const isQueryData = ref<boolean>(true);
|
||||
// 传入的开始和结束时间
|
||||
const marskType = ref<string>('hour');
|
||||
const start = ref<any>(dayjs('2025-09-15 00:00:00'));
|
||||
const end = ref<any>(dayjs('2025-09-16 00:00:00'));
|
||||
const marskType = ref<string>("hour");
|
||||
const start = ref<any>(dayjs("2025-09-15 00:00:00"));
|
||||
const end = ref<any>(dayjs("2025-09-16 00:00:00"));
|
||||
const totalHours = ref<number>(end.value.diff(start.value, marskType.value));
|
||||
const value = ref<number>(0);
|
||||
const playFalg = ref<boolean>(false);
|
||||
const slodtooltip: any = (toolNum: number) => {
|
||||
return start.value.add(toolNum, marskType.value).format('YYYY-MM-DD HH:mm:ss');
|
||||
return start.value
|
||||
.add(toolNum, marskType.value)
|
||||
.format("YYYY-MM-DD HH:mm:ss");
|
||||
};
|
||||
|
||||
const active = ref('浓度分布');
|
||||
const active = ref("浓度分布");
|
||||
|
||||
function switchActive(tab: string) {
|
||||
if (playFalg.value)
|
||||
return;
|
||||
if (playFalg.value) return;
|
||||
active.value = tab;
|
||||
sendPlaybackPostMassage({ code: 'queryHSJMNType', data: JSON.parse(JSON.stringify(active.value)) }, {});
|
||||
sendPlaybackPostMassage(
|
||||
{ code: "queryHSJMNType", data: JSON.parse(JSON.stringify(active.value)) },
|
||||
{}
|
||||
);
|
||||
stopAnimation();
|
||||
}
|
||||
|
||||
// 生成 marks,每隔6小时一个
|
||||
const dataRequestOpt = computed(() => {
|
||||
const obj: Record<number, string> = {};
|
||||
const baseSpeed = marskType.value === 'hour' ? 6 : 1;
|
||||
const baseSpeed = marskType.value === "hour" ? 6 : 1;
|
||||
const totalPoints = Math.floor(totalHours.value / baseSpeed) + 1; // 原始总标签数
|
||||
// const maxShow = 6; // 最多显示10个标签
|
||||
|
||||
|
|
@ -107,9 +127,13 @@ const dataRequestOpt = computed(() => {
|
|||
|
||||
// 按实际步长生成标签(确保不超过10个)
|
||||
let count = 0;
|
||||
for (let i = 0; i <= totalHours.value && count < totalPoints; i += baseSpeed) {
|
||||
for (
|
||||
let i = 0;
|
||||
i <= totalHours.value && count < totalPoints;
|
||||
i += baseSpeed
|
||||
) {
|
||||
const t = start.value.add(i, marskType.value);
|
||||
obj[i] = t.format('YYYY-MM-DD HH:mm:ss');
|
||||
obj[i] = t.format("YYYY-MM-DD HH:mm:ss");
|
||||
count++;
|
||||
}
|
||||
|
||||
|
|
@ -128,8 +152,18 @@ const dataRequestOpt = computed(() => {
|
|||
function handleChange(val: number) {
|
||||
// 滑块值代表距离开始时间的小时数
|
||||
const currentTime = start.value.add(val, marskType.value);
|
||||
labelText.value = currentTime.format("YYYY-MM-DD HH:mm:ss");
|
||||
|
||||
setcurrentTime(currentTime.valueOf());
|
||||
console.log(currentTime.format('YYYY-MM-DD HH:mm:ss'));
|
||||
nextTick(() => {
|
||||
const sliderDom = document.querySelector('.slider .el-slider__runway')
|
||||
if (!sliderDom) return
|
||||
const width = sliderDom.offsetWidth;
|
||||
// 百分比位置
|
||||
const percent = val / totalHours.value
|
||||
// 基础位置,居中偏移,微调数值控制对齐
|
||||
labelLeft.value = percent * width - 60
|
||||
})
|
||||
}
|
||||
// 切换显示标签
|
||||
function switchTab(tab: TabItem) {
|
||||
|
|
@ -143,7 +177,7 @@ function switchTab(tab: TabItem) {
|
|||
|
||||
// 进行起止动画
|
||||
function playAnimation() {
|
||||
if (props.activeMenu === '输运模拟' && !playFalg.value && isQueryData.value) {
|
||||
if (props.activeMenu === "输运模拟" && !playFalg.value && isQueryData.value) {
|
||||
const param = {
|
||||
taskId: props.taskId,
|
||||
speciesId: JSON.parse(JSON.stringify(speciesValue.value)),
|
||||
|
|
@ -153,10 +187,17 @@ function playAnimation() {
|
|||
};
|
||||
isDisabledSlider.value = true;
|
||||
isQueryData.value = false;
|
||||
sendPlaybackPostMassage({ code: 'querySYMN', data: JSON.parse(JSON.stringify(param)) }, {});
|
||||
sendPlaybackPostMassage(
|
||||
{ code: "querySYMN", data: JSON.parse(JSON.stringify(param)) },
|
||||
{}
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (props.activeMenu === '核事件模拟' && !playFalg.value && isQueryData.value) {
|
||||
if (
|
||||
props.activeMenu === "核事件模拟" &&
|
||||
!playFalg.value &&
|
||||
isQueryData.value
|
||||
) {
|
||||
const param = {
|
||||
taskId: props.taskId,
|
||||
hour: 1,
|
||||
|
|
@ -165,12 +206,23 @@ function playAnimation() {
|
|||
};
|
||||
isDisabledSlider.value = true;
|
||||
isQueryData.value = false;
|
||||
sendPlaybackPostMassage({ code: 'queryHSJMNType', data: JSON.parse(JSON.stringify(active.value)) }, {});
|
||||
if (active.value === '浓度分布') {
|
||||
sendPlaybackPostMassage({ code: 'queryHSJMNndfb', data: JSON.parse(JSON.stringify(param)) }, {});
|
||||
}
|
||||
else {
|
||||
sendPlaybackPostMassage({ code: 'queryHSJMNjlfb', data: JSON.parse(JSON.stringify(param)) }, {});
|
||||
sendPlaybackPostMassage(
|
||||
{
|
||||
code: "queryHSJMNType",
|
||||
data: JSON.parse(JSON.stringify(active.value)),
|
||||
},
|
||||
{}
|
||||
);
|
||||
if (active.value === "浓度分布") {
|
||||
sendPlaybackPostMassage(
|
||||
{ code: "queryHSJMNndfb", data: JSON.parse(JSON.stringify(param)) },
|
||||
{}
|
||||
);
|
||||
} else {
|
||||
sendPlaybackPostMassage(
|
||||
{ code: "queryHSJMNjlfb", data: JSON.parse(JSON.stringify(param)) },
|
||||
{}
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
@ -184,8 +236,8 @@ function stopAnimation() {
|
|||
// 停止播放
|
||||
stopPlay();
|
||||
// 关掉图例
|
||||
playback_EventBusCallback.publish('legendUiData', {
|
||||
key: 'showLengend',
|
||||
playback_EventBusCallback.publish("legendUiData", {
|
||||
key: "showLengend",
|
||||
value: false,
|
||||
});
|
||||
// 清空要素
|
||||
|
|
@ -199,7 +251,7 @@ function stopAnimation() {
|
|||
isQueryData.value = true;
|
||||
// 进度条设为0
|
||||
value.value = 0;
|
||||
sendPlaybackPostMassage({ code: 'abortSYMN', data: false }, {});
|
||||
sendPlaybackPostMassage({ code: "abortSYMN", data: false }, {});
|
||||
}
|
||||
|
||||
// 更新时间线标签
|
||||
|
|
@ -207,27 +259,33 @@ function updateTimeLabel(ctime: any) {
|
|||
// 获取开始时间
|
||||
const startTimestamp = start.value.valueOf();
|
||||
// 获取时间差
|
||||
const currentHourDiff = Math.floor((ctime - startTimestamp) / (3600000));
|
||||
const currentHourDiff = Math.floor((ctime - startTimestamp) / 3600000);
|
||||
// 获取当前的marks键集合(即所有6小时整数倍的刻度值)
|
||||
const markKeys = Object.keys(dataRequestOpt.value).map(Number);
|
||||
const isDifferentValue = value.value !== currentHourDiff;
|
||||
const is6HourInterval = props.activeMenu === '输运模拟' ? currentHourDiff % 3 === 0 : currentHourDiff % 1 === 0;
|
||||
const is6HourInterval =
|
||||
props.activeMenu === "输运模拟"
|
||||
? currentHourDiff % 3 === 0
|
||||
: currentHourDiff % 1 === 0;
|
||||
|
||||
// 仅当currentHourDiff是marks中的刻度值时,才更新滑块
|
||||
if (
|
||||
currentHourDiff >= 0
|
||||
&& currentHourDiff <= totalHours.value
|
||||
currentHourDiff >= 0 &&
|
||||
currentHourDiff <= totalHours.value &&
|
||||
// && markKeys.includes(currentHourDiff) // 关键判断:是否为刻度值
|
||||
&& isDifferentValue // 只有值不同时才更新
|
||||
&& is6HourInterval
|
||||
isDifferentValue && // 只有值不同时才更新
|
||||
is6HourInterval
|
||||
) {
|
||||
value.value = currentHourDiff;
|
||||
if (markKeys.includes(currentHourDiff)) {
|
||||
// 获取当前currentHourDiff在markKeys中的索引(第几个刻度)
|
||||
const currentIndex = markKeys.indexOf(currentHourDiff);
|
||||
|
||||
if (activeMoudleInf.activeMenu === '天气预报运算') {
|
||||
console.log(`获取第${currentIndex + 1}组数据,当前时间为`, dataRequestOpt.value[currentHourDiff]);
|
||||
if (activeMoudleInf.activeMenu === "天气预报运算") {
|
||||
console.log(
|
||||
`获取第${currentIndex + 1}组数据,当前时间为`,
|
||||
dataRequestOpt.value[currentHourDiff]
|
||||
);
|
||||
setWeathRequesTime(dataRequestOpt.value[currentHourDiff]);
|
||||
// 其他气象进行请求数据
|
||||
const params = { ...gisImgOpt };
|
||||
|
|
@ -238,8 +296,8 @@ function updateTimeLabel(ctime: any) {
|
|||
|
||||
playbackSearchData(params, true, (res) => {
|
||||
// 往态势传递数据
|
||||
EventBusTool.getEventBus().publish('playData', {
|
||||
key: 'addyctqjsGis',
|
||||
EventBusTool.getEventBus().publish("playData", {
|
||||
key: "addyctqjsGis",
|
||||
data: res.result,
|
||||
});
|
||||
});
|
||||
|
|
@ -275,10 +333,12 @@ const speciesValueChange = () => {
|
|||
// key: 'speciesId',
|
||||
// data: { taskId: props.taskId, speciesId: speciesValue.value },
|
||||
// });
|
||||
console.log(speciesValue.value,"2222")
|
||||
sessionStorage.setItem("symnZxHsId",speciesValue.value);
|
||||
console.log(speciesValue.value, "2222");
|
||||
sessionStorage.setItem("symnZxHsId", speciesValue.value);
|
||||
};
|
||||
|
||||
const ssmnOption = ref({});
|
||||
|
||||
// 监听 speciesList 变化(比如父组件异步获取数据后更新)
|
||||
watch(
|
||||
() => props.speciesList,
|
||||
|
|
@ -287,18 +347,17 @@ watch(
|
|||
console.log(newVal);
|
||||
|
||||
speciesValue.value = newVal[0].value;
|
||||
sessionStorage.setItem("symnZxHsId",newVal[0].value);
|
||||
|
||||
EventBusTool.getEventBus().publish('speciesChange', {
|
||||
key: 'speciesId',
|
||||
sessionStorage.setItem("symnZxHsId", newVal[0].value);
|
||||
|
||||
EventBusTool.getEventBus().publish("speciesChange", {
|
||||
key: "speciesId",
|
||||
data: { taskId: props.taskId, speciesId: newVal[0].value },
|
||||
});
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
speciesValue.value = null;
|
||||
}
|
||||
},
|
||||
{ deep: true }, // 深度监听数组变化(比如数组元素新增/替换)
|
||||
{ deep: true } // 深度监听数组变化(比如数组元素新增/替换)
|
||||
);
|
||||
|
||||
// 监听 layer 变化
|
||||
|
|
@ -307,43 +366,64 @@ watch(
|
|||
(newVal: any) => {
|
||||
if (newVal.length > 0) {
|
||||
layerValue.value = newVal[0].value;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
layerValue.value = null;
|
||||
}
|
||||
},
|
||||
{ deep: true },
|
||||
{ deep: true }
|
||||
);
|
||||
|
||||
watch(value, (newVal, oldVal) => {
|
||||
let currentTime = null;
|
||||
if(ssmnOption.value.taskMode==-1){
|
||||
currentTime = end.value.clone().subtract(newVal, marskType.value);
|
||||
}else{
|
||||
currentTime = start.value.clone().add(newVal, marskType.value);
|
||||
}
|
||||
labelText.value = currentTime.format("YYYY-MM-DD HH:mm:ss");
|
||||
nextTick(() => {
|
||||
const sliderDom = document.querySelector('.slider .el-slider__runway')
|
||||
if (!sliderDom) return
|
||||
const width = sliderDom.offsetWidth;
|
||||
// 百分比位置
|
||||
const percent = newVal / totalHours.value
|
||||
// 基础位置,居中偏移,微调数值控制对齐
|
||||
labelLeft.value = percent * width - 60
|
||||
})
|
||||
}, {
|
||||
// immediate: true // 【可选】页面初次加载立即执行一次
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
EventBusTool.getEventBus().subscribe('timeSliderUi', (opt: any) => {
|
||||
EventBusTool.getEventBus().subscribe("timeSliderUi", (opt: any) => {
|
||||
ssmnOption.value = JSON.parse(sessionStorage.getItem("ssmnDataItem"));
|
||||
switch (opt.key) {
|
||||
case 'updateUi':// 更新时间
|
||||
case "updateUi": // 更新时间
|
||||
updateTimeLabel(opt.time);
|
||||
break;
|
||||
case 'setTime':// 更新起止时间
|
||||
case "setTime": // 更新起止时间
|
||||
setStartAndEndTime(opt);
|
||||
isQueryData.value = true;
|
||||
break;
|
||||
case 'playFalg':// 更行播放ui
|
||||
case "playFalg": // 更行播放ui
|
||||
playFalg.value = opt.playFalg;
|
||||
if (!playFalg.value) {
|
||||
isQueryData.value = true;
|
||||
}
|
||||
break;
|
||||
case 'isQueryData':// 更行播放ui
|
||||
case "isQueryData": // 更行播放ui
|
||||
isQueryData.value = opt.value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
playback_EventBusCallback.subscribe('timeSliderUiData', (opt: any) => {
|
||||
playback_EventBusCallback.subscribe("timeSliderUiData", (opt: any) => {
|
||||
switch (opt.key) {
|
||||
case 'isDisabledSlider': // 动画轴是否禁用
|
||||
case "isDisabledSlider": // 动画轴是否禁用
|
||||
isDisabledSlider.value = opt.value;
|
||||
break;
|
||||
case 'playFalg':// 更行播放ui
|
||||
case "playFalg": // 更行播放ui
|
||||
playFalg.value = opt.value;
|
||||
break;
|
||||
default:
|
||||
|
|
@ -354,47 +434,131 @@ onMounted(() => {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div class="sliderDom"
|
||||
:style="{ width: props.widthPx ?? props.activeMenu === '天气预报运算' ? '65vw' : '68vw', left: props.leftPx ?? '320px' }">
|
||||
<div
|
||||
class="sliderDom"
|
||||
:style="{
|
||||
width:
|
||||
props.widthPx ?? props.activeMenu === '天气预报运算' ? '65vw' : '68vw',
|
||||
left: props.leftPx ?? '320px',
|
||||
}"
|
||||
>
|
||||
<div v-if="props.activeMenu === '核事件模拟'" class="switchTabs">
|
||||
<div class="left" :class="{ active: active === '浓度分布', disable: playFalg }" @click="switchActive('浓度分布')">
|
||||
<div
|
||||
class="left"
|
||||
:class="{ active: active === '浓度分布', disable: playFalg }"
|
||||
@click="switchActive('浓度分布')"
|
||||
>
|
||||
浓度分布
|
||||
</div>
|
||||
<div class="right" :class="{ active: active === '剂量分布', disable: playFalg }" @click="switchActive('剂量分布')">
|
||||
<div
|
||||
class="right"
|
||||
:class="{ active: active === '剂量分布', disable: playFalg }"
|
||||
@click="switchActive('剂量分布')"
|
||||
>
|
||||
剂量分布
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="isShowSelect" class="selectDom">
|
||||
<el-select-v2 v-if="props.activeMenu === '核事件模拟'" v-model="layerValue" :disabled="!isQueryData"
|
||||
:options="props.layerList" placeholder="请选择图层" style="width: 230px" />
|
||||
<el-select-v2 v-if="props.activeMenu === '输运模拟' && speciesValue" v-model="speciesValue" :disabled="!isQueryData"
|
||||
:options="props.speciesList" placeholder="请选择物种" style="width: 230px" @change="speciesValueChange" />
|
||||
<el-select-v2
|
||||
v-if="props.activeMenu === '核事件模拟'"
|
||||
v-model="layerValue"
|
||||
:disabled="!isQueryData"
|
||||
:options="props.layerList"
|
||||
placeholder="请选择图层"
|
||||
style="width: 230px"
|
||||
/>
|
||||
<el-select-v2
|
||||
v-if="props.activeMenu === '输运模拟' && speciesValue"
|
||||
v-model="speciesValue"
|
||||
:disabled="!isQueryData"
|
||||
:options="props.speciesList"
|
||||
placeholder="请选择物种"
|
||||
style="width: 230px"
|
||||
@change="speciesValueChange"
|
||||
/>
|
||||
</div>
|
||||
<div v-if="isShowTabs" class="tabs">
|
||||
<div v-for="(v, i) in tabsList" :key="i" class="tabItem" :class="{ active: v.isActive }" @click="switchTab(v)">
|
||||
<div
|
||||
v-for="(v, i) in tabsList"
|
||||
:key="i"
|
||||
class="tabItem"
|
||||
:class="{ active: v.isActive }"
|
||||
@click="switchTab(v)"
|
||||
>
|
||||
{{ v.label }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="icon" @click="playAnimation()">
|
||||
<SvgIcon :name="!playFalg ? 'playAnimation' : 'zanting'" :title="!playFalg ? '播放' : '暂停'" width="34" height="34" />
|
||||
<SvgIcon
|
||||
:name="!playFalg ? 'playAnimation' : 'zanting'"
|
||||
:title="!playFalg ? '播放' : '暂停'"
|
||||
width="34"
|
||||
height="34"
|
||||
/>
|
||||
</div>
|
||||
<div v-if="props.activeMenu === '输运模拟' || props.activeMenu === '核事件模拟'" class="icon" @click="stopAnimation()">
|
||||
<div
|
||||
v-if="
|
||||
props.activeMenu === '输运模拟' || props.activeMenu === '核事件模拟'
|
||||
"
|
||||
class="icon"
|
||||
@click="stopAnimation()"
|
||||
>
|
||||
<SvgIcon name="stop" title="停止" width="34" height="34" />
|
||||
</div>
|
||||
<div class="slider">
|
||||
<!-- <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" />
|
||||
<div class="slider" style="position: relative;">
|
||||
<!-- <div style="color: white">value:{{ start.format("YYYY-MM-DD HH:mm:ss") }} ----- totalHours:{{ end.format("YYYY-MM-DD HH:mm:ss") }}</div> -->
|
||||
<div class="startTimes">{{ ssmnOption.taskMode==-1?ssmnOption.endTime:ssmnOption.startTime }}</div>
|
||||
<el-slider
|
||||
v-model="value"
|
||||
:disabled="isDisabledSlider"
|
||||
:style="{ width: isShowTabs ? props.sliderWidth ?? '58vw' : '62vw' }"
|
||||
:max="totalHours"
|
||||
:format-tooltip="slodtooltip"
|
||||
:show-tooltip="false"
|
||||
:marks="marks"
|
||||
@input="handleChange"
|
||||
/>
|
||||
<div class="endTimes">{{ ssmnOption.taskMode==-1?ssmnOption.startTime:ssmnOption.endTime }}</div>
|
||||
<div class="slider-label" :style="{ left: labelLeft + 'px' }" v-if="labelText">
|
||||
{{ labelText }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.slider-wrap {
|
||||
margin-top: 30px; /* 留出标签空间,防止重叠 */
|
||||
}
|
||||
.slider-label {
|
||||
position: absolute;
|
||||
top: -28px;
|
||||
background: #409eff;
|
||||
color: #fff;
|
||||
padding: 3px 8px;
|
||||
border-radius: 4px;
|
||||
font-size: 12px;
|
||||
white-space: nowrap;
|
||||
transition: left 0.08s linear;
|
||||
}
|
||||
|
||||
.startTimes{
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: -10px;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.endTimes{
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: -10px;
|
||||
color: #fff;
|
||||
}
|
||||
.switchTabs {
|
||||
width: 500px;
|
||||
height: 52px;
|
||||
background: url('@/assets/img/tabsBg.png') no-repeat center center;
|
||||
background: url("@/assets/img/tabsBg.png") no-repeat center center;
|
||||
background-size: 100% 100%;
|
||||
position: fixed;
|
||||
left: 50%;
|
||||
|
|
@ -409,7 +573,7 @@ onMounted(() => {
|
|||
.right {
|
||||
width: 141px;
|
||||
height: 30px;
|
||||
background: url('@/assets/img/tabsBtn_default.png') no-repeat center center;
|
||||
background: url("@/assets/img/tabsBtn_default.png") no-repeat center center;
|
||||
background-size: 100% 100%;
|
||||
text-align: center;
|
||||
line-height: 30px;
|
||||
|
|
@ -424,7 +588,7 @@ onMounted(() => {
|
|||
}
|
||||
|
||||
.active {
|
||||
background: url('@/assets/img/tabsBtn_active.png') no-repeat center center;
|
||||
background: url("@/assets/img/tabsBtn_active.png") no-repeat center center;
|
||||
background-size: 100% 100%;
|
||||
color: rgb(42, 255, 223);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1892,49 +1892,7 @@ getStations();
|
|||
max-height="40vh"
|
||||
class="custom-table"
|
||||
>
|
||||
<!-- 样品ID -->
|
||||
<ElTableColumn :label="t('sampleId')">
|
||||
<template #default="scope">
|
||||
<el-input
|
||||
v-model="scope.row.sampleId"
|
||||
type="number"
|
||||
/>
|
||||
</template>
|
||||
</ElTableColumn>
|
||||
|
||||
<!-- 样品类型 -->
|
||||
<ElTableColumn :label="t('sampleType')">
|
||||
<template #default="scope">
|
||||
<el-select
|
||||
v-model="scope.row.sampleType"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in ['B','P']"
|
||||
:key="item"
|
||||
:label="item"
|
||||
:value="item"
|
||||
/>
|
||||
</el-select>
|
||||
</template>
|
||||
</ElTableColumn>
|
||||
|
||||
<!-- 样品级别 -->
|
||||
<ElTableColumn :label="t('sampleLevel')">
|
||||
<template #default="scope">
|
||||
<el-select
|
||||
v-model="scope.row.sampleCategory"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in [1,2,3,4,5]"
|
||||
:key="item"
|
||||
:label="item"
|
||||
:value="item"
|
||||
/>
|
||||
</el-select>
|
||||
</template>
|
||||
</ElTableColumn>
|
||||
|
||||
<ElTableColumn prop="index" :label="t('deviceCode')" width="130">
|
||||
<ElTableColumn prop="index" :label="t('deviceCode')" width="100">
|
||||
<template #default="scope">
|
||||
<!-- <ElSelect v-if="configForm.taskMode === 1" v-model="scope.row.index" filterable-->
|
||||
<!-- :placeholder="t('pleaseSelect')" class="config-custom-select" style="color:#fff;"-->
|
||||
|
|
@ -1959,8 +1917,8 @@ getStations();
|
|||
</template>
|
||||
</ElTableColumn>
|
||||
|
||||
<ElTableColumn prop="lon" :label="t('longitude')" />
|
||||
<ElTableColumn prop="lat" :label="t('latitude')" />
|
||||
<ElTableColumn prop="lon" :label="t('longitude')" width="90" />
|
||||
<ElTableColumn prop="lat" :label="t('latitude')" width="90" />
|
||||
<ElTableColumn
|
||||
v-if="configForm.taskMode === -1"
|
||||
prop="index"
|
||||
|
|
@ -1991,13 +1949,54 @@ getStations();
|
|||
/>
|
||||
</template>
|
||||
</ElTableColumn>
|
||||
<!-- 样品ID -->
|
||||
<ElTableColumn :label="t('sampleId')" width="80">
|
||||
<template #default="scope">
|
||||
<el-input
|
||||
v-model="scope.row.sampleId"
|
||||
type="number"
|
||||
/>
|
||||
</template>
|
||||
</ElTableColumn>
|
||||
|
||||
<!-- 样品类型 -->
|
||||
<ElTableColumn :label="t('sampleType')" width="80">
|
||||
<template #default="scope">
|
||||
<el-select
|
||||
v-model="scope.row.sampleType"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in ['B','P']"
|
||||
:key="item"
|
||||
:label="item"
|
||||
:value="item"
|
||||
/>
|
||||
</el-select>
|
||||
</template>
|
||||
</ElTableColumn>
|
||||
|
||||
<!-- 样品级别 -->
|
||||
<ElTableColumn :label="t('sampleLevel')" width="80">
|
||||
<template #default="scope">
|
||||
<el-select
|
||||
v-model="scope.row.sampleCategory"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in [1,2,3,4,5]"
|
||||
:key="item"
|
||||
:label="item"
|
||||
:value="item"
|
||||
/>
|
||||
</el-select>
|
||||
</template>
|
||||
</ElTableColumn>
|
||||
<!-- <ElTableColumn :label="t('releaseAmount')">
|
||||
<template #default="scope">
|
||||
<el-input v-model="scope.row.releaseAmount" :placeholder="t('enterContent')" />
|
||||
</template>
|
||||
</ElTableColumn> -->
|
||||
|
||||
<ElTableColumn :label="t('operation')">
|
||||
<ElTableColumn :label="t('operation')" width="90">
|
||||
<template #default="scope">
|
||||
<!-- <ElButton type="text" class="custom-text-btn" @click="editTask(scope.row, scope.$index)"> -->
|
||||
<!-- {{ t('edit') }} -->
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { baseURL, serverIp } from "@/gis/common/config";
|
||||
import { ElMessage } from "element-plus";
|
||||
import { ElLoading, ElMessage } from "element-plus";
|
||||
import request from "@/utils/request"; // 复用已有的Axios请求实例
|
||||
|
||||
import axios from "axios";
|
||||
/**
|
||||
* 生成任务所属GIF文件
|
||||
*/
|
||||
|
|
@ -31,16 +31,36 @@ 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",
|
||||
// 开启Loading,和你项目样式保持一致
|
||||
const loadingInstance = ElLoading.service({
|
||||
lock: true,
|
||||
text: "Loading...",
|
||||
background: "rgba(0, 0, 0, 0.7)",
|
||||
target: document.querySelector(".base-layout"),
|
||||
});
|
||||
console.log(response, "22222222222222");
|
||||
|
||||
// HTTP 200 = 文件流正常返回,直接执行下载回调
|
||||
callback?.(response);
|
||||
try {
|
||||
const token = localStorage.getItem("token");
|
||||
const fullResponse = await axios({
|
||||
baseURL: serverIp,
|
||||
url: `${serverIp}${baseURL}/transportResult/downloadGif`,
|
||||
method: "GET",
|
||||
params,
|
||||
responseType: "blob",
|
||||
timeout: 300000,
|
||||
headers: {
|
||||
"Content-Type": "application/json;charset=utf-8",
|
||||
...(token ? { "X-Access-Token": token } : {}),
|
||||
},
|
||||
});
|
||||
console.log(fullResponse, "完整响应");
|
||||
callback?.(fullResponse);
|
||||
} catch (err) {
|
||||
ElMessage.error("gif下载请求失败");
|
||||
throw err;
|
||||
} finally {
|
||||
// 无论成功失败,一定关闭loading
|
||||
loadingInstance.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -59,4 +79,4 @@ export async function getRwscGifFileGcrz(
|
|||
if (response.success && response.code === 200) {
|
||||
callback?.(response);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user