feat(componentDeployment): 实现新增实例-线上运行功能

master
钟良源 3 months ago
parent 128d0953b1
commit 44afe3073f

@ -27,3 +27,8 @@ export function downloadEnvConfigFile(id: string) {
export function testEnv(id: string) {
return axios.get(`${urlPrefix}/componentDeployEnv/check?id=${id}`);
}
// 主机列表
export function getHostList(params) {
return axios.get(`${urlPrefix}/componentDeployEnv/list`, { params });
}

@ -1,7 +1,9 @@
import React, { useEffect, useState } from 'react' ;
import { Modal, Form, Select, Grid, Slider, Switch, Input } from '@arco-design/web-react';
import { Modal, Form, Select, Grid, Slider, Switch, Input, Message } from '@arco-design/web-react';
import EditableTable from '@/components/EditableTable';
import { getComponentClassify } from '@/api/componentClassify';
import { getHostList } from '@/api/componentDeployEnv';
import { createInstance } from '@/api/componentInstance';
const FormItem = Form.Item;
const Option = Select.Option;
@ -75,45 +77,95 @@ const deviceColumns = [
}
];
const AddModal = ({ visible, setVisible }) => {
const AddModal = ({ addItem, visible, setVisible }) => {
const [form] = Form.useForm();
const [currentRunType, setCurrentRunType] = useState('local');
const [envType, setEnvType] = useState([]); // 环境类型
const [tableData, setTableData] = useState([
{
key: '1',
name: 'Jane Doe',
salary: 23000,
email: 'jane.doe@example.com'
}
]);
const [hostOptions, setHostOptions] = useState([]); // 主机
const [tableData, setTableData] = useState([]);
const [loading, setLoading] = useState(false);
const getEnvOptions = async () => {
const res: any = await getComponentClassify('docker-env');
if (res.code === 200) setEnvType(res.data);
};
const getHostOptions = async () => {
const res: any = await getHostList({
type: 'docker-env',
componentBaseId: addItem.componentBaseId
});
if (res.code === 200) setHostOptions(res.data);
};
useEffect(() => {
if (visible) {
getHostOptions();
getEnvOptions();
}, []);
}
else {
// 关闭时重置表单
form.resetFields();
setCurrentRunType('local');
setTableData([]);
}
}, [visible]);
// 处理取消
const handleCancel = () => {
form.resetFields();
setCurrentRunType('local');
setTableData([]);
setVisible(false);
};
// 处理确认
const handleOk = async () => {
if (currentRunType === 'local') {
// TODO: 本地运行逻辑,由用户自己实现
Message.info('本地运行逻辑待实现');
return;
}
// 线上运行 - 校验表单
try {
const values = await form.validate();
// 整理参数
const params = {
deployEnvId: values.deployEnvId,
componentBaseId: addItem.componentBaseId
};
const res: any = await createInstance(params);
console.log('新增实例CB:', res);
Message.info('接口调用逻辑待实现');
} catch (error) {
console.error('表单校验失败:', error);
}
};
return (
<Modal
title="新增实例"
visible={visible}
onOk={() => setVisible(false)}
onCancel={() => setVisible(false)}
onOk={handleOk}
onCancel={handleCancel}
confirmLoading={loading}
autoFocus={false}
focusLock={true}
style={{ width: '75%' }}
style={{ width: '35%' }}
>
<Form autoComplete="off" labelCol={{ flex: 'none' }}>
<Form form={form} autoComplete="off">
<Grid.Row gutter={8}>
<Grid.Col span={12}>
<FormItem label="部署方式:">
<Select
placeholder="请选择"
style={{ width: '60%' }}
defaultValue={currentRunType}
value={currentRunType}
onChange={(value) => setCurrentRunType(value)}
>
{runTypes.map((option, index) => (
@ -129,29 +181,47 @@ const AddModal = ({ visible, setVisible }) => {
currentRunType === 'online' && (
<>
<Grid.Row gutter={8}>
{/*<Grid.Col span={12}>*/}
{/* <FormItem label="部署环境:" field="tags">*/}
{/* <Select*/}
{/* placeholder="请选择部署环境"*/}
{/* style={{ width: '90%' }}*/}
{/* >*/}
{/* {envType.map((option, index) => (*/}
{/* <Option key={option.id} value={option.id}>*/}
{/* {option.classifyName}*/}
{/* </Option>*/}
{/* ))}*/}
{/* </Select>*/}
{/* </FormItem>*/}
{/*</Grid.Col>*/}
<Grid.Col span={12}>
<FormItem label="部署环境:" field="tags">
<Select
placeholder="请选择部署环境"
style={{ width: '90%' }}
<FormItem
label="主机:"
field="deployEnvId"
required
rules={[
{
validator: (value, cb) => {
if (!value) {
return cb('请选择主机');
}
return cb(null);
}
}
]}
>
{envType.map((option, index) => (
<Option key={option.id} value={option.id}>
{option.classifyName}
</Option>
))}
</Select>
</FormItem>
</Grid.Col>
<Grid.Col span={12}>
<FormItem label="主机:" field="type">
<Select
placeholder="请选择主机"
style={{ width: '90%' }}
allowClear={true}
>
{runTypes.map((option, index) => (
<Option key={option.value} value={option.value}>
{option.label}
{hostOptions.map((option, index) => (
<Option key={option.ip} value={option.id}>
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
<span>{option.name}</span>
<span style={{ color: '#999', fontSize: 12 }}>{option.ip}</span>
</div>
</Option>
))}
</Select>

@ -19,6 +19,7 @@ const CollapseList: React.FC<CollapseListProps> = ({ searchKeyword, runStatus })
const [showOffSaleModal, setShowOffSaleModal] = useState(false);
const [selectedItem, setSelectedItem] = useState(null); // 选中的折叠面板数据
const [expandedItem, setExpandedItem] = useState(null); // 当前展开的折叠面板数据
const [addItem, setAddItem] = useState(null); // 点击新增实例按钮时记录当前信息
// 获取组件列表
const getList = async () => {
@ -73,6 +74,7 @@ const CollapseList: React.FC<CollapseListProps> = ({ searchKeyword, runStatus })
getList();
}, [searchKeyword, runStatus]);
// 折叠面板头部
const headerNode = (item) => {
const getRunStatus = () => {
return runStatusDic.find((v) => v.value === runStatusConstant[item.runStatus]) || {
@ -91,10 +93,10 @@ const CollapseList: React.FC<CollapseListProps> = ({ searchKeyword, runStatus })
<Space size={10}>
<Tag>{item.componentClassify}</Tag>
<Tag>{item.arches}</Tag>
<Tag color={getRunStatus().color}>{getRunStatus().label}</Tag>
<div className={styles['flex-box']}>
<img src={'/icons/countIcon.png'} style={{ width: 16, height: 16, marginRight: 5 }} />
<span style={{ color: '#A2A2AB' }}> :</span>
<span style={{ color: '#A2A2AB' }}>{item.instanceCount}</span>
</div>
</Space>
@ -102,13 +104,17 @@ const CollapseList: React.FC<CollapseListProps> = ({ searchKeyword, runStatus })
);
};
// 折叠面板右侧的额外节点
const extraNode = (item) => {
return (
<div className={styles['extra-node']}>
<Space size={20}>
{/*新增实例*/}
{item.runStatus === 'RUN' && (
<div className={styles['flex-box']} onClick={() => setVisible(true)}>
<div className={styles['flex-box']} onClick={() => {
setAddItem(item);
setVisible(true);
}}>
<img src={'/icons/addIcon.png'} style={{ width: 16, height: 16, marginRight: 5 }} />
<span style={{ color: '#A2A2AB' }}></span>
</div>
@ -182,6 +188,7 @@ const CollapseList: React.FC<CollapseListProps> = ({ searchKeyword, runStatus })
</div>
<AddModal
addItem={addItem}
visible={visible}
setVisible={setVisible}
/>

@ -1,11 +1,11 @@
.collapse-list {
:global(.arco-collapse-item-header-extra) {
.flex-box {
display: flex;
align-items: center;
}
:global(.arco-collapse-item-header-extra) {
.custom-red {
color: #F53F3F;

Loading…
Cancel
Save