Browse Source

feat: 任务管理列表

Leo 2 years ago
parent
commit
e7d066e003

+ 3 - 3
src/index.css

@@ -1,3 +1,3 @@
-/* section {
-  height: 100vh;
-} */
+body {
+  background-color: #f0f2f5 !important;
+}

+ 81 - 89
src/module/tasklog/component/LogTable.jsx

@@ -1,29 +1,27 @@
-import { Button, Form, Input, Popconfirm, Table } from 'antd';
-import React, { useContext, useEffect, useRef, useState } from 'react';
+import { Button, Form, Input, Popconfirm, Table } from 'antd'
+import React, { useContext, useEffect, useRef, useState } from 'react'
 import styled from 'styled-components'
-import { Link } from 'react-router-dom';
-const EditableContext = React.createContext(null);
+import { Link } from 'react-router-dom'
+const EditableContext = React.createContext(null)
 const FormItem = Form.Item
 
 const LogTable = styled.div`
-background-color: #FFFFFF;
-height: 960px;
-margin-left: 24px;
-.delButton {
-  margin-left: 40px;
-}
+  margin-left: 24px;
+  .delButton {
+    margin-left: 40px;
+  }
 `
 
 const EditableRow = ({ index, ...props }) => {
-  const [form] = Form.useForm();
+  const [form] = Form.useForm()
   return (
     <Form form={form} component={false}>
       <EditableContext.Provider value={form}>
         <tr {...props} />
       </EditableContext.Provider>
     </Form>
-  );
-};
+  )
+}
 
 const EditableCell = ({
   title,
@@ -34,33 +32,33 @@ const EditableCell = ({
   handleSave,
   ...restProps
 }) => {
-  const [editing, setEditing] = useState(false);
-  const inputRef = useRef(null);
-  const form = useContext(EditableContext);
+  const [editing, setEditing] = useState(false)
+  const inputRef = useRef(null)
+  const form = useContext(EditableContext)
   useEffect(() => {
     if (editing) {
-      inputRef.current.focus();
+      inputRef.current.focus()
     }
-  }, [editing]);
+  }, [editing])
 
   const toggleEdit = () => {
-    setEditing(!editing);
+    setEditing(!editing)
     form.setFieldsValue({
       [dataIndex]: record[dataIndex],
-    });
-  };
+    })
+  }
 
   const save = async () => {
     try {
-      const values = await form.validateFields();
-      toggleEdit();
-      handleSave({ ...record, ...values });
+      const values = await form.validateFields()
+      toggleEdit()
+      handleSave({ ...record, ...values })
     } catch (errInfo) {
-      console.log('Save failed:', errInfo);
+      console.log('Save failed:', errInfo)
     }
-  };
+  }
 
-  let childNode = children;
+  let childNode = children
 
   if (editable) {
     childNode = editing ? (
@@ -74,8 +72,7 @@ const EditableCell = ({
             required: true,
             message: `${title} is required.`,
           },
-        ]}
-      >
+        ]}>
         <Input ref={inputRef} onPressEnter={save} onBlur={save} />
       </FormItem>
     ) : (
@@ -84,15 +81,14 @@ const EditableCell = ({
         style={{
           paddingRight: 24,
         }}
-        onClick={toggleEdit}
-      >
+        onClick={toggleEdit}>
         {children}
       </div>
-    );
+    )
   }
 
-  return <td {...restProps}>{childNode}</td>;
-};
+  return <td {...restProps}>{childNode}</td>
+}
 
 export default function LogItems() {
   const itemData = [
@@ -111,34 +107,35 @@ export default function LogItems() {
       sort: '业务预测',
       creTime: '2022.8.18 12:00:00',
       updTime: '2022.8.18 12:00:00',
-    }
-  ];
-  const [dataSource, setDataSource] = useState(itemData
-  //   [
-  //   {
-  //     key: '0',
-  //     name: '每日供应商销量预测作业2',
-  //     type: 'java',
-  //     sort: '业务预测',
-  //     creTime: '2022.8.18 12:00:00',
-  //     updTime: '2022.8.18 12:00:00',
-  //   },
-  //   {
-  //     key: '1',
-  //     name: '每日供应商销量预测作业21',
-  //     type: 'java',
-  //     sort: '业务预测',
-  //     creTime: '2022.8.18 12:00:00',
-  //     updTime: '2022.8.18 12:00:00',
-  //   },
-  // ]
-  );
-  const [count, setCount] = useState(2);
-
-  const handleDelete = (key) => {
-    const newData = dataSource.filter((item) => item.key !== key);
-    setDataSource(newData);
-  };
+    },
+  ]
+  const [dataSource, setDataSource] = useState(
+    itemData
+    //   [
+    //   {
+    //     key: '0',
+    //     name: '每日供应商销量预测作业2',
+    //     type: 'java',
+    //     sort: '业务预测',
+    //     creTime: '2022.8.18 12:00:00',
+    //     updTime: '2022.8.18 12:00:00',
+    //   },
+    //   {
+    //     key: '1',
+    //     name: '每日供应商销量预测作业21',
+    //     type: 'java',
+    //     sort: '业务预测',
+    //     creTime: '2022.8.18 12:00:00',
+    //     updTime: '2022.8.18 12:00:00',
+    //   },
+    // ]
+  )
+  const [count, setCount] = useState(2)
+
+  const handleDelete = key => {
+    const newData = dataSource.filter(item => item.key !== key)
+    setDataSource(newData)
+  }
 
   const defaultColumns = [
     {
@@ -155,19 +152,16 @@ export default function LogItems() {
       title: '作业分类',
       dataIndex: 'sort',
       width: '16.6%',
-
     },
     {
       title: '创建时间',
       dataIndex: 'creTime',
       width: '16.6%',
-
     },
     {
       title: '更新时间',
       dataIndex: 'updTime',
       width: '16.6%',
-
     },
     {
       title: '操作',
@@ -177,51 +171,49 @@ export default function LogItems() {
       render: (_, record) =>
         dataSource.length >= 1 ? (
           <>
-            <Popconfirm >
+            <Popconfirm>
               <a>编辑</a>
             </Popconfirm>
-            <Popconfirm 
-            title="Sure to delete?" 
-            onConfirm={() => handleDelete(record.key)}
-            >
-              <a className='delButton'>删除</a>
+            <Popconfirm
+              title="Sure to delete?"
+              onConfirm={() => handleDelete(record.key)}>
+              <a className="delButton">删除</a>
             </Popconfirm>
           </>
         ) : null,
-          
     },
-  ];
-
-  const handleSave = (row) => {
-    const newData = [...dataSource];
-    const index = newData.findIndex((item) => row.key === item.key);
-    const item = newData[index];
-    newData.splice(index, 1, { ...item, ...row });
-    setDataSource(newData);
-  };
+  ]
+
+  const handleSave = row => {
+    const newData = [...dataSource]
+    const index = newData.findIndex(item => row.key === item.key)
+    const item = newData[index]
+    newData.splice(index, 1, { ...item, ...row })
+    setDataSource(newData)
+  }
 
   const components = {
     body: {
       row: EditableRow,
       cell: EditableCell,
     },
-  };
-  const columns = defaultColumns.map((col) => {
+  }
+  const columns = defaultColumns.map(col => {
     if (!col.editable) {
-      return col;
+      return col
     }
 
     return {
       ...col,
-      onCell: (record) => ({
+      onCell: record => ({
         record,
         editable: col.editable,
         dataIndex: col.dataIndex,
         title: col.title,
         handleSave,
       }),
-    };
-  });
+    }
+  })
   return (
     <LogTable>
       <Table
@@ -235,5 +227,5 @@ export default function LogItems() {
         }}
       />
     </LogTable>
-  );
-};
+  )
+}

+ 7 - 23
src/module/tasklog/page/TaskLog.jsx

@@ -1,28 +1,12 @@
-import React from 'react';
+import React from 'react'
 import styled from 'styled-components'
 import LogTable from '../component/LogTable'
 const TSLog = styled.div``
 
-export default function TaskLog() {  
-      document.body.style.background = '#F0F2F5'
-      return (
-        <TSLog>
-          <div>
-          <header  style={{ 
-          height: '40px', 
-          fontSize: '14px',
-          paddingLeft: '24px',
-          lineHeight: '40px',
-          backgroundColor: 'white',
-          marginBottom: '16px',
-          }}>
-          <span>
-            任务日志
-          </span>
-          </header>
-          </div>
-          <LogTable/>
-        </TSLog>
-    )
+export default function TaskLog() {
+  return (
+    <TSLog>
+      <LogTable />
+    </TSLog>
+  )
 }
-  

+ 7 - 0
src/module/taskmgmt/component/TaskCreaterView.jsx

@@ -0,0 +1,7 @@
+import React from 'react'
+
+const TaskCreaterView = () => {
+  return <div>11</div>
+}
+
+export default TaskCreaterView

+ 134 - 5
src/module/taskmgmt/page/TaskMgmtView.jsx

@@ -1,8 +1,46 @@
-import React from 'react'
-import { Table, Space } from 'antd'
-import { useNavigate } from 'react-router-dom'
+import React, { useState } from 'react'
+import { Table, Switch, Space, Button } from 'antd'
+import { Link } from 'react-router-dom'
+import styled from 'styled-components'
+import errImgUrl from '../style/img/err.png'
+import successImgUrl from '../style/img/success.png'
+
+const TaskMgmtWrapper = styled.div`
+  padding: 20px;
+  .icon_wrapper {
+    margin-right: 15px;
+  }
+  .link_btn {
+    display: flex;
+    justify-content: end;
+    margin-bottom: 20px;
+  }
+`
+const data = [
+  {
+    key: 1,
+    taskName: '每日供应商销量预测任务',
+    taskType: '单作业离线任务',
+    taskTag: '业务预测',
+    executionCycle: '循环触发,1小时',
+    historicalRuntime: [1, 0, 1, 1, 1, 1, 1, 0, 0, 1],
+    taskState: false,
+  },
+  {
+    key: 2,
+    taskName: 'AI平台算法服务定时监测',
+    taskType: '多作业离线任务',
+    taskTag: '任务监测',
+    executionCycle: '循环触发6小时',
+    historicalRuntime: [1, 1, 1, 0, 0, 1],
+    taskState: true,
+  },
+]
 
 const TaskMgmtView = () => {
+  // 表格Loading状态
+  const [dataLoading, setDataLoading] = useState(false)
+
   const columns = [
     {
       title: '任务名称',
@@ -31,13 +69,104 @@ const TaskMgmtView = () => {
       render: list => (
         <div>
           {list.map((item, index) => {
-            return <img src={item} alt="" />
+            return (
+              <img
+                key={index}
+                src={item === 0 ? errImgUrl : successImgUrl}
+                alt=""
+                className="icon_wrapper"
+              />
+            )
           })}
         </div>
       ),
     },
+    {
+      title: '状态',
+      dataIndex: 'taskState',
+      key: 'taskState',
+      render: val => (
+        <Switch
+          checkedChildren="开启"
+          unCheckedChildren="关闭"
+          defaultChecked={val}
+          onChange={changeTaskState}
+        />
+      ),
+    },
+    {
+      title: '操作',
+      key: 'operation',
+      render: (_, record) => (
+        <Space size="middle">
+          <span
+            onClick={() => {
+              runTimeOnce(record.key)
+            }}
+            style={{ color: '#1881DA', cursor: 'pointer' }}>
+            执行一次
+          </span>
+          <span
+            onClick={() => {
+              editTask(record.key)
+            }}
+            style={{ color: '#1881DA', cursor: 'pointer' }}>
+            编辑
+          </span>
+          <span
+            onClick={() => {
+              deleteTask(record.key)
+            }}
+            style={{ color: '#1881DA', cursor: 'pointer' }}>
+            删除
+          </span>
+          <span
+            onClick={() => {
+              getApiUri(record.key)
+            }}
+            style={{ color: '#1881DA', cursor: 'pointer' }}>
+            API调用
+          </span>
+        </Space>
+      ),
+    },
   ]
-  return <div></div>
+  // 切换状态
+  const changeTaskState = checked => {
+    console.log(checked)
+  }
+  //执行
+  const runTimeOnce = id => {
+    console.log('runtime', id)
+  }
+  //删除
+  const deleteTask = id => {
+    console.log('delete', id)
+  }
+  //Api调用
+  const getApiUri = id => {
+    console.log('api', id)
+  }
+  //编辑
+  const editTask = id => {
+    console.log('edit', id)
+  }
+
+  return (
+    <TaskMgmtWrapper>
+      <div className="link_btn">
+        <Link to="/task-mgmt/create-task">
+          <Button type="primary">创建离线任务</Button>
+        </Link>
+      </div>
+      <Table
+        columns={columns}
+        dataSource={data}
+        bordered
+        loading={dataLoading}
+      />
+    </TaskMgmtWrapper>
+  )
 }
 
 export default TaskMgmtView

+ 0 - 0
src/module/datasource/style/img/err.png → src/module/taskmgmt/style/img/err.png


+ 0 - 0
src/module/datasource/style/img/success.png → src/module/taskmgmt/style/img/success.png


+ 327 - 365
src/module/workmgmt/component/JobCreate.jsx

@@ -1,16 +1,24 @@
-import { Button, Form, Input, Select, Radio, Space, Upload, Steps, message } from 'antd';
-import type { RadioChangeEvent } from 'antd';
-import type { UploadProps } from 'antd';
-import { UploadOutlined } from '@ant-design/icons';
-import React, { useState , Component, useEffect } from 'react';
-import styled from 'styled-components';
-import JobStepOne from './JobStepOne';
-import JobStepTwo from './JobStepTwo';
+import {
+  Button,
+  Form,
+  Input,
+  Select,
+  Radio,
+  Space,
+  Upload,
+  Steps,
+  message,
+} from 'antd'
+import type { RadioChangeEvent } from 'antd'
+import type { UploadProps } from 'antd'
+import { UploadOutlined } from '@ant-design/icons'
+import React, { useState, Component, useEffect } from 'react'
+import styled from 'styled-components'
+import JobStepOne from './JobStepOne'
+import JobStepTwo from './JobStepTwo'
 
 const JobCre = styled.div``
 const CreContent = styled.div`
-  background-color: #FFFFFF;
-  height: 960px;
   margin-left: 24px;
   .ant-form {
     display: flex;
@@ -19,7 +27,6 @@ const CreContent = styled.div`
     justify-content: center;
     flex-wrap: wrap;
     align-items: stretch;
-    
   }
   .creTitle {
     width: 120px;
@@ -27,7 +34,7 @@ const CreContent = styled.div`
     margin-left: 15px;
     display: flex;
   }
-  .bluetTitle { 
+  .bluetTitle {
     background-color: rgba(24, 129, 218, 1);
     width: 3px;
     height: 16px;
@@ -36,7 +43,7 @@ const CreContent = styled.div`
   }
   .creText {
     width: 105px;
-    height: 20px;    
+    height: 20px;
     margin-left: 10px;
     overflow-wrap: break-word;
     color: rgba(74, 74, 74, 1);
@@ -51,43 +58,43 @@ const CreContent = styled.div`
     top: 36%;
     padding-left: 7px;
     height: 20px;
-    border-left: 1px solid
+    border-left: 1px solid;
   }
   .ant-col {
     flex: unset;
   }
-   
+
   .ant-select {
     width: 295px;
     height: 32px;
   }
   .ant-form-item-control-input {
-    width:295px;
+    width: 295px;
   }
   .ant-row {
     margin-left: 60px;
   }
   .JsPyInfo {
-    width:464px;
+    width: 464px;
     .ant-form {
       align-content: end;
     }
     .choseJs {
       .ant-row {
         margin-left: 43px;
-      },
+      }
+      ,
       .ant-form-item-control-input {
-      left: 11px;
-    }
-    .upButton {
-      width: 88px;
-      height: 32px;
-      margin-left: 7px;
-      background-color: #4883FB;
-      color: white;
-    }
+        left: 11px;
+      }
+      .upButton {
+        width: 88px;
+        height: 32px;
+        margin-left: 7px;
+        background-color: #4883fb;
+        color: white;
+      }
     }
-    
   }
   .mirrorLeft {
     margin-left: -25px;
@@ -110,14 +117,14 @@ const CreContent = styled.div`
       margin-left: 67px;
     }
     .ant-steps-label-vertical .ant-steps-item-content {
-      width:220px
+      width: 220px;
     }
   }
-  `
+`
 
-const { Option } = Select;
+const { Option } = Select
 const FormItem = Form.Item
-const RadioGroup = Radio.Group;
+const RadioGroup = Radio.Group
 
 const layout = {
   labelCol: {
@@ -126,30 +133,28 @@ const layout = {
   wrapperCol: {
     span: 16,
   },
-};
+}
 const tailLayout = {
   wrapperCol: {
     offset: 8,
     span: 16,
   },
-};
-export default function JobCreate () {
-  // 设置背景颜色
-  document.body.style.background = '#F0F2F5'
-  const [form] = Form.useForm();
-  const { Step } = Steps 
-  
+}
+export default function JobCreate() {
+  const [form] = Form.useForm()
+  const { Step } = Steps
+
   // 显示/隐藏配置Js作业信息模块
-  const [JsIsShow,setJsIsShow]=useState('none')
+  const [JsIsShow, setJsIsShow] = useState('none')
 
   // 显示/隐藏配置Python作业信息模块
-  const [PyIsShow,setPyIsShow]=useState('none')
+  const [PyIsShow, setPyIsShow] = useState('none')
 
   // 显示/隐藏配置Dag作业信息模块
-  const [DagIsShow,setDagIsShow]=useState('none')
+  const [DagIsShow, setDagIsShow] = useState('none')
 
   // 单选框动态传值
-  const [value, setValue] = useState(1);
+  const [value, setValue] = useState(1)
 
   // 步骤数
   const [currentStep, setCurrentStep] = useState(0)
@@ -159,11 +164,11 @@ export default function JobCreate () {
   const [currentForm, setCurrentForm] = useState(drawDataForm)
 
   // 设置单选框value值
-  const onChange = (e) => {
-    console.log('radio checked', e.target.value);
-    setValue(e.target.value);
-  };
-  
+  const onChange = e => {
+    console.log('radio checked', e.target.value)
+    setValue(e.target.value)
+  }
+
   //上传文件配置
   const UpProps: UploadProps = {
     name: 'file',
@@ -175,29 +180,27 @@ export default function JobCreate () {
     // 上传文件提交状态
     onChange(info) {
       if (info.file.status !== 'uploading') {
-        console.log(info.file, info.fileList);
+        console.log(info.file, info.fileList)
       }
       if (info.file.status === 'done') {
-        message.success(`${info.file.name} file uploaded successfully`);
+        message.success(`${info.file.name} file uploaded successfully`)
       } else if (info.file.status === 'error') {
-        message.error(`${info.file.name} file upload failed.`);
+        message.error(`${info.file.name} file upload failed.`)
       }
     },
-  };
+  }
 
   //根据作业类型做出判断
-  const onGenderChange = (value) => {
-    if (value === "Java") {
+  const onGenderChange = value => {
+    if (value === 'Java') {
       setJsIsShow('block')
       setDagIsShow('none')
-      setPyIsShow('none') 
-    }
-    else if (value === "Python") {
+      setPyIsShow('none')
+    } else if (value === 'Python') {
       setJsIsShow('none')
       setDagIsShow('none')
-      setPyIsShow('block') 
-    }
-    else if (value === "Dag") {
+      setPyIsShow('block')
+    } else if (value === 'Dag') {
       setJsIsShow('none')
       setDagIsShow('block')
       setPyIsShow('none')
@@ -211,7 +214,7 @@ export default function JobCreate () {
 
   //下一步
   const nextStep = () => {
-  changeStep(1)
+    changeStep(1)
   }
 
   useEffect(() => {
@@ -222,315 +225,274 @@ export default function JobCreate () {
         break
       default:
         break
-   
-
-
-
-    }},[currentStep])
+    }
+  }, [currentStep])
   return (
     <JobCre>
-      <div>
-        <header  style={{ 
-        height: '40px', 
-        fontSize: '14px',
-        paddingLeft: '24px',
-        lineHeight: '40px',
-        backgroundColor: 'white',
-        marginBottom: '16px',
-        }}>
-          <span>
-            作业列表
-          </span>
-        </header>
-      </div>
-    <CreContent>
-    <div className="choseJob">
-      <div className='creTitle'>
-        <div className='bluetTitle' />
-        <span className='creText'>配置作业类型</span>
-      </div>
-
-      {/* 作业类型选择       */}
-      <Form {...layout} form={form} name="control-hooks" >
-      <FormItem
-        name="type
+      <CreContent>
+        <div className="choseJob">
+          <div className="creTitle">
+            <div className="bluetTitle" />
+            <span className="creText">配置作业类型</span>
+          </div>
+
+          {/* 作业类型选择       */}
+          <Form {...layout} form={form} name="control-hooks">
+            <FormItem
+              name="type
         "
-        label="选择作业类型"
-        rules={[
-          {
-            required: true,
-          },
-        ]}
-      >
-        <Select
-          placeholder="请选择作业类型..."
-          onChange={onGenderChange}
-          allowClear
-          value = {value}
-        >
-          <Option value="Java">Java</Option>
-          <Option value="Python">Python</Option>
-          <Option value="Dag">Dag</Option>
-        </Select>
-      </FormItem>
-    </Form>   
-    </div>
-    <div className="DagInfo" style={{display: DagIsShow}}>
-      <Steps labelPlacement="vertical" size="small" current={currentStep}>
-        <Step title="步骤1: 配置作业信息" />
-        <Step title="步骤2: 定义输入数据源" />
-        <Step title="步骤3: 定义输出数据源" />
-      </Steps>
-      <div className='creTitle'>
-        <div className='bluetTitle' />
-        <span className='creText'>配置作业信息</span>
-      </div>  
-
-      {/* 配置Dag作业信息 */}
-
-      {/* 第一步 */}
-      {currentStep === 0 && (
-        <JobStepOne
-          drawDataForm={drawDataForm}
-        />
-      )}
-
-      {/* 第二步 */}
-      {currentStep === 1 && (
-        <JobStepTwo/>
-      )}
-
-    <Space style={{ margin: '20px' }}>
-      <Button onClick={() => {changeStep(-1)}}>上一步</Button>
-      <Button type="primary" onClick={nextStep}>下一步</Button>
-    </Space>
-    </div>
-    
-
-    {/* 配置Js作业信息 */}
-    <div className="JsPyInfo" style={{display: JsIsShow}}>
-      <div className='creTitle'>
-        <div className='bluetTitle' />
-        <span className='creText'>配置作业信息</span>
-      </div>  
-
-      {/* 输入作业名称 */}
-      <Form {...layout} form={form} name="control-hooks" >
-      <FormItem
-        name="JsJobName
+              label="选择作业类型"
+              rules={[
+                {
+                  required: true,
+                },
+              ]}>
+              <Select
+                placeholder="请选择作业类型..."
+                onChange={onGenderChange}
+                allowClear
+                value={value}>
+                <Option value="Java">Java</Option>
+                <Option value="Python">Python</Option>
+                <Option value="Dag">Dag</Option>
+              </Select>
+            </FormItem>
+          </Form>
+        </div>
+        <div className="DagInfo" style={{ display: DagIsShow }}>
+          <Steps labelPlacement="vertical" size="small" current={currentStep}>
+            <Step title="步骤1: 配置作业信息" />
+            <Step title="步骤2: 定义输入数据源" />
+            <Step title="步骤3: 定义输出数据源" />
+          </Steps>
+          <div className="creTitle">
+            <div className="bluetTitle" />
+            <span className="creText">配置作业信息</span>
+          </div>
+
+          {/* 配置Dag作业信息 */}
+
+          {/* 第一步 */}
+          {currentStep === 0 && <JobStepOne drawDataForm={drawDataForm} />}
+
+          {/* 第二步 */}
+          {currentStep === 1 && <JobStepTwo />}
+
+          <Space style={{ margin: '20px' }}>
+            <Button
+              onClick={() => {
+                changeStep(-1)
+              }}>
+              上一步
+            </Button>
+            <Button type="primary" onClick={nextStep}>
+              下一步
+            </Button>
+          </Space>
+        </div>
+
+        {/* 配置Js作业信息 */}
+        <div className="JsPyInfo" style={{ display: JsIsShow }}>
+          <div className="creTitle">
+            <div className="bluetTitle" />
+            <span className="creText">配置作业信息</span>
+          </div>
+
+          {/* 输入作业名称 */}
+          <Form {...layout} form={form} name="control-hooks">
+            <FormItem
+              name="JsJobName
         "
-        label="作业名称"
-        rules={[
-          {
-            required: true,
-          },
-        ]}
-      >
-        <Input
-          placeholder="请输入作业名称..."
-          allowClear
-        >
-        </Input>
-      </FormItem>
-    </Form>  
-
-    {/* 选择作业分类 */}
-    <Form {...layout} form={form} name="control-hooks">
-      <FormItem
-        name="JsJobSort
+              label="作业名称"
+              rules={[
+                {
+                  required: true,
+                },
+              ]}>
+              <Input placeholder="请输入作业名称..." allowClear></Input>
+            </FormItem>
+          </Form>
+
+          {/* 选择作业分类 */}
+          <Form {...layout} form={form} name="control-hooks">
+            <FormItem
+              name="JsJobSort
         "
-        label="作业分类"
-        rules={[
-          {
-            required: true,
-          },
-        ]}
-      >
-        <Select
-          placeholder="请选择作业分类..."
-          allowClear
-        >
-          <Option value="Java">Java</Option>
-          <Option value="Python">Python</Option>
-          <Option value="Dag">Dag</Option>
-        </Select>
-      </FormItem>
-    </Form>  
-
-    {/* 选择执行镜像 */}
-    <Form {...layout} form={form} name="control-hooks">
-      <FormItem
-        className='mirrorLeft'
-        name="JsMirror
+              label="作业分类"
+              rules={[
+                {
+                  required: true,
+                },
+              ]}>
+              <Select placeholder="请选择作业分类..." allowClear>
+                <Option value="Java">Java</Option>
+                <Option value="Python">Python</Option>
+                <Option value="Dag">Dag</Option>
+              </Select>
+            </FormItem>
+          </Form>
+
+          {/* 选择执行镜像 */}
+          <Form {...layout} form={form} name="control-hooks">
+            <FormItem
+              className="mirrorLeft"
+              name="JsMirror
         "
-        label="配置执行的镜像"
-        rules={[
-          {
-            required: true,
-          },
-        ]}
-      >
-        <Select
-          placeholder="请选择镜像..."
-          allowClear
-        >
-          <Option value="Java">Java</Option>
-          <Option value="Python">Python</Option>
-          <Option value="Dag">Dag</Option>
-        </Select>
-      </FormItem>
-    </Form>
-
-    {/* 选择执行的Java脚本 */}
-    <Form {...layout} form={form} name="control-hooks" className='choseJs'>
-      <FormItem
-        className='mirrorLeft'
-        label="配置执行的Java脚本"
-        name="JsScripter"
-        rules={[
-          {
-            required: true,
-          },
-        ]}
-      >
-      <RadioGroup onChange={onChange} value={value}>
-      <Space direction="vertical" className='jsSel'>
-        <Radio value={1}>
-        <Select
-          placeholder="在工作目录中选择"
-          allowClear
-          className='javaSelect'
-          disabled={value === 1 ? false : true}
-        >
-          <Option value="Java">Java</Option>
-          <Option value="Python">Python</Option>
-          <Option value="Dag">Dag</Option>
-        </Select>
-        </Radio>
-        
-        <Radio value={4}>
-          <Upload {...UpProps}>
-            <Button  className='upButton'>本地上传</Button>
-          </Upload>
-        </Radio>
-      </Space>
-    </RadioGroup>
-      </FormItem>
-    </Form>
-    </div>
-    
-    {/* 配置Python作业信息 */}
-    <div className="JsPyInfo" style={{display: PyIsShow}}>
-      <div className='creTitle'>
-        <div className='bluetTitle' />
-        <span className='creText'>配置作业信息</span>
-      </div>  
-
-      {/* 输入作业名称 */}
-      <Form {...layout} form={form} name="control-hooks" >
-      <FormItem
-        name="PyJobName
+              label="配置执行的镜像"
+              rules={[
+                {
+                  required: true,
+                },
+              ]}>
+              <Select placeholder="请选择镜像..." allowClear>
+                <Option value="Java">Java</Option>
+                <Option value="Python">Python</Option>
+                <Option value="Dag">Dag</Option>
+              </Select>
+            </FormItem>
+          </Form>
+
+          {/* 选择执行的Java脚本 */}
+          <Form
+            {...layout}
+            form={form}
+            name="control-hooks"
+            className="choseJs">
+            <FormItem
+              className="mirrorLeft"
+              label="配置执行的Java脚本"
+              name="JsScripter"
+              rules={[
+                {
+                  required: true,
+                },
+              ]}>
+              <RadioGroup onChange={onChange} value={value}>
+                <Space direction="vertical" className="jsSel">
+                  <Radio value={1}>
+                    <Select
+                      placeholder="在工作目录中选择"
+                      allowClear
+                      className="javaSelect"
+                      disabled={value === 1 ? false : true}>
+                      <Option value="Java">Java</Option>
+                      <Option value="Python">Python</Option>
+                      <Option value="Dag">Dag</Option>
+                    </Select>
+                  </Radio>
+
+                  <Radio value={4}>
+                    <Upload {...UpProps}>
+                      <Button className="upButton">本地上传</Button>
+                    </Upload>
+                  </Radio>
+                </Space>
+              </RadioGroup>
+            </FormItem>
+          </Form>
+        </div>
+
+        {/* 配置Python作业信息 */}
+        <div className="JsPyInfo" style={{ display: PyIsShow }}>
+          <div className="creTitle">
+            <div className="bluetTitle" />
+            <span className="creText">配置作业信息</span>
+          </div>
+
+          {/* 输入作业名称 */}
+          <Form {...layout} form={form} name="control-hooks">
+            <FormItem
+              name="PyJobName
         "
-        label="作业名称"
-        rules={[
-          {
-            required: true,
-          },
-        ]}
-      >
-        <Input
-          placeholder="请输入作业名称..."
-          allowClear
-        >
-        </Input>
-      </FormItem>
-    </Form>  
-
-    {/* 选择作业分类 */}
-    <Form {...layout} form={form} name="control-hooks">
-      <FormItem
-        name="PyJobSort
+              label="作业名称"
+              rules={[
+                {
+                  required: true,
+                },
+              ]}>
+              <Input placeholder="请输入作业名称..." allowClear></Input>
+            </FormItem>
+          </Form>
+
+          {/* 选择作业分类 */}
+          <Form {...layout} form={form} name="control-hooks">
+            <FormItem
+              name="PyJobSort
         "
-        label="作业分类"
-        rules={[
-          {
-            required: true,
-          },
-        ]}
-      >
-        <Select
-          placeholder="请选择作业分类..."
-          allowClear
-        >
-          <Option value="Java">Java</Option>
-          <Option value="Python">Python</Option>
-          <Option value="Dag">Dag</Option>
-        </Select>
-      </FormItem>
-    </Form>  
-
-    {/* 选择执行镜像 */}
-    <Form {...layout} form={form} name="control-hooks">
-      <FormItem
-        className='mirrorLeft'
-        name="PyMirror
+              label="作业分类"
+              rules={[
+                {
+                  required: true,
+                },
+              ]}>
+              <Select placeholder="请选择作业分类..." allowClear>
+                <Option value="Java">Java</Option>
+                <Option value="Python">Python</Option>
+                <Option value="Dag">Dag</Option>
+              </Select>
+            </FormItem>
+          </Form>
+
+          {/* 选择执行镜像 */}
+          <Form {...layout} form={form} name="control-hooks">
+            <FormItem
+              className="mirrorLeft"
+              name="PyMirror
         "
-        label="配置执行的镜像"
-        rules={[
-          {
-            required: true,
-          },
-        ]}
-      >
-        <Select
-          placeholder="请选择镜像..."
-          allowClear
-        >
-          <Option value="Java">Java</Option>
-          <Option value="Python">Python</Option>
-          <Option value="Dag">Dag</Option>
-        </Select>
-      </FormItem>
-    </Form>
-
-    {/* 选择执行的Java脚本 */}
-    <Form {...layout} form={form} name="control-hooks" className='choseJs'>
-      <FormItem
-        className='mirrorLeft'
-        label="配置执行的Java脚本"
-        name="PyScripter"
-        rules={[
-          {
-            required: true,
-          },
-        ]}
-      >
-      <RadioGroup onChange={onChange} value={value}>
-      <Space direction="vertical" className='jsSel'>
-        <Radio value={1}>
-        <Select
-          placeholder="在工作目录中选择"
-          allowClear
-          className='javaSelect'
-          disabled={value === 1 ? false : true}
-        >
-          <Option value="Java">Java</Option>
-          <Option value="Python">Python</Option>
-          <Option value="Dag">Dag</Option>
-        </Select>
-        </Radio>
-        
-        <Radio value={2}>
-          <Upload {...UpProps}>
-            <Button  className='upButton'>本地上传</Button>
-          </Upload>
-        </Radio>
-      </Space>
-    </RadioGroup>
-      </FormItem>
-    </Form>
-    </div>     
-    </CreContent>
-  </JobCre>
-  );
-};
+              label="配置执行的镜像"
+              rules={[
+                {
+                  required: true,
+                },
+              ]}>
+              <Select placeholder="请选择镜像..." allowClear>
+                <Option value="Java">Java</Option>
+                <Option value="Python">Python</Option>
+                <Option value="Dag">Dag</Option>
+              </Select>
+            </FormItem>
+          </Form>
+
+          {/* 选择执行的Java脚本 */}
+          <Form
+            {...layout}
+            form={form}
+            name="control-hooks"
+            className="choseJs">
+            <FormItem
+              className="mirrorLeft"
+              label="配置执行的Java脚本"
+              name="PyScripter"
+              rules={[
+                {
+                  required: true,
+                },
+              ]}>
+              <RadioGroup onChange={onChange} value={value}>
+                <Space direction="vertical" className="jsSel">
+                  <Radio value={1}>
+                    <Select
+                      placeholder="在工作目录中选择"
+                      allowClear
+                      className="javaSelect"
+                      disabled={value === 1 ? false : true}>
+                      <Option value="Java">Java</Option>
+                      <Option value="Python">Python</Option>
+                      <Option value="Dag">Dag</Option>
+                    </Select>
+                  </Radio>
+
+                  <Radio value={2}>
+                    <Upload {...UpProps}>
+                      <Button className="upButton">本地上传</Button>
+                    </Upload>
+                  </Radio>
+                </Space>
+              </RadioGroup>
+            </FormItem>
+          </Form>
+        </div>
+      </CreContent>
+    </JobCre>
+  )
+}

+ 95 - 104
src/module/workmgmt/component/JobItems.jsx

@@ -1,28 +1,26 @@
-import { Button, Form, Input, Popconfirm, Table } from 'antd';
-import React, { useContext, useEffect, useRef, useState } from 'react';
+import { Button, Form, Input, Popconfirm, Table } from 'antd'
+import React, { useContext, useEffect, useRef, useState } from 'react'
 import styled from 'styled-components'
-import { Link } from 'react-router-dom';
-const EditableContext = React.createContext(null);
+import { Link } from 'react-router-dom'
+const EditableContext = React.createContext(null)
 const FormItem = Form.Item
 
 const JobItems = styled.div`
-  background-color: #FFFFFF;
-  height: 960px;
   margin-left: 24px;
   .delButton {
-  margin-left: 40px;
+    margin-left: 40px;
   }
-  `
+`
 const EditableRow = ({ index, ...props }) => {
-  const [form] = Form.useForm();
+  const [form] = Form.useForm()
   return (
     <Form form={form} component={false}>
       <EditableContext.Provider value={form}>
         <tr {...props} />
       </EditableContext.Provider>
     </Form>
-  );
-};
+  )
+}
 
 const EditableCell = ({
   title,
@@ -33,33 +31,33 @@ const EditableCell = ({
   handleSave,
   ...restProps
 }) => {
-  const [editing, setEditing] = useState(false);
-  const inputRef = useRef(null);
-  const form = useContext(EditableContext);
+  const [editing, setEditing] = useState(false)
+  const inputRef = useRef(null)
+  const form = useContext(EditableContext)
   useEffect(() => {
     if (editing) {
-      inputRef.current.focus();
+      inputRef.current.focus()
     }
-  }, [editing]);
+  }, [editing])
 
   const toggleEdit = () => {
-    setEditing(!editing);
+    setEditing(!editing)
     form.setFieldsValue({
       [dataIndex]: record[dataIndex],
-    });
-  };
+    })
+  }
 
   const save = async () => {
     try {
-      const values = await form.validateFields();
-      toggleEdit();
-      handleSave({ ...record, ...values });
+      const values = await form.validateFields()
+      toggleEdit()
+      handleSave({ ...record, ...values })
     } catch (errInfo) {
-      console.log('Save failed:', errInfo);
+      console.log('Save failed:', errInfo)
     }
-  };
+  }
 
-  let childNode = children;
+  let childNode = children
 
   if (editable) {
     childNode = editing ? (
@@ -73,8 +71,7 @@ const EditableCell = ({
             required: true,
             message: `${title} is required.`,
           },
-        ]}
-      >
+        ]}>
         <Input ref={inputRef} onPressEnter={save} onBlur={save} />
       </FormItem>
     ) : (
@@ -83,15 +80,14 @@ const EditableCell = ({
         style={{
           paddingRight: 24,
         }}
-        onClick={toggleEdit}
-      >
+        onClick={toggleEdit}>
         {children}
       </div>
-    );
+    )
   }
 
-  return <td {...restProps}>{childNode}</td>;
-};
+  return <td {...restProps}>{childNode}</td>
+}
 
 const App = () => {
   const itemData = [
@@ -110,34 +106,35 @@ const App = () => {
       sort: '业务预测',
       creTime: '2022.8.18 12:00:00',
       updTime: '2022.8.18 12:00:00',
-    }
-  ];
-  const [dataSource, setDataSource] = useState(itemData
-  //   [
-  //   {
-  //     key: '0',
-  //     name: '每日供应商销量预测作业2',
-  //     type: 'java',
-  //     sort: '业务预测',
-  //     creTime: '2022.8.18 12:00:00',
-  //     updTime: '2022.8.18 12:00:00',
-  //   },
-  //   {
-  //     key: '1',
-  //     name: '每日供应商销量预测作业21',
-  //     type: 'java',
-  //     sort: '业务预测',
-  //     creTime: '2022.8.18 12:00:00',
-  //     updTime: '2022.8.18 12:00:00',
-  //   },
-  // ]
-  );
-  const [count, setCount] = useState(2);
+    },
+  ]
+  const [dataSource, setDataSource] = useState(
+    itemData
+    //   [
+    //   {
+    //     key: '0',
+    //     name: '每日供应商销量预测作业2',
+    //     type: 'java',
+    //     sort: '业务预测',
+    //     creTime: '2022.8.18 12:00:00',
+    //     updTime: '2022.8.18 12:00:00',
+    //   },
+    //   {
+    //     key: '1',
+    //     name: '每日供应商销量预测作业21',
+    //     type: 'java',
+    //     sort: '业务预测',
+    //     creTime: '2022.8.18 12:00:00',
+    //     updTime: '2022.8.18 12:00:00',
+    //   },
+    // ]
+  )
+  const [count, setCount] = useState(2)
 
-  const handleDelete = (key) => {
-    const newData = dataSource.filter((item) => item.key !== key);
-    setDataSource(newData);
-  };
+  const handleDelete = key => {
+    const newData = dataSource.filter(item => item.key !== key)
+    setDataSource(newData)
+  }
 
   const defaultColumns = [
     {
@@ -154,19 +151,16 @@ const App = () => {
       title: '作业分类',
       dataIndex: 'sort',
       width: '16.6%',
-
     },
     {
       title: '创建时间',
       dataIndex: 'creTime',
       width: '16.6%',
-
     },
     {
       title: '更新时间',
       dataIndex: 'updTime',
       width: '16.6%',
-
     },
     {
       title: '操作',
@@ -176,21 +170,19 @@ const App = () => {
       render: (_, record) =>
         dataSource.length >= 1 ? (
           <>
-            <Popconfirm >
+            <Popconfirm>
               <a>编辑</a>
             </Popconfirm>
-            <Popconfirm 
-            title="Sure to delete?" 
-            onConfirm={() => handleDelete(record.key)}
-            >
-              <a className='delButton'>删除</a>
+            <Popconfirm
+              title="Sure to delete?"
+              onConfirm={() => handleDelete(record.key)}>
+              <a className="delButton">删除</a>
             </Popconfirm>
           </>
         ) : null,
-          
     },
-  ];
-//创建作业
+  ]
+  //创建作业
   const handleAdd = () => {
     const newData = {
       key: count,
@@ -199,59 +191,58 @@ const App = () => {
       sort: '业务预测',
       creTime: '2022.8.18 12:00:00',
       updTime: '2022.8.18 12:00:00',
-    };
-    setDataSource([...dataSource, newData]);
-    setCount(count + 1);
-  };
+    }
+    setDataSource([...dataSource, newData])
+    setCount(count + 1)
+  }
 
-  const handleSave = (row) => {
-    const newData = [...dataSource];
-    const index = newData.findIndex((item) => row.key === item.key);
-    const item = newData[index];
-    newData.splice(index, 1, { ...item, ...row });
-    setDataSource(newData);
-  };
+  const handleSave = row => {
+    const newData = [...dataSource]
+    const index = newData.findIndex(item => row.key === item.key)
+    const item = newData[index]
+    newData.splice(index, 1, { ...item, ...row })
+    setDataSource(newData)
+  }
 
   const components = {
     body: {
       row: EditableRow,
       cell: EditableCell,
     },
-  };
-  const columns = defaultColumns.map((col) => {
+  }
+  const columns = defaultColumns.map(col => {
     if (!col.editable) {
-      return col;
+      return col
     }
 
     return {
       ...col,
-      onCell: (record) => ({
+      onCell: record => ({
         record,
         editable: col.editable,
         dataIndex: col.dataIndex,
         title: col.title,
         handleSave,
       }),
-    };
-  });
+    }
+  })
   return (
     <JobItems>
       <Link to="/cre">
         <Button
-        onClick={handleAdd}
-        type="primary"
-        style={{
-          float: 'right',
-          marginBottom: 16,
-          marginTop: '18px',
-          marginRight: '16px',
-          fontSize: '12px',
-        }}
-      >
-        创建作业
-      </Button>
+          onClick={handleAdd}
+          type="primary"
+          style={{
+            float: 'right',
+            marginBottom: 16,
+            marginTop: '18px',
+            marginRight: '16px',
+            fontSize: '12px',
+          }}>
+          创建作业
+        </Button>
       </Link>
-      
+
       <Table
         components={components}
         rowClassName={() => 'editable-row'}
@@ -260,7 +251,7 @@ const App = () => {
         columns={columns}
       />
     </JobItems>
-  );
-};
+  )
+}
 
-export default App;
+export default App

+ 7 - 23
src/module/workmgmt/page/JobManagement.jsx

@@ -1,28 +1,12 @@
-import React from 'react';
+import React from 'react'
 import JobItems from '../component/JobItems'
 import styled from 'styled-components'
 const JobManage = styled.div``
 
-export default function JobManagement() {  
-      document.body.style.background = '#F0F2F5'
-      return (
-        <JobManage>
-          <div>
-          <header  style={{ 
-          height: '40px', 
-          fontSize: '14px',
-          paddingLeft: '24px',
-          lineHeight: '40px',
-          backgroundColor: 'white',
-          marginBottom: '16px',
-          }}>
-          <span>
-            作业列表
-          </span>
-          </header>
-          </div>
-         <JobItems/>
-        </JobManage>
-    )
+export default function JobManagement() {
+  return (
+    <JobManage>
+      <JobItems />
+    </JobManage>
+  )
 }
-  

+ 12 - 1
src/routes/index.js

@@ -1,7 +1,9 @@
 import DatasourceView from '../module/datasource/page/DatasourceView.jsx'
 import SyncTaskAdd from '../module/datasource/component/SyncTaskAdd.jsx'
 import LogWatcher from '../module/datasource/component/LogWatcher.jsx'
-import TaskLog from '../module/tasklog/page/TaskLog';
+import TaskLog from '../module/tasklog/page/TaskLog.jsx';
+import TaskMgmtView from '../module/taskmgmt/page/TaskMgmtView.jsx';
+import TaskCreaterView from '../module/taskmgmt/component/TaskCreaterView.jsx';
 
 export const routes = [
     {
@@ -17,6 +19,15 @@ export const routes = [
             component: LogWatcher,
         }]
     },
+    {
+        path: '/task-mgmt',
+        title: '任务管理',
+        component: TaskMgmtView,
+        children: [{
+            path: '/task-mgmt/create-task',
+            component: TaskCreaterView,
+        }]
+    },
     {
         path: '/task-log',
         title: '任务日志',