1778 lines
57 KiB
Vue
1778 lines
57 KiB
Vue
<script setup lang="ts">
|
||
import type { SvgMarkerOptions } from '@/gis/ol/olTarget.ts';
|
||
import dayjs from 'dayjs';
|
||
import {ElButton, ElMessage, ElMessageBox, ElNotification, ElOption} from 'element-plus';
|
||
import { useI18n } from 'vue-i18n';
|
||
import targetIconA from '@/assets/icon/targetIconA.svg';
|
||
import targetIconB from '@/assets/icon/targetIconB.svg';
|
||
|
||
import { setAnimationTime, setMultiplier } from '@/gis/ol/olClock';
|
||
import { classInstances } from '@/gis/ol/olHandleEntry';
|
||
import { sendPlaybackPostMassage } from '@/gis/worker/playbackWorkerMa';
|
||
import { add, deleteData, edit, getAllNuclearfacility, getAllStations,getReleaseDataByForwardId,saveSiteAndReleaseData,delSiteAndReleaseData, getById, getData, getTaskLog, resume, exportTemplate, importFile, pinToTop, unpin } from '@/utils/axios/symn';
|
||
import fhdfx from './compliance/index.vue';
|
||
import gxfx from './contribution/index.vue';
|
||
import log from './log/index.vue';
|
||
import sxfx from './timingAnalysis/index.vue';
|
||
import {activeMoudleInf} from "@/gis/ol";
|
||
|
||
const { t, locale } = useI18n();
|
||
const formEl = ref<FormInstance>();
|
||
const dialogVisible = ref(true);
|
||
const drawerVisible = ref(false);
|
||
const gxfxVisible = ref(false);
|
||
const fhdVisible = ref(false);
|
||
const sxfxVisible = ref(false);
|
||
const importVisible = ref(false);
|
||
const configVisible = ref(false);
|
||
const logVisible = ref(false);
|
||
const currentPage = ref(1);
|
||
const pageSize = ref(20);
|
||
const total = ref(0);
|
||
|
||
const taskMode = ref(1);
|
||
const oldNuclear = ref('');
|
||
const nuclear = ref('');
|
||
const nuclearData = ref([]);
|
||
const nuclearOldData = ref({});
|
||
|
||
const currentPageLog = ref(1);
|
||
const pageSizeLog = ref(20);
|
||
const totalLog = ref(0);
|
||
|
||
const configType = ref('');
|
||
const logData = ref([]);
|
||
|
||
const gxfxRef = ref<InstanceType<typeof gxfx> | null>(null);
|
||
const activeTab = ref(0);
|
||
|
||
/* 任务列表搜索表单 */
|
||
const searchForm = reactive({
|
||
createTime: [] as unknown as [Date, Date],
|
||
});
|
||
|
||
/* 台站 */
|
||
const stations = reactive<any>([]);
|
||
|
||
/* 核设施列表 */
|
||
const nuclearfacility = reactive<any>([]);
|
||
const nuclearfacilityChild = reactive<any>([]);
|
||
|
||
/* 增、改表格数据 */
|
||
const childList = reactive<any>([]);
|
||
const childJson = reactive<any>({});
|
||
|
||
/* drawer侧边栏表单 */
|
||
const form = ref<any>({
|
||
taskName: '',
|
||
taskMode: '',
|
||
taskType: '',
|
||
site: '',
|
||
startTime: '',
|
||
endTime: '',
|
||
dataSource: '',
|
||
});
|
||
|
||
const rules = reactive({
|
||
taskName: [
|
||
{ required: true, message: t('pleaseEnter'), trigger: 'blur' },
|
||
],
|
||
taskMode: [
|
||
{
|
||
required: true,
|
||
message: t('pleaseSelect'),
|
||
trigger: 'change',
|
||
},
|
||
],
|
||
useMetType: [
|
||
{
|
||
required: true,
|
||
message: t('pleaseSelect'),
|
||
trigger: 'change',
|
||
},
|
||
],
|
||
z1: [
|
||
{ required: true, message: t('pleaseEnter'), trigger: 'blur' },
|
||
],
|
||
z2: [
|
||
{ required: true, message: t('pleaseEnter'), trigger: 'blur' },
|
||
],
|
||
particleCount: [
|
||
{ required: true, message: t('pleaseEnter'), trigger: 'blur' },
|
||
],
|
||
startTime: [
|
||
{
|
||
required: true,
|
||
message: t('pleaseSelect'),
|
||
trigger: 'change',
|
||
},
|
||
],
|
||
endTime: [
|
||
{
|
||
required: true,
|
||
message: t('pleaseSelect'),
|
||
trigger: 'change',
|
||
},
|
||
],
|
||
releaseDataSource: [
|
||
{
|
||
required: true,
|
||
message: t('pleaseSelect'),
|
||
trigger: 'change',
|
||
},
|
||
],
|
||
nuclear: [
|
||
{
|
||
required: true,
|
||
message: t('pleaseSelect'),
|
||
trigger: 'change',
|
||
},
|
||
],
|
||
speciesArr: [
|
||
{
|
||
required: true,
|
||
message: t('pleaseSelect'),
|
||
trigger: 'change',
|
||
},
|
||
],
|
||
});
|
||
/* 新增、编辑表单 */
|
||
const configForm = ref<any>({});
|
||
|
||
const taskList = ref<any[]>([
|
||
|
||
]);
|
||
|
||
interface OptionItem {
|
||
label: string;
|
||
value: number;
|
||
}
|
||
const taskStatusList = ref<OptionItem[]>([
|
||
// -1执行失败,0未开始,1等待中,2运行中,3已完成,4检查未通过
|
||
{ label: '执行失败', value: -1 },
|
||
{ label: '未开始', value: 0 },
|
||
{ label: '等待中', value: 1 },
|
||
{ label: '运行中', value: 2 },
|
||
{ label: '已完成', value: 3 },
|
||
{ label: '检查未通过', value: 4 },
|
||
]);
|
||
|
||
function handleClose() {
|
||
dialogVisible.value = false;
|
||
}
|
||
|
||
// 查询所有核设施
|
||
function getNuclearfacility() {
|
||
getAllNuclearfacility((res: any) => {
|
||
nuclearfacility.splice(0, nuclearfacility.length, ...res);
|
||
});
|
||
}
|
||
|
||
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 deleteTask(task: any) {
|
||
console.log('删除任务', task);
|
||
ElMessageBox.confirm(
|
||
t('isSureDelete'),
|
||
'Warning',
|
||
{
|
||
confirmButtonText: t('sure'),
|
||
cancelButtonText: t('cancel'),
|
||
type: 'warning',
|
||
},
|
||
)
|
||
.then(() => {
|
||
deleteData({ id: task.id }, () => {
|
||
getList();
|
||
});
|
||
})
|
||
.catch(() => {
|
||
});
|
||
}
|
||
function deleteChild(index: any) {
|
||
childList.splice(index, 1); // 删除索引为index的这一列
|
||
}
|
||
function deleteChild2(index: any,tableIndex: any,) {
|
||
nuclearfacilityChild[index].forwardReleaseChild.splice(tableIndex, 1); // 删除索引为index的这一列
|
||
}
|
||
function deleteChild3(tableIndex: any,) {
|
||
nuclearData.value.splice(tableIndex, 1); // 删除索引为index的这一列
|
||
}
|
||
function addChild() {
|
||
console.log('??', configForm.value.taskMode);
|
||
if (configForm.value.taskMode !== -1 && configForm.value.taskMode !== 1) {
|
||
return ElNotification({
|
||
title: 'Tips',
|
||
message: '请先选择任务模式',
|
||
type: 'warning',
|
||
duration: 1800,
|
||
});
|
||
}
|
||
childList.push({
|
||
releaseAmount: '0',
|
||
lat: '',
|
||
lon: '',
|
||
});
|
||
}
|
||
|
||
function addChild2(index:any) {
|
||
console.log('??', nuclearfacilityChild[index],index,nuclearfacilityChild);
|
||
nuclearfacilityChild[index].forwardReleaseChild.push({
|
||
releaseAmount: '0',
|
||
startTime: '',
|
||
endTime: '',
|
||
});
|
||
}
|
||
function addChild3() {
|
||
nuclearData.value.push({
|
||
releaseAmount: '0',
|
||
startTime: '',
|
||
endTime: '',
|
||
});
|
||
}
|
||
|
||
function clearChild() {
|
||
childList.splice(0);
|
||
}
|
||
// 置顶和取消置顶
|
||
const pinToTopTask = (row: any, isPin: boolean) => {
|
||
if (!isPin) {
|
||
pinToTop({ taskId: row.id }, (res) => {
|
||
if (res.code === 200) {
|
||
ElMessage.success('置顶成功!');
|
||
getList();
|
||
}
|
||
});
|
||
} else {
|
||
unpin({ taskId: row.id }, (res) => {
|
||
if (res.code === 200) {
|
||
ElMessage.success('取消置顶成功!');
|
||
getList();
|
||
}
|
||
});
|
||
}
|
||
};
|
||
function viewTask(task: any) {
|
||
debugger
|
||
console.log('查看任务:', task);
|
||
handleClose();
|
||
form.value = {
|
||
...task,
|
||
};
|
||
drawerVisible.value = true;
|
||
// if (task.taskStatus === 2) {
|
||
// 测试代码
|
||
// 任务运行完成 显示 时间轴
|
||
EventBusTool.getEventBus().publish('playData', {
|
||
key: 'show',
|
||
task,
|
||
});
|
||
EventBusTool.getEventBus().publish('timeSliderUi', {
|
||
key: 'isQueryData',
|
||
value: true,
|
||
});
|
||
if (task.taskMode === 1) {
|
||
EventBusTool.getEventBus().publish('mapRightMenuUIEvent', {
|
||
key: 'gifIcon'
|
||
});
|
||
}
|
||
|
||
// 移除所有台站
|
||
classInstances.olTarget?.clearMarkers();
|
||
|
||
// 查询所有台站
|
||
getAllStations((res: any) => {
|
||
const markerList = res.map((item: any) => {
|
||
return {
|
||
lon: item.lon,
|
||
lat: item.lat,
|
||
name: item.stationCode,
|
||
};
|
||
});
|
||
const styleOptions: SvgMarkerOptions = {
|
||
svgUrl: targetIconB, // 替换为实际的SVG URL
|
||
};
|
||
classInstances.olTarget?.addMarkers(markerList, styleOptions);
|
||
});
|
||
|
||
// 查询所有核设施
|
||
getAllNuclearfacility((res: any) => {
|
||
const markerList = res.map((item: any) => {
|
||
return {
|
||
lon: item.lonValue,
|
||
lat: item.latValue,
|
||
name: item.unitName,
|
||
};
|
||
});
|
||
const styleOptions: SvgMarkerOptions = {
|
||
svgUrl: targetIconA, // 替换为实际的SVG URL
|
||
};
|
||
classInstances.olTarget?.addMarkers(markerList, styleOptions);
|
||
});
|
||
|
||
sendPlaybackPostMassage({ code: 'clearCache' }, {});
|
||
|
||
const time = {
|
||
startTime: task.startTime,
|
||
endTime: task.endTime,
|
||
};
|
||
|
||
setMultiplier(60 * 20 * 3);
|
||
|
||
setAnimationTime(time);
|
||
// }
|
||
}
|
||
|
||
function saveConfigForm(formEl: FormInstance | undefined) {
|
||
console.log('保存或新增');
|
||
|
||
if (!formEl)
|
||
return;
|
||
|
||
formEl.validate(async (valid: any) => {
|
||
console.log('valid', valid);
|
||
if (valid) {
|
||
// if (!childList.length) {
|
||
// return ElNotification({
|
||
// title: 'Tips',
|
||
// message: '至少填写一条站点信息',
|
||
// type: 'warning',
|
||
// duration: 1800,
|
||
// });
|
||
// }
|
||
if (configType.value === 'add') {
|
||
const addValue = configForm.value = {
|
||
...configForm.value
|
||
};
|
||
if(configForm.value.taskMode === 1){
|
||
addValue.forwardChild = nuclearfacilityChild;
|
||
}else{
|
||
addValue.backwardChild = childList;
|
||
}
|
||
add(addValue, () => {
|
||
ElNotification({
|
||
title: 'Tips',
|
||
message: 'Added successfully',
|
||
type: 'success',
|
||
duration: 1800,
|
||
});
|
||
getList();
|
||
configVisible.value = false;
|
||
});
|
||
}
|
||
if (configType.value === 'edit') {
|
||
const editValue = configForm.value = {
|
||
...configForm.value
|
||
};
|
||
if(configForm.value.taskMode === 1){
|
||
if(nuclearData.value.length){
|
||
saveSite(nuclearData.value)
|
||
}
|
||
editValue.forwardChild = nuclearfacilityChild;
|
||
}else{
|
||
editValue.backwardChild = childList.map(({ id, ...rest }) => rest);
|
||
}
|
||
edit(editValue, () => {
|
||
ElNotification({
|
||
title: 'Tips',
|
||
message: 'Saved successfully',
|
||
type: 'success',
|
||
duration: 1800,
|
||
});
|
||
getList();
|
||
configVisible.value = false;
|
||
});
|
||
}
|
||
}
|
||
else {
|
||
console.log('error submit!');
|
||
}
|
||
});
|
||
}
|
||
|
||
function addTask() {
|
||
console.log('新增任务');
|
||
childList.length = 0;
|
||
configForm.value = {};
|
||
configForm.value.speciesArr = []
|
||
configForm.value.species = []
|
||
nuclearfacilityChild.splice(0);
|
||
configVisible.value = true;
|
||
configType.value = 'add';
|
||
|
||
}
|
||
|
||
function release() {
|
||
nuclearfacilityChild.map(item=>{
|
||
delete item.id
|
||
item.forwardReleaseChild = []
|
||
})
|
||
}
|
||
function editTask(task: any, $index?: any) {
|
||
console.log('编辑任务', task, $index);
|
||
childList.length = 0;
|
||
|
||
getById({ id: task.id }, (res) => {
|
||
console.log('task.taskMode', task.taskMode);
|
||
configForm.value.speciesArr = []
|
||
configForm.value.species = []
|
||
nuclearfacilityChild.splice(0);
|
||
|
||
if (res.species) {
|
||
res.species.map(item => {
|
||
configForm.value.speciesArr.push(item.speciesId)
|
||
configForm.value.species.push({speciesId:item.speciesId})
|
||
|
||
})
|
||
}
|
||
if (res.backwardChild) {
|
||
res.backwardChild.map((item: any) => {
|
||
let index = nuclearfacility.findIndex((v: any) => v.unitName === item.stationCode);
|
||
console.log('stationCode', item.stationCode);
|
||
if (task.taskMode === -1) {
|
||
index = stations.findIndex((v: any) => v.stationCode === item.stationCode);
|
||
console.log('item,stations', item, stations);
|
||
}
|
||
console.log('index', index);
|
||
|
||
delete item.createBy;
|
||
delete item.createTime;
|
||
delete item.taskId;
|
||
childList.push({
|
||
...item,
|
||
index,
|
||
});
|
||
});
|
||
}
|
||
|
||
if (res.forwardChild) {
|
||
var arr = []
|
||
res.forwardChild.map(item=>{
|
||
if(!item.forwardReleaseChild){
|
||
item.forwardReleaseChild = [];
|
||
}
|
||
})
|
||
nuclearfacilityChild.splice(0,nuclearfacilityChild.length,...res.forwardChild);
|
||
console.log('nuclearfacilityChild',nuclearfacilityChild)
|
||
res.forwardChild.map((item: any) => {
|
||
let index = nuclearfacility.findIndex((v: any) => v.unitName === item.stationCode);
|
||
arr.push(index)
|
||
});
|
||
configForm.value.nuclear = arr;
|
||
lastSelectedKeys.value = new Set(arr);
|
||
}
|
||
|
||
configForm.value.z1 = res.z1;
|
||
configForm.value.z2 = res.z2;
|
||
configForm.value.particleCount = res.particleCount;
|
||
configForm.value.startTime = res.startTime;
|
||
configForm.value.endTime = res.endTime;
|
||
configForm.value.releaseDataSource = res.releaseDataSource;
|
||
});
|
||
|
||
configForm.value = {
|
||
...task,
|
||
$index,
|
||
};
|
||
|
||
delete configForm.value.taskType;
|
||
delete configForm.value.taskPprogress;
|
||
delete configForm.value.taskStatus;
|
||
delete configForm.value.timeConsuming;
|
||
delete configForm.value.updateBy;
|
||
delete configForm.value.updateTime;
|
||
delete configForm.value.createBy;
|
||
console.log('编辑任务', configForm.value);
|
||
nuclearData.value = [];
|
||
nuclear.value = '';
|
||
configVisible.value = true;
|
||
configType.value = 'edit';
|
||
}
|
||
function getPFXX() {
|
||
// childList.length = 0;
|
||
|
||
getById({ id: configForm.value.id }, (res) => {
|
||
nuclearfacilityChild.splice(0);
|
||
|
||
if (res.forwardChild) {
|
||
var arr = []
|
||
res.forwardChild.map(item=>{
|
||
if(!item.forwardReleaseChild){
|
||
item.forwardReleaseChild = [];
|
||
}
|
||
})
|
||
nuclearfacilityChild.splice(0,nuclearfacilityChild.length,...res.forwardChild);
|
||
console.log('nuclearfacilityChild',nuclearfacilityChild)
|
||
res.forwardChild.map((item: any) => {
|
||
let index = nuclearfacility.findIndex((v: any) => v.unitName === item.stationCode);
|
||
arr.push(index)
|
||
});
|
||
configForm.value.nuclear = arr;
|
||
lastSelectedKeys.value = new Set(arr);
|
||
}
|
||
|
||
});
|
||
|
||
}
|
||
|
||
function handleSizeChange(val: number) {
|
||
console.log(`${val} items per page`);
|
||
pageSize.value = val;
|
||
getList();
|
||
}
|
||
function handleCurrentChange(val: number) {
|
||
console.log(`current page: ${val}`);
|
||
currentPageLog.value = val;
|
||
getList();
|
||
}
|
||
const logId = ref('');
|
||
|
||
function handleSizeChangeLog(val: number) {
|
||
console.log(`${val} items per page`);
|
||
pageSizeLog.value = val;
|
||
getTaskLog({
|
||
taskId: logId.value,
|
||
pageNum:currentPageLog.value,
|
||
pageSize:pageSizeLog.value,
|
||
}, (res) => {
|
||
logData.value = res.rows;
|
||
totalLog.value = res.total;
|
||
});
|
||
}
|
||
function handleCurrentChangeLog(val: number) {
|
||
console.log(`current page: ${val}`);
|
||
currentPageLog.value = val;
|
||
getTaskLog({
|
||
taskId: logId.value,
|
||
pageNum:currentPageLog.value,
|
||
pageSize:pageSizeLog.value,
|
||
}, (res) => {
|
||
logData.value = res.rows;
|
||
totalLog.value = res.total;
|
||
});
|
||
}
|
||
|
||
function refresh() {
|
||
console.log('刷新任务列表');
|
||
getList();
|
||
}
|
||
|
||
function showLog(id: any) {
|
||
console.log('显示运行日志');
|
||
logId.value = id;
|
||
getTaskLog({
|
||
taskId: id,
|
||
pageNum:currentPageLog.value,
|
||
pageSize:pageSizeLog.value,
|
||
}, (res) => {
|
||
console.log('log',res)
|
||
logData.value = res.rows;
|
||
totalLog.value = res.total;
|
||
logVisible.value = true;
|
||
|
||
|
||
});
|
||
}
|
||
|
||
function start(id: any) {
|
||
console.log('开始运行', form.value);
|
||
|
||
resume({ taskId: id }, () => {
|
||
ElNotification({
|
||
title: 'Tips',
|
||
message: 'Execution Successful',
|
||
type: 'success',
|
||
duration: 1800,
|
||
});
|
||
// form.value.taskStatus = 1;
|
||
getList();
|
||
});
|
||
}
|
||
|
||
function cancle() {
|
||
console.log('取消运行', form);
|
||
ElMessageBox.confirm(
|
||
t('isSureCancelTask'),
|
||
'Warning',
|
||
{
|
||
confirmButtonText: t('sure'),
|
||
cancelButtonText: t('cancel'),
|
||
type: 'warning',
|
||
},
|
||
)
|
||
.then(() => {
|
||
// form.value = {
|
||
// ...form.value,
|
||
// start: false,
|
||
// };
|
||
ElMessage({
|
||
type: 'success',
|
||
message: `Cancelled successfully`,
|
||
});
|
||
})
|
||
.catch(() => {
|
||
|
||
});
|
||
}
|
||
|
||
function showChart() {
|
||
console.log('贡献分析');
|
||
gxfxVisible.value = true;
|
||
}
|
||
|
||
function showFhdChart() {
|
||
console.log('符合度');
|
||
fhdVisible.value = true;
|
||
}
|
||
|
||
function showsxfxChart() {
|
||
console.log('符合度');
|
||
sxfxVisible.value = true;
|
||
}
|
||
|
||
async function exportCharts() {
|
||
console.log('子组件实例:', gxfxRef.value); // 此时能正确获取
|
||
if (gxfxRef.value) {
|
||
await gxfxRef.value.exportCharts('');
|
||
}
|
||
}
|
||
// 通过watch监听侧边栏的变化
|
||
watch(drawerVisible, (newValue) => {
|
||
console.log('抽屉状态变化:', newValue);
|
||
if (newValue === false) {
|
||
dialogVisible.value = true;
|
||
EventBusTool.getEventBus().publish('mapRightMenuUIEvent', {
|
||
key: 'baseList'
|
||
});
|
||
}
|
||
});
|
||
|
||
function setDate(val: string, index: any) {
|
||
console.log('val', nuclearfacility[val], index, val);
|
||
childList[index].lon = nuclearfacility[val].lonValue;
|
||
childList[index].lat = nuclearfacility[val].latValue;
|
||
childList[index].stationCode = nuclearfacility[val].unitName;
|
||
childList[index].releaseAmount = 0;
|
||
console.log(childList);
|
||
}
|
||
function setStationDate(val: string, index: any) {
|
||
childList[index].lon = stations[val].lon;
|
||
childList[index].lat = stations[val].lat;
|
||
childList[index].stationCode = stations[val].stationCode;
|
||
childList[index].releaseAmount = 0;
|
||
}
|
||
|
||
function setSpecies(val: any) {
|
||
configForm.value.species = []
|
||
val.map(item=>{
|
||
configForm.value.species.push({
|
||
speciesId:item
|
||
})
|
||
})
|
||
console.log('val', val,configForm.value.species);
|
||
|
||
}
|
||
|
||
// function setCode(val: any) {
|
||
// nuclearfacilityChild.splice(0);
|
||
// val.map(item=>{
|
||
// console.log('val', nuclearfacility[item]);
|
||
// nuclearfacilityChild.push({
|
||
// ...nuclearfacility[item],
|
||
// stationCode:nuclearfacility[item].unitName,
|
||
// lon:nuclearfacility[item].lonValue,
|
||
// lat:nuclearfacility[item].latValue,
|
||
// forwardReleaseChild:[]
|
||
// })
|
||
// }
|
||
// }
|
||
const lastSelectedKeys = ref(new Set()); // 响应式存储上一次选中的key
|
||
|
||
function setCode(val: any[]) {
|
||
if(configType.value === 'edit'){
|
||
|
||
// ===== 核心:对比上一次和当前选中值,提取新增/删除项 =====
|
||
const currentSelectedKeys = new Set(val);
|
||
console.log('currentSelectedKeys',currentSelectedKeys)
|
||
const prevSelectedKeys = lastSelectedKeys.value; // 上一次的选中值
|
||
|
||
// ① 新增项(当前选中但上一次未选中 → 选中操作)
|
||
const addItems = val.filter(item => !prevSelectedKeys.has(item));
|
||
// ② 删除项(上一次选中但当前未选中 → 取消操作)
|
||
const deleteItems = Array.from(prevSelectedKeys).filter(item => !currentSelectedKeys.has(item));
|
||
console.log('本次对比',prevSelectedKeys,currentSelectedKeys)
|
||
console.log('本次选中新增项:', addItems);
|
||
console.log('本次取消选中项:', deleteItems);
|
||
|
||
// ===== 把新增/删除项传给接口(按需调用)=====
|
||
// 新增项调用保存接口
|
||
if (addItems.length > 0) {
|
||
addItems.forEach(item => {
|
||
lastSelectedKeys.value = new Set(val);
|
||
console.log('nuclearfacility[item]',nuclearfacility[item],configForm.value)
|
||
saveSiteAndReleaseData({
|
||
taskId: configForm.value.id,
|
||
stationCode: nuclearfacility[item].unitName,
|
||
lon: nuclearfacility[item].lonValue,
|
||
lat: nuclearfacility[item].latValue,
|
||
forwardReleaseChild: []
|
||
}, (res: any) => {
|
||
ElMessage.success('保存成功');
|
||
getPFXX()
|
||
});
|
||
});
|
||
}
|
||
|
||
// 删除项调用删除接口
|
||
if (deleteItems.length > 0) {
|
||
deleteItems.forEach(item => {
|
||
// 先找到对应项的id(根据unitName匹配)
|
||
const deleteItem = nuclearfacilityChild.find(
|
||
child => child.stationCode === nuclearfacility[item].unitName
|
||
);
|
||
lastSelectedKeys.value = new Set(val);
|
||
console.log('deleteItem',deleteItem)
|
||
if (deleteItem?.id) {
|
||
delSite(deleteItem.id, (res: any) => {
|
||
// ElMessage.success('删除成功');
|
||
});
|
||
}
|
||
});
|
||
}
|
||
}else{
|
||
|
||
|
||
// 1. 提取当前选中项的标识(假设item是nuclearfacility的key/索引)
|
||
const selectedKeys = new Set(val);
|
||
console.log('selectedKeys',selectedKeys)
|
||
|
||
// 2. 移除不在选中列表中的项
|
||
// 倒序遍历避免删除元素导致的索引错乱
|
||
for (let i = nuclearfacilityChild.length - 1; i >= 0; i--) {
|
||
const childItem = nuclearfacilityChild[i];
|
||
// 找到当前childItem对应的原始数据key(根据你的逻辑,这里用unitName反向匹配)
|
||
const originalKey = Object.keys(nuclearfacility).find(
|
||
key => nuclearfacility[key].unitName === childItem.stationCode
|
||
);
|
||
if (originalKey && !selectedKeys.has(originalKey)) {
|
||
nuclearfacilityChild.splice(i, 1); // 移除未选中的项
|
||
// delSite(nuclearfacilityChild[i].id)
|
||
// console.log('删除',nuclearfacilityChild[i])
|
||
}
|
||
}
|
||
|
||
// 3. 添加新选中但尚未在数组中的项
|
||
val.forEach(item => {
|
||
// 检查当前项是否已存在于nuclearfacilityChild中
|
||
const isExist = nuclearfacilityChild.some(
|
||
child => child.stationCode === nuclearfacility[item].unitName
|
||
);
|
||
// console.log('isExist',isExist,nuclearfacilityChild,nuclearfacility[item].unitName)
|
||
if (!isExist) {
|
||
// 不存在则新增,初始化forwardReleaseChild为空数组(保留原有逻辑)
|
||
nuclearfacilityChild.push({
|
||
// ...nuclearfacility[item],
|
||
stationCode: nuclearfacility[item].unitName,
|
||
lon: nuclearfacility[item].lonValue,
|
||
lat: nuclearfacility[item].latValue,
|
||
forwardReleaseChild: [] // 新项初始化空数组
|
||
});
|
||
// console.log('保存')
|
||
|
||
// saveSiteAndReleaseData({
|
||
// // ...nuclearfacility[item],
|
||
// stationCode: nuclearfacility[item].unitName,
|
||
// lon: nuclearfacility[item].lonValue,
|
||
// lat: nuclearfacility[item].latValue,
|
||
// forwardReleaseChild: [] // 新项初始化空数组
|
||
// },(res: any) => {
|
||
// ElMessage.success('保存成功');
|
||
// });
|
||
}
|
||
});
|
||
}
|
||
|
||
}
|
||
function setChildCode(val: any) {
|
||
if(nuclearData.value.length){
|
||
saveSite(nuclearData.value)
|
||
}
|
||
oldNuclear.value = nuclear.value;
|
||
getReleaseDataByForwardId({forwardId:nuclear.value},(res: any) => {
|
||
nuclearData.value = res;
|
||
});
|
||
}
|
||
|
||
function delSite(id:any) {
|
||
//删除单个站点排放数据
|
||
|
||
delSiteAndReleaseData({forwardId:id},(res: any) => {
|
||
ElMessage.success('删除成功');
|
||
});
|
||
}
|
||
|
||
function saveSite(data:any) {
|
||
//保存单个站点排放数据
|
||
|
||
nuclearfacilityChild.map(item=>{
|
||
if(item.id === oldNuclear.value){
|
||
console.log('item',item);
|
||
nuclearOldData.value = item;
|
||
|
||
}
|
||
})
|
||
|
||
data.map(item=>{
|
||
delete item.id
|
||
})
|
||
const param = {
|
||
...nuclearOldData.value,
|
||
forwardReleaseChild:data
|
||
}
|
||
delete param.id
|
||
saveSiteAndReleaseData(param,(res: any) => {
|
||
ElMessage.success('保存成功');
|
||
});
|
||
}
|
||
// 下载模板
|
||
const exportLoading = ref<boolean>(false);
|
||
|
||
async function exportFile() {
|
||
exportLoading.value = true;
|
||
try {
|
||
console.log('开始下载模板...',taskMode.value);
|
||
const {blob} = await exportTemplate({taskMode:taskMode.value});
|
||
const filename = '模版'
|
||
console.log('文件信息:', {
|
||
filename,
|
||
blob,
|
||
blobType: blob.type,
|
||
blobSize: `${blob.size} bytes`,
|
||
});
|
||
|
||
const excelBlob = new Blob([blob], {
|
||
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' // xlsx 标准类型
|
||
// 如果是 xls 格式,用:'application/vnd.ms-excel'
|
||
});
|
||
|
||
// 验证 Blob 是否有效
|
||
if (!blob || blob.size === 0) {
|
||
throw new Error('获取到的文件为空');
|
||
}
|
||
|
||
// 创建下载链接
|
||
const url = window.URL.createObjectURL(excelBlob);
|
||
const link = document.createElement('a');
|
||
link.href = url;
|
||
link.download = filename; // 使用从响应头获取的文件名
|
||
link.style.display = 'none';
|
||
document.body.appendChild(link);
|
||
link.click();
|
||
|
||
console.log('文件下载成功:', filename);
|
||
ElMessage.success('模板下载成功');
|
||
}
|
||
catch (error) {
|
||
console.error('文件下载失败:', error);
|
||
}
|
||
finally {
|
||
exportLoading.value = false;
|
||
}
|
||
}
|
||
|
||
|
||
// 定义 ref 的类型
|
||
const fileInput: Ref<HTMLInputElement | null> = ref(null);
|
||
|
||
function handleClick(): void {
|
||
console.log('fileInput',fileInput.value)
|
||
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];
|
||
console.log('file',file)
|
||
if (!file) {
|
||
console.warn('未选择文件');
|
||
return;
|
||
}
|
||
|
||
form.value.file = file.name;
|
||
// 创建 FormData 对象
|
||
const formData = new FormData();
|
||
// 添加文件
|
||
formData.append('file', file);
|
||
formData.append('taskMode', taskMode.value);
|
||
|
||
// 调用接口,现在importTask只需要formData和callback
|
||
importFile(formData, (res) => {
|
||
console.log('接口响应:', res);
|
||
getList()
|
||
target.value = '';
|
||
});
|
||
}
|
||
|
||
|
||
// 查询所有台站
|
||
function getStations() {
|
||
getAllStations((res: any) => {
|
||
stations.splice(0, stations.length, ...res);
|
||
console.log('111', stations);
|
||
});
|
||
}
|
||
|
||
getList();
|
||
// 查询所有核设施
|
||
getNuclearfacility();
|
||
// 查询所有台站
|
||
getStations();
|
||
</script>
|
||
|
||
<template>
|
||
<div class="container-wrapper ysmn">
|
||
<!-- 查看 -->
|
||
<Drawer v-model="drawerVisible">
|
||
<div class="drawer-wrapper">
|
||
<el-form class="left-form" :model="form" label-position="top" label-width="120px">
|
||
<div class="drawer-header">
|
||
{{ t('basicParameters') }}
|
||
</div>
|
||
|
||
<el-form-item :label="t('taskName')">
|
||
<el-input v-model="form.taskName" />
|
||
</el-form-item>
|
||
<el-form-item :label="t('taskMode')">
|
||
<el-input :value="form.taskMode === -1 ? '反向模拟' : '正向模拟'" />
|
||
</el-form-item>
|
||
<el-form-item :label="t('taskType')">
|
||
<el-input :value="form.taskType === 1 ? '手动创建' : '自动创建'" />
|
||
</el-form-item>
|
||
<el-form-item :label="t('taskStatus')">
|
||
<el-input v-if="form.taskStatus === -1" value="执行失败" />
|
||
<el-input v-if="form.taskStatus === 0" value="未开始" />
|
||
<el-input v-if="form.taskStatus === 1" value="等待中" />
|
||
<el-input v-if="form.taskStatus === 2" value="运行中" />
|
||
<el-input v-if="form.taskStatus === 3" value="已完成" />
|
||
<el-input v-if="form.taskStatus === 4" value="检查未通过" />
|
||
</el-form-item>
|
||
<el-form-item :label="t('dataSource')">
|
||
<el-input v-if="form.useMetType === 1" value="盘古模型" />
|
||
<el-input v-if="form.useMetType === 2" value="graphcast" />
|
||
<el-input v-if="form.useMetType === 3" value="cra40" />
|
||
<el-input v-if="form.useMetType === 4" value="ncep" />
|
||
<el-input v-if="form.useMetType === 5" value="fnl" />
|
||
<el-input v-if="form.useMetType === 6" value="t1h" />
|
||
<el-input v-if="form.useMetType === 7" value="GFS" />
|
||
</el-form-item>
|
||
|
||
<el-form-item :label="t('startTime')">
|
||
<el-input v-model="form.startTime" />
|
||
</el-form-item>
|
||
|
||
<el-form-item :label="t('endTime')">
|
||
<el-input v-model="form.endTime" />
|
||
</el-form-item>
|
||
<!-- <div class="drawer-header"> -->
|
||
<!-- {{ t('operationParameters') }} -->
|
||
<!-- </div> -->
|
||
|
||
<el-form-item :label="t('creator')">
|
||
<el-input v-model="form.createBy" />
|
||
</el-form-item>
|
||
<el-form-item :label="t('creationTime')">
|
||
<el-input v-model="form.createTime" />
|
||
</el-form-item>
|
||
|
||
<el-form-item class="drawer-footer-btn">
|
||
<el-button v-if="form.progress === 100" type="success"
|
||
style="width:calc(50% - 5px); background-color: #098839;" :disabled="true">
|
||
{{ t('operationCompleted') }}
|
||
</el-button>
|
||
<!-- <el-button v-else-if="form.start" type="success" style="width:calc(50% - 5px); background-color: #406979;" -->
|
||
<!-- @click="cancle"> -->
|
||
<!-- {{ t('cancelOperation') }} -->
|
||
<!-- </el-button> -->
|
||
<!-- <el-button v-else type="success" style="width:calc(50% - 5px); background-color: #098839;" @click="start" :disabled="form.taskStatus === 2"> -->
|
||
<!-- {{ t('startOperation') }} -->
|
||
<!-- </el-button> -->
|
||
<!-- <el-button type="primary" style="width:calc(50% - 5px);margin-left: 10px;background-color: #1397a3;" -->
|
||
<!-- @click="showLog(form.id)"> -->
|
||
<!-- {{ t('operationLog') }} -->
|
||
<!-- </el-button> -->
|
||
<template v-if="form.taskMode === -1">
|
||
<el-button type="warning" style="width:calc(50% - 5px);margin:10px 0px;background-color: #406979;"
|
||
:disabled="false" @click="showChart">
|
||
{{ t('contributionAnalysis') }}
|
||
</el-button>
|
||
<el-button type="warning" style="width:calc(50% - 5px);margin:10px 0px;margin-left: 10px"
|
||
@click="showsxfxChart">
|
||
{{ t('timingAnalysis') }}
|
||
</el-button>
|
||
</template>
|
||
<template v-else>
|
||
<el-button type="warning" style="margin:10px 0px;background-color: #406979;width: 100%"
|
||
:disabled="form.progress !== 100 && false" @click="showFhdChart">
|
||
{{ t('conformanceAnalysis') }}
|
||
</el-button>
|
||
</template>
|
||
</el-form-item>
|
||
</el-form>
|
||
</div>
|
||
</Drawer>
|
||
|
||
<!-- 贡献分析 -->
|
||
<Dialog v-model="gxfxVisible" :title="t('contributionAnalysis')" width="80vw">
|
||
<gxfx ref="gxfxRef" :data="form" />
|
||
</Dialog>
|
||
|
||
<!-- 符合度分析 -->
|
||
<Dialog v-model="fhdVisible" :title="t('conformanceAnalysis')" width="80vw">
|
||
<fhdfx ref="gxfxRef" :data="form" />
|
||
</Dialog>
|
||
|
||
<!-- 时序分析 -->
|
||
<Dialog v-model="sxfxVisible" :title="t('timingAnalysis')" width="80vw">
|
||
<sxfx :data="form" />
|
||
</Dialog>
|
||
|
||
<!-- 日志 -->
|
||
<Dialog v-model="logVisible" :title="t('operationLog')" width="56vw" class="log-custom-dialog" style="height: 700px">
|
||
<log :data="logData" />
|
||
<div class="pagination" style="display: flex;justify-content: space-around">
|
||
<el-pagination v-model:current-page="currentPageLog" v-model:page-size="pageSizeLog"
|
||
:page-sizes="[10, 20, 50, 100, 200, 500, 1000, 1500, 2000]" size="small" :background="true"
|
||
layout="total, sizes, prev, pager, next, jumper" :total="totalLog" @size-change="handleSizeChangeLog"
|
||
@current-change="handleCurrentChangeLog" />
|
||
</div>
|
||
</Dialog>
|
||
<Dialog v-model="importVisible" :title="t('import')" width="16vw" :hide-close="false">
|
||
|
||
<div style="width: 100%;display: flex;justify-content: space-around;padding-bottom: 20px">
|
||
<el-radio-group
|
||
v-model="taskMode" text-color="#00F7E8"
|
||
fill="#00F7E8" @change="radioChange"
|
||
style="padding: 0 10px 0 20px"
|
||
>
|
||
<el-radio label="正演" :value="1" text-color="#00F7E8" fill="#00F7E8">
|
||
正演
|
||
</el-radio>
|
||
<el-radio label="反演" :value="-1" text-color="#00F7E8" fill="#00F7E8">
|
||
反演
|
||
</el-radio>
|
||
</el-radio-group>
|
||
</div>
|
||
<div style="width: 100%;display: flex;justify-content: center">
|
||
<el-button class="custom-btn" @click="handleClick">
|
||
<SvgIcon name="import" width="30" height="20" style="font-weight:bold;margin-right: 1px;" />
|
||
|
||
{{ t('import') }}
|
||
<input
|
||
ref="fileInput"
|
||
type="file"
|
||
style="display: none"
|
||
@change="handleFileChange"
|
||
>
|
||
</el-button>
|
||
|
||
<el-button class="custom-btn" @click="exportFile">
|
||
<SvgIcon name="export" width="20" height="16" style="margin-right: 3px;" />
|
||
{{ t('exportTemplate') }}
|
||
</el-button>
|
||
</div>
|
||
|
||
|
||
</Dialog>
|
||
|
||
<!-- 主表 -->
|
||
<Dialog v-model="dialogVisible" :title="t('taskList')" width="86vw" :hide-close="true">
|
||
<!-- 搜索条件 -->
|
||
<ElForm :inline="true" :model="searchForm" class="custom-form">
|
||
<ElFormItem label="">
|
||
<ElInput v-model="searchForm.taskName" :placeholder="`${t('taskName')}...`" class="custom-input"
|
||
style="width: 160px" />
|
||
</ElFormItem>
|
||
<ElFormItem :label="t('taskMode')">
|
||
<ElSelect v-model="searchForm.taskMode" clearable :placeholder="t('pleaseSelect')" class="custom-select">
|
||
<ElOption label="正向模拟" :value="1" />
|
||
<ElOption label="反向模拟" :value="-1" />
|
||
</ElSelect>
|
||
</ElFormItem>
|
||
<ElFormItem :label="t('taskStatus')">
|
||
<ElSelect v-model="searchForm.taskStatus" clearable :placeholder="t('pleaseSelect')" class="custom-select">
|
||
<ElOption v-for="item in taskStatusList" :key="item.value" :label="item.label" :value="item.value" />
|
||
</ElSelect>
|
||
</ElFormItem>
|
||
<ElFormItem :label="t('dataSource')">
|
||
<ElSelect v-model="searchForm.metType" clearable :placeholder="t('pleaseSelect')" class="custom-select">
|
||
<ElOption label="盘古模型" :value="1" />
|
||
<ElOption label="graphcast" :value="2" />
|
||
<ElOption label="cra40" :value="3" />
|
||
<ElOption label="ncep" :value="4" />
|
||
<ElOption label="fnl" :value="5" />
|
||
<ElOption label="t1h" :value="6" />
|
||
<ElOption label="GFS" :value="7" />
|
||
</ElSelect>
|
||
</ElFormItem>
|
||
<ElFormItem :label="t('creationTime')">
|
||
<ElDatePicker v-model="searchForm.createTime" type="daterange" value-format="YYYY-MM-DD" range-separator="--"
|
||
:start-placeholder="t('startDate')" :end-placeholder="t('endDate')" class="custom-date-picker"
|
||
style="width: 246px" />
|
||
</ElFormItem>
|
||
<ElFormItem>
|
||
<ElButton type="primary" class="custom-btn" icon="Search" @click="search">
|
||
{{ t('search') }}
|
||
</ElButton>
|
||
</ElFormItem>
|
||
</ElForm>
|
||
|
||
<!-- 表格 -->
|
||
<ElTable :data="taskList" width="100%" max-height="60vh" class="custom-table">
|
||
<ElTableColumn type="index" :label="t('serialNumber')" width="100" />
|
||
<ElTableColumn prop="taskName" :label="t('taskName')" />
|
||
<ElTableColumn prop="taskMode" :label="t('taskMode')">
|
||
<template #default="scope">
|
||
{{ scope.row.taskMode === 1 ? '正向模拟' : '反向模拟' }}
|
||
</template>
|
||
</ElTableColumn>
|
||
<ElTableColumn prop="taskType" :label="t('taskType')">
|
||
<template #default="scope">
|
||
{{ scope.row.taskType === 1 ? '手动创建' : '自动创建' }}
|
||
</template>
|
||
</ElTableColumn>
|
||
<!-- <ElTableColumn :label="t('taskProgress')"> -->
|
||
<!-- <template #default="scope"> -->
|
||
<!-- <ElProgress :percentage="scope.row.progress" class="custom-progress" /> -->
|
||
<!-- </template> -->
|
||
<!-- </ElTableColumn> -->
|
||
<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 :label="t('dataSource')">
|
||
<!-- 1-盘古模型,2-graphcast,3-cra40,4-ncep,5-fnl,6-t1h,7-GFS -->
|
||
<template #default="scope">
|
||
<div v-if="scope.row.useMetType === 1">
|
||
盘古模型
|
||
</div>
|
||
<div v-if="scope.row.useMetType === 2">
|
||
graphcast
|
||
</div>
|
||
<div v-if="scope.row.useMetType === 3">
|
||
cra40
|
||
</div>
|
||
<div v-if="scope.row.useMetType === 4">
|
||
ncep
|
||
</div>
|
||
<div v-if="scope.row.useMetType === 5">
|
||
fnl
|
||
</div>
|
||
<div v-if="scope.row.useMetType === 6">
|
||
t1h
|
||
</div>
|
||
<div v-if="scope.row.useMetType === 7">
|
||
GFS
|
||
</div>
|
||
</template>
|
||
</ElTableColumn>
|
||
<ElTableColumn prop="timeConsuming" :label="t('timeConsuming')" >
|
||
<template #default="scope">
|
||
<div>{{scope.row.timeConsuming}}分钟</div>
|
||
</template>
|
||
</ElTableColumn>
|
||
<!--<ElTableColumn prop="createBy" :label="t('creator')" />-->
|
||
<ElTableColumn prop="createTime" :label="t('creationTime')" />
|
||
<ElTableColumn :label="t('operation')" width="330">
|
||
<template #default="scope">
|
||
<ElButton v-if="scope.row.taskStatus === 1" type="text" class="table-btn" @click="pinToTopTask(scope, scope.topTask)">
|
||
{{ !scope.topTask ? t('pinToTop') : t('unpin') }}
|
||
</ElButton>
|
||
<ElButton v-else type="text" style="color:#588589;cursor:no-drop">
|
||
{{ !scope.topTask ? t('pinToTop') : t('unpin') }}
|
||
</ElButton>
|
||
<!-- -1执行失败,0未开始,1等待中,2运行中,3已完成,4检查未通过-->
|
||
<!--任务处于等待中,运行中状态时,不能编辑和删除;处于未开始,已完成,检查未通过时可以删除;处于已完成状态时也不能编辑-->
|
||
<ElButton v-if="scope.row.taskStatus === -1 || scope.row.taskStatus === 0 || scope.row.taskStatus === 4" type="text" class="custom-text-btn" @click="start(scope.row.id)">
|
||
{{ t('startOperation') }}
|
||
</ElButton>
|
||
<ElButton v-else type="text" style="color:#588589;cursor:no-drop">
|
||
{{ t('startOperation') }}
|
||
</ElButton>
|
||
<ElButton v-if="scope.row.taskStatus === 3" type="text" class="custom-text-btn" @click="viewTask(scope.row)">
|
||
{{ t('view') }}
|
||
</ElButton>
|
||
<ElButton v-else type="text" style="color:#588589;cursor:no-drop">
|
||
{{ t('view') }}
|
||
</ElButton>
|
||
<ElButton v-if="scope.row.taskStatus === -1 || scope.row.taskStatus === 0 && scope.row.taskStatus === 4" type="text" class="custom-text-btn" @click="editTask(scope.row, scope.$index)">
|
||
{{ t('edit') }}
|
||
</ElButton>
|
||
<ElButton v-else type="text" style="color:#588589;cursor:no-drop">
|
||
{{ t('edit') }}
|
||
</ElButton>
|
||
<ElButton v-if="scope.row.taskStatus == -1 || scope.row.taskStatus == 0 || scope.row.taskStatus === 3 || scope.row.taskStatus === 4" type="text" class="custom-text-btn" @click="deleteTask(scope.row)">
|
||
{{ t('delete') }}
|
||
</ElButton>
|
||
<ElButton v-else type="text" style="color:#588589;cursor:no-drop">
|
||
{{ t('delete') }}
|
||
</ElButton>
|
||
<ElButton v-if="scope.row.taskStatus === -1 || scope.row.taskStatus === 0 || scope.row.taskStatus === 1 || scope.row.taskStatus === 2 || scope.row.taskStatus === 3 || scope.row.taskStatus === 4" type="text" class="custom-text-btn" @click="showLog(scope.row.id)">
|
||
{{ t('operationLog') }}
|
||
</ElButton>
|
||
<ElButton v-else type="text" style="color:#588589;cursor:no-drop">
|
||
{{ t('operationLog') }}
|
||
</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, 500, 1000, 1500, 2000]" size="small" :background="true"
|
||
layout="total, sizes, prev, pager, next, jumper" :total="total" @size-change="handleSizeChange"
|
||
@current-change="handleCurrentChange" />
|
||
</div>
|
||
|
||
<template #footer>
|
||
<div class="dialog-footer">
|
||
|
||
|
||
|
||
|
||
<el-button class="custom-btn" @click="importVisible = true">
|
||
<SvgIcon name="import" width="30" height="20" style="font-weight:bold;margin-right: 1px;" />
|
||
{{ t('import') }}
|
||
</el-button>
|
||
|
||
|
||
<el-button class="custom-btn" icon="Plus" @click="addTask">
|
||
{{ t('add') }}
|
||
</el-button>
|
||
|
||
<el-button type="primary" class="custom-btn" icon="Refresh" @click="refresh">
|
||
{{ t('refresh') }}
|
||
</el-button>
|
||
</div>
|
||
</template>
|
||
</Dialog>
|
||
|
||
<!-- 增、改 -->
|
||
<Dialog v-model="configVisible" :title="configType === 'add' ? t('add') : t('edit')" width="60vw"
|
||
class="config-dialog">
|
||
<div class="config-dialog-title">
|
||
{{ t('basicInformation') }}
|
||
</div>
|
||
<ElForm ref="formEl" label-position="top" label-width="120px" :model="configForm" class="config-custom-form"
|
||
:rules="rules">
|
||
<ElFormItem prop="taskName" :label="t('taskName')">
|
||
<ElInput v-model="configForm.taskName" :placeholder="t('pleaseEnter')" class="config-custom-input" />
|
||
</ElFormItem>
|
||
<ElFormItem prop="taskMode" :label="t('taskMode')">
|
||
<ElSelect v-model="configForm.taskMode" :placeholder="t('pleaseSelect')" popper-class="custom-select-dropdown"
|
||
class="config-custom-select" @change="clearChild">
|
||
<ElOption label="正向模拟" :value="1" />
|
||
<ElOption label="反向模拟" :value="-1" />
|
||
</ElSelect>
|
||
</ElFormItem>
|
||
|
||
<ElFormItem prop="useMetType" :label="t('meteorologicalDataSource')">
|
||
<ElSelect v-model="configForm.useMetType" clearable :placeholder="t('pleaseSelect')"
|
||
class="config-custom-select">
|
||
<ElOption label="盘古模型" :value="1" />
|
||
<ElOption label="graphcast" :value="2" />
|
||
<ElOption label="cra40" :value="3" />
|
||
<ElOption label="ncep" :value="4" />
|
||
<ElOption label="fnl" :value="5" />
|
||
<ElOption label="t1h" :value="6" />
|
||
<ElOption label="GFS" :value="7" />
|
||
</ElSelect>
|
||
</ElFormItem>
|
||
|
||
<ElFormItem prop="z1" :label="t('releaseTheLowerHeight')">
|
||
<ElInput v-model="configForm.z1" :placeholder="t('pleaseEnter')" class="config-custom-input" />
|
||
</ElFormItem>
|
||
<ElFormItem prop="z2" :label="t('releaseTheUpperHeight')">
|
||
<ElInput v-model="configForm.z2" :placeholder="t('pleaseEnter')" class="config-custom-input" />
|
||
</ElFormItem>
|
||
<ElFormItem prop="particleCount" :label="t('particleCount')">
|
||
<ElInput v-model="configForm.particleCount" :placeholder="t('pleaseEnter')" class="config-custom-input" />
|
||
</ElFormItem>
|
||
<!-- <div style="display: flex"> -->
|
||
<ElFormItem prop="startTime" :label="t('startTime')">
|
||
<el-date-picker v-model="configForm.startTime" type="datetime" class="config-custom-input"
|
||
:placeholder="t('selectDateTime')" value-format="YYYY-MM-DD HH:mm:ss" />
|
||
</ElFormItem>
|
||
<ElFormItem prop="endTime" :label="t('endTime')">
|
||
<el-date-picker v-model="configForm.endTime" type="datetime" class="config-custom-input"
|
||
:placeholder="t('selectDateTime')" value-format="YYYY-MM-DD HH:mm:ss" />
|
||
</ElFormItem>
|
||
|
||
<ElFormItem prop="releaseDataSource" :label="t('释放数据来源')" v-if="configForm.taskMode === 1">
|
||
<ElSelect v-model="configForm.releaseDataSource" clearable :placeholder="t('pleaseSelect')"
|
||
@change="release"
|
||
class="config-custom-select">
|
||
<ElOption label="自动选择" :value="1" />
|
||
<ElOption label="手动填写" :value="2" />
|
||
</ElSelect>
|
||
</ElFormItem>
|
||
|
||
<ElFormItem prop="nuclear" :label="t('deviceCode')" v-if="configForm.taskMode === 1">
|
||
<ElSelect v-model="configForm.nuclear" filterable multiple collapse-tags
|
||
:placeholder="t('pleaseSelect')" class="config-custom-select" style="color:#fff;"
|
||
@change="setCode($event)">
|
||
<ElOption v-for="(item, index) in nuclearfacility" :key="index" :label="item.unitName" :value="index" />
|
||
</ElSelect>
|
||
</ElFormItem>
|
||
|
||
<ElFormItem prop="speciesArr" :label="t('nuclideName')" v-if="configForm.taskMode === 1">
|
||
<ElSelect multiple
|
||
collapse-tags
|
||
v-model="configForm.speciesArr"
|
||
@change="setSpecies($event)"
|
||
:placeholder="t('pleaseSelect')"
|
||
class="config-custom-select">
|
||
<ElOption label="Xe-133m" value="53" />
|
||
<ElOption label="Xe-131m" value="51" />
|
||
<ElOption label="Xe-135" value="54" />
|
||
<ElOption label="Xe-133" value="52" />
|
||
</ElSelect>
|
||
</ElFormItem>
|
||
|
||
<div type="text" class="config-custom-input" />
|
||
</ElForm>
|
||
|
||
|
||
<!-- 正、 多条排放信息-->
|
||
<template v-if="configForm.releaseDataSource === 2 && configForm.taskMode === 1 && configType === 'add'">
|
||
<div
|
||
v-for="(v,index) in nuclearfacilityChild"
|
||
>
|
||
<div class="config-dialog-title"
|
||
|
||
style="display: flex;justify-content: space-between;margin-bottom: 20px;align-items: center">
|
||
<div>{{v.stationCode+'排放信息'}}</div>
|
||
|
||
<SvgIcon name="add" width="20" height="20" style="cursor: pointer" @click="addChild2(index)" />
|
||
</div>
|
||
|
||
<ElTable
|
||
:data="v.forwardReleaseChild" width="100%" max-height="40vh" class="custom-table" style="margin-bottom: 30px">
|
||
|
||
<ElTableColumn prop="index" label="开始时间" >
|
||
<template #default="scope">
|
||
<el-date-picker v-model="scope.row.startTime" type="datetime" class="config-custom-input"
|
||
:placeholder="t('selectDateTime')" value-format="YYYY-MM-DD HH:mm:ss"
|
||
/>
|
||
</template>
|
||
</ElTableColumn>
|
||
<ElTableColumn prop="index" label="结束时间">
|
||
<template #default="scope">
|
||
<el-date-picker v-model="scope.row.endTime" type="datetime" class="config-custom-input"
|
||
:placeholder="t('selectDateTime')" value-format="YYYY-MM-DD HH:mm:ss"
|
||
/>
|
||
</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')" >
|
||
<template #default="scope">
|
||
<ElButton type="text" class="custom-text-btn" @click="deleteChild2(index,scope.$index)">
|
||
{{ t('delete') }}
|
||
</ElButton>
|
||
</template>
|
||
</ElTableColumn>
|
||
</ElTable>
|
||
</div>
|
||
</template>
|
||
|
||
<template v-if="configForm.releaseDataSource === 2 && configForm.taskMode === 1 && configType === 'edit'">
|
||
|
||
|
||
|
||
|
||
<div class="config-dialog-title"
|
||
|
||
style="display: flex;justify-content: space-between;margin-bottom: 20px;align-items: center">
|
||
<div>{{'排放信息'}}
|
||
|
||
</div>
|
||
<div style="display: flex;justify-content: space-between;align-items: center">
|
||
<ElSelect v-model="nuclear" filterable
|
||
:placeholder="t('pleaseSelect')" class="config-custom-select" style="color:#fff;width: 200px"
|
||
@change="setChildCode($event)">
|
||
<ElOption v-for="(item, index) in nuclearfacilityChild" :key="index" :label="item.stationCode" :value="item.id" />
|
||
</ElSelect>
|
||
<SvgIcon name="add" width="20" height="20" style="cursor: pointer;margin-left: 20px" @click="addChild3()" />
|
||
</div>
|
||
|
||
</div>
|
||
|
||
|
||
|
||
<ElTable
|
||
v-if="nuclear"
|
||
:data="nuclearData" width="100%" max-height="40vh" class="custom-table" style="margin-bottom: 30px">
|
||
|
||
<ElTableColumn prop="index" label="开始时间" >
|
||
<template #default="scope">
|
||
<el-date-picker v-model="scope.row.startTime" type="datetime" class="config-custom-input"
|
||
:placeholder="t('selectDateTime')" value-format="YYYY-MM-DD HH:mm:ss"
|
||
/>
|
||
</template>
|
||
</ElTableColumn>
|
||
<ElTableColumn prop="index" label="结束时间">
|
||
<template #default="scope">
|
||
<el-date-picker v-model="scope.row.endTime" type="datetime" class="config-custom-input"
|
||
:placeholder="t('selectDateTime')" value-format="YYYY-MM-DD HH:mm:ss"
|
||
/>
|
||
</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')" >
|
||
<template #default="scope">
|
||
<ElButton type="text" class="custom-text-btn" @click="deleteChild3(scope.$index)">
|
||
{{ t('delete') }}
|
||
</ElButton>
|
||
</template>
|
||
</ElTableColumn>
|
||
</ElTable>
|
||
</template>
|
||
|
||
|
||
|
||
<!-- 反-->
|
||
<div class="config-dialog-title"
|
||
v-if="configForm.releaseDataSource !== 1 && configForm.taskMode === -1"
|
||
style="display: flex;justify-content: space-between;margin-bottom: 20px;align-items: center">
|
||
<div>{{t('siteInformation') }}</div>
|
||
|
||
<SvgIcon name="add" width="20" height="20" style="cursor: pointer" @click="addChild" />
|
||
</div>
|
||
|
||
|
||
<ElTable
|
||
v-if="configForm.releaseDataSource !== 1 && configForm.taskMode === -1"
|
||
:data="childList" width="100%" max-height="40vh" class="custom-table">
|
||
|
||
|
||
<ElTableColumn prop="index" :label="t('deviceCode')" width="200">
|
||
<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;"-->
|
||
<!-- @change="setDate($event, scope.$index)">-->
|
||
<!-- <ElOption v-for="(item, index) in nuclearfacility" :key="index" :label="item.unitName" :value="index" />-->
|
||
<!-- </ElSelect>-->
|
||
<ElSelect v-model="scope.row.index" filterable
|
||
:placeholder="t('pleaseSelect')" class="config-custom-select" style="color:#fff;"
|
||
@change="setStationDate($event, scope.$index)">
|
||
<ElOption v-for="(item, index) in stations" :key="index" :label="item.stationCode" :value="index" />
|
||
</ElSelect>
|
||
</template>
|
||
</ElTableColumn>
|
||
|
||
<ElTableColumn prop="lon" :label="t('longitude')" />
|
||
<ElTableColumn prop="lat" :label="t('latitude')" />
|
||
<ElTableColumn v-if="configForm.taskMode === -1" prop="index" label="测量开始时间" width="250">
|
||
<template #default="scope">
|
||
<el-date-picker v-model="scope.row.acqStartTime" type="datetime" class="config-custom-input"
|
||
:placeholder="t('selectDateTime')" value-format="YYYY-MM-DD HH:mm:ss"
|
||
/>
|
||
</template>
|
||
</ElTableColumn>
|
||
<ElTableColumn v-if="configForm.taskMode === -1" prop="index" label="测量结束时间" width="250">
|
||
<template #default="scope">
|
||
<el-date-picker v-model="scope.row.acqEndTime" type="datetime" class="config-custom-input"
|
||
:placeholder="t('selectDateTime')" value-format="YYYY-MM-DD HH:mm:ss"
|
||
/>
|
||
</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')" >
|
||
<template #default="scope">
|
||
<!-- <ElButton type="text" class="custom-text-btn" @click="editTask(scope.row, scope.$index)"> -->
|
||
<!-- {{ t('edit') }} -->
|
||
<!-- </ElButton> -->
|
||
<ElButton type="text" class="custom-text-btn" @click="deleteChild(scope.$index)">
|
||
{{ t('delete') }}
|
||
</ElButton>
|
||
</template>
|
||
</ElTableColumn>
|
||
</ElTable>
|
||
<!-- </ElForm> -->
|
||
|
||
<template #footer>
|
||
<div class="config-custom-btn">
|
||
<el-button v-if="configType === 'add'" @click="saveConfigForm(formEl)">
|
||
{{ t('add') }}
|
||
</el-button>
|
||
<el-button v-if="configType === 'edit'" @click="saveConfigForm(formEl)">
|
||
{{ t('save') }}
|
||
</el-button>
|
||
<el-button type="warning" @click="configVisible = false">
|
||
{{ t('cancel') }}
|
||
</el-button>
|
||
</div>
|
||
</template>
|
||
</Dialog>
|
||
</div>
|
||
</template>
|
||
|
||
<style lang='less'>
|
||
.ysmn {
|
||
.drawer-wrapper {
|
||
width: 100%;
|
||
|
||
.left-form {
|
||
.el-form-item {
|
||
padding: 0 10px;
|
||
}
|
||
|
||
.drawer-header {
|
||
width: 100%;
|
||
height: 40px;
|
||
background-color: #03353f;
|
||
font-size: 16px;
|
||
line-height: 40px;
|
||
color: #3aecf0;
|
||
margin: 15px 0;
|
||
padding-left: 10px;
|
||
}
|
||
}
|
||
|
||
.drawer-footer-btn {
|
||
.el-button {
|
||
width: 92px;
|
||
height: 32px;
|
||
border-radius: 0;
|
||
border: 0;
|
||
color: #fff;
|
||
|
||
&:hover {
|
||
filter: brightness(1.3);
|
||
}
|
||
}
|
||
}
|
||
|
||
.address {
|
||
width: 100%;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
|
||
.el-input {
|
||
width: calc(50% - 10px) !important;
|
||
}
|
||
}
|
||
|
||
.el-input-group__append,
|
||
.el-input-group__prepend {
|
||
border: 1px solid #09726b;
|
||
box-shadow: none;
|
||
background-color: inherit;
|
||
color: #01b6e5;
|
||
}
|
||
}
|
||
|
||
.custom-select {
|
||
width: 130px;
|
||
}
|
||
|
||
.config-dialog {
|
||
margin-top: 20vh;
|
||
|
||
.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;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.custom-btn {
|
||
background-color: #1397a3;
|
||
border-color: #1397a3;
|
||
color: #fff;
|
||
|
||
&:hover {
|
||
background-color: #185c5c;
|
||
border-color: #4ac1c1;
|
||
}
|
||
}
|
||
|
||
.custom-progress {
|
||
.el-progress-bar__outer {
|
||
background-color: #1a4a5a;
|
||
border-radius: 0;
|
||
}
|
||
|
||
.el-progress-bar__inner {
|
||
background-color: #fff;
|
||
border-radius: 0;
|
||
}
|
||
|
||
.el-progress__text {
|
||
color: #fff;
|
||
}
|
||
}
|
||
|
||
.custom-text-btn {
|
||
color: #36e7f7;
|
||
font-weight: normal !important;
|
||
|
||
&:hover {
|
||
color: #6aeaea;
|
||
}
|
||
}
|
||
|
||
.dialog-footer {
|
||
width: calc(100% - 32px);
|
||
display: flex;
|
||
justify-content: end;
|
||
padding-left: 16px;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
.el-date-picker__time-header {
|
||
.el-input__wrapper {
|
||
background-color: #fff !important;
|
||
|
||
.el-input__inner {
|
||
color: #000 !important;
|
||
}
|
||
}
|
||
}
|
||
|
||
.log-custom-dialog {
|
||
.el-dialog__body {
|
||
/*background-color: #000 !important;*/
|
||
}
|
||
}
|
||
|
||
.my-loading {
|
||
/* 固定定位,脱离文档流 */
|
||
position: fixed !important;
|
||
/* 覆盖整个屏幕 */
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
/* 确保在最上层 */
|
||
z-index: 9999 !important;
|
||
/* 半透明背景 */
|
||
background-color: rgba(255, 255, 255, 0.7);
|
||
}
|
||
|
||
.pagination {
|
||
width: 100%;
|
||
display: flex;
|
||
justify-content: left;
|
||
margin-top: 10px;
|
||
}
|
||
|
||
.config-dialog-title {
|
||
width: 100%;
|
||
background: #0a4f44;
|
||
color: #fff;
|
||
padding: 10px 20px;
|
||
}
|
||
.tab-container {
|
||
display: flex;
|
||
margin: 10px 0;
|
||
width: 100%;
|
||
overflow-x: auto;
|
||
/* Tab 项:默认样式 */
|
||
.tab-item {
|
||
cursor: pointer;
|
||
border-right: none; /* 去掉右侧边框,避免重复 */
|
||
margin-right: 10px;
|
||
width: 161px;
|
||
height: 30px;
|
||
background-color: #024343;
|
||
text-align: center;
|
||
line-height: 30px;
|
||
color: #c9f6f6;
|
||
}
|
||
|
||
/* 激活状态样式:调整背景、文字颜色等 */
|
||
.tab-active {
|
||
background-color: #034242; /* 激活时的背景色 */
|
||
color: #2affdf; /* 激活时的文字颜色 */
|
||
}
|
||
}
|
||
}
|
||
</style>
|