Commit 19848612 authored by chenshouchao's avatar chenshouchao

feat: 完成任务详情联调

parent 19af5d31
...@@ -35,6 +35,7 @@ const RESTAPI = { ...@@ -35,6 +35,7 @@ const RESTAPI = {
API_WORKBENCH_DEL_WORKFLOWJOB: `${BACKEND_API_URI_PREFIX}/cpp/workflow/job/`, //删除工作流任务 API_WORKBENCH_DEL_WORKFLOWJOB: `${BACKEND_API_URI_PREFIX}/cpp/workflow/job/`, //删除工作流任务
API_WORKBENCH_CANCEL_WORKFLOWJOB: `${BACKEND_API_URI_PREFIX}/cpp/workflow/cancel`, //取消工作流 API_WORKBENCH_CANCEL_WORKFLOWJOB: `${BACKEND_API_URI_PREFIX}/cpp/workflow/cancel`, //取消工作流
API_SUBMIT_WORKFLOW: `${BACKEND_API_URI_PREFIX}/cpp/workflow/submit`, //提交工作流 API_SUBMIT_WORKFLOW: `${BACKEND_API_URI_PREFIX}/cpp/workflow/submit`, //提交工作流
API_WORKBENCH_WORKFLOW_TASKINFO: `${BACKEND_API_URI_PREFIX}/cpp/workbench/workflowjob/task-info`, //查询任务某个算子详情
}; };
export default RESTAPI; export default RESTAPI;
...@@ -235,6 +235,14 @@ const submitWorkFlow = (params: submitWorkFlowParams) => { ...@@ -235,6 +235,14 @@ const submitWorkFlow = (params: submitWorkFlowParams) => {
}); });
}; };
// 查询任务某个算子详情
const getworkFlowTaskInfo = (params: { jobId: string; taskId: string }) => {
return request({
url: `${Api.API_WORKBENCH_WORKFLOW_TASKINFO}?jobId=${params.jobId}&taskId=${params.taskId}`,
method: "get",
});
};
export { export {
current, current,
menu, menu,
...@@ -254,4 +262,5 @@ export { ...@@ -254,4 +262,5 @@ export {
fetchTemplateConfigInfo, fetchTemplateConfigInfo,
fetchWorkFlowJob, fetchWorkFlowJob,
submitWorkFlow, submitWorkFlow,
getworkFlowTaskInfo,
}; };
...@@ -31,8 +31,6 @@ ...@@ -31,8 +31,6 @@
font-size: 14px; font-size: 14px;
color: rgba(30, 38, 51, 1); color: rgba(30, 38, 51, 1);
font-weight: 600; font-weight: 600;
padding-right: 20px;
border-right: 1px solid rgba(235, 237, 240, 1);
} }
.swContent { .swContent {
...@@ -42,12 +40,109 @@ ...@@ -42,12 +40,109 @@
.swFormBox { .swFormBox {
background-color: #fff; background-color: #fff;
border-right: 1xp solid rgba(235, 237, 240, 1); border-right: 1xp solid rgba(235, 237, 240, 1);
width: 608px; width: 360px;
overflow-y: scroll; overflow-y: scroll;
box-sizing: border-box; box-sizing: border-box;
padding: 36px; padding: 24px;
} }
.swFlowBox { .swFlowBox {
flex: 1; flex: 1;
height: calc(100vh - 56px); height: calc(100vh - 56px);
} }
.title {
color: rgba(30, 38, 51, 1);
font-size: 16px;
line-height: 24px;
font-weight: 600;
margin-bottom: 16px;
}
.taskResults {
padding: 24px;
background-color: rgba(247, 248, 250, 1);
margin-bottom: 24px;
}
.notResults {
background-color: rgba(247, 248, 250, 1);
padding: 54px 0;
text-align: center;
color: rgba(138, 144, 153, 1);
font-size: 14px;
line-height: 22px;
margin-bottom: 24px;
}
.taskInfoLi {
margin-bottom: 20px;
display: flex;
justify-content: space-between;
align-items: flex-start;
}
.taskInfoParams {
color: rgba(138, 144, 153, 1);
font-size: 14px;
line-height: 22px;
}
.taskInfoValue {
color: rgba(30, 38, 51, 1);
font-size: 14px;
line-height: 22px;
max-width: 210px;
text-overflow: ellipsis;
white-space: nowrap;
display: flex;
overflow: hidden;
position: relative;
align-items: center;
}
.taskInfoValueShowAll {
white-space: normal;
}
.taskInfoValueIcon {
margin-right: 9px;
}
.tabs {
display: flex;
justify-content: flex-start;
border-bottom: 1px solid rgba(240, 242, 245, 1);
}
.tabLi {
cursor: pointer;
font-size: 14px;
line-height: 22px;
padding-bottom: 8px;
color: rgba(138, 144, 153, 1);
margin-right: 32px;
position: relative;
}
.tabLiAcitve {
color: rgba(19, 112, 255, 1);
border-bottom: 2px solid rgba(19, 112, 255, 1);
}
.overview {
padding-top: 19px;
}
.params {
padding-top: 19px;
}
.options {
position: absolute;
top: 33px;
max-height: 230px;
overflow-y: scroll;
padding: 8px 0px;
background: #ffffff;
box-shadow: 0px 3px 10px 0px rgba(0, 24, 57, 0.14);
border-radius: 4px;
}
.option {
padding: 7px 16px;
font-size: 14px;
color: rgba(30, 38, 51, 1);
line-height: 22px;
cursor: pointer;
}
.option:hover {
color: rgba(19, 112, 255, 1);
}
.optionActive {
color: rgba(19, 112, 255, 1);
}
...@@ -6,28 +6,54 @@ ...@@ -6,28 +6,54 @@
* @FilePath: /bkunyun/src/views/Project/ProjectSubmitWork/index.tsx * @FilePath: /bkunyun/src/views/Project/ProjectSubmitWork/index.tsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/ */
import { useEffect, useState } from "react"; import { useEffect, useState, useMemo } from "react";
import ButtonComponent from "@/components/mui/Button"; import ButtonComponent from "@/components/mui/Button";
import ArrowBackIosNewIcon from "@mui/icons-material/ArrowBackIosNew"; import ArrowBackIosNewIcon from "@mui/icons-material/ArrowBackIosNew";
import IconButton from "@mui/material/IconButton"; import IconButton from "@mui/material/IconButton";
import useMyRequest from "@/hooks/useMyRequest"; import useMyRequest from "@/hooks/useMyRequest";
import { fetchWorkFlowJob } from "@/api/project_api"; import { fetchWorkFlowJob, getworkFlowTaskInfo } from "@/api/project_api";
import { useLocation, useNavigate } from "react-router-dom"; import { useLocation, useNavigate } from "react-router-dom";
import { IResponse } from "@/api/http"; import { IResponse } from "@/api/http";
import jobSue from "@/assets/project/jobSue.svg";
import jobStop from "@/assets/project/jobStop.svg";
import jobRun from "@/assets/project/jobRun.svg";
import jobFail from "@/assets/project/jobFail.svg";
import classNames from "classnames";
import styles from "./index.module.css"; import styles from "./index.module.css";
import { ITemplateConfig } from "../ProjectSubmitWork/interface"; import { ITaskInfo } from "../ProjectSubmitWork/interface";
import Flow from "../components/Flow"; import Flow from "../components/Flow";
import { style } from "@mui/system";
const stateMap = {
RUNNING: "正在运行",
ABORTED: "运行终止",
FAILED: "运行失败",
SUCCEEDED: "运行成功",
};
const statusMap = {
Done: "运行完成",
Running: "正在运行",
Failed: "运行失败",
Pending: "等待运行",
};
type IStatus = "Done" | "Running" | "Failed" | "Pending";
const ProjectSubmitWork = () => { const ProjectSubmitWork = () => {
const [workFlowJobInfo, setWorkFlowJobInfo] = useState<ITemplateConfig>(); const [workFlowJobInfo, setWorkFlowJobInfo] = useState<ITaskInfo>();
const [patchInfo, setPatchInfo] = useState<any>();
const [activePatchId, setActivePatchId] = useState<string>("");
const [overviewActive, setOverviewActive] = useState(true);
const [activeFlowIndex, setActiveFlowIndex] = useState<number>(0);
const [showOptions, setShowOptions] = useState<boolean>(false);
const location: any = useLocation(); const location: any = useLocation();
const navigate = useNavigate(); const navigate = useNavigate();
/** 获取模版数据 */ /** 获取模版数据 */
const { run } = useMyRequest(fetchWorkFlowJob, { const { run } = useMyRequest(fetchWorkFlowJob, {
onSuccess: (res: IResponse<ITemplateConfig>) => { onSuccess: (res: IResponse<ITaskInfo>) => {
console.log(res.data, "1111");
setWorkFlowJobInfo(res.data); setWorkFlowJobInfo(res.data);
}, },
}); });
...@@ -35,10 +61,46 @@ const ProjectSubmitWork = () => { ...@@ -35,10 +61,46 @@ const ProjectSubmitWork = () => {
useEffect(() => { useEffect(() => {
const locationInfo: any = location?.state; const locationInfo: any = location?.state;
run({ run({
id: locationInfo.taskId, // id: locationInfo.taskId,
id: "89a00e93-8bba-45ee-85b0-63c5cd42c570",
}); });
}, [location?.state, run]); }, [location?.state, run]);
const { run: getworkFlowTaskInfoRun } = useMyRequest(getworkFlowTaskInfo, {
onSuccess: (res) => {
console.log(res);
setPatchInfo(res.data);
},
});
const handleBatch = (id: string) => {
setActivePatchId(id);
if (id) {
setActiveFlowIndex(0);
getworkFlowTaskInfoRun({
jobId: workFlowJobInfo?.id as string,
taskId: id,
});
}
};
const randerParameters = useMemo(() => {
if (patchInfo?.children) {
if (patchInfo.children.length > 0) {
return patchInfo.children[activeFlowIndex].parameters;
} else {
return patchInfo?.parameters;
}
} else {
return patchInfo?.parameters;
}
}, [activeFlowIndex, patchInfo]);
const handleParams = () => {
setOverviewActive(false);
setShowOptions(!showOptions);
};
return ( return (
<div className={styles.swBox}> <div className={styles.swBox}>
<div className={styles.swHeader}> <div className={styles.swHeader}>
...@@ -59,7 +121,7 @@ const ProjectSubmitWork = () => { ...@@ -59,7 +121,7 @@ const ProjectSubmitWork = () => {
/> />
</IconButton> </IconButton>
<div className={styles.swTemplateTitle}>{workFlowJobInfo?.title}</div> <div className={styles.swTemplateTitle}>{workFlowJobInfo?.name}</div>
</div> </div>
<div className={styles.swHeaderRight}> <div className={styles.swHeaderRight}>
<ButtonComponent <ButtonComponent
...@@ -71,10 +133,226 @@ const ProjectSubmitWork = () => { ...@@ -71,10 +133,226 @@ const ProjectSubmitWork = () => {
</div> </div>
<div className={styles.swContent}> <div className={styles.swContent}>
<div className={styles.swFormBox}> <div className={styles.swFormBox}>
<div>详情</div> {!activePatchId && (
<div className={styles.taskInfo}>
<div className={styles.title}>任务结果</div>
<div className={styles.taskResults}>任务结果</div>
<div className={styles.notResults}>暂无结果文件</div>
<div className={styles.title}>任务信息</div>
<div className={styles.taskInfoLi}>
<div className={styles.taskInfoParams}>任务名称</div>
<div
className={styles.taskInfoValue}
title={workFlowJobInfo?.name}
>
{workFlowJobInfo?.name || "-"}
</div>
</div>
<div className={styles.taskInfoLi}>
<div className={styles.taskInfoParams}>任务ID</div>
<div
className={styles.taskInfoValue}
title={workFlowJobInfo?.id}
>
{workFlowJobInfo?.id || "-"}
</div>
</div>
<div className={styles.taskInfoLi}>
<div className={styles.taskInfoParams}>输出路径</div>
<div className={styles.taskInfoValue}>
{workFlowJobInfo?.outputPath || "-"}
</div>
</div>
<div className={styles.taskInfoLi}>
<div className={styles.taskInfoParams}>运行状态</div>
<div className={styles.taskInfoValue}>
{workFlowJobInfo?.state === "SUCCEEDED" && (
<img
className={styles.taskInfoValueIcon}
src={jobSue}
alt=""
/>
)}
{workFlowJobInfo?.state === "RUNNING" && (
<img
className={styles.taskInfoValueIcon}
src={jobRun}
alt=""
/>
)}
{workFlowJobInfo?.state === "ABORTED" && (
<img
className={styles.taskInfoValueIcon}
src={jobStop}
alt=""
/>
)}
{workFlowJobInfo?.state === "FAILED" && (
<img
className={styles.taskInfoValueIcon}
src={jobFail}
alt=""
/>
)}
{workFlowJobInfo?.state
? stateMap[workFlowJobInfo?.state]
: "-"}
</div>
</div>
<div className={styles.taskInfoLi}>
<div className={styles.taskInfoParams}>源模板</div>
<div className={styles.taskInfoValue}>
{workFlowJobInfo?.specTitle || "-"}
</div>
</div>
<div className={styles.taskInfoLi}>
<div className={styles.taskInfoParams}>源模板版本</div>
<div className={styles.taskInfoValue}>
{workFlowJobInfo?.specVersion || "-"}
</div>
</div>
<div className={styles.taskInfoLi}>
<div className={styles.taskInfoParams}>花费(元)</div>
<div className={styles.taskInfoValue}>
{workFlowJobInfo?.jobCost || "-"}
</div>
</div>
<div className={styles.taskInfoLi}>
<div className={styles.taskInfoParams}>创建人</div>
<div className={styles.taskInfoValue}>
{workFlowJobInfo?.creator || "-"}
</div>
</div>
<div className={styles.taskInfoLi}>
<div className={styles.taskInfoParams}>创建时间</div>
<div className={styles.taskInfoValue}>
{workFlowJobInfo?.createTime || "-"}
</div>
</div>
<div className={styles.taskInfoLi}>
<div className={styles.taskInfoParams}>运行时间</div>
<div className={styles.taskInfoValue}>
{workFlowJobInfo?.costTime || "-"}
</div>
</div>
<div className={styles.taskInfoLi}>
<div className={styles.taskInfoParams}>日志文件</div>
<div className={styles.taskInfoValue}>
{workFlowJobInfo?.logPath}
</div>
</div>
</div>
)}
{activePatchId && (
<div className={styles.suanziInfo}>
<div className={styles.title}>{patchInfo?.title}</div>
<div className={styles.tabs}>
<div
className={classNames({
[styles.tabLi]: true,
[styles.tabLiAcitve]: overviewActive,
})}
onClick={() => setOverviewActive(true)}
>
概览
</div>
<div
className={classNames({
[styles.tabLi]: true,
[styles.tabLiAcitve]: !overviewActive,
})}
// onClick={() => setOverviewActive(false)}
onClick={() => handleParams()}
>
{patchInfo?.children.length > 0
? patchInfo?.children[activeFlowIndex].title
: patchInfo?.title}
{showOptions && patchInfo?.children.length > 0 && (
<div className={styles.options}>
{patchInfo?.children.map((item: any, index: number) => {
return (
<div
key={index}
className={styles.option}
onClick={() => setActiveFlowIndex(index)}
>
{item.title}
</div>
);
})}
</div>
)}
</div>
</div>
{overviewActive && (
<div className={styles.overview}>
<div className={styles.taskInfoLi}>
<div className={styles.taskInfoParams}>描述</div>
<div
className={classNames({
[styles.taskInfoValue]: true,
[styles.taskInfoValueShowAll]: true,
})}
>
{patchInfo?.description}
</div>
</div>
<div className={styles.taskInfoLi}>
<div className={styles.taskInfoParams}>算子版本</div>
<div className={styles.taskInfoValue}>
{patchInfo?.creator || "-"}
</div>
</div>
<div className={styles.taskInfoLi}>
<div className={styles.taskInfoParams}>算子状态</div>
<div className={styles.taskInfoValue}>
{patchInfo?.status === "Done" && (
<img
className={styles.taskInfoValueIcon}
src={jobSue}
alt=""
/>
)}
{patchInfo?.status === "Running" && (
<img
className={styles.taskInfoValueIcon}
src={jobRun}
alt=""
/>
)}
{patchInfo?.status === "Failed" && (
<img
className={styles.taskInfoValueIcon}
src={jobFail}
alt=""
/>
)}
{statusMap[patchInfo?.status as IStatus]}
</div>
</div>
</div>
)}
{!overviewActive && (
<div className={styles.params}>
{randerParameters.map((parameter: any) => {
return (
<div className={styles.taskInfoLi} key={parameter.name}>
<div className={styles.taskInfoParams}>
{parameter.name}
</div>
<div className={styles.taskInfoValue}>
{parameter.value || "-"}
</div>
</div>
);
})}
</div>
)}
</div>
)}
</div> </div>
<div className={styles.swFlowBox}> <div className={styles.swFlowBox}>
<Flow tasks={workFlowJobInfo?.tasks} /> <Flow tasks={workFlowJobInfo?.tasks} onBatchClick={handleBatch} />
</div> </div>
</div> </div>
</div> </div>
......
...@@ -191,7 +191,7 @@ const ConfigForm = (props: ConfigFormProps) => { ...@@ -191,7 +191,7 @@ const ConfigForm = (props: ConfigFormProps) => {
> >
{parameter.name} {parameter.name}
<span className={styles.parameterDataType}> <span className={styles.parameterDataType}>
{parameter.classType} {parameter.classTypeName}
</span> </span>
</div> </div>
<div className={styles.parameterContent}> <div className={styles.parameterContent}>
......
...@@ -133,7 +133,7 @@ const ProjectSubmitWork = () => { ...@@ -133,7 +133,7 @@ const ProjectSubmitWork = () => {
} }
} }
promotedParameters[parameter.name] = { promotedParameters[parameter.name] = {
[parameter.classType]: value, [parameter.classTypeName]: value,
}; };
}); });
}); });
......
...@@ -14,6 +14,7 @@ export interface IParameter { ...@@ -14,6 +14,7 @@ export interface IParameter {
required: boolean; required: boolean;
domType: IDomType; domType: IDomType;
classType: string; classType: string;
classTypeName: string;
value: any; value: any;
description: string; description: string;
language: string; language: string;
...@@ -104,3 +105,18 @@ export type IRenderTask = { ...@@ -104,3 +105,18 @@ export type IRenderTask = {
flows: ITask[]; flows: ITask[];
isCheck: boolean; // 里面的子项表单校验是否全部通过 isCheck: boolean; // 里面的子项表单校验是否全部通过
}; };
export interface ITaskInfo extends ITemplateConfig {
name: string;
outputPath: string;
state: IState;
specTitle: string;
specVersion: string;
jobCost: string;
creator: string;
createTime: string;
costTime: string;
logPath: string;
}
type IState = "SUCCEEDED" | "RUNNING" | "ABORTED" | "FAILED";
...@@ -261,7 +261,7 @@ const Flow = (props: IProps) => { ...@@ -261,7 +261,7 @@ const Flow = (props: IProps) => {
onBatchClick && onBatchClick(item.parentNode); onBatchClick && onBatchClick(item.parentNode);
} else { } else {
setSelectedNodeId(node.id); setSelectedNodeId(node.id);
onBatchClick && onBatchClick(item.parentNode || ""); onBatchClick && onBatchClick(node.id || "");
} }
} }
}); });
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment