This commit is contained in:
2026-01-27 20:19:29 +08:00
10 changed files with 413 additions and 309 deletions

View File

@@ -58,7 +58,7 @@ export const dataExportKnowledgeListApi = (params: any, filename: string) => {
return download(`${PREFIX}data/exportKnowledgeList`, params, filename);
};
export const dataDownloadFileApi = (params: any) => {
return get(`${PREFIX}data/downloadFile`, params);
return post(`${PREFIX}data/downloadFile`, params);
};
export const getFileBaseInfoApi = (params: any) => {

View File

@@ -267,3 +267,12 @@ export const syncKeyResultToTaskApi = (params: any) => {
export const generateNewReportApi = (params: any) => {
return download(`${PREFIX}run/generateNewReport`, params, params.fileName);
};
/**
* 流程失败节点重试
* @param params processInstanceId failNodeId
* @returns
*/
export const retryFailedNodeApi = (params: any) => {
return post(`${PREFIX}run/retryFailedNode`, params);
};

View File

@@ -238,10 +238,12 @@ const formatDataFun = (list: any, parentId: any) => {
}
}
};
const uploadFileFlag = ref(false);
const checkParamRequired = ref(false);
// 保存参数
const saveNodeParamFun = async () => {
const saveNodeParamFun = async (flag?: any) => {
uploadFileFlag.value = false;
const runNodeInfo = props.currentNode?.store?.data?.data?.flowNodeInfo;
const runNodeData = props.currentNode?.store?.data?.data;
const newParams: any = cloneDeep(tableData.value);
@@ -251,7 +253,7 @@ const saveNodeParamFun = async () => {
checkParamRequiredFun(newParams);
if (checkParamRequired.value) {
ElMessage.warning('存在必填项没有填写!');
// ElMessage.warning('存在必填项没有填写!');
checkParamRequired.value = false;
// return;
inputParams.executeMode = 'MANUAL';
@@ -259,7 +261,7 @@ const saveNodeParamFun = async () => {
inputParams.executeMode = 'AUTO';
}
await setDataToParam(newParams, inputParams, true);
await setDataToParam(newParams, inputParams, true, flag);
if (runNodeData.nodeType === 'HPC') {
setSpecialParamData(inputParams, runNodeData);
@@ -276,7 +278,7 @@ const saveNodeParamFun = async () => {
const res: any = await saveNodeParamsApi(params);
if (res && res.code === 200) {
ElMessage.success('保存成功');
emits('confirm');
emits('confirm', { flag: uploadFileFlag.value });
}
};
@@ -301,15 +303,16 @@ const checkParamRequiredFun = (list: any) => {
}
};
const setDataToParam = async (list: any, obj: any, isUpload?: any) => {
const setDataToParam = async (list: any, obj: any, isUpload?: any, flag?: any) => {
for (let i = 0; i < list.length; i++) {
if (list[i]?.englishLabel) {
if (list[i].tagType === WIDGET_TYPE.FILE && list[i]?.fileList?.length) {
const fileList = list[i]?.fileList || [];
let arrs: any = [];
if (fileList.length) {
const fileData = await runUploadRunFilesFun(fileList);
const fileData = await runUploadRunFilesFun(fileList, flag);
arrs = fileData;
uploadFileFlag.value = true;
// for (let j = 0; j < fileList.length; j++) {
// if (isUpload) {
// await uploadRunFilesFun(fileList[j].raw);
@@ -326,14 +329,14 @@ const setDataToParam = async (list: any, obj: any, isUpload?: any) => {
if (list[i].tagType === WIDGET_TYPE.VIEW && list[i].tagIcon === 'row') {
if (list[i]?.children?.length) {
obj[list[i].vModel] = {};
setDataToParam(list[i]?.children, obj[list[i].vModel], isUpload);
setDataToParam(list[i]?.children, obj[list[i].vModel], isUpload, flag);
}
}
}
}
};
const runUploadRunFilesFun = async (list: any) => {
const runUploadRunFilesFun = async (list: any, flag: any) => {
const sourceFiles = [];
for (let i = 0; i < list.length; i++) {
@@ -370,6 +373,7 @@ const runUploadRunFilesFun = async (list: any) => {
...item,
isApprove: 0, // 0否 1是
taskType: 4, // 4交付物
callbackFlag: flag,
},
});
});
@@ -468,7 +472,9 @@ const setReportSpecialParamDataFun = (param: any) => {
localStorage.getItem('CURRENT_FILTER_RUN_TASK_TREE_PARAM') as string
);
param.reportName = '算例报告_' + dayjs().format('YYYY_MM_DD_HH_mm');
if (!param.reportName) {
param.reportName = '算例报告_' + dayjs().format('YYYY_MM_DD_HH_mm');
}
param.applicants = getUserData().nickname;
param.date = dayjs().format('YYYY-MM-DD HH:mm:ss');
param.loadcaseName = props.runInfo.parentName;

View File

@@ -12,17 +12,26 @@
fullHeight
>
<template #totalElapsedTime="{ row }">
<span>{{ row.totalElapsedTime || '--' }}h</span>
<span>{{ row.totalElapsedTime ? row.totalElapsedTime + 'h' : '--' }}</span>
</template>
<template #jobStatus="{ row }">
<span>{{ WORK_STATUS.O[row.jobStatus] }}</span>
<el-tag v-if="row.jobStatus === 'Finished'" type="success">{{
WORK_STATUS.O[row.jobStatus]
}}</el-tag>
<el-tag type="info" v-else-if="row.jobStatus === 'Canceled'">{{
WORK_STATUS.O[row.jobStatus]
}}</el-tag>
<el-tag v-else-if="row.jobStatus === 'Failed'" type="danger">{{
WORK_STATUS.O[row.jobStatus]
}}</el-tag>
<el-tag v-else type="primary">{{ WORK_STATUS.O[row.jobStatus] }}</el-tag>
</template>
</BaseTable>
</div>
</el-tab-pane>
<el-tab-pane label="本地作业执行列表" name="local">
<!-- <el-tab-pane label="本地作业执行列表" name="local">
<div class="table"></div>
</el-tab-pane>
</el-tab-pane> -->
</el-tabs>
</div>
</Dialog>

View File

@@ -159,7 +159,7 @@ export const getNodeList = async (noload?: any) => {
if (!noload) {
apps[i].nodeParamConfigName = await getAppConfigListFun(apps[i].uuid);
}
typeKeyArray[apps[i].appType].nodes.push(apps[i]);
typeKeyArray[apps[i].appType]?.nodes?.push(apps[i]);
appList.push(apps[i]);
}
}

View File

@@ -610,6 +610,7 @@ const createRunFun = async (data: any) => {
currentNodeInfo.value = runInfo;
defaultExpandKeys.value = [runInfo.id];
taskTreeRef.value.setCurrentKey(runInfo.id);
emits('nodeClickFn', { node: currentNodeInfo.value });
}
} else {
info.label = info.runNames;

View File

@@ -3,21 +3,9 @@
<div class="run-title-box" v-show="!leftFullScreen && !rightFullScreen">
<div class="task-info">
<div class="task-name">{{ currentRunNodeInfo?.runName }}</div>
<!-- <div class="task-executor">
执行人
<el-icon class="blue">
<UserFilled />
</el-icon>
<span class="name">
{{ '执行人' }}</span>
</div> -->
<div class="task-status">
任务状态
<div class="status">
<!-- <el-icon class="info" title="未开始" v-if="!runFlowPocesInfo?.status">
<InfoFilled />
</el-icon> -->
<el-icon class="upload" title="运行中" v-if="runFlowPocesInfo?.status === 'running'">
<HelpFilled />
</el-icon>
@@ -62,37 +50,14 @@
</div>
</div>
<div class="task-operate">
<!-- <el-dropdown placement="bottom-end">
<el-button type="primary">
操作 <el-icon class="el-icon--right"><ArrowDown /></el-icon>
</el-button>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item
v-if="runInfo.status === RUN_STATUS.UNSTART"
@click="startTaskRunJobFun"
>开始</el-dropdown-item
>
<el-dropdown-item v-if="runInfo.status === RUN_STATUS.RUNNING">暂停</el-dropdown-item>
<el-dropdown-item @click="refreshFun">刷新</el-dropdown-item>
<el-dropdown-item @click="visible = true">查看所有活动</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown> -->
<el-button
type="primary"
v-if="runInfo.status === RUN_STATUS.UNSTART"
:disabled="uploadFileFlag"
@click="startTaskRunJobFun"
>开始</el-button
>
<!-- <el-button size="small" type="danger" v-if="runInfo.status === RUN_STATUS.RUNNING"
>暂停</el-button
> -->
<!-- <el-button size="small" type="primary">完成</el-button> -->
<el-button @click="refreshFun">刷新</el-button>
<el-button @click="visible = true">作业列表</el-button>
</div>
</div>
@@ -110,47 +75,36 @@
</div>
<div :class="leftFullScreen || rightFullScreen ? 'run-info-box is-all-page' : 'run-info-box'">
<!-- <div class="run-flow-info-box">
<div
v-if="!rightFullScreen"
:class="leftFullScreen ? 'info-box-left allpage ' : 'info-box-left'"
>
<div class="bottom-title">
<div class="title-name">节点信息</div>
<div class="title-name">节点详情</div>
<div class="title-operate">
<el-icon
v-if="!leftFullScreen"
@click="leftFullScreen = !leftFullScreen"
class="icon-style"
><FullScreen
/></el-icon>
<el-icon v-else @click="leftFullScreen = !leftFullScreen" class="icon-style"
><Close
/></el-icon>
</div>
</div>
</div> -->
<!-- <DragSplit :left-content-width="'50%'">
<template #left> -->
<div
v-if="!rightFullScreen"
:class="leftFullScreen ? 'info-box-left allpage ' : 'info-box-left'"
>
<div class="bottom-title">
<div class="title-name">节点详情</div>
<div class="title-operate">
<el-icon
v-if="!leftFullScreen"
@click="leftFullScreen = !leftFullScreen"
class="icon-style"
><FullScreen
/></el-icon>
<el-icon v-else @click="leftFullScreen = !leftFullScreen" class="icon-style"
><Close
/></el-icon>
</div>
</div>
<div class="bottom-info-content">
<div class="tabs-box left-tab">
<el-tabs
v-model="nodeActiveName"
class="demo-tabs"
@tab-change="handleLeftClickFun"
>
<el-tab-pane label="节点信息" name="info"></el-tab-pane>
<el-tab-pane label="参数设置" name="param"></el-tab-pane>
<el-tab-pane label="数据输入" name="input"></el-tab-pane>
<el-tab-pane label="数据输出" name="output"></el-tab-pane>
</el-tabs>
</div>
<div class="operate-box">
<!-- <el-switch
<div class="bottom-info-content">
<div class="tabs-box left-tab">
<el-tabs v-model="nodeActiveName" class="demo-tabs" @tab-change="handleLeftClickFun">
<el-tab-pane label="节点信息" name="info"></el-tab-pane>
<el-tab-pane label="参数设置" name="param"></el-tab-pane>
<el-tab-pane label="数据输入" name="input"></el-tab-pane>
<el-tab-pane label="数据输出" name="output"></el-tab-pane>
</el-tabs>
</div>
<div class="operate-box">
<!-- <el-switch
v-model="executeMode"
class="mr10"
active-value="AUTO"
@@ -159,28 +113,28 @@
inactive-text="手动执行"
@change="FlowNodeExecuteModeChangeFun"
/> -->
<!-- <el-button
<!-- <el-button
type=""
v-if="flowNodeParamData?.nodeTypeValue === '1'"
@click="startLocalAppFun"
>启动</el-button
> -->
<!-- <el-button type="primary" @click="startLocalAppFun">执行</el-button> -->
<!-- <el-button
<!-- <el-button type="primary" @click="startLocalAppFun">执行</el-button> -->
<!-- <el-button
type="primary"
v-if="flowNodeData.nodeStatus === RUN_NODE_STATUS.WAITING_FOR_USER"
@click="continueStartRunJobFun"
>执行手动节点</el-button
> -->
<!-- <el-button
<!-- <el-button
type="primary"
@click="skipCurrentNodeFlowFun"
v-if="flowNodeParamData?.nodeTypeValue === '1'"
>跳过当前本地节点</el-button
> -->
</div>
<div class="tabs-info-content">
<!-- <paramSetting
</div>
<div class="tabs-info-content">
<!-- <paramSetting
:current-run-flow-node="flowNode"
:node-param-data="nodeParamDataList"
:node-data="flowNodeParamData"
@@ -191,161 +145,149 @@
@update="refreshFlowNodeParamFun"
>
</paramSetting> -->
<!-- v-if="nodeActiveName === 'param' && showPage" -->
<!-- v-if="nodeActiveName === 'param' && showPage" -->
<flowNodeParamTable
v-show="nodeActiveName === 'param' && showPage"
:node-params="nodeParamDataList"
:current-node="flowNode"
:page-info="flowNodeData"
:run-info="runInfo"
:online-file-param="onlineFileParam"
@confirm="refreshFlowNodeParamFun"
@update="updateFlowNodeParamFun"
></flowNodeParamTable>
<runDataPage
v-show="nodeActiveName === 'input' || nodeActiveName === 'output'"
:file-id="
nodeActiveName === 'input'
? flowNodeData?.inputDirId
: flowNodeData?.outputDirId
"
:node-info="flowNodeData"
></runDataPage>
<flowNodeParamTable
ref="flowNodeParamTableRef"
v-show="nodeActiveName === 'param' && showPage"
:node-params="nodeParamDataList"
:current-node="flowNode"
:page-info="flowNodeData"
:run-info="runInfo"
:online-file-param="onlineFileParam"
@confirm="refreshFlowNodeParamFun"
@update="updateFlowNodeParamFun"
></flowNodeParamTable>
<runDataPage
v-show="nodeActiveName === 'input' || nodeActiveName === 'output'"
:file-id="
nodeActiveName === 'input' ? flowNodeData?.inputDirId : flowNodeData?.outputDirId
"
:node-info="flowNodeData"
></runDataPage>
<div class="bottom-info-content-tab" v-show="nodeActiveName === 'info'">
<div class="node-img">
<img :src="flowNodeParamData.iconUrl" alt="" />
</div>
<div class="node-content">
<el-form>
<el-form-item label="节点名称">
<span>{{ flowNodeData.nodeName }}</span>
</el-form-item>
<el-form-item label="节点类型">
<el-tag v-if="flowNodeParamData.nodeTypeValue === '3'" type="primary">{{
getTypeNameFun(flowNodeParamData.nodeTypeValue)
}}</el-tag>
<el-tag
v-else-if="flowNodeParamData.nodeTypeValue === '2'"
type="success"
>{{ getTypeNameFun(flowNodeParamData.nodeTypeValue) }}</el-tag
>
<el-tag
v-else-if="flowNodeParamData.nodeTypeValue === '1'"
type="warning"
>{{ getTypeNameFun(flowNodeParamData.nodeTypeValue) }}</el-tag
>
<el-tag v-else type="primary">{{
getTypeNameFun(flowNodeParamData.nodeTypeValue)
}}</el-tag>
<div class="bottom-info-content-tab" v-show="nodeActiveName === 'info'">
<div class="node-img">
<img :src="flowNodeParamData.iconUrl" alt="" />
</div>
<div class="node-content">
<el-form>
<el-form-item label="节点名称">
<span>{{ flowNodeData.nodeName }}</span>
</el-form-item>
<el-form-item label="节点类型">
<el-tag v-if="flowNodeParamData.nodeTypeValue === '3'" type="primary">{{
getTypeNameFun(flowNodeParamData.nodeTypeValue)
}}</el-tag>
<el-tag v-else-if="flowNodeParamData.nodeTypeValue === '2'" type="success">{{
getTypeNameFun(flowNodeParamData.nodeTypeValue)
}}</el-tag>
<el-tag v-else-if="flowNodeParamData.nodeTypeValue === '1'" type="warning">{{
getTypeNameFun(flowNodeParamData.nodeTypeValue)
}}</el-tag>
<el-tag v-else type="primary">{{
getTypeNameFun(flowNodeParamData.nodeTypeValue)
}}</el-tag>
<!-- {{ flowNodeParamData?.nodeTypeValue }} -->
</el-form-item>
<el-form-item label="节点状态">
<div class="app-status">
<div
class="round"
:style="{
background: getStyleFun(flowNodeData?.nodeStatus).color,
}"
></div>
<div class="text">
{{ getStyleFun(flowNodeData?.nodeStatus).title }}
</div>
</div>
<!-- {{ flowNodeParamData?.nodeTypeValue }} -->
</el-form-item>
<el-form-item label="节点状态">
<div class="app-status">
<div
class="round"
:style="{
background: getStyleFun(flowNodeData?.nodeStatus).color,
}"
></div>
<div class="text">
{{ getStyleFun(flowNodeData?.nodeStatus).title }}
</div>
</div>
<!-- {{ flowNodeData?.nodeDetailInfo?.status }} -->
</el-form-item>
<el-form-item label="执行时间">
<el-icon class="icon-style mr5"><Timer /></el-icon>
<span class="gl-text-ellipsis">
{{ flowNodeData?.nodeDetailInfo?.durationFormatted || '--' }}
</span>
</el-form-item>
<el-form-item label="开始时间">
<el-icon class="icon-style mr5"><Calendar /></el-icon>
<span class="gl-text-ellipsis">
{{ flowNodeData?.nodeDetailInfo?.startTime || '--' }}
</span>
</el-form-item>
<el-form-item label="完成时间">
<el-icon class="icon-style mr5"><Calendar /></el-icon>
<span class="gl-text-ellipsis">
{{ flowNodeData?.nodeDetailInfo?.endTime || '--' }}
</span>
</el-form-item>
</el-form>
</div>
</div>
<!-- {{ flowNodeData?.nodeDetailInfo?.status }} -->
</el-form-item>
<el-form-item label="执行时间">
<el-icon class="icon-style mr5"><Timer /></el-icon>
<span class="gl-text-ellipsis">
{{ flowNodeData?.nodeDetailInfo?.durationFormatted || '--' }}
</span>
</el-form-item>
<el-form-item label="开始时间">
<el-icon class="icon-style mr5"><Calendar /></el-icon>
<span class="gl-text-ellipsis">
{{ flowNodeData?.nodeDetailInfo?.startTime || '--' }}
</span>
</el-form-item>
<el-form-item label="完成时间">
<el-icon class="icon-style mr5"><Calendar /></el-icon>
<span class="gl-text-ellipsis">
{{ flowNodeData?.nodeDetailInfo?.endTime || '--' }}
</span>
</el-form-item>
</el-form>
</div>
</div>
</div>
<!-- </template> -->
<!-- <template #right> -->
<div
v-if="!leftFullScreen"
:class="rightFullScreen ? 'info-box-right allpage ' : 'info-box-right'"
>
<div class="bottom-title">
<div class="title-name">作业相关</div>
<div class="title-operate">
<el-icon
v-if="!rightFullScreen"
class="icon-style"
@click="rightFullScreen = !rightFullScreen"
><FullScreen
/></el-icon>
<el-icon v-else class="icon-style" @click="rightFullScreen = !rightFullScreen"
><Close
/></el-icon>
</div>
</div>
<div class="bottom-info-content">
<div class="tabs-box">
<el-tabs
v-model="taskActiveName"
class="demo-tabs"
@tab-click="handleRightClickFun"
>
<el-tab-pane label="作业列表" name="job-list"></el-tab-pane>
<!-- <el-tab-pane label="日志输出" name="job-log"></el-tab-pane> -->
<el-tab-pane label="关联任务" name="associated-run"></el-tab-pane>
<el-tab-pane label="仿真结果" name="result"></el-tab-pane>
<!-- <el-tab-pane label="性能指标" name="performance"></el-tab-pane> -->
<el-tab-pane label="报告结果" name="report"></el-tab-pane>
<el-tab-pane label="标准规范" name="standard"></el-tab-pane>
<!-- <el-tab-pane label="3D模型预览" name="3D-model"></el-tab-pane> -->
</el-tabs>
</div>
<div class="tabs-info-content">
<resultData
v-if="taskActiveName === 'result'"
:current-run-ifno="runInfo"
></resultData>
<jobList v-if="taskActiveName === 'job-list'" :current-run-info="runInfo"></jobList>
<taskPerformance
v-if="taskActiveName === 'performance'"
:param-type="'run'"
:run-info="runInfo"
:show-save-button="true"
:full-height="true"
></taskPerformance>
<runLogs v-if="taskActiveName === 'job-log'"></runLogs>
<ModelReview v-if="taskActiveName === '3D-model'"></ModelReview>
<runVersionTree
v-if="taskActiveName === 'associated-run'"
:current-task-info="runInfo"
></runVersionTree>
<runStandard v-if="taskActiveName === 'standard'" :run-info="runInfo"></runStandard>
<reportResult
v-if="taskActiveName === 'report'"
:current-run-ifno="runInfo"
></reportResult>
</div>
</div>
</div>
</div>
<!-- </template> -->
<!-- <template #right> -->
<div
v-if="!leftFullScreen"
:class="rightFullScreen ? 'info-box-right allpage ' : 'info-box-right'"
>
<div class="bottom-title">
<div class="title-name">作业相关</div>
<div class="title-operate">
<el-icon
v-if="!rightFullScreen"
class="icon-style"
@click="rightFullScreen = !rightFullScreen"
><FullScreen
/></el-icon>
<el-icon v-else class="icon-style" @click="rightFullScreen = !rightFullScreen"
><Close
/></el-icon>
</div>
<!-- </template>
</div>
<div class="bottom-info-content">
<div class="tabs-box">
<el-tabs v-model="taskActiveName" class="demo-tabs" @tab-click="handleRightClickFun">
<el-tab-pane label="作业列表" name="job-list"></el-tab-pane>
<!-- <el-tab-pane label="日志输出" name="job-log"></el-tab-pane> -->
<el-tab-pane label="关联任务" name="associated-run"></el-tab-pane>
<el-tab-pane label="仿真结果" name="result"></el-tab-pane>
<!-- <el-tab-pane label="性能指标" name="performance"></el-tab-pane> -->
<el-tab-pane label="报告结果" name="report"></el-tab-pane>
<el-tab-pane label="标准规范" name="standard"></el-tab-pane>
<!-- <el-tab-pane label="3D模型预览" name="3D-model"></el-tab-pane> -->
</el-tabs>
</div>
<div class="tabs-info-content">
<resultData v-if="taskActiveName === 'result'" :current-run-ifno="runInfo"></resultData>
<jobList v-if="taskActiveName === 'job-list'" :current-run-info="runInfo"></jobList>
<taskPerformance
v-if="taskActiveName === 'performance'"
:param-type="'run'"
:run-info="runInfo"
:show-save-button="true"
:full-height="true"
></taskPerformance>
<runLogs v-if="taskActiveName === 'job-log'"></runLogs>
<ModelReview v-if="taskActiveName === '3D-model'"></ModelReview>
<runVersionTree
v-if="taskActiveName === 'associated-run'"
:current-task-info="runInfo"
></runVersionTree>
<runStandard v-if="taskActiveName === 'standard'" :run-info="runInfo"></runStandard>
<reportResult
v-if="taskActiveName === 'report'"
:current-run-ifno="runInfo"
></reportResult>
</div>
</div>
</div>
<!-- </template>
</DragSplit> -->
</div>
<HpcList v-model="visible" />
@@ -353,7 +295,7 @@
</template>
<script setup lang="ts">
import { onMounted, ref, watch } from 'vue';
import { onActivated, onBeforeUnmount, onDeactivated, onMounted, ref, watch } from 'vue';
import resultData from './runPagecomponent/resultData.vue';
import runDataPage from './runPagecomponent/runDataPage.vue';
import jobList from './runPagecomponent/jobList.vue';
@@ -365,6 +307,7 @@ import runFlowPage from './runPagecomponent/flow/runFlowPage.vue';
import HpcList from '@/components/task/hpcList.vue';
import {
queryRunDirApi,
retryFailedNodeApi,
saveNodeParamsApi,
startProcessInstanceApi,
uploadRunFilesApi,
@@ -388,7 +331,6 @@ import { getDictionaryDataApi } from '@/api/system/systemData';
import { getUserData, getUserId, getUserTenantId } from '@/utils/user';
import reportResult from './runPagecomponent/reportResult.vue';
import dayjs from 'dayjs';
import DragSplit from '@/components/common/dragSplit/index.vue';
const props = defineProps({
runInfo: {
@@ -406,7 +348,7 @@ const statusList = ref<any>({
error: '异常',
waiting_for_user: '待操作',
});
const flowNodeParamTableRef = ref();
const executeMode = ref('MANUAL');
const visible = ref(false);
const nodeActiveName = ref('info');
@@ -430,6 +372,9 @@ const onlineFileParam = ref<any>({});
const changeCurrentFlowNodeFun = (info: any) => {
refreshPage.value = false;
const { node, data, process }: any = info;
console.log(info, 'info');
flowNode.value = node;
flowNodeData.value = data;
// nodeParamDataList.value = flowNode.value?.store?.data?.data?.pageConfigList || [];
@@ -494,6 +439,7 @@ const startTaskRunJobFun = async () => {
// 在开始执行任务之前,保存每个节点的参数后再调用执行任务的接口
// 检查每个节点的参数
uploadFileFlag.value = false;
for (const key in pageParamInfo.value) {
const params = pageUserParam.value[key];
@@ -507,14 +453,18 @@ const startTaskRunJobFun = async () => {
await saveParamsFun(params, list, data, node);
}
const res: any = await startProcessInstanceApi({
runId: props.runInfo.uuid,
});
if (res && res.code === 200) {
ElMessage.success(res.message);
showPage.value = false;
refreshRunFlowInfo();
emits('update', { status: RUN_STATUS.RUNNING });
if (!uploadFileFlag.value) {
const res: any = await startProcessInstanceApi({
runId: props.runInfo.uuid,
});
if (res && res.code === 200) {
ElMessage.success(res.message);
showPage.value = false;
refreshRunFlowInfo();
emits('update', { status: RUN_STATUS.RUNNING });
}
} else {
ElMessage.success('文件正在上传中,请勿进行其他操作!');
}
};
@@ -552,6 +502,7 @@ const saveParamsFun = async (params: any, list: any, data: any, node: any) => {
}
};
const uploadFileFlag = ref(false);
const setDataToParam = async (list: any, obj: any, isUpload?: any, inputDirId?: any) => {
for (let i = 0; i < list.length; i++) {
if (list[i]?.englishLabel) {
@@ -561,13 +512,7 @@ const setDataToParam = async (list: any, obj: any, isUpload?: any, inputDirId?:
if (fileList.length) {
const fileData = await runUploadRunFilesFun(fileList, inputDirId);
arrs = fileData;
// for (let j = 0; j < fileList.length; j++) {
// if (isUpload) {
// await uploadRunFilesFun(fileList[j].raw);
// }
// arrs.push({ fileName: fileList[j].name });
// }
uploadFileFlag.value = true;
}
list[i].defaultValue = arrs;
@@ -603,6 +548,7 @@ const runUploadRunFilesFun = async (list: any, inputDirId: any) => {
if (res && res.code === 200) {
res.data.forEach((item: any, index: any) => {
item.isSaveLocal = 'Y';
emitter.emit('ADD_UPLOAD_FILE', {
file: list[index].raw,
data: {
@@ -610,6 +556,7 @@ const runUploadRunFilesFun = async (list: any, inputDirId: any) => {
...item,
isApprove: 0, // 0否 1是
taskType: 4, // 4交付物
callbackFlag: 'START_FLOW',
},
});
});
@@ -701,6 +648,11 @@ const continueStartRunJobFun = async () => {
const startLocalAppFun = async () => {
if (flowNodeData.value?.nodeStatus === RUN_NODE_STATUS.WAITING_FOR_USER) {
continueStartRunJobFun();
} else if (flowNodeData.value?.nodeStatus === RUN_NODE_STATUS.ERROR) {
// 重新执行失败的流程节点
// 重新保存该流程节点的参数
await flowNodeParamTableRef.value.saveNodeParamFun('RESTART_FLOW_NODE');
// 调用重新执行的接口
} else {
// 本地节点拉起应用
if (flowNodeParamData.value?.nodeTypeValue === '1') {
@@ -732,6 +684,25 @@ const startLocalAppFun = async () => {
}
};
// 重新执行节点按钮
const retryFailedNodeFun = async () => {
const param = {
processInstanceId: flowNodeData.value.processInstanceId,
failNodeId: flowNodeData.value.nodeId,
};
try {
const res: any = await retryFailedNodeApi(param);
if (res && res.code === 200) {
ElMessage.success('节点已重新执行!');
showPage.value = false;
refreshRunFlowInfo();
}
} catch (error) {
console.log(error);
}
};
// 获取插件提交计算的参数信息
const getSubmitParamFun = async () => {
const taskName = props.runInfo?.parentName;
@@ -790,6 +761,22 @@ const getNodeFileIdAndNames = async () => {
const fileIds: any = [];
const fileNames: any = [];
let taskCmdParam: any = {};
// 本地应用执行的脚本也需要下载下来
if (flowNodeParamData.value?.postScripts?.length) {
for (let i = 0; i < flowNodeParamData.value?.postScripts?.length; i++) {
fileIds.push(flowNodeParamData.value?.postScripts[i].fileId);
fileNames.push(flowNodeParamData.value?.postScripts[i].name);
}
}
if (flowNodeParamData.value?.preScripts?.length) {
for (let i = 0; i < flowNodeParamData.value?.preScripts?.length; i++) {
fileIds.push(flowNodeParamData.value?.preScripts[i].fileId);
fileNames.push(flowNodeParamData.value?.preScripts[i].name);
}
}
try {
const res: any = await queryRunDirApi({
current: 1,
@@ -916,9 +903,17 @@ const refreshFun = () => {
// } catch {}
// };
const refreshFlowNodeParamFun = () => {
showPage.value = false;
refreshRunFlowInfo();
const refreshFlowNodeParamFun = async (data: any) => {
const { flag }: any = data;
if (flag === false) {
await retryFailedNodeFun();
showPage.value = false;
refreshRunFlowInfo();
}
if (flag === true) {
ElMessage.success('文件正在上传中,请等待文件上传完成后再操作');
}
};
const newNodeData = ref<any>({});
const updateFlowNodeParamFun = (data: any) => {
@@ -1002,6 +997,27 @@ const executeFun = () => {
startLocalAppFun();
};
// 文件上传完成后的回调事件
const uploadFinishedFun = async (data: any) => {
// 开始任务执行
if (data.callbackFlag === 'START_FLOW') {
const res: any = await startProcessInstanceApi({
runId: props.runInfo.uuid,
});
if (res && res.code === 200) {
ElMessage.success(res.message);
showPage.value = false;
refreshRunFlowInfo();
emits('update', { status: RUN_STATUS.RUNNING });
}
}
// 重复执行失败节点
if (data.callbackFlag === 'RESTART_FLOW_NODE') {
await retryFailedNodeFun();
}
};
watch(
() => props.runInfo,
(newVal) => {
@@ -1017,6 +1033,19 @@ watch(
onMounted(async () => {
await getDictionaryDataFun();
emitter.on('UPLOAD_FINISHED', uploadFinishedFun);
});
onBeforeUnmount(() => {
emitter.off('UPLOAD_FINISHED', uploadFinishedFun);
});
onActivated(() => {
emitter.on('UPLOAD_FINISHED', uploadFinishedFun);
});
onDeactivated(() => {
emitter.off('UPLOAD_FINISHED', uploadFinishedFun);
});
</script>

View File

@@ -8,8 +8,24 @@
:params="{
runId: currentRunInfo?.uuid,
}"
:actionList="actionList"
:fullHeight="true"
>
<template #totalElapsedTime="{ row }">
<span>{{ row.totalElapsedTime ? row.totalElapsedTime + 'h' : '--' }}</span>
</template>
<template #jobStatus="{ row }">
<el-tag v-if="row.jobStatus === 'Finished'" type="success">{{
WORK_STATUS.O[row.jobStatus]
}}</el-tag>
<el-tag type="info" v-else-if="row.jobStatus === 'Canceled'">{{
WORK_STATUS.O[row.jobStatus]
}}</el-tag>
<el-tag v-else-if="row.jobStatus === 'Failed'" type="danger">{{
WORK_STATUS.O[row.jobStatus]
}}</el-tag>
<el-tag v-else type="primary">{{ WORK_STATUS.O[row.jobStatus] }}</el-tag>
</template>
</BaseTable>
</div>
</template>
@@ -18,6 +34,7 @@
import { ref } from 'vue';
import BaseTable from '@/components/common/table/baseTable.vue';
import { queryJobsApi } from '@/api/pbs/pbs';
import { useDict } from '@/utils/useDict';
defineProps({
currentRunInfo: {
@@ -25,8 +42,20 @@ defineProps({
default: () => {},
},
});
const { WORK_STATUS } = useDict('WORK_STATUS');
const baseTableRef = ref();
const actionList = ref([
{
title: '暂停',
type: 'danger',
click: (row: any) => {},
hide: (row: any) => {
return !['Canceled', 'Finished', 'Failed'].includes(row.jobStatus);
},
},
]);
</script>
<style lang="scss" scoped>

View File

@@ -18,7 +18,7 @@
:show-task-info="false"
></taskDetailPage>
<runDetailPage
v-else-if="treeCurrentNodeInfo?.nodeType === NODE_TYPE.RUN"
v-else-if="treeCurrentNodeInfo?.nodeType === NODE_TYPE.RUN && showPage"
:run-info="treeCurrentNodeInfo"
@update="updateLeftTreeNodeInfoFun"
></runDetailPage>
@@ -29,7 +29,7 @@
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { nextTick, ref } from 'vue';
import { NODE_TYPE } from '@/utils/enum/node';
import leftTaskTree from './components/leftTaskTree/index.vue';
import taskDetailPage from './components/taskDetailPage/index.vue';
@@ -40,15 +40,21 @@ const toggleFun = () => {
isToggleShow.value = !isToggleShow.value;
};
const leftTreeRef = ref();
const showPage = ref(true);
const treeCurrentNodeInfo = ref<any>(null);
const getTreeCurrentNodeFun = (data: any) => {
showPage.value = false;
treeCurrentNodeInfo.value = {};
setTimeout(() => {
// setTimeout(() => {
// }, 1000);
nextTick(() => {
const { node }: any = data;
treeCurrentNodeInfo.value = node;
}, 1000);
showPage.value = true;
});
};
// 作业启动更新左侧树的算例的状态

View File

@@ -86,46 +86,35 @@
/>
</el-tab-pane>
<el-tab-pane label="项目详情" name="projectDetail">
<baseInfo
ref="basePageRef"
@update:projectInfo="updateProjectInfo"
@loaded="projectInfoLoadCompleteFun"
v-if="projectUuid"
:nodeId="projectUuid"
/>
</el-tab-pane>
<el-tab-pane
v-if="enableConfigByTenant([TENANT_ENUM.LYRIC])"
label="方案维护"
name="schemeMaintain"
>
<SchemeMaintain
ref="schemeMaintainRef"
v-if="displayedTabs.includes('schemeMaintain') && projectUuid"
:nodeId="projectUuid"
/>
</el-tab-pane>
<el-tab-pane
v-if="enableConfigByTenant([TENANT_ENUM.LYRIC])"
label="批次信息"
name="batchInfo"
>
<BatchInfo
ref="batchInfoRef"
v-if="displayedTabs.includes('batchInfo') && projectUuid"
:nodeId="projectUuid"
/>
</el-tab-pane>
<el-tab-pane
v-if="enableConfigByTenant([TENANT_ENUM.LYRIC])"
label="产线信息"
name="productionLine"
>
<productionLine
ref="productionLineRef"
v-if="displayedTabs.includes('productionLine') && projectUuid"
:nodeCode="currentProjectInfo.nodeCode"
/>
<div
class="project-detail-content"
v-if="displayedTabs.includes('projectDetail') && projectUuid"
>
<!-- 基本信息 -->
<div class="section-block">
<div class="section-title">基本信息</div>
<baseInfo
ref="basePageRef"
@update:projectInfo="updateProjectInfo"
@loaded="projectInfoLoadCompleteFun"
:nodeId="projectUuid"
/>
</div>
<template v-if="enableConfigByTenant([TENANT_ENUM.LYRIC])">
<div class="section-block">
<div class="section-title">方案维护</div>
<SchemeMaintain ref="schemeMaintainRef" :nodeId="projectUuid" />
</div>
<div class="section-block">
<div class="section-title">批次信息</div>
<BatchInfo ref="batchInfoRef" :nodeId="projectUuid" />
</div>
<div class="section-block">
<div class="section-title">产线信息</div>
<productionLine ref="productionLineRef" :nodeCode="currentProjectInfo.nodeCode" />
</div>
</template>
</div>
</el-tab-pane>
<el-tab-pane v-if="enableConfigByTenant([TENANT_ENUM.LYRIC])" label="项目PDT" name="PDT">
<PDT
@@ -418,4 +407,30 @@ const projectInfoLoadCompleteFun = () => {
height: 100%;
}
}
.project-detail-content {
height: 100%;
overflow-y: auto;
padding-right: 10px;
}
.section-block {
margin-bottom: 24px;
padding-bottom: 20px;
border-bottom: 1px solid var(--el-border-color-lighter);
&:last-child {
border-bottom: none;
margin-bottom: 0;
}
}
.section-title {
font-size: 16px;
font-weight: 600;
color: var(--el-text-color-primary);
margin-bottom: 12px;
padding-left: 10px;
border-left: 3px solid var(--el-color-primary);
}
</style>