|
|
|
@ -0,0 +1,196 @@
|
|
|
|
|
|
|
|
import React, { useEffect, useState } from 'react';
|
|
|
|
|
|
|
|
import styles from './style/index.module.less';
|
|
|
|
|
|
|
|
import { Button, Input, Space, Select, Divider, Table, TableColumnProps, Message, Modal } from '@arco-design/web-react';
|
|
|
|
|
|
|
|
import { getComponentClassify } from '@/api/componentClassify';
|
|
|
|
|
|
|
|
import { IconSearch } from '@arco-design/web-react/icon';
|
|
|
|
|
|
|
|
import AddModal from './addModal';
|
|
|
|
|
|
|
|
import { getEnvConfigList, deleteEnvConfig } from '@/api/componentDeployEnv';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const Option = Select.Option;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const ComponentEnv = () => {
|
|
|
|
|
|
|
|
const [envType, setEnvType] = useState([]); // 环境类型
|
|
|
|
|
|
|
|
const [architectureType, setArchitectureType] = useState(['x86_64', 'aarch64']); // 结构类型
|
|
|
|
|
|
|
|
const [visible, setVisible] = useState(false);
|
|
|
|
|
|
|
|
const [data, setData] = useState([]);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const columns: TableColumnProps[] = [
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
title: '环境IP',
|
|
|
|
|
|
|
|
dataIndex: 'ip'
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
title: 'docker端口',
|
|
|
|
|
|
|
|
dataIndex: 'dockerTcpPort'
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
title: '环境类型',
|
|
|
|
|
|
|
|
dataIndex: 'type'
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
title: '架构类型',
|
|
|
|
|
|
|
|
dataIndex: 'arch'
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
title: '环境别名',
|
|
|
|
|
|
|
|
dataIndex: 'name'
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
title: '备注',
|
|
|
|
|
|
|
|
dataIndex: 'description'
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
title: '实例数量',
|
|
|
|
|
|
|
|
dataIndex: 'instanceCount'
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
title: '操作',
|
|
|
|
|
|
|
|
width: 230,
|
|
|
|
|
|
|
|
align: 'center',
|
|
|
|
|
|
|
|
render: (_, record: any) => (
|
|
|
|
|
|
|
|
<Space>
|
|
|
|
|
|
|
|
<Button type="text" onClick={() => handleTestEnv(record)}>环境测试</Button>
|
|
|
|
|
|
|
|
<Button type="text" onClick={() => handleConfigEnv(record)}>环境配置</Button>
|
|
|
|
|
|
|
|
<Button type="text" status="danger" onClick={() => handleDeleteEnv(record)}>删除</Button>
|
|
|
|
|
|
|
|
</Space>
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 环境测试处理函数
|
|
|
|
|
|
|
|
const handleTestEnv = (record: any) => {
|
|
|
|
|
|
|
|
Message.info(`正在测试环境 ${record.name}...`);
|
|
|
|
|
|
|
|
// 这里可以添加实际的环境测试逻辑
|
|
|
|
|
|
|
|
console.log('测试环境:', record);
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 环境配置处理函数
|
|
|
|
|
|
|
|
const handleConfigEnv = (record: any) => {
|
|
|
|
|
|
|
|
Message.info(`配置环境 ${record.name}`);
|
|
|
|
|
|
|
|
// 这里可以添加环境配置逻辑,比如打开配置模态框
|
|
|
|
|
|
|
|
console.log('配置环境:', record);
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 删除环境处理函数
|
|
|
|
|
|
|
|
const handleDeleteEnv = (record: any) => {
|
|
|
|
|
|
|
|
Modal.confirm({
|
|
|
|
|
|
|
|
title: '删除环境',
|
|
|
|
|
|
|
|
content: (
|
|
|
|
|
|
|
|
<div>
|
|
|
|
|
|
|
|
<p>删除环境后,组件实例将无法继续部署到该环境下。</p>
|
|
|
|
|
|
|
|
<p style={{ color: 'red', fontWeight: 'bold' }}>确认删除环境 {record.name} IP: {record.ip}?</p>
|
|
|
|
|
|
|
|
<p>请输入环境名称 <strong>{record.name}</strong> 以确认删除:</p>
|
|
|
|
|
|
|
|
<Input placeholder={`请输入 ${record.name}`} id="confirm-env-name" />
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
okButtonProps: { status: 'danger' },
|
|
|
|
|
|
|
|
onOk: async () => {
|
|
|
|
|
|
|
|
// 获取用户输入的环境名称
|
|
|
|
|
|
|
|
const confirmInput = document.getElementById('confirm-env-name') as HTMLInputElement;
|
|
|
|
|
|
|
|
if (!confirmInput || confirmInput.value !== record.name) {
|
|
|
|
|
|
|
|
Message.error('环境名称输入不匹配,请重新输入');
|
|
|
|
|
|
|
|
// 阻止关闭确认框
|
|
|
|
|
|
|
|
return Promise.reject();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
const res: any = await deleteEnvConfig(record.id);
|
|
|
|
|
|
|
|
if (res.code === 200) {
|
|
|
|
|
|
|
|
Message.success('环境删除成功');
|
|
|
|
|
|
|
|
// 重新加载数据
|
|
|
|
|
|
|
|
getEnvList();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else {
|
|
|
|
|
|
|
|
Message.error('环境删除失败: ' + res.message);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
|
|
Message.error('环境删除失败: ' + error.message);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const getEnvList = async () => {
|
|
|
|
|
|
|
|
const res: any = await getEnvConfigList(1, 10);
|
|
|
|
|
|
|
|
if (res.code === 200) setData(res.data.list);
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const getEnvType = async () => {
|
|
|
|
|
|
|
|
const res: any = await getComponentClassify('docker-env');
|
|
|
|
|
|
|
|
if (res.code === 200) setEnvType(res.data);
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
|
|
|
getEnvType();
|
|
|
|
|
|
|
|
getEnvList();
|
|
|
|
|
|
|
|
}, []);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
|
|
<div className={styles['component-env']}>
|
|
|
|
|
|
|
|
<div className={styles['component-env-header']}>
|
|
|
|
|
|
|
|
<div className={styles['component-env-header-left']}>
|
|
|
|
|
|
|
|
<Space size={20}>
|
|
|
|
|
|
|
|
<div className={styles['handle-row-item']}>
|
|
|
|
|
|
|
|
<span>环境类型:</span>
|
|
|
|
|
|
|
|
<Select
|
|
|
|
|
|
|
|
placeholder="选择环境类型"
|
|
|
|
|
|
|
|
style={{ width: 154 }}
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
{envType.map((option, index) => (
|
|
|
|
|
|
|
|
<Option key={option.id} value={option.id}>
|
|
|
|
|
|
|
|
{option.classifyName}
|
|
|
|
|
|
|
|
</Option>
|
|
|
|
|
|
|
|
))}
|
|
|
|
|
|
|
|
</Select>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div className={styles['handle-row-item']}>
|
|
|
|
|
|
|
|
<span>架构类型:</span>
|
|
|
|
|
|
|
|
<Select
|
|
|
|
|
|
|
|
placeholder="选择架构类型"
|
|
|
|
|
|
|
|
style={{ width: 154 }}
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
{architectureType.map((option, index) => (
|
|
|
|
|
|
|
|
<Option key={option} value={option}>
|
|
|
|
|
|
|
|
{option}
|
|
|
|
|
|
|
|
</Option>
|
|
|
|
|
|
|
|
))}
|
|
|
|
|
|
|
|
</Select>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</Space>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<div className={styles['component-env-header-right']}>
|
|
|
|
|
|
|
|
<Space split={<Divider type="vertical" />}>
|
|
|
|
|
|
|
|
<Input
|
|
|
|
|
|
|
|
prefix={<IconSearch />}
|
|
|
|
|
|
|
|
placeholder={'搜索'}
|
|
|
|
|
|
|
|
style={{ width: 236 }}
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
<Button
|
|
|
|
|
|
|
|
type="primary"
|
|
|
|
|
|
|
|
style={{ borderRadius: 4 }}
|
|
|
|
|
|
|
|
onClick={() => setVisible(true)}
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
+ 新增
|
|
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
|
|
</Space>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<Table columns={columns} data={data} />
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<AddModal
|
|
|
|
|
|
|
|
visible={visible}
|
|
|
|
|
|
|
|
envType={envType}
|
|
|
|
|
|
|
|
setVisible={setVisible}
|
|
|
|
|
|
|
|
onOk={() => {
|
|
|
|
|
|
|
|
console.log('Add component env');
|
|
|
|
|
|
|
|
getEnvList(); // 新增完成后刷新列表
|
|
|
|
|
|
|
|
}}
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export default ComponentEnv;
|
|
|
|
|
|
|
|
|