Commit 7ea40843 authored by godkaikai's avatar godkaikai

statement

parent 2cda298f
......@@ -80,6 +80,15 @@ public class ClusterController {
return Result.succeed(cluster,"获取成功");
}
/**
* 获取指定ID的信息
*/
@PostMapping("/listEnabledAll")
public Result listEnabledAll() throws Exception {
List<Cluster >clusters = clusterService.listEnabledAll();
return Result.succeed(clusters,"获取成功");
}
/**
* 全部心跳监测
*/
......
......@@ -31,10 +31,10 @@ public class TaskController {
*/
@PutMapping
public Result saveOrUpdate(@RequestBody Task task) throws Exception {
if(taskService.saveOrUpdate(task)){
return Result.succeed("新增成功");
if(taskService.saveOrUpdateTask(task)){
return Result.succeed("操作成功");
}else {
return Result.failed("新增失败");
return Result.failed("操作失败");
}
}
......
package com.dlink.mapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.dlink.db.mapper.SuperMapper;
import com.dlink.model.Statement;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
/**
* StatementMapper
......@@ -12,4 +14,7 @@ import org.apache.ibatis.annotations.Mapper;
**/
@Mapper
public interface StatementMapper extends SuperMapper<Statement> {
int insert(Statement statement);
}
......@@ -10,4 +10,5 @@ import com.dlink.model.Statement;
* @since 2021/5/28 13:45
**/
public interface StatementService extends ISuperService<Statement> {
boolean insert(Statement statement);
}
......@@ -16,4 +16,6 @@ public interface TaskService extends ISuperService<Task> {
SubmitResult submitByTaskId(Integer id);
Task getTaskInfoById(Integer id);
boolean saveOrUpdateTask(Task task);
}
......@@ -7,6 +7,7 @@ import com.dlink.mapper.CatalogueMapper;
import com.dlink.model.Catalogue;
import com.dlink.model.Task;
import com.dlink.service.CatalogueService;
import com.dlink.service.StatementService;
import com.dlink.service.TaskService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
......@@ -25,6 +26,8 @@ public class CatalogueServiceImpl extends SuperServiceImpl<CatalogueMapper, Cata
@Autowired
private TaskService taskService;
@Autowired
private StatementService statementService;
@Override
public List<Catalogue> getAllData() {
......@@ -37,7 +40,7 @@ public class CatalogueServiceImpl extends SuperServiceImpl<CatalogueMapper, Cata
Task task = new Task();
task.setName(catalogueTaskDTO.getName());
task.setAlias(catalogueTaskDTO.getAlias());
taskService.save(task);
taskService.saveOrUpdateTask(task);
Catalogue catalogue = new Catalogue();
catalogue.setName(catalogueTaskDTO.getAlias());
catalogue.setIsLeaf(true);
......@@ -70,6 +73,7 @@ public class CatalogueServiceImpl extends SuperServiceImpl<CatalogueMapper, Cata
}else{
if(catalogue.getTaskId()!=null) {
taskService.removeById(catalogue.getTaskId());
statementService.removeById(catalogue.getTaskId());
}
this.removeById(id);
return true;
......
......@@ -14,4 +14,12 @@ import org.springframework.stereotype.Service;
**/
@Service
public class StatementServiceImpl extends SuperServiceImpl<StatementMapper, Statement> implements StatementService {
@Override
public boolean insert(Statement statement) {
if(baseMapper.insert(statement)>0){
return true;
}else{
return false;
}
}
}
......@@ -50,13 +50,36 @@ public class TaskServiceImpl extends SuperServiceImpl<TaskMapper, Task> implemen
@Override
public Task getTaskInfoById(Integer id) {
Task task = this.getById(id);
if(task!=null){
if (task != null) {
Statement statement = statementService.getById(id);
if(statement!=null){
if (statement != null) {
task.setStatement(statement.getStatement());
}
}
return task;
}
@Override
public boolean saveOrUpdateTask(Task task) {
if (task.getId() != null) {
this.updateById(task);
if (task.getStatement() != null) {
Statement statement = new Statement();
statement.setId(task.getId());
statement.setStatement(task.getStatement());
statementService.updateById(statement);
}
} else {
this.save(task);
Statement statement = new Statement();
statement.setId(task.getId());
if (task.getStatement() == null) {
task.setStatement("");
}
statement.setStatement(task.getStatement());
statementService.insert(statement);
}
return true;
}
}
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/dlink?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&zeroDateTimeBehavior=convertToNull&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
username: dlink
password: dlink
url: jdbc:mysql://10.1.51.25:3306/dlink?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&zeroDateTimeBehavior=convertToNull&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
username: dfly
password: Dareway@2020
driver-class-name: com.mysql.cj.jdbc.Driver
application:
name: dlink
......
......@@ -11,6 +11,10 @@
id,statement
</sql>
<insert id="insert">
insert into dlink_task_statement (id,statement) values (#{id},#{statement})
</insert>
<select id="selectForProTable" resultType="com.dlink.model.Task">
select
a.*
......
......@@ -67,7 +67,7 @@ export const handleAddOrUpdate = async (url:string,fields: any) => {
return true;
} catch (error) {
hide();
message.error(error);
message.error('出错啦');
return false;
}
};
......
import { Tabs,Empty } from "antd";
import {CodeOutlined, TableOutlined,RadarChartOutlined,CalendarOutlined,FileSearchOutlined} from "@ant-design/icons";
import {CodeOutlined, TableOutlined,RadarChartOutlined,CalendarOutlined,FileSearchOutlined,DesktopOutlined} from "@ant-design/icons";
import {StateType} from "@/pages/FlinkSqlStudio/model";
import {connect} from "umi";
import styles from "./index.less";
......@@ -52,6 +52,17 @@ const StudioConsole = (props:any) => {
>
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
</TabPane>
<TabPane
tab={
<span>
<DesktopOutlined />
进程
</span>
}
key="4"
>
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
</TabPane>
<TabPane
tab={
<span>
......@@ -59,7 +70,7 @@ const StudioConsole = (props:any) => {
历史
</span>
}
key="4"
key="5"
>
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
</TabPane>
......@@ -70,7 +81,7 @@ const StudioConsole = (props:any) => {
文档
</span>
}
key="5"
key="6"
>
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />
</TabPane>
......
......@@ -29,7 +29,8 @@ const FlinkSqlEditor = (props:any) => {
selectOnLineNumbers: true,
renderSideBySide: false,
},
sql=props.catalogue.sql,
sql=props.current.value,
current=props.current,
// sql,
dispatch,
} = props
......@@ -41,7 +42,7 @@ const FlinkSqlEditor = (props:any) => {
const monacoInstance: any = useRef();
const code: any = useRef(sql ? sql : '');
const code: any = useRef(current.sql ? current.sql : '');
// const code: any = useRef(value ? value.formulaContent : '');
const cache: any = useRef(code.current);
......@@ -60,10 +61,6 @@ const FlinkSqlEditor = (props:any) => {
getEditorData: () => cache.current,
}));
const submit = async () => {
await executeSql({statement:cache.current});
};
const handleSetEditorVal = (value: string): void => {
if (!value) return;
// 为所选取的值赋值到编辑器中
......@@ -155,7 +152,7 @@ return (
width={width}
height={height}
language={language}
//value={cache.current}
value={current.value}
options={options}
onChange={onChangeHandle}
theme="vs-dark"
......@@ -167,6 +164,6 @@ return (
export default connect(({ Studio }: { Studio: StateType }) => ({
current: Studio.current,
catalogue: Studio.catalogue,
sql: Studio.sql,
tabs: Studio.tabs,
}))(FlinkSqlEditor);
import styles from "./index.less";
import {Menu, Dropdown, Typography, Row, Col} from "antd";
import {Menu, Dropdown, Tooltip, Row, Col,Popconfirm,Badge} from "antd";
import {PauseCircleTwoTone, CopyTwoTone, DeleteTwoTone,PlayCircleTwoTone,DiffTwoTone,
FileAddTwoTone,FolderOpenTwoTone,SafetyCertificateTwoTone,SaveTwoTone,FlagTwoTone,EnvironmentOutlined} from "@ant-design/icons";
import Space from "antd/es/space";
......@@ -9,6 +9,7 @@ import Breadcrumb from "antd/es/breadcrumb/Breadcrumb";
import {StateType} from "@/pages/FlinkSqlStudio/model";
import {connect} from "umi";
import {useEffect, useState} from "react";
import {handleAddOrUpdate} from "@/components/Common/crud";
const {SubMenu} = Menu;
//<Button shape="circle" icon={<CaretRightOutlined />} />
......@@ -30,11 +31,33 @@ const menu = (
const StudioMenu = (props: any) => {
const {catalogue,currentPath} = props;
const {tabs,current,currentPath,form,dispatch} = props;
const [pathItem, setPathItem] = useState<[]>();
const executeSql = () => {
console.log('获取' + catalogue.sql);
console.log('获取' + current.value);
};
const saveSqlAndSettingToTask = async() => {
const fieldsValue = await form.validateFields();
console.log(fieldsValue);
if(current.task){
let task = {
id:current.key,
statement:current.value,
...fieldsValue
};
dispatch&&dispatch({
type: "Studio/saveTask",
payload: task,
});
/*const success = handleAddOrUpdate('api/task',task);
console.log(success);
console.log(tabs);*/
}else{
}
console.log('获取' + current.value);
};
const runMenu = (
......@@ -43,17 +66,6 @@ const StudioMenu = (props: any) => {
</Menu>
);
/*const getPath = ()=>{
let itemList = [];
for(let item of currentPath){
itemList.push(<Breadcrumb.Item>{item}</Breadcrumb.Item>)
}
setPathItem(itemList);
};
useEffect(() => {
getPath();
}, []);*/
const getPathItem = (paths)=>{
let itemList = [];
for(let item of paths){
......@@ -109,10 +121,13 @@ const StudioMenu = (props: any) => {
type="text"
icon={<FolderOpenTwoTone />}
/>
<Tooltip title="保存当前的 FlinkSql">
<Button
type="text"
icon={<SaveTwoTone />}
onClick={saveSqlAndSettingToTask}
/>
</Tooltip>
<Divider type="vertical" />
<Button
type="text"
......@@ -122,16 +137,30 @@ const StudioMenu = (props: any) => {
type="text"
icon={<FlagTwoTone />}
/>
<Tooltip title="执行当前的 FlinkSql">
<Button
type="text"
icon={<PlayCircleTwoTone />}
//loading={loadings[2]}
//onClick={() => this.enterLoading(2)}
onClick={executeSql}
/>
</Tooltip>
<Popconfirm
title="您确定要停止所有的 FlinkSql 任务吗?"
// onConfirm={confirm}
//onCancel={cancel}
okText="停止"
cancelText="取消"
>
<Tooltip title="停止所有的 FlinkSql 任务">
<Badge size="small" count={1} offset={[-5, 5]}>
<Button
type="text"
icon={<PauseCircleTwoTone />}
/>
</Badge>
</Tooltip>
</Popconfirm>
<Divider type="vertical" />
<Button
type="text"
......@@ -145,7 +174,6 @@ const StudioMenu = (props: any) => {
type="text"
icon={<DeleteTwoTone />}
/>
</Col>
</Row>
</Col>
......@@ -154,6 +182,7 @@ const StudioMenu = (props: any) => {
};
export default connect(({Studio}: { Studio: StateType }) => ({
catalogue: Studio.catalogue,
current: Studio.current,
currentPath: Studio.currentPath,
tabs: Studio.tabs,
}))(StudioMenu);
......@@ -9,8 +9,7 @@ const { Option } = Select;
const StudioSetting = (props: any) => {
const [form] = Form.useForm();
const {cluster} = props;
const {cluster,current,form,dispatch} = props;
const [clusterOption, setClusterOption] = useState<[]>();
......@@ -37,9 +36,9 @@ const StudioSetting = (props: any) => {
form={form}
layout="vertical"
className={styles.form_setting}
initialValues={{}}
initialValues={current.task}
>
<Form.Item label="Flink集群" tooltip="选择Flink集群进行远程提交任务"
<Form.Item label="Flink集群" tooltip="选择Flink集群进行远程提交任务" name="clusterId"
className={styles.form_item}>
<Select
//mode="multiple"
......@@ -55,18 +54,18 @@ const StudioSetting = (props: any) => {
{clusterOption}
</Select>
</Form.Item>
<Form.Item label="CheckPoint" tooltip="设置Flink任务的检查点步长,0 代表不启用"
<Form.Item label="CheckPoint" tooltip="设置Flink任务的检查点步长,0 代表不启用" name="checkPoint"
className={styles.form_item}>
<InputNumber min={0} max={999999} defaultValue={0}/>
</Form.Item>
<Form.Item
label="Parallelism" className={styles.form_item}
label="Parallelism" className={styles.form_item} name="parallelism"
tooltip="设置Flink任务的并行度,最小为 1"
>
<InputNumber min={1} max={9999} defaultValue={1}/>
</Form.Item>
<Form.Item
label="Fragment" className={styles.form_item}
label="Fragment" className={styles.form_item} name="fragment"
tooltip={{ title: '【增强特性】 开启FlinkSql片段机制,使用“:=”进行定义(以“;”结束),“${}”进行调用', icon: <InfoCircleOutlined /> }}
>
<Switch checkedChildren="启用" unCheckedChildren="禁用"
......@@ -74,7 +73,7 @@ const StudioSetting = (props: any) => {
/>
</Form.Item>
<Form.Item
label="SavePointPath" className={styles.form_item}
label="SavePointPath" className={styles.form_item} name="savePointPath"
tooltip='从SavePointPath恢复Flink任务'
>
<Input placeholder="hdfs://..." />
......@@ -85,5 +84,5 @@ const StudioSetting = (props: any) => {
export default connect(({Studio}: { Studio: StateType }) => ({
cluster: Studio.cluster,
sql: Studio.sql,
current: Studio.current,
}))(StudioSetting);
......@@ -6,10 +6,6 @@ import {StateType} from "@/pages/FlinkSqlStudio/model";
const { TabPane } = Tabs;
const initialPanes = [
{ title: '草稿', key: '0' ,value:'select * from ',closable: false,},
];
const EditorTabs = (props: any) => {
const {tabs,dispatch} = props;
const [newTabIndex, setNewTabIndex] = useState<number>(0);
......@@ -18,6 +14,7 @@ const EditorTabs = (props: any) => {
const onChange = (activeKey: any) => {
//setActiveKey(activeKey);
console.log(activeKey);
dispatch({
type: "Studio/changeActiveKey",
payload: activeKey,
......@@ -98,7 +95,6 @@ const EditorTabs = (props: any) => {
export default connect(({ Studio }: { Studio: StateType }) => ({
current: Studio.current,
catalogue: Studio.catalogue,
sql: Studio.sql,
tabs: Studio.tabs,
}))(EditorTabs);
......@@ -92,10 +92,9 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => {
if(node.isLeaf&&node.taskId) {
for(let item of tabs.panes){
if(item.key==node.taskId){
tabs.activeKey = node.taskId;
dispatch({
dispatch&&dispatch({
type: "Studio/changeActiveKey",
payload: tabs.activeKey,
payload: node.taskId,
});
return;
}
......@@ -112,9 +111,12 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => {
};
newTabs.activeKey = node.taskId;
newTabs.panes.push(newPane);
dispatch({
dispatch&&dispatch({
type: "Studio/saveTabs",
payload: newTabs,
payload: {
current:newPane,
tabs:newTabs,
},
});
})
}
......@@ -175,20 +177,33 @@ const StudioTree: React.FC<StudioTreeProps> = (props) => {
const {pageX, pageY} = {...rightClickNodeTreeItem};
const tmpStyle = {
position: 'absolute',
left: `${pageX - 50}px`,
top: `${pageY - 202}px`
// left: `${pageX - 50}px`,
// top: `${pageY - 202}px`,
left: `${pageX - 30}px`,
top: `${pageY - 152}px`,
};
let menuItems;
if(rightClickNode&&rightClickNode.isLeaf){
menuItems=(<>
<Menu.Item key='Open'>{'打开'}</Menu.Item>
<Menu.Item key='Rename'>{'重命名'}</Menu.Item>
<Menu.Item key='Delete'>{'删除'}</Menu.Item>
</>)
}else{
menuItems=(<>
<Menu.Item key='CreateCatalogue'>{'创建目录'}</Menu.Item>
<Menu.Item key='CreateTask'>{'创建作业'}</Menu.Item>
<Menu.Item key='Rename'>{'重命名'}</Menu.Item>
<Menu.Item key='Delete'>{'删除'}</Menu.Item>
</>)
}
const menu = (
<Menu
onClick={({key}) => handleMenuClick(key)}
style={tmpStyle}
className={style.right_click_menu}
>
<Menu.Item key='Open'>{'打开'}</Menu.Item>
<Menu.Item key='CreateCatalogue'>{'创建目录'}</Menu.Item>
<Menu.Item key='CreateTask'>{'创建作业'}</Menu.Item>
<Menu.Item key='Rename'>{'重命名'}</Menu.Item>
<Menu.Item key='Delete'>{'删除'}</Menu.Item>
{menuItems}
</Menu>
);
return (rightClickNodeTreeItem == null) ? '' : menu;
......
......@@ -4,7 +4,7 @@ import styles from './index.less';
import {BarsOutlined,SettingOutlined} from "@ant-design/icons";
import StudioMenu from "./StudioMenu";
import {Row, Col, Card, Empty, Tabs} from "antd";
import {Row, Col, Card, Empty, Tabs, Form} from "antd";
import StudioTree from "./StudioTree";
import StudioTabs from "./StudioTabs";
import {StateType} from "@/pages/FlinkSqlStudio/model";
......@@ -21,6 +21,7 @@ const Studio: React.FC<StudioProps> = ({sql}) => {
const [console, setConsole] = useState<boolean>(false);
const [sqls, setSqls] = useState<String>();
const [form] = Form.useForm();
useEffect(() => {
setSqls(sql);
......@@ -28,7 +29,7 @@ const Studio: React.FC<StudioProps> = ({sql}) => {
return (
<div>
<StudioMenu/>
<StudioMenu form={form}/>
<Card bordered={false} className={styles.card} size="small">
<Row>
<Col span={4}>
......@@ -46,7 +47,7 @@ const Studio: React.FC<StudioProps> = ({sql}) => {
<Col span={4}>
<Tabs defaultActiveKey="1" size="small">
<TabPane tab={<span><SettingOutlined />配置</span>} key="1" >
<StudioSetting />
<StudioSetting form={form} />
</TabPane>
</Tabs>
</Col>
......
import {Effect, Reducer} from "umi";
import {executeSql} from "./service";
import {message} from "antd";
import {getInfoById, handleInfo, queryData, removeData} from "@/components/Common/crud";
export type CatalogueType = {
id?: number;
taskId?: number;
sql?: string;
clusterId?: number;
}
import {addOrUpdateData, handleAddOrUpdate, postAll, queryData} from "@/components/Common/crud";
import {Form} from "antd";
export type ClusterType = {
id: number,
......@@ -57,9 +50,8 @@ export type TabsType = {
}
export type StateType = {
current?: number;
cluster?:ClusterType[];
catalogue: CatalogueType[];
current: TabsItemType;
sql?: string;
currentPath?: string[];
tabs:TabsType;
......@@ -69,17 +61,26 @@ export type ModelType = {
namespace: string;
state: StateType;
effects: {
executeSql: Effect;
saveTask: Effect;
};
reducers: {
saveSql: Reducer<StateType>;
saveCurrentPath: Reducer<StateType>;
saveTabs: Reducer<StateType>;
changeActiveKey: Reducer<StateType>;
saveTaskData: Reducer<StateType>;
};
};
const getClusters = async () => {
try {
const msg = await queryData('api/cluster');
return msg.data;
const msg = await postAll('api/cluster/listEnabledAll');
let data:any= [];
msg.then(value=>{
data = value.datas;
});
console.log(data);
return data;
} catch (error) {
console.error('获取Flink集群失败');
return [];
......@@ -90,11 +91,13 @@ const getClusters = async () => {
const Model: ModelType = {
namespace: 'Studio',
state: {
current: 0,
cluster:getClusters(),
catalogue: [{
sql: '',
}],
current: {
title: '草稿',
key: 0 ,
value:'',
closable: false,
},
sql: '',
currentPath: [],
tabs:{
......@@ -105,35 +108,37 @@ const Model: ModelType = {
value:'',
closable: false,
}],
}
},
},
effects: {
*executeSql({ payload }, { call, put }) {
yield call(executeSql, payload);
*saveTask({ payload }, { call, put }) {
yield call(handleAddOrUpdate,'api/task', payload);
yield put({
type: 'saveStepFormData',
type: 'saveTaskData',
payload,
});
yield put({
type: 'saveCurrentStep',
payload: 'result',
});
},
},
reducers: {
saveSql(state, { payload }) {
const catalogues = state.catalogue;
for(let i=0;i<catalogues.length;i++){
if(catalogues[i].id==payload.id){
catalogues[i].sql=payload.sql;
const tabs = state.tabs;
let newCurrent = state.current;
newCurrent.value=payload;
for(let i=0;i<tabs.panes.length;i++){
if(tabs.panes[i].key==tabs.activeKey){
tabs.panes[i].value=payload;
tabs.panes[i].task&&(tabs.panes[i].task.statement=payload);
}
}
return {
...state,
catalogue:{
...catalogues
current:{
...newCurrent
},
tabs:{
...tabs
},
};
},
......@@ -144,23 +149,57 @@ const Model: ModelType = {
};
},
saveTabs(state, { payload }) {
/*let newCurrent = state.current;
for(let i=0;i<payload.tabs.panes.length;i++){
if(payload.tabs.panes[i].key==payload.tabs.activeKey){
newCurrent=payload.tabs.panes[i];
}
}*/
return {
...state,
current:{
...payload.current,
},
tabs:{
...payload
...payload.tabs,
},
};
},
changeActiveKey(state, { payload }) {
let tabs = state.tabs;
tabs.activeKey = payload;
let newCurrent = state.current;
for(let i=0;i<tabs.panes.length;i++){
if(tabs.panes[i].key==tabs.activeKey){
newCurrent=tabs.panes[i];
}
}
return {
...state,
current:{
...newCurrent,
},
tabs:{
...tabs,
},
};
},
saveTaskData(state, { payload }) {
let newTabs = state.tabs;
for(let i=0;i<newTabs.panes.length;i++){
if(newTabs.panes[i].key==newTabs.activeKey){
newTabs.panes[i]={
...payload
};
}
}
return {
...state,
tabs:{
...newTabs,
},
};
},
},
};
......
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