Commit 1f78ff1b authored by wenmo's avatar wenmo

前端重构

parent c61d1a6e
...@@ -7,6 +7,7 @@ import lombok.Getter; ...@@ -7,6 +7,7 @@ import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.LocalDateTime;
/** /**
* Job * Job
...@@ -26,8 +27,8 @@ public class Job { ...@@ -26,8 +27,8 @@ public class Job {
private String error; private String error;
private IResult result; private IResult result;
private ExecutorSetting executorSetting; private ExecutorSetting executorSetting;
private LocalDate startTime; private LocalDateTime startTime;
private LocalDate endTime; private LocalDateTime endTime;
private Executor executor; private Executor executor;
enum JobStatus{ enum JobStatus{
...@@ -38,7 +39,7 @@ public class Job { ...@@ -38,7 +39,7 @@ public class Job {
CANCEL CANCEL
} }
public Job(JobConfig jobConfig, String jobManagerAddress, JobStatus status, String statement,ExecutorSetting executorSetting, LocalDate startTime, Executor executor) { public Job(JobConfig jobConfig, String jobManagerAddress, JobStatus status, String statement,ExecutorSetting executorSetting, LocalDateTime startTime, Executor executor) {
this.jobConfig = jobConfig; this.jobConfig = jobConfig;
this.jobManagerAddress = jobManagerAddress; this.jobManagerAddress = jobManagerAddress;
this.status = status; this.status = status;
......
...@@ -278,7 +278,7 @@ public class JobManager extends RunTime { ...@@ -278,7 +278,7 @@ public class JobManager extends RunTime {
public JobResult executeSql(String statement) { public JobResult executeSql(String statement) {
Job job = new Job(config,jobManagerHost+NetConstant.COLON+jobManagerPort, Job job = new Job(config,jobManagerHost+NetConstant.COLON+jobManagerPort,
Job.JobStatus.INITIALIZE,statement,executorSetting, LocalDate.now(),executor); Job.JobStatus.INITIALIZE,statement,executorSetting, LocalDateTime.now(),executor);
JobContextHolder.setJob(job); JobContextHolder.setJob(job);
ready(); ready();
String[] statements = statement.split(";"); String[] statements = statement.split(";");
...@@ -304,7 +304,7 @@ public class JobManager extends RunTime { ...@@ -304,7 +304,7 @@ public class JobManager extends RunTime {
break; break;
} }
} }
job.setEndTime(LocalDate.now()); job.setEndTime(LocalDateTime.now());
job.setStatus(Job.JobStatus.SUCCESS); job.setStatus(Job.JobStatus.SUCCESS);
success(); success();
} catch (Exception e) { } catch (Exception e) {
...@@ -314,7 +314,7 @@ public class JobManager extends RunTime { ...@@ -314,7 +314,7 @@ public class JobManager extends RunTime {
for (StackTraceElement s : trace) { for (StackTraceElement s : trace) {
resMsg.append(" \n " + s + " "); resMsg.append(" \n " + s + " ");
} }
LocalDate now = LocalDate.now(); LocalDateTime now = LocalDateTime.now();
job.setEndTime(now); job.setEndTime(now);
job.setStatus(Job.JobStatus.FAILED); job.setStatus(Job.JobStatus.FAILED);
String error = now.toString() + ":" + "运行第" + currentIndex + "个sql时出现异常:" + e.getMessage() + " \n >>>堆栈信息<<<" + resMsg.toString(); String error = now.toString() + ":" + "运行第" + currentIndex + "个sql时出现异常:" + e.getMessage() + " \n >>>堆栈信息<<<" + resMsg.toString();
......
...@@ -6,6 +6,7 @@ import lombok.Getter; ...@@ -6,6 +6,7 @@ import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.LocalDateTime;
/** /**
* JobResult * JobResult
...@@ -25,10 +26,10 @@ public class JobResult { ...@@ -25,10 +26,10 @@ public class JobResult {
private String jobId; private String jobId;
private String error; private String error;
private IResult result; private IResult result;
private LocalDate startTime; private LocalDateTime startTime;
private LocalDate endTime; private LocalDateTime endTime;
public JobResult(Integer id, JobConfig jobConfig, String jobManagerAddress, Job.JobStatus status, String statement, String jobId, String error, IResult result, LocalDate startTime, LocalDate endTime) { public JobResult(Integer id, JobConfig jobConfig, String jobManagerAddress, Job.JobStatus status, String statement, String jobId, String error, IResult result, LocalDateTime startTime, LocalDateTime endTime) {
this.id = id; this.id = id;
this.jobConfig = jobConfig; this.jobConfig = jobConfig;
this.jobManagerAddress = jobManagerAddress; this.jobManagerAddress = jobManagerAddress;
......
...@@ -51,6 +51,7 @@ ...@@ -51,6 +51,7 @@
"@ant-design/pro-descriptions": "^1.6.8", "@ant-design/pro-descriptions": "^1.6.8",
"@ant-design/pro-form": "^1.18.3", "@ant-design/pro-form": "^1.18.3",
"@ant-design/pro-layout": "^6.18.0", "@ant-design/pro-layout": "^6.18.0",
"@ant-design/pro-list": "^1.10.3",
"@ant-design/pro-table": "^2.36.0", "@ant-design/pro-table": "^2.36.0",
"@types/lodash.isequal": "^4.5.5", "@types/lodash.isequal": "^4.5.5",
"@umijs/openapi": "^1.1.14", "@umijs/openapi": "^1.1.14",
......
import {Typography, Divider, Badge, Empty} from "antd";
import {StateType} from "@/pages/FlinkSqlStudio/model"; import {StateType} from "@/pages/FlinkSqlStudio/model";
import {connect} from "umi"; import {connect} from "umi";
import {Button, Tag, Space} from 'antd';
import ProList from '@ant-design/pro-list';
import request from 'umi-request';
const { Title, Paragraph, Text, Link } = Typography;
const StudioHistory = (props:any) => { type GithubIssueItem = {
url: string;
id: number;
number: number;
title: string;
labels: {
name: string;
color: string;
}[];
state: string;
comments: number;
created_at: string;
updated_at: string;
closed_at?: string;
};
const StudioHistory = (props: any) => {
const {current} = props; const {current} = props;
return ( return (
<Typography> <><ProList<GithubIssueItem>
{current.console.result.map((item)=> { toolBarRender={() => {
return (<Paragraph> return [
<blockquote><Link href={`http://${item.flinkHost}:${item.flinkPort}`} target="_blank"> <Button key="3" type="primary">
[{item.sessionId}:{item.flinkHost}:{item.flinkPort}] 新建
</Link> <Divider type="vertical" />{item.finishDate} </Button>,
<Divider type="vertical" /> ];
{!item.success ? <><Badge status="error"/><Text type="danger">Error</Text></> : }}
<><Badge status="success"/><Text type="success">Success</Text></>} search={{
<Divider type="vertical" /> filterType: 'light',
{item.jobName&&<Text code>{item.jobName}</Text>} }}
{item.jobId&&<Text code>{item.jobId}</Text>} rowKey="name"
<Text keyboard>{item.time}ms</Text></blockquote> headerTitle="基础列表"
{item.statement && (<pre style={{height:'40px'}}>{item.statement}</pre>)} request={async (params = {}) =>
{item.msg ? item.msg : ''} request<{
{item.error && (<pre style={{height:'100px'}}>{item.error}</pre>)} data: GithubIssueItem[];
</Paragraph>) }>('https://proapi.azurewebsites.net/github/issues', {
})} params,
{current.console.result.length==0?<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />:''} })
</Typography> }
pagination={{
pageSize: 5,
}}
showActions="hover"
metas={{
title: {
dataIndex: 'user',
title: '用户',
},
avatar: {
dataIndex: 'avatar',
search: false,
},
description: {
dataIndex: 'title',
search: false,
},
subTitle: {
dataIndex: 'labels',
render: (_, row) => {
return (
<Space size={0}>
{row.labels?.map((label: { name: string }) => (
<Tag color="blue" key={label.name}>
{label.name}
</Tag>
))}
</Space>
);
},
search: false,
},
actions: {
render: (text, row) => [
<a href={row.url} target="_blank" rel="noopener noreferrer" key="link">
链路
</a>,
<a href={row.url} target="_blank" rel="noopener noreferrer" key="warning">
报警
</a>,
<a href={row.url} target="_blank" rel="noopener noreferrer" key="view">
查看
</a>,
],
search: false,
},
status: {
// 自己扩展的字段,主要用于筛选,不在列表中显示
title: '状态',
valueType: 'select',
valueEnum: {
all: {text: '全部', status: 'Default'},
open: {
text: '未解决',
status: 'Error',
},
closed: {
text: '已解决',
status: 'Success',
},
processing: {
text: '解决中',
status: 'Processing',
},
},
},
}}
/>
</>
); );
}; };
export default connect(({ Studio }: { Studio: StateType }) => ({ export default connect(({Studio}: {Studio: StateType}) => ({
current: Studio.current, current: Studio.current,
}))(StudioHistory); }))(StudioHistory);
import {Typography, Divider, Badge, Empty} from "antd";
import {StateType} from "@/pages/FlinkSqlStudio/model";
import {connect} from "umi";
const { Title, Paragraph, Text, Link } = Typography;
const StudioHistory2 = (props:any) => {
const {current} = props;
return (
<Typography>
{current.console.result.map((item)=> {
return (<Paragraph>
<blockquote><Link href={`http://${item.flinkHost}:${item.flinkPort}`} target="_blank">
[{item.sessionId}:{item.flinkHost}:{item.flinkPort}]
</Link> <Divider type="vertical" />{item.finishDate}
<Divider type="vertical" />
{!item.success ? <><Badge status="error"/><Text type="danger">Error</Text></> :
<><Badge status="success"/><Text type="success">Success</Text></>}
<Divider type="vertical" />
{item.jobName&&<Text code>{item.jobName}</Text>}
{item.jobId&&<Text code>{item.jobId}</Text>}
<Text keyboard>{item.time}ms</Text></blockquote>
{item.statement && (<pre style={{height:'40px'}}>{item.statement}</pre>)}
{item.msg ? item.msg : ''}
{item.error && (<pre style={{height:'100px'}}>{item.error}</pre>)}
</Paragraph>)
})}
{current.console.result.length==0?<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />:''}
</Typography>
);
};
export default connect(({ Studio }: { Studio: StateType }) => ({
current: Studio.current,
}))(StudioHistory2);
import {Tabs, Empty} from "antd";
import {BarsOutlined,DatabaseOutlined,AppstoreOutlined,ClusterOutlined,ApiOutlined,FireOutlined,FunctionOutlined} from "@ant-design/icons";
import {StateType} from "@/pages/FlinkSqlStudio/model";
import {connect} from "umi";
import styles from "./index.less";
import StudioTree from "../StudioTree";
import StudioConnector from "./StudioConnector";
const { TabPane } = Tabs;
const StudioLeftTool = (props:any) => {
return (
<Tabs defaultActiveKey="1" size="small" tabPosition="left" style={{ height: "100%",border: "1px solid #f0f0f0"}}>
<TabPane tab={<span><BarsOutlined/> 目录</span>} key="StudioTree" >
<StudioTree/>
</TabPane>
<TabPane tab={<span><DatabaseOutlined /> 数据源</span>} key="DataSource" >
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
</TabPane>
<TabPane tab={<span><AppstoreOutlined /> 元数据</span>} key="MetaData" >
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
</TabPane>
<TabPane tab={<span><ClusterOutlined /> 集群</span>} key="Cluster" >
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
</TabPane>
<TabPane tab={<span><ApiOutlined /> 连接器</span>} key="Connectors" >
<StudioConnector />
</TabPane>
<TabPane tab={<span><FireOutlined /> 任务</span>} key="FlinkTask" >
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
</TabPane>
<TabPane tab={<span><FunctionOutlined /> 函数</span>} key="Function" >
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
</TabPane>
</Tabs>
);
};
export default connect(({ Studio }: { Studio: StateType }) => ({
sql: Studio.sql,
}))(StudioLeftTool);
...@@ -11,7 +11,7 @@ import {StateType} from "@/pages/FlinkSqlStudio/model"; ...@@ -11,7 +11,7 @@ import {StateType} from "@/pages/FlinkSqlStudio/model";
import {connect} from "umi"; import {connect} from "umi";
import { postDataArray} from "@/components/Common/crud"; import { postDataArray} from "@/components/Common/crud";
import {executeSql} from "@/pages/FlinkSqlStudio/service"; import {executeSql} from "@/pages/FlinkSqlStudio/service";
import StudioHelp from "../StudioHelp"; import StudioHelp from "./StudioHelp";
import {showTables} from "@/components/Studio/StudioEvent/DDL"; import {showTables} from "@/components/Studio/StudioEvent/DDL";
const menu = ( const menu = (
......
import {Tabs, Empty, Form} from "antd";
import {SettingOutlined,ScheduleOutlined,AuditOutlined} from "@ant-design/icons";
import {StateType} from "@/pages/FlinkSqlStudio/model";
import {connect} from "umi";
import styles from "./index.less";
import StudioConfig from "./StudioConfig";
import StudioSetting from "./StudioSetting";
const { TabPane } = Tabs;
const StudioRightTool = (props:any) => {
const [form] = Form.useForm();
return (
<Tabs defaultActiveKey="1" size="small" tabPosition="right" style={{ height: "100%",border: "1px solid #f0f0f0"}}>
<TabPane tab={<span><SettingOutlined /> 作业配置</span>} key="StudioSetting" >
<StudioSetting form={form} />
</TabPane>
<TabPane tab={<span><ScheduleOutlined /> 执行配置</span>} key="StudioConfig" >
<StudioConfig form={form}/>
</TabPane>
<TabPane tab={<span><ScheduleOutlined /> 详情</span>} key="3" >
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
</TabPane>
<TabPane tab={<span><AuditOutlined /> 审计</span>} key="4" >
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
</TabPane>
</Tabs>
);
};
export default connect(({ Studio }: { Studio: StateType }) => ({
sql: Studio.sql,
}))(StudioRightTool);
import React, {useEffect, useState} from "react"; import React from "react";
import {connect} from "umi"; import {connect} from "umi";
import styles from './index.less'; import styles from './index.less';
import {BarsOutlined,SettingOutlined,AuditOutlined,ScheduleOutlined,AppstoreOutlined,ApiOutlined,DashboardOutlined, import {} from "@ant-design/icons";
FireOutlined,ClusterOutlined,DatabaseOutlined,FunctionOutlined} from "@ant-design/icons";
import StudioMenu from "./StudioMenu"; import StudioMenu from "./StudioMenu";
import {Row, Col, Card, Empty, Tabs, Form,BackTop} from "antd"; import {Row, Col, Card, Form,BackTop} from "antd";
import StudioTree from "./StudioTree";
import StudioTabs from "./StudioTabs"; import StudioTabs from "./StudioTabs";
import {StateType} from "@/pages/FlinkSqlStudio/model"; import {StateType} from "@/pages/FlinkSqlStudio/model";
import StudioConsole from "./StudioConsole"; import StudioConsole from "./StudioConsole";
import StudioSetting from "./StudioSetting"; import StudioLeftTool from "./StudioLeftTool";
import StudioEdit from "./StudioEdit"; import StudioRightTool from "./StudioRightTool";
import StudioConnector from "./StudioConnector";
import StudioConfig from "./StudioConfig";
const {TabPane} = Tabs;
type StudioProps = { type StudioProps = {
// sql: StateType['sql'];
rightClickMenu:StateType['rightClickMenu']; rightClickMenu:StateType['rightClickMenu'];
dispatch:any; dispatch:any;
}; };
...@@ -29,10 +22,6 @@ const Studio: React.FC<StudioProps> = (props) => { ...@@ -29,10 +22,6 @@ const Studio: React.FC<StudioProps> = (props) => {
const {rightClickMenu,dispatch} = props; const {rightClickMenu,dispatch} = props;
const [form] = Form.useForm(); const [form] = Form.useForm();
/*useEffect(() => {
setSqls(sql);
}, [sql]);*/
const onClick=()=>{ const onClick=()=>{
if(rightClickMenu){ if(rightClickMenu){
dispatch&&dispatch({ dispatch&&dispatch({
...@@ -48,49 +37,14 @@ const Studio: React.FC<StudioProps> = (props) => { ...@@ -48,49 +37,14 @@ const Studio: React.FC<StudioProps> = (props) => {
<Card bordered={false} className={styles.card} size="small" id="studio_card"> <Card bordered={false} className={styles.card} size="small" id="studio_card">
<Row> <Row>
<Col span={4} className={styles["vertical-tabs"]}> <Col span={4} className={styles["vertical-tabs"]}>
<Tabs defaultActiveKey="1" size="small" tabPosition="left" style={{ height: "100%",border: "1px solid #f0f0f0"}}> <StudioLeftTool/>
<TabPane tab={<span><BarsOutlined/> 目录</span>} key="StudioTree" >
<StudioTree/>
</TabPane>
<TabPane tab={<span><DatabaseOutlined /> 数据源</span>} key="DataSource" >
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
</TabPane>
<TabPane tab={<span><AppstoreOutlined /> 元数据</span>} key="MetaData" >
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
</TabPane>
<TabPane tab={<span><ClusterOutlined /> 集群</span>} key="Cluster" >
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
</TabPane>
<TabPane tab={<span><ApiOutlined /> 连接器</span>} key="Connectors" >
<StudioConnector />
</TabPane>
<TabPane tab={<span><FireOutlined /> 任务</span>} key="FlinkTask" >
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
</TabPane>
<TabPane tab={<span><FunctionOutlined /> 函数</span>} key="Function" >
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
</TabPane>
</Tabs>
</Col> </Col>
<Col span={16}> <Col span={16}>
<StudioTabs/> <StudioTabs/>
{/*<StudioConsole/>*/} {/*<StudioConsole/>*/}
</Col> </Col>
<Col span={4} className={styles["vertical-tabs"]}> <Col span={4} className={styles["vertical-tabs"]}>
<Tabs defaultActiveKey="1" size="small" tabPosition="right" style={{ height: "100%",border: "1px solid #f0f0f0"}}> <StudioRightTool/>
<TabPane tab={<span><SettingOutlined /> 作业配置</span>} key="StudioSetting" >
<StudioSetting form={form} />
</TabPane>
<TabPane tab={<span><ScheduleOutlined /> 执行配置</span>} key="StudioConfig" >
<StudioConfig form={form}/>
</TabPane>
<TabPane tab={<span><ScheduleOutlined /> 详情</span>} key="3" >
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
</TabPane>
<TabPane tab={<span><AuditOutlined /> 审计</span>} key="4" >
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
</TabPane>
</Tabs>
</Col> </Col>
</Row> </Row>
<Row> <Row>
......
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