mirror of
https://github.com/didi/KnowStreaming.git
synced 2026-01-05 04:50:55 +08:00
kafka-manager 2.0
This commit is contained in:
277
kafka-manager-console/src/container/modal/admin/cluster.ts
Normal file
277
kafka-manager-console/src/container/modal/admin/cluster.ts
Normal file
@@ -0,0 +1,277 @@
|
||||
import { notification } from 'component/antd';
|
||||
import { wrapper } from 'store';
|
||||
import { IClusterTopics, IEditTopic, IConfigInfo, ILogicalCluster, INewLogical, IMetaData, IBrokersRegions, INewRegions } from 'types/base-type';
|
||||
import { editTopic } from 'lib/api';
|
||||
import { transMSecondToHour, transHourToMSecond } from 'lib/utils';
|
||||
import { cluster } from 'store/cluster';
|
||||
import { admin } from 'store/admin';
|
||||
import { app } from 'store/app';
|
||||
|
||||
export const showEditClusterTopic = (item: IClusterTopics) => {
|
||||
const xFormModal = {
|
||||
formMap: [
|
||||
{
|
||||
key: 'clusterName',
|
||||
label: '集群名称',
|
||||
rules: [{
|
||||
required: true,
|
||||
}],
|
||||
attrs: {
|
||||
disabled: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'appId',
|
||||
label: '应用ID',
|
||||
rules: [{
|
||||
required: true,
|
||||
}],
|
||||
attrs: {
|
||||
disabled: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'topicName',
|
||||
label: 'Topic名称',
|
||||
rules: [{
|
||||
required: true,
|
||||
}],
|
||||
attrs: {
|
||||
disabled: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'retentionTime',
|
||||
label: '保存时间',
|
||||
rules: [{
|
||||
required: true,
|
||||
message: '请输入保存时间',
|
||||
}],
|
||||
attrs: {
|
||||
placeholder: '请输入保存时间',
|
||||
suffix: '小时',
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'properties',
|
||||
label: 'Topic属性列表',
|
||||
type: 'text_area',
|
||||
rules: [{ required: false}],
|
||||
attrs: {
|
||||
placeholder: '请输入Topic属性列表',
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'description',
|
||||
label: '备注',
|
||||
type: 'text_area',
|
||||
rules: [{
|
||||
required: false,
|
||||
}],
|
||||
attrs: {
|
||||
placeholder: '请输入备注',
|
||||
},
|
||||
},
|
||||
],
|
||||
formData: {
|
||||
clusterName: item.clusterName,
|
||||
appId: item.appId,
|
||||
topicName: item.topicName,
|
||||
retentionTime: transMSecondToHour(item.retentionTime),
|
||||
properties: JSON.stringify(item.properties, null, 4),
|
||||
description: item.description,
|
||||
},
|
||||
visible: true,
|
||||
title: 'Topic编辑',
|
||||
onSubmit: (value: IEditTopic) => {
|
||||
value.clusterId = item.clusterId;
|
||||
value.properties = value.properties ? JSON.parse(value.properties) : {};
|
||||
value.retentionTime = transHourToMSecond(value.retentionTime);
|
||||
editTopic(value).then(data => {
|
||||
notification.success({ message: '编辑Topic成功' });
|
||||
});
|
||||
},
|
||||
};
|
||||
wrapper.open(xFormModal);
|
||||
};
|
||||
|
||||
export const showLogicalClusterOpModal = (clusterId: number, record?: ILogicalCluster) => {
|
||||
let clusterModes = [] as IConfigInfo[];
|
||||
clusterModes = cluster.clusterModes ? cluster.clusterModes : clusterModes;
|
||||
const xFormModal = {
|
||||
formMap: [
|
||||
{
|
||||
key: 'logicalClusterName',
|
||||
label: '逻辑集群名称',
|
||||
rules: [{ required: true, message: '请输入逻辑集群名称' }],
|
||||
attrs: {
|
||||
disabled: record ? true : false,
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'appId',
|
||||
label: '所属应用',
|
||||
rules: [{ required: true, message: '请选择所属应用' }],
|
||||
type: 'select',
|
||||
options: app.adminAppData.map(item => {
|
||||
return {
|
||||
label: item.name,
|
||||
value: item.appId,
|
||||
};
|
||||
}),
|
||||
attrs: {
|
||||
placeholder: '请选择所属应用',
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'mode',
|
||||
label: '集群模式',
|
||||
type: 'select',
|
||||
rules: [{ required: true, message: '请选择集群模式' }],
|
||||
options: clusterModes.map(item => {
|
||||
return {
|
||||
label: item.message,
|
||||
value: item.code,
|
||||
};
|
||||
}),
|
||||
attrs: {
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'regionIdList',
|
||||
label: 'RegionIdList',
|
||||
type: 'select',
|
||||
defaultValue: [] as any,
|
||||
options: admin.brokersRegions.map(item => {
|
||||
return {
|
||||
label: item.name,
|
||||
value: item.id,
|
||||
};
|
||||
}),
|
||||
rules: [{ required: true, message: '请选择BrokerIdList' }],
|
||||
attrs: {
|
||||
mode: 'multiple',
|
||||
placeholder: '请选择BrokerIdList',
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'description',
|
||||
label: '备注',
|
||||
type: 'text_area',
|
||||
rules: [{
|
||||
required: false,
|
||||
}],
|
||||
attrs: {
|
||||
placeholder: '请输入备注',
|
||||
},
|
||||
},
|
||||
],
|
||||
formData: record,
|
||||
visible: true,
|
||||
title: '新增逻辑集群',
|
||||
onSubmit: (value: INewLogical) => {
|
||||
const params = {
|
||||
appId: value.appId,
|
||||
clusterId,
|
||||
description: value.description,
|
||||
id: record ? record.logicalClusterId : '',
|
||||
mode: value.mode,
|
||||
name: value.logicalClusterName,
|
||||
regionIdList: value.regionIdList,
|
||||
} as INewLogical;
|
||||
if (record) {
|
||||
return admin.editLogicalClusters(clusterId, params).then(data => {
|
||||
notification.success({ message: '编辑逻辑集群成功' });
|
||||
});
|
||||
}
|
||||
return admin.createLogicalClusters(clusterId, params).then(data => {
|
||||
notification.success({ message: '新建逻辑集群成功' });
|
||||
});
|
||||
},
|
||||
};
|
||||
wrapper.open(xFormModal);
|
||||
};
|
||||
|
||||
export const showClusterRegionOpModal = (clusterId: number, content: IMetaData, record?: IBrokersRegions) => {
|
||||
const xFormModal = {
|
||||
formMap: [
|
||||
{
|
||||
key: 'name',
|
||||
label: 'Region名称',
|
||||
rules: [{ required: true, message: '请输入Region名称' }],
|
||||
attrs: { placeholder: '请输入Region名称' },
|
||||
},
|
||||
{
|
||||
key: 'clusterName',
|
||||
label: '集群名称',
|
||||
rules: [{ required: true, message: '请输入集群名称' }],
|
||||
defaultValue: content.clusterName,
|
||||
attrs: {
|
||||
disabled: true,
|
||||
placeholder: '请输入集群名称',
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'brokerIdList',
|
||||
label: 'Broker列表',
|
||||
defaultValue: record ? record.brokerIdList.join(',') : [] as any,
|
||||
rules: [{ required: true, message: '请输入BrokerIdList' }],
|
||||
attrs: {
|
||||
placeholder: '请输入BrokerIdList',
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'status',
|
||||
label: '状态',
|
||||
type: 'select',
|
||||
options: [
|
||||
{
|
||||
label: '正常',
|
||||
value: 0,
|
||||
},
|
||||
{
|
||||
label: '容量已满',
|
||||
value: 1,
|
||||
},
|
||||
],
|
||||
defaultValue: 0,
|
||||
rules: [{ required: true, message: '请选择状态' }],
|
||||
attrs: {
|
||||
placeholder: '请选择状态',
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'description',
|
||||
label: '备注',
|
||||
type: 'text_area',
|
||||
rules: [{
|
||||
required: false,
|
||||
}],
|
||||
attrs: {
|
||||
placeholder: '请输入备注',
|
||||
},
|
||||
},
|
||||
],
|
||||
formData: record,
|
||||
visible: true,
|
||||
title: `${record ? '编辑' : '新增Region'}`,
|
||||
onSubmit: (value: INewRegions) => {
|
||||
value.clusterId = clusterId;
|
||||
value.brokerIdList = value.brokerIdList && Array.isArray(value.brokerIdList) ?
|
||||
value.brokerIdList : value.brokerIdList.split(',');
|
||||
if (record) {
|
||||
value.id = record.id;
|
||||
}
|
||||
delete value.clusterName;
|
||||
if (record) {
|
||||
return admin.editRegions(clusterId, value).then(data => {
|
||||
notification.success({ message: '编辑Region成功' });
|
||||
});
|
||||
}
|
||||
return admin.addNewRegions(clusterId, value).then(data => {
|
||||
notification.success({ message: '新建Region成功' });
|
||||
});
|
||||
},
|
||||
};
|
||||
wrapper.open(xFormModal);
|
||||
};
|
||||
@@ -0,0 +1,149 @@
|
||||
import * as React from 'react';
|
||||
import { admin } from 'store/admin';
|
||||
import { notification, Modal, Form, Input, Switch, Select, Tooltip } from 'antd';
|
||||
import { IBrokersMetadata, IBrokersRegions, IExpand } from 'types/base-type';
|
||||
import { searchProps } from 'constants/table';
|
||||
import { expandPartition } from 'lib/api';
|
||||
|
||||
const layout = {
|
||||
labelCol: { span: 6 },
|
||||
wrapperCol: { span: 15 },
|
||||
};
|
||||
|
||||
interface IXFormProps {
|
||||
form: any;
|
||||
formData?: any;
|
||||
visible?: boolean;
|
||||
handleVisible?: any;
|
||||
clusterId?: number;
|
||||
}
|
||||
|
||||
class CustomForm extends React.Component<IXFormProps> {
|
||||
public state = {
|
||||
checked: false,
|
||||
};
|
||||
|
||||
public onSwitchChange(checked: boolean) {
|
||||
this.setState({ checked });
|
||||
this.props.form.validateFields((err: any, values: any) => {
|
||||
checked ? values.brokerIdList = [] : values.regionId = '';
|
||||
});
|
||||
}
|
||||
|
||||
public handleExpandOk() {
|
||||
this.props.form.validateFields((err: any, values: any) => {
|
||||
if (!err) {
|
||||
this.props.handleVisible(false);
|
||||
const params = {
|
||||
topicName: values.topicName,
|
||||
clusterId: this.props.clusterId,
|
||||
partitionNum: values.partitionNum,
|
||||
} as IExpand;
|
||||
if (values.brokerIdList) {
|
||||
params.brokerIdList = values.brokerIdList;
|
||||
} else {
|
||||
params.regionId = values.regionId;
|
||||
}
|
||||
const valueParams = [] as IExpand[];
|
||||
valueParams.push(params);
|
||||
expandPartition(valueParams).then(data => {
|
||||
notification.success({ message: '扩分成功' });
|
||||
this.props.form.resetFields();
|
||||
admin.getClusterTopics(this.props.clusterId);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public handleExpandCancel() {
|
||||
this.props.handleVisible(false);
|
||||
this.props.form.resetFields();
|
||||
}
|
||||
|
||||
public componentDidMount() {
|
||||
admin.getBrokersMetadata(this.props.clusterId);
|
||||
admin.getBrokersRegions(this.props.clusterId);
|
||||
}
|
||||
|
||||
public render() {
|
||||
const { formData = {} as any, visible } = this.props;
|
||||
const { getFieldDecorator } = this.props.form;
|
||||
let metadata = [] as IBrokersMetadata[];
|
||||
metadata = admin.brokersMetadata ? admin.brokersMetadata : metadata;
|
||||
let regions = [] as IBrokersRegions[];
|
||||
regions = admin.brokersRegions ? admin.brokersRegions : regions;
|
||||
return (
|
||||
<Modal
|
||||
title="Topic扩分区"
|
||||
visible={visible}
|
||||
onOk={() => this.handleExpandOk()}
|
||||
onCancel={() => this.handleExpandCancel()}
|
||||
maskClosable={false}
|
||||
okText="确认"
|
||||
cancelText="取消"
|
||||
>
|
||||
<Form {...layout} name="basic" onSubmit={() => ({})} >
|
||||
<Form.Item label="Topic名称" >
|
||||
{getFieldDecorator('topicName', {
|
||||
initialValue: formData.topicName,
|
||||
rules: [{ required: true, message: '请输入Topic名称' }],
|
||||
})(<Input disabled={true} placeholder="请输入Topic名称" />)}
|
||||
</Form.Item>
|
||||
<Form.Item label="分区数" >
|
||||
{getFieldDecorator('partitionNum', {
|
||||
rules: [{ required: true,
|
||||
message: '请输入分区数' }],
|
||||
})(<Input placeholder="请输入分区数" />)}
|
||||
</Form.Item>
|
||||
<Form.Item label={this.state.checked ? 'Region类型' : 'Borker类型'} >
|
||||
<Switch onChange={(checked) => this.onSwitchChange(checked)} />
|
||||
</Form.Item>
|
||||
<Form.Item label="brokerIdList" style={{ display: this.state.checked ? 'none' : '' }}>
|
||||
{getFieldDecorator('brokerIdList', {
|
||||
initialValue: formData.brokerIdList,
|
||||
rules: [{ required: !this.state.checked, message: '请输入brokerIdList' }],
|
||||
})(
|
||||
<Select
|
||||
mode="multiple"
|
||||
{...searchProps}
|
||||
>
|
||||
{ metadata.map((v, index) => (
|
||||
<Select.Option
|
||||
key={v.brokerId || v.key || index}
|
||||
value={v.brokerId}
|
||||
>
|
||||
{v.host.length > 16 ?
|
||||
<Tooltip placement="bottomLeft" title={v.host}> {v.host} </Tooltip>
|
||||
: v.host}
|
||||
</Select.Option>
|
||||
))}
|
||||
</Select>,
|
||||
)}
|
||||
|
||||
</Form.Item>
|
||||
<Form.Item label="regionId" style={{ display: this.state.checked ? '' : 'none' }} >
|
||||
{getFieldDecorator('regionId', {
|
||||
initialValue: formData.regionId,
|
||||
rules: [{ required: this.state.checked, message: '请选择regionId' }],
|
||||
})(
|
||||
<Select {...searchProps}>
|
||||
{ regions.map((v, index) => (
|
||||
<Select.Option
|
||||
key={v.id || v.key || index}
|
||||
value={v.id}
|
||||
>
|
||||
{v.name.length > 16 ?
|
||||
<Tooltip placement="bottomLeft" title={v.name}> {v.name} </Tooltip>
|
||||
: v.name}
|
||||
</Select.Option>
|
||||
))}
|
||||
</Select>,
|
||||
)}
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export const ExpandPartitionFormWrapper = Form.create<IXFormProps>()(CustomForm);
|
||||
5
kafka-manager-console/src/container/modal/admin/index.ts
Normal file
5
kafka-manager-console/src/container/modal/admin/index.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
export * from './user';
|
||||
export * from './version';
|
||||
export * from './cluster';
|
||||
export * from './task';
|
||||
export * from './migration';
|
||||
@@ -0,0 +1,186 @@
|
||||
import * as React from 'react';
|
||||
import { Table, notification, Button, Modal, Input, Form, Select, message, Tooltip } from 'component/antd';
|
||||
import { IBrokersMetadata, IRebalance } from 'types/base-type';
|
||||
import { admin } from 'store/admin';
|
||||
import { implementRegions, rebalanceStatus } from 'lib/api';
|
||||
import { searchProps } from 'constants/table';
|
||||
|
||||
interface IXFormProps {
|
||||
form: any;
|
||||
changeVisible?: (visible: boolean) => any;
|
||||
visible?: boolean;
|
||||
clusterId?: number;
|
||||
clusterName?: string;
|
||||
}
|
||||
|
||||
const layout = {
|
||||
labelCol: { span: 6 },
|
||||
wrapperCol: { span: 15 },
|
||||
};
|
||||
|
||||
class LeaderRebalanceModal extends React.Component<IXFormProps> {
|
||||
public brokerId: number;
|
||||
public host: string;
|
||||
public metadata = [] as IBrokersMetadata[];
|
||||
public timer = null as any;
|
||||
|
||||
public state = {
|
||||
imVisible: false,
|
||||
status: '',
|
||||
};
|
||||
|
||||
public handleRebalanceCancel() {
|
||||
this.props.changeVisible(false);
|
||||
this.props.form.resetFields();
|
||||
this.setState({ imVisible: false });
|
||||
clearInterval(this.timer);
|
||||
}
|
||||
|
||||
public onMetaChange(value: number) {
|
||||
this.brokerId = value;
|
||||
this.metadata.forEach((element: IBrokersMetadata) => {
|
||||
if (element.brokerId === value) {
|
||||
this.host = element.host;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public handleSubmit = (e: any) => {
|
||||
e.preventDefault();
|
||||
this.props.form.validateFields((err: any, values: any) => {
|
||||
if (!err) {
|
||||
let params = {} as IRebalance;
|
||||
params = {
|
||||
clusterId: this.props.clusterId,
|
||||
brokerId: values.brokerId,
|
||||
dimension: 2,
|
||||
regionId: 0,
|
||||
topicName: '',
|
||||
};
|
||||
implementRegions(params).then(data => {
|
||||
message.success('获取成功');
|
||||
this.getStatus();
|
||||
this.setState({
|
||||
imVisible: true,
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 定时器
|
||||
public iTimer = () => {
|
||||
this.timer = setInterval(() => {
|
||||
this.getStatus();
|
||||
}, 3000);
|
||||
}
|
||||
|
||||
public getStatus() {
|
||||
rebalanceStatus(this.props.clusterId).then((data: any) => {
|
||||
message.success('状态更新成功');
|
||||
if (data.code === 30) { // code -1 未知 101 成功 30 运行中
|
||||
setTimeout(this.iTimer, 0);
|
||||
} else {
|
||||
this.setState({ status: data.message });
|
||||
clearInterval(this.timer);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 组件清除时清除定时器
|
||||
public componentWillUnmount() {
|
||||
clearInterval(this.timer);
|
||||
}
|
||||
|
||||
public render() {
|
||||
const { visible } = this.props;
|
||||
const reblanceData = [
|
||||
{
|
||||
clusterName: this.props.clusterName,
|
||||
host: this.host,
|
||||
status: this.state.status,
|
||||
},
|
||||
];
|
||||
const columns = [
|
||||
{
|
||||
title: '集群名称',
|
||||
dataIndex: 'clusterName',
|
||||
key: 'clusterName',
|
||||
},
|
||||
{
|
||||
title: 'BrokerHost',
|
||||
dataIndex: 'host',
|
||||
key: 'host',
|
||||
},
|
||||
{
|
||||
title: 'Status',
|
||||
dataIndex: 'status',
|
||||
key: 'status',
|
||||
},
|
||||
];
|
||||
this.metadata = admin.brokersMetadata ? admin.brokersMetadata : this.metadata;
|
||||
const { getFieldDecorator } = this.props.form;
|
||||
return (
|
||||
<>
|
||||
<Modal
|
||||
visible={visible}
|
||||
title="Leader Rebalance"
|
||||
onCancel={() => this.handleRebalanceCancel()}
|
||||
maskClosable={false}
|
||||
footer={null}
|
||||
>
|
||||
<Form {...layout} name="basic" onSubmit={this.handleSubmit} >
|
||||
<Form.Item label="集群名称" >
|
||||
{getFieldDecorator('clusterName', {
|
||||
initialValue: this.props.clusterName,
|
||||
rules: [{ required: true, message: '请输入集群名称' }],
|
||||
})(<Input disabled={true} />)}
|
||||
</Form.Item>
|
||||
<Form.Item label="Broker" >
|
||||
{getFieldDecorator('brokerId', {
|
||||
rules: [{ required: true, message: '请输入Broker' }],
|
||||
})(
|
||||
<Select
|
||||
onChange={(value: number) => this.onMetaChange(value)}
|
||||
{...searchProps}
|
||||
>
|
||||
{this.metadata.map((v, index) => (
|
||||
<Select.Option
|
||||
key={v.brokerId || v.key || index}
|
||||
value={v.brokerId}
|
||||
>
|
||||
{v.host.length > 16 ?
|
||||
<Tooltip placement="bottomLeft" title={v.host}> {v.host} </Tooltip>
|
||||
: v.host}
|
||||
</Select.Option>
|
||||
))}
|
||||
</Select>)}
|
||||
</Form.Item>
|
||||
<Form.Item label="" >
|
||||
{getFieldDecorator('submit')(
|
||||
<Button
|
||||
htmlType="submit"
|
||||
type="primary"
|
||||
className="implement-button"
|
||||
>
|
||||
执行
|
||||
</Button>,
|
||||
)}
|
||||
</Form.Item>
|
||||
{
|
||||
this.state.imVisible && <Table
|
||||
rowKey="clusterName"
|
||||
bordered={true}
|
||||
dataSource={reblanceData}
|
||||
columns={columns}
|
||||
pagination={false}
|
||||
/>
|
||||
}
|
||||
</Form>
|
||||
</Modal>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export const LeaderRebalanceWrapper = Form.create<IXFormProps>()(LeaderRebalanceModal);
|
||||
303
kafka-manager-console/src/container/modal/admin/migration.ts
Normal file
303
kafka-manager-console/src/container/modal/admin/migration.ts
Normal file
@@ -0,0 +1,303 @@
|
||||
import { wrapper } from 'store';
|
||||
import { IReassignTasks, IExecute, IReassign, INewBulidEnums, IEnumsMap } from 'types/base-type';
|
||||
import { notification } from 'component/antd';
|
||||
import { expert } from 'store/expert';
|
||||
import { transMBToB, transBToMB } from 'lib/utils';
|
||||
import moment = require('moment');
|
||||
import { admin } from 'store/admin';
|
||||
import { timeFormat } from 'constants/strategy';
|
||||
|
||||
export const startMigrationTask = (item: IReassignTasks, action: string) => {
|
||||
const params = {
|
||||
action,
|
||||
beginTime: +moment(item.beginTime).format('x'),
|
||||
taskId: item.taskId,
|
||||
} as IExecute;
|
||||
expert.getExecuteTask(params).then(data => {
|
||||
notification.success({ message: '操作成功' });
|
||||
});
|
||||
};
|
||||
|
||||
export const modifyMigrationTask = (item: IReassignTasks, action: string) => {
|
||||
const status: number = item.status;
|
||||
const xFormModal = {
|
||||
formMap: [
|
||||
{
|
||||
key: 'beginTime',
|
||||
label: '计划开始时间',
|
||||
type: 'date_picker',
|
||||
rules: [{
|
||||
required: status === 0,
|
||||
message: '请输入计划开始时间',
|
||||
}],
|
||||
attrs: {
|
||||
placeholder: '请输入计划开始时间',
|
||||
format: timeFormat,
|
||||
showTime: true,
|
||||
disabled: status !== 0,
|
||||
},
|
||||
},
|
||||
],
|
||||
formData: {
|
||||
beginTime: moment(item.beginTime),
|
||||
},
|
||||
visible: true,
|
||||
title: '操作迁移任务',
|
||||
onSubmit: (value: IExecute) => {
|
||||
const params = {
|
||||
action,
|
||||
beginTime: +moment(value.beginTime).format('x'),
|
||||
taskId: item.taskId,
|
||||
} as IExecute;
|
||||
expert.getExecuteTask(params).then(data => {
|
||||
notification.success({ message: '操作成功' });
|
||||
});
|
||||
},
|
||||
};
|
||||
wrapper.open(xFormModal);
|
||||
};
|
||||
|
||||
export const modifyTransferTask = (item: IReassign, action: string, taskId: number) => {
|
||||
const status: number = item.status;
|
||||
const xFormModal = {
|
||||
formMap: [
|
||||
{
|
||||
key: 'throttle',
|
||||
label: '初始限流',
|
||||
rules: [{
|
||||
required: true,
|
||||
message: '请输入初始限流',
|
||||
}],
|
||||
attrs: {
|
||||
placeholder: '请输入初始限流',
|
||||
suffix: 'MB/s',
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'maxThrottle',
|
||||
label: '限流上限',
|
||||
rules: [{
|
||||
required: true,
|
||||
message: '请输入限流上限',
|
||||
}],
|
||||
attrs: {
|
||||
placeholder: '请输入限流上限',
|
||||
suffix: 'MB/s',
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'minThrottle',
|
||||
label: '限流下限',
|
||||
rules: [{
|
||||
required: true,
|
||||
message: '请输入限流下限',
|
||||
}],
|
||||
attrs: {
|
||||
placeholder: '请输入限流下限',
|
||||
suffix: 'MB/s',
|
||||
},
|
||||
},
|
||||
],
|
||||
formData: {
|
||||
throttle: transBToMB(item.realThrottle),
|
||||
maxThrottle: transBToMB(item.maxThrottle),
|
||||
minThrottle: transBToMB(item.minThrottle),
|
||||
},
|
||||
visible: true,
|
||||
title: '修改',
|
||||
onSubmit: (value: IExecute) => {
|
||||
const params = {
|
||||
action,
|
||||
throttle: transMBToB(value.throttle),
|
||||
maxThrottle: transMBToB(value.maxThrottle),
|
||||
minThrottle: transMBToB(value.minThrottle),
|
||||
subTaskId: item.subTaskId,
|
||||
} as IExecute;
|
||||
expert.getExecuteSubTask(params, taskId).then(data => {
|
||||
notification.success({ message: '操作成功' });
|
||||
});
|
||||
},
|
||||
};
|
||||
wrapper.open(xFormModal);
|
||||
};
|
||||
|
||||
const updateFormModal = () => {
|
||||
const formMap = wrapper.xFormWrapper.formMap;
|
||||
formMap[2].options = admin.packageList;
|
||||
formMap[3].options = admin.serverPropertiesList;
|
||||
// tslint:disable-next-line:no-unused-expression
|
||||
wrapper.ref && wrapper.ref.updateFormMap$(formMap, wrapper.xFormWrapper.formData);
|
||||
};
|
||||
|
||||
const updateFormExclude = (value: boolean) => {
|
||||
const formMap = wrapper.xFormWrapper.formMap;
|
||||
if (value) {
|
||||
formMap[4].invisible = false;
|
||||
formMap[5].invisible = false;
|
||||
formMap[6].invisible = true;
|
||||
|
||||
formMap[4].rules = [{
|
||||
required: true,
|
||||
}];
|
||||
formMap[5].rules = [{
|
||||
required: false,
|
||||
}];
|
||||
formMap[6].rules = [{
|
||||
required: false,
|
||||
}];
|
||||
} else {
|
||||
formMap[4].invisible = true;
|
||||
formMap[5].invisible = true;
|
||||
formMap[6].invisible = false;
|
||||
|
||||
formMap[4].rules = [{
|
||||
required: false,
|
||||
}];
|
||||
formMap[5].rules = [{
|
||||
required: false,
|
||||
}];
|
||||
formMap[6].rules = [{
|
||||
required: true,
|
||||
}];
|
||||
}
|
||||
// tslint:disable-next-line:no-unused-expression
|
||||
wrapper.ref && wrapper.ref.updateFormMap$(formMap, wrapper.xFormWrapper.formData);
|
||||
};
|
||||
|
||||
export const addMigrationTask = () => {
|
||||
const taskStatus = admin.configsTaskStatus ? admin.configsTaskStatus : [] as IEnumsMap[];
|
||||
const xFormModal = {
|
||||
formMap: [
|
||||
{
|
||||
key: 'clusterId',
|
||||
label: '集群',
|
||||
type: 'select',
|
||||
options: admin.metaList.map(item => {
|
||||
return {
|
||||
label: item.clusterName,
|
||||
value: item.clusterId,
|
||||
};
|
||||
}),
|
||||
rules: [{
|
||||
required: true,
|
||||
}],
|
||||
attrs: {
|
||||
placeholder: '请选择集群',
|
||||
onChange: (value: number) => {
|
||||
admin.getTasksKafkaFiles(value).then(() => {
|
||||
updateFormModal();
|
||||
});
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'taskType',
|
||||
label: '任务类型',
|
||||
type: 'select',
|
||||
options: admin.tasksEnums,
|
||||
rules: [{
|
||||
required: true,
|
||||
message: '请选择集群任务',
|
||||
}],
|
||||
attrs: {
|
||||
placeholder: '请选择集群任务',
|
||||
onChange: (value: string) => {
|
||||
value === 'role_upgrade' ? updateFormExclude(true) : updateFormExclude(false);
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'kafkafileNameMd5',
|
||||
label: '包版本',
|
||||
type: 'select',
|
||||
options: admin.packageList,
|
||||
rules: [{
|
||||
required: true,
|
||||
message: '请选择包版本',
|
||||
}],
|
||||
attrs: {
|
||||
placeholder: '请选择包版本',
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'serverfileNameMd5',
|
||||
label: 'server配置',
|
||||
type: 'select',
|
||||
options: admin.serverPropertiesList,
|
||||
rules: [{
|
||||
required: true,
|
||||
message: '请选择server配置',
|
||||
}],
|
||||
attrs: {
|
||||
placeholder: '请选择server配置',
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'upgradeSequenceList',
|
||||
label: '升级顺序',
|
||||
type: 'select',
|
||||
options: admin.kafkaRoles.map(item => {
|
||||
return {
|
||||
label: item.role,
|
||||
value: item.role,
|
||||
};
|
||||
}),
|
||||
rules: [{
|
||||
required: true,
|
||||
message: '请输入升级顺序',
|
||||
}],
|
||||
defaultValue: [] as any,
|
||||
attrs: {
|
||||
mode: 'multiple',
|
||||
placeholder: '请选择升级顺序',
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'ignoreList',
|
||||
label: '排除主机列表',
|
||||
type: 'select',
|
||||
invisible: true,
|
||||
rules: [{
|
||||
required: false,
|
||||
message: '请输入排除主机列表',
|
||||
}],
|
||||
defaultValue: [] as any,
|
||||
attrs: {
|
||||
placeholder: '请输入排除主机列表',
|
||||
mode: 'tags',
|
||||
tokenSeparators: [','],
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'hostList',
|
||||
label: '主机列表',
|
||||
type: 'select',
|
||||
rules: [{
|
||||
required: true,
|
||||
message: '请输入主机列表',
|
||||
}],
|
||||
defaultValue: [] as any,
|
||||
attrs: {
|
||||
placeholder: '请输入主机列表',
|
||||
mode: 'tags',
|
||||
tokenSeparators: [' '],
|
||||
},
|
||||
},
|
||||
],
|
||||
formData: {},
|
||||
visible: true,
|
||||
title: '新建集群任务',
|
||||
onSubmit: (value: INewBulidEnums) => {
|
||||
value.kafkaPackageName = value.kafkafileNameMd5.split(',')[0];
|
||||
value.kafkaPackageMd5 = value.kafkafileNameMd5.split(',')[1];
|
||||
value.serverPropertiesName = value.serverfileNameMd5.split(',')[0];
|
||||
value.serverPropertiesMd5 = value.serverfileNameMd5.split(',')[1];
|
||||
delete value.kafkafileNameMd5;
|
||||
delete value.serverfileNameMd5;
|
||||
admin.addMigrationTask(value).then(data => {
|
||||
notification.success({ message: '新建集群任务成功' });
|
||||
});
|
||||
},
|
||||
};
|
||||
wrapper.open(xFormModal);
|
||||
};
|
||||
277
kafka-manager-console/src/container/modal/admin/task.ts
Normal file
277
kafka-manager-console/src/container/modal/admin/task.ts
Normal file
@@ -0,0 +1,277 @@
|
||||
import { wrapper } from 'store';
|
||||
import { notification } from 'component/antd';
|
||||
import { expert } from 'store/expert';
|
||||
import { admin } from 'store/admin';
|
||||
import { IMigration, IReassignTasks, IExecute } from 'types/base-type';
|
||||
import { createMigrationTask } from 'lib/api';
|
||||
import { transMBToB, transHourToMSecond, transMSecondToHour } from 'lib/utils';
|
||||
import moment = require('moment');
|
||||
import { timeFormat } from 'constants/strategy';
|
||||
|
||||
const updateFormModal = (topicName?: string) => {
|
||||
const formMap = wrapper.xFormWrapper.formMap;
|
||||
const formData = wrapper.xFormWrapper.formData;
|
||||
if (topicName) {
|
||||
formMap[5].options = expert.partitionIdMap[topicName]; // 3
|
||||
formData.originalRetentionTime = transMSecondToHour(admin.topicsBasic.retentionTime);
|
||||
} else {
|
||||
formMap[1].options = expert.taskTopicMetadata;
|
||||
formMap[3].options = admin.brokersMetadata; // 2
|
||||
formMap[4].options = admin.brokersRegions;
|
||||
}
|
||||
// tslint:disable-next-line:no-unused-expression
|
||||
wrapper.ref && wrapper.ref.updateFormMap$(formMap, wrapper.xFormWrapper.formData, !!topicName, ['partitionIdList']);
|
||||
};
|
||||
|
||||
const updateInputModal = (status?: string) => {
|
||||
const formMap = wrapper.xFormWrapper.formMap;
|
||||
formMap[3].invisible = status === 'region';
|
||||
formMap[4].invisible = status !== 'region';
|
||||
|
||||
formMap[3].rules = [{required: status !== 'region'}];
|
||||
formMap[4].rules = [{required: status === 'region'}];
|
||||
// tslint:disable-next-line:no-unused-expression
|
||||
wrapper.ref && wrapper.ref.updateFormMap$(formMap, wrapper.xFormWrapper.formData);
|
||||
};
|
||||
|
||||
let clusterId = 0 as number;
|
||||
|
||||
export const createMigrationTasks = () => {
|
||||
const xFormModal = {
|
||||
type: 'drawer',
|
||||
width: 700,
|
||||
formMap: [
|
||||
{
|
||||
key: 'clusterId',
|
||||
label: '集群名称',
|
||||
type: 'select',
|
||||
options: expert.metaData ? expert.metaData.slice(1).map(item => {
|
||||
return {
|
||||
label: item.clusterName,
|
||||
value: item.clusterId,
|
||||
};
|
||||
}) : [],
|
||||
rules: [{
|
||||
required: true,
|
||||
}],
|
||||
attrs: {
|
||||
async onChange(value: number) {
|
||||
clusterId = value;
|
||||
await admin.getBrokersMetadata(value);
|
||||
await admin.getBrokersRegions(value);
|
||||
await expert.getTaskTopicMetadata(value);
|
||||
updateFormModal();
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'topicName',
|
||||
label: 'Topic名称',
|
||||
type: 'select',
|
||||
options: (expert.taskTopicMetadata),
|
||||
rules: [{
|
||||
required: true,
|
||||
}],
|
||||
attrs: {
|
||||
showSearch: true,
|
||||
optionFilterProp: 'children',
|
||||
async onChange(value: string) {
|
||||
await admin.getTopicsBasicInfo(clusterId, value);
|
||||
updateFormModal(value);
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'species',
|
||||
label: '类型',
|
||||
type: 'radio_group',
|
||||
defaultValue: 'broker',
|
||||
options: [{
|
||||
label: 'Region',
|
||||
value: 'region',
|
||||
}, {
|
||||
label: 'Borker',
|
||||
value: 'broker',
|
||||
}],
|
||||
rules: [{
|
||||
required: false,
|
||||
message: '请选择类型',
|
||||
}],
|
||||
attrs: {
|
||||
onChange(item: any) {
|
||||
updateInputModal(item.target.value);
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'brokerIdList',
|
||||
label: 'Broker',
|
||||
type: 'select',
|
||||
defaultValue: [] as any,
|
||||
invisible: false,
|
||||
options: admin.brokersMetadata,
|
||||
rules: [{ required: true, message: '请选择Broker' }],
|
||||
attrs: {
|
||||
mode: 'multiple',
|
||||
placeholder: '请选择Broker',
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'regionId',
|
||||
label: 'Region',
|
||||
type: 'select',
|
||||
defaultValue: [] as any,
|
||||
invisible: true,
|
||||
options: admin.brokersRegions,
|
||||
rules: [{ required: false, message: '请选择Region' }],
|
||||
attrs: {
|
||||
placeholder: '请选择Region',
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'partitionIdList',
|
||||
label: '分区ID',
|
||||
type: 'select',
|
||||
defaultValue: [] as any,
|
||||
rules: [{
|
||||
required: false,
|
||||
}],
|
||||
attrs: {
|
||||
mode: 'tags',
|
||||
placeholder: '请选择PartitionIdList',
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'beginTime',
|
||||
label: '计划开始时间',
|
||||
type: 'date_picker',
|
||||
rules: [{
|
||||
required: true,
|
||||
message: '请输入计划开始时间',
|
||||
}],
|
||||
attrs: {
|
||||
placeholder: '请输入计划开始时间',
|
||||
format: timeFormat,
|
||||
showTime: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'originalRetentionTime',
|
||||
label: '原本保存时间',
|
||||
rules: [{
|
||||
required: true,
|
||||
message: '请输入原本保存时间',
|
||||
}],
|
||||
attrs: {
|
||||
disabled: true,
|
||||
placeholder: '请输入原本保存时间',
|
||||
suffix: '小时',
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'reassignRetentionTime',
|
||||
label: '迁移保存时间',
|
||||
rules: [{
|
||||
required: true,
|
||||
message: '请输入迁移保存时间',
|
||||
}],
|
||||
attrs: {
|
||||
placeholder: '请输入迁移保存时间',
|
||||
suffix: '小时',
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'throttle',
|
||||
label: '初始限流',
|
||||
rules: [{
|
||||
required: true,
|
||||
message: '请输入初始限流',
|
||||
}],
|
||||
attrs: {
|
||||
placeholder: '请输入初始限流',
|
||||
suffix: 'MB/s',
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'maxThrottle',
|
||||
label: '限流上限',
|
||||
rules: [{
|
||||
required: true,
|
||||
message: '请输入限流上限',
|
||||
}],
|
||||
attrs: {
|
||||
placeholder: '请输入限流上限',
|
||||
suffix: 'MB/s',
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'minThrottle',
|
||||
label: '限流下限',
|
||||
rules: [{
|
||||
required: true,
|
||||
message: '请输入限流下限',
|
||||
}],
|
||||
attrs: {
|
||||
placeholder: '请输入限流下限',
|
||||
suffix: 'MB/s',
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'description',
|
||||
label: '备注',
|
||||
type: 'text_area',
|
||||
rules: [{
|
||||
required: false,
|
||||
message: '请输入至少5个字符',
|
||||
pattern: /^.{5,}.$/,
|
||||
}],
|
||||
attrs: {
|
||||
placeholder: '请输入备注',
|
||||
},
|
||||
},
|
||||
],
|
||||
formData: {},
|
||||
visible: true,
|
||||
title: '新建迁移任务',
|
||||
onSubmit: (value: any) => {
|
||||
const params = {
|
||||
clusterId: value.clusterId,
|
||||
beginTime: +moment(value.beginTime).format('x'),
|
||||
originalRetentionTime: transHourToMSecond(value.originalRetentionTime),
|
||||
reassignRetentionTime: transHourToMSecond(value.reassignRetentionTime),
|
||||
throttle: transMBToB(value.throttle),
|
||||
maxThrottle: transMBToB(value.maxThrottle),
|
||||
minThrottle: transMBToB(value.minThrottle),
|
||||
description: value.description,
|
||||
brokerIdList: value.brokerIdList,
|
||||
regionId: value.regionId,
|
||||
partitionIdList: value.partitionIdList,
|
||||
topicName: value.topicName,
|
||||
} as IMigration;
|
||||
if (value.regionId) {
|
||||
delete params.brokerIdList;
|
||||
} else {
|
||||
delete params.regionId;
|
||||
}
|
||||
createMigrationTask([params]).then(data => {
|
||||
notification.success({ message: '新建迁移任务成功' });
|
||||
expert.getReassignTasks();
|
||||
});
|
||||
},
|
||||
};
|
||||
wrapper.open(xFormModal);
|
||||
};
|
||||
|
||||
export const cancelMigrationTask = (item: IReassignTasks, action: string) => {
|
||||
const params = {
|
||||
action,
|
||||
taskId: item.taskId,
|
||||
beginTime: +moment(item.beginTime).format('x'),
|
||||
throttle: Number(item.throttle),
|
||||
maxThrottle: Number(item.maxThrottle),
|
||||
minThrottle: Number(item.minThrottle),
|
||||
} as IExecute;
|
||||
expert.getExecuteTask(params).then(data => {
|
||||
notification.success({ message: '操作成功' });
|
||||
});
|
||||
};
|
||||
46
kafka-manager-console/src/container/modal/admin/user.ts
Normal file
46
kafka-manager-console/src/container/modal/admin/user.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
import { IUser } from 'types/base-type';
|
||||
import { users } from 'store/users';
|
||||
import { wrapper } from 'store';
|
||||
import { roleMap } from 'constants/status-map';
|
||||
import { message } from 'component/antd';
|
||||
import { FormItemType } from 'component/x-form';
|
||||
|
||||
export const showApplyModal = (record?: IUser) => {
|
||||
const xFormModal = {
|
||||
formMap: [
|
||||
{
|
||||
key: 'username',
|
||||
label: '用户名',
|
||||
rules: [{ required: true, message: '请输入用户名' }],
|
||||
}, {
|
||||
key: 'role',
|
||||
label: '角色',
|
||||
type: 'select',
|
||||
options: Object.keys(roleMap).map((item) => ({
|
||||
label: roleMap[+item],
|
||||
value: +item,
|
||||
})),
|
||||
rules: [{ required: true, message: '请选择角色' }],
|
||||
}, {
|
||||
key: 'password',
|
||||
label: '密码',
|
||||
type: FormItemType.inputPassword,
|
||||
rules: [{ required: !record, message: '请输入密码' }],
|
||||
},
|
||||
],
|
||||
formData: record || {},
|
||||
visible: true,
|
||||
title: record ? '修改用户信息' : '新增用户',
|
||||
onSubmit: (value: IUser) => {
|
||||
if (record) {
|
||||
return users.modfiyUser(value).then(() => {
|
||||
message.success('操作成功');
|
||||
});
|
||||
}
|
||||
return users.addUser(value).then(() => {
|
||||
message.success('操作成功');
|
||||
});
|
||||
},
|
||||
};
|
||||
wrapper.open(xFormModal);
|
||||
};
|
||||
191
kafka-manager-console/src/container/modal/admin/version.ts
Normal file
191
kafka-manager-console/src/container/modal/admin/version.ts
Normal file
@@ -0,0 +1,191 @@
|
||||
import { notification } from 'component/antd';
|
||||
import { IUploadFile, IConfigure } from 'types/base-type';
|
||||
import { version } from 'store/version';
|
||||
import { admin } from 'store/admin';
|
||||
import { wrapper } from 'store';
|
||||
import { computeChecksumMd5 } from 'lib/utils';
|
||||
|
||||
const handleSelectChange = (e: number) => {
|
||||
version.setAcceptFileType(e);
|
||||
updateFormModal(e);
|
||||
};
|
||||
|
||||
export const showUploadModal = () => {
|
||||
const xFormModal = {
|
||||
formMap: [
|
||||
{
|
||||
key: 'fileType',
|
||||
label: '文件类型',
|
||||
type: 'select',
|
||||
options: version.fileTypeList,
|
||||
attrs: {
|
||||
onChange: (e: number) => handleSelectChange(e),
|
||||
},
|
||||
rules: [{ required: true, message: '请选择文件类型' }],
|
||||
}, {
|
||||
key: 'clusterId',
|
||||
label: '集群',
|
||||
type: 'select',
|
||||
invisible: true,
|
||||
options: admin.metaList.map(item => ({
|
||||
...item,
|
||||
label: item.clusterName,
|
||||
value: item.clusterId,
|
||||
})),
|
||||
rules: [{ required: false, message: '请选择集群' }],
|
||||
}, {
|
||||
key: 'uploadFile',
|
||||
label: '上传文件',
|
||||
type: 'upload',
|
||||
attrs: {
|
||||
accept: version.fileSuffix,
|
||||
},
|
||||
rules: [{
|
||||
required: true,
|
||||
validator: (rule: any, value: any, callback: any) => {
|
||||
if (value.length) {
|
||||
if (value.length > 1) {
|
||||
callback('一次仅支持上传一份文件!');
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
callback(`请上传文件`);
|
||||
return false;
|
||||
}
|
||||
},
|
||||
}],
|
||||
}, {
|
||||
key: 'description',
|
||||
label: '备注',
|
||||
type: 'text_area',
|
||||
rules: [{ required: false, message: '请输入备注' }],
|
||||
},
|
||||
],
|
||||
formData: {},
|
||||
visible: true,
|
||||
title: '上传',
|
||||
onText: '保存',
|
||||
isWaitting: true,
|
||||
onSubmit: (value: IUploadFile) => {
|
||||
value.file = value.uploadFile[0].originFileObj;
|
||||
return computeChecksumMd5(value.file).then(md5 => {
|
||||
const params = {
|
||||
fileName: value.file.name,
|
||||
fileMd5: md5,
|
||||
clusterId: value.clusterId || -1,
|
||||
...value,
|
||||
};
|
||||
return version.addFile(params);
|
||||
});
|
||||
},
|
||||
};
|
||||
wrapper.open(xFormModal);
|
||||
};
|
||||
|
||||
const updateFormModal = (type: number) => {
|
||||
const formMap = wrapper.xFormWrapper.formMap;
|
||||
|
||||
if (formMap && formMap.length > 2) {
|
||||
formMap[1].invisible = !version.currentFileType;
|
||||
formMap[1].rules = [{ required: version.currentFileType, message: '请上传文件' }];
|
||||
formMap[2].attrs = {
|
||||
accept: version.fileSuffix,
|
||||
},
|
||||
// tslint:disable-next-line:no-unused-expression
|
||||
wrapper.ref && wrapper.ref.updateFormMap$(formMap, wrapper.xFormWrapper.formData, true);
|
||||
}
|
||||
};
|
||||
|
||||
export const showModifyModal = (record: IUploadFile) => {
|
||||
version.setAcceptFileType(record.fileType);
|
||||
const xFormModal = {
|
||||
formMap: [
|
||||
{
|
||||
key: 'uploadFile',
|
||||
label: '上传文件',
|
||||
type: 'upload',
|
||||
attrs: {
|
||||
accept: version.fileSuffix,
|
||||
},
|
||||
rules: [{
|
||||
required: true,
|
||||
validator: (rule: any, value: any, callback: any) => {
|
||||
if (value.length) {
|
||||
if (value.length > 1) {
|
||||
callback('一次仅支持上传一份文件!');
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
callback(`请上传文件`);
|
||||
return false;
|
||||
}
|
||||
},
|
||||
}],
|
||||
}, {
|
||||
key: 'description',
|
||||
label: '备注',
|
||||
type: 'text_area',
|
||||
rules: [{ required: false, message: '请输入备注' }],
|
||||
},
|
||||
],
|
||||
formData: record || {},
|
||||
visible: true,
|
||||
isWaitting: true,
|
||||
title: '修改',
|
||||
onSubmit: async (value: IUploadFile) => {
|
||||
value.file = value.uploadFile[0].originFileObj;
|
||||
const md5 = await computeChecksumMd5(value.file);
|
||||
const params = {
|
||||
fileName: value.file.name,
|
||||
fileMd5: md5 as string,
|
||||
description: value.description,
|
||||
file: value.file,
|
||||
id: record.id,
|
||||
};
|
||||
return version.modfiyFile(params);
|
||||
},
|
||||
};
|
||||
wrapper.open(xFormModal);
|
||||
};
|
||||
|
||||
export const showConfigureModal = (record?: IConfigure) => {
|
||||
const xFormModal = {
|
||||
formMap: [
|
||||
{
|
||||
key: 'configKey',
|
||||
label: '配置键',
|
||||
rules: [{ required: true, message: '请输入配置键' }],
|
||||
attrs: {
|
||||
disabled: record ? true : false,
|
||||
},
|
||||
}, {
|
||||
key: 'configValue',
|
||||
label: '配置值',
|
||||
type: 'text_area',
|
||||
rules: [{ required: true, message: '请输入配置值' }],
|
||||
}, {
|
||||
key: 'configDescription',
|
||||
label: '备注',
|
||||
type: 'text_area',
|
||||
rules: [{ required: true, message: '请输入备注' }],
|
||||
},
|
||||
],
|
||||
formData: record || {},
|
||||
visible: true,
|
||||
isWaitting: true,
|
||||
title: `${record ? '修改配置' : '新建配置'}`,
|
||||
onSubmit: async (value: IConfigure) => {
|
||||
if (record) {
|
||||
return admin.editConfigure(value).then(data => {
|
||||
notification.success({ message: '修改配置成功' });
|
||||
});
|
||||
}
|
||||
return admin.addNewConfigure(value).then(data => {
|
||||
notification.success({ message: '新建配置成功' });
|
||||
});
|
||||
},
|
||||
};
|
||||
wrapper.open(xFormModal);
|
||||
};
|
||||
Reference in New Issue
Block a user