update 定时任务计划相关

This commit is contained in:
2021-07-15 15:53:11 +08:00
parent 82460caf6a
commit 231e998277
14 changed files with 1452 additions and 346 deletions

View File

@@ -0,0 +1,243 @@
import React, { Component } from 'react'
import { Row, Col, Form, Input, Spin, Radio, Switch } from 'antd'
import { AntIcon } from 'components'
import { cloneDeep } from 'lodash'
import { api } from 'common/api'
const initialValues = { requestType: 2, startNow: 0, doOnce: 1, timerType: 1, executeType: 1 }
export default class form extends Component {
state = {
// 加载状态
loading: true,
timerType: 1,
requestType: 2,
}
// 表单实例
form = React.createRef()
// 初始化数据
record = {}
/**
* mount后回调
*/
componentDidMount() {
this.props.created && this.props.created(this)
}
/**
* 填充数据
* 可以在设置this.record之后对其作出数据结构调整
* [异步,必要]
* @param {*} params
*/
async fillData(params) {
if (params.id) {
this.record = (await api.sysTimersDetail({ id: params.id })).data
}
this.record = {
...this.record,
}
//#region 从后端转换成前段所需格式
//#endregion
this.form.current && this.form.current.setFieldsValue(this.record)
this.setState({
loading: false,
})
}
/**
* 获取数据
* 可以对postData进行数据结构调整
* [异步,必要]
* @returns
*/
async getData() {
const form = this.form.current
const valid = await form.validateFields()
if (valid) {
const postData = form.getFieldsValue()
if (this.record) {
postData.id = this.record.id
}
//#region 从前段转换后端所需格式
//#endregion
return postData
}
}
render() {
const { requestType, timerType } = this.state
return (
<Spin spinning={this.state.loading} indicator={<AntIcon type="loading" />}>
<Form initialValues={initialValues} ref={this.form} className="yo-form">
<div className="yo-form-group">
<Row gutter={24}>
<Col span={12}>
<Form.Item
name="jobName"
label="任务名称"
rules={[{ required: true, message: '请选择任务名称' }]}
>
<Input autoComplete="off" placeholder="请输入任务名称" />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
label="请求地址"
name="requestUrl"
rules={[{ required: true, message: '请输入请求地址' }]}
>
<Input autoComplete="off" placeholder="请输入请求地址" />
</Form.Item>
</Col>
</Row>
<Form.Item
label="请求类型"
name="requestType"
rules={[{ required: true, message: '请选择请求类型' }]}
>
<Radio.Group
// disabled={this.state.exist}
// buttonStyle="solid"
onChange={e => this.setState({ requestType: e.target.value })}
>
{/* <Radio value={0}>
<span>Run</span>
</Radio> */}
<Radio value={1}>
<span>Get</span>
</Radio>
<Radio value={2}>
<span>Post</span>
</Radio>
<Radio value={3}>
<span>Put</span>
</Radio>
<Radio value={4}>
<span>Delete</span>
</Radio>
</Radio.Group>
</Form.Item>
{requestType != 0 && (
<Form.Item name="requestHeader" label="请求头">
<Input autoComplete="off" placeholder="请输入请求头" />
</Form.Item>
)}
<Form.Item
name="requestParameters"
label={requestType == 0 ? '配置项参数' : '请求参数'}
>
<Input
autoComplete="off"
placeholder={
requestType == 0 ? '请输入配置项参数' : '请输入请求参数'
}
/>
</Form.Item>
<Row gutter={24}>
<Col span={12}>
<Form.Item
name="timerType"
label="定时器类型"
rules={[{ required: true, message: '请选择定时器类型' }]}
>
<Radio.Group
buttonStyle="solid"
onChange={e => this.setState({ timerType: e.target.value })}
>
<Radio.Button value={1}>
<span>间隔方式</span>
</Radio.Button>
<Radio.Button value={2}>
<span>Cron表达式</span>
</Radio.Button>
</Radio.Group>
</Form.Item>
</Col>
<Col span={12}>
{timerType == 1 && (
<Form.Item
label="执行间隔(秒)"
name="interval"
rules={[
{ required: true, message: '请输入执行间隔(秒)' },
]}
>
<Input
autoComplete="off"
placeholder="请输入执行间隔(秒)"
/>
</Form.Item>
)}
{timerType == 2 && (
<Form.Item
label="任务表达式"
name="cron"
rules={[{ required: true, message: '请输入任务表达式' }]}
>
<Input
autoComplete="off"
placeholder="请输入任务表达式"
addonAfter={
<a
href="https://www.bejson.com/othertools/cron/"
target="_Blank"
rel="noreferrer"
>
参考
</a>
}
/>
</Form.Item>
)}
</Col>
</Row>
<Row gutter={24}>
<Col span={12}>
<Form.Item name="startNow" label="立即执行">
<Switch checkedChildren="是" unCheckedChildren="否" />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item name="doOnce" label="只执行一次">
<Switch checkedChildren="是" unCheckedChildren="否" />
</Form.Item>
</Col>
</Row>
<Row gutter={24}>
<Col span={12}>
<Form.Item
name="executeType"
label="执行类型"
rules={[{ required: true, message: '请选择执行类型' }]}
>
<Radio.Group
buttonStyle="solid"
// onChange={e => this.onHouseTypeChange(e)}
>
<Radio.Button value={1}>
<span>并行方式</span>
</Radio.Button>
<Radio.Button value={2}>
<span>串行方式</span>
</Radio.Button>
</Radio.Group>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item label="备注" name="remark">
<Input autoComplete="off" placeholder="请输入备注" />
</Form.Item>
</Col>
</Row>
</div>
</Form>
</Spin>
)
}
}

View File

@@ -0,0 +1,318 @@
import React, { Component } from 'react'
import { Button, Card, Form, Input, message as Message, Popconfirm } from 'antd'
import { AntIcon, Auth, Container, ModalForm, QueryTable, QueryTableActions } from 'components'
import { api } from 'common/api'
import auth from 'components/authorized/handler'
import { isEqual } from 'lodash'
import getDictData from 'util/dic'
import { toCamelCase } from 'util/format'
import FormBody from './form'
/**
* 配置页面所需接口函数
*/
const apiAction = {
page: api.sysTimersPage,
add: api.sysTimersAdd,
edit: api.sysTimersEdit,
delete: api.sysTimersDelete,
start: api.sysTimersStart,
stop: api.sysTimersStop,
}
const name = '任务计划'
const authName = 'sysTimers'
export default class index extends Component {
state = {
codes: {
requestType: [
{ code: '0', value: 'Run' },
{ code: '1', value: 'Get' },
{ code: '2', value: 'Post' },
{ code: '3', value: 'Put' },
{ code: '4', value: 'Delete' },
],
timerStatus: [
{ code: '0', value: '运行中' },
{ code: '1', value: '已停止' },
{ code: '2', value: '执行失败' },
{ code: '3', value: '已取消' },
],
},
}
// 表格实例
table = React.createRef()
// 新增窗口实例
addForm = React.createRef()
// 编辑窗口实例
editForm = React.createRef()
columns = [
{
title: '任务名称',
width: 80,
dataIndex: 'jobName',
},
{
title: '请求地址',
width: 300,
dataIndex: 'requestUrl',
},
{
title: '请求类型',
width: 80,
dataIndex: 'requestType',
render: text => <>{this.bindCodeValue(text, 'request_type')}</>,
},
{
title: '请求参数',
width: 300,
dataIndex: 'requestParameters',
},
{
title: '间隔时间',
width: 80,
dataIndex: 'interval',
},
{
title: 'Cron',
width: 300,
dataIndex: 'cron',
},
{
title: '执行次数',
width: 80,
dataIndex: 'runNumber',
},
{
title: '状态',
width: 80,
dataIndex: 'timerStatus',
render: (text, record) => (
<>
{(text == 0 || text == 1 || text == 2) && (
<Popconfirm
placement="topRight"
title={`是否确认${text == 0 ? '停止' : text == 2 ? '重启' : '启动'}?`}
onConfirm={() =>
text == 0
? this.onStop(record.jobName)
: this.onStart(record.jobName)
}
>
<a>{this.bindCodeValue(text, 'timer_status')}</a>
</Popconfirm>
)}
{text == 3 && this.bindCodeValue(text, 'timer_status')}
</>
),
},
{
title: '备注',
width: 120,
dataIndex: 'remark',
},
]
/**
* 构造函数,在渲染前动态添加操作字段等
* @param {*} props
*/
constructor(props) {
super(props)
const flag = auth({ [authName]: [['edit'], ['delete']] })
if (flag) {
this.columns.push({
title: '操作',
width: 150,
dataIndex: 'actions',
render: (text, { id }) => (
<QueryTableActions>
<Auth auth={{ [authName]: 'edit' }}>
<a onClick={() => this.onOpen(this.editForm, id)}>编辑</a>
</Auth>
<Auth auth={{ [authName]: 'delete' }}>
<Popconfirm
placement="topRight"
title="是否确认删除"
onConfirm={() => this.onDelete(id)}
>
<a>删除</a>
</Popconfirm>
</Auth>
</QueryTableActions>
),
})
}
}
/**
* 阻止外部组件引发的渲染,提升性能
* 可自行添加渲染条件
* [必要]
* @param {*} props
* @param {*} state
* @returns
*/
shouldComponentUpdate(props, state) {
return !isEqual(this.state, state)
}
/**
* 加载字典数据,之后开始加载表格数据
* 如果必须要加载字典数据,可直接对表格设置autoLoad=true
*/
componentDidMount() {
const { onLoading, onLoadData } = this.table.current
onLoading()
onLoadData()
// getDictData('house_company_type').then(codes => {
// this.setState({ codes }, () => {
// onLoadData()
// })
// })
}
/**
* 调用加载数据接口,可在调用前对query进行处理
* [异步,必要]
* @param {*} params
* @param {*} query
* @returns
*/
loadData = async (params, query) => {
const { data } = await apiAction.page({
...params,
...query,
})
return data
}
/**
* 绑定字典数据
* @param {*} code
* @param {*} name
* @returns
*/
bindCodeValue(code, name) {
name = toCamelCase(name)
const codes = this.state.codes[name]
if (codes) {
const c = codes.find(p => p.code == code)
if (c) {
return c.value
}
}
return null
}
/**
* 打开新增/编辑弹窗
* @param {*} modal
* @param {*} id
*/
onOpen(modal, id) {
modal.current.open({ id })
}
/**
* 对表格上的操作进行统一处理
* [异步]
* @param {*} action
* @param {*} successMessage
*/
async onAction(action, successMessage) {
const { onLoading, onLoaded, onReloadData } = this.table.current
onLoading()
try {
if (action) {
await action
}
if (successMessage) {
Message.success(successMessage)
}
onReloadData()
} catch {
onLoaded()
}
}
/**
* 删除
* @param {*} id
*/
onDelete(id) {
this.onAction(apiAction.delete({ id }), '删除成功')
}
onStart(jobName) {
this.onAction(apiAction.start({ jobName }), '启动成功')
}
onStop(jobName) {
this.onAction(apiAction.stop({ jobName }), '停止成功')
}
render() {
return (
<Container mode="fluid">
<br />
<Card bordered={false}>
<QueryTable
ref={this.table}
autoLoad={false}
loadData={this.loadData}
columns={this.columns}
query={
<Auth auth={{ [authName]: 'page' }}>
<Form.Item label="任务名称" name="jobName">
<Input
autoComplete="off"
placeholder="请输入任务名称"
className="w-200"
/>
</Form.Item>
</Auth>
}
operator={
<Auth auth={{ [authName]: 'add' }}>
<Button
icon={<AntIcon type="plus" />}
onClick={() => this.onOpen(this.addForm)}
>
新增{name}
</Button>
</Auth>
}
/>
</Card>
<Auth auth={{ [authName]: 'add' }}>
<ModalForm
width={900}
title={`新增${name}`}
action={apiAction.add}
ref={this.addForm}
onSuccess={() => this.table.current.onReloadData()}
>
<FormBody />
</ModalForm>
</Auth>
<Auth auth={{ [authName]: 'edit' }}>
<ModalForm
width={900}
title={`编辑${name}`}
action={apiAction.edit}
ref={this.editForm}
onSuccess={() => this.table.current.onReloadData()}
>
<FormBody />
</ModalForm>
</Auth>
</Container>
)
}
}