|
|
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, testEnv } 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 [editingRecord, setEditingRecord] = useState(null);
|
|
|
const [selectedEnvType, setSelectedEnvType] = useState(null); // 选中的环境类型
|
|
|
const [selectedArch, setSelectedArch] = useState(null); // 选中的架构类型
|
|
|
const [searchText, setSearchText] = 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 = async (record: any) => {
|
|
|
Message.info(`正在测试环境 ${record.name}...`);
|
|
|
const res: any = await testEnv(record.id);
|
|
|
if (res.code === 200) {
|
|
|
Message.success(`环境 ${record.name} 测试成功`);
|
|
|
}
|
|
|
else {
|
|
|
Message.error(`环境 ${record.name} 测试失败: ${res.message}`);
|
|
|
}
|
|
|
};
|
|
|
|
|
|
// 环境配置处理函数
|
|
|
const handleConfigEnv = (record: any) => {
|
|
|
// 设置编辑记录
|
|
|
setEditingRecord(record);
|
|
|
|
|
|
// 打开模态框
|
|
|
setVisible(true);
|
|
|
};
|
|
|
|
|
|
// 删除环境处理函数
|
|
|
const handleDeleteEnv = (record: any) => {
|
|
|
Modal.confirm({
|
|
|
title: '删除环境',
|
|
|
content: (
|
|
|
<div>
|
|
|
<p>删除环境后,组件实例将无法继续部署到该环境下。</p>
|
|
|
<p style={{ color: 'red', fontWeight: 'bold' }}>确认删除环境 {record.name}?</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 (extraValue?: string, type?: string) => {
|
|
|
// 构造查询参数
|
|
|
const params: any = {
|
|
|
current: 1,
|
|
|
size: 10
|
|
|
};
|
|
|
|
|
|
if (extraValue) params[type] = extraValue;
|
|
|
|
|
|
const res: any = await getEnvConfigList(params);
|
|
|
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 }}
|
|
|
allowClear
|
|
|
value={selectedEnvType}
|
|
|
onChange={(value) => {
|
|
|
setSelectedEnvType(value);
|
|
|
getEnvList(value, 'type');
|
|
|
}}
|
|
|
>
|
|
|
{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 }}
|
|
|
allowClear
|
|
|
value={selectedArch}
|
|
|
onChange={(value) => {
|
|
|
setSelectedArch(value);
|
|
|
getEnvList(value, 'arch');
|
|
|
}}
|
|
|
>
|
|
|
{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" />}>
|
|
|
<div>
|
|
|
<Input
|
|
|
prefix={<IconSearch />}
|
|
|
placeholder={'搜索'}
|
|
|
style={{ width: 236, marginRight: 5 }}
|
|
|
value={searchText}
|
|
|
onChange={(value) => setSearchText(value)}
|
|
|
/>
|
|
|
<Button
|
|
|
type="primary"
|
|
|
style={{ borderRadius: 4 }}
|
|
|
onClick={() => getEnvList(searchText, 'name')}
|
|
|
>
|
|
|
搜索
|
|
|
</Button>
|
|
|
</div>
|
|
|
<Button
|
|
|
type="primary"
|
|
|
style={{ borderRadius: 4 }}
|
|
|
onClick={() => {
|
|
|
setEditingRecord(null);
|
|
|
setVisible(true);
|
|
|
}}
|
|
|
>
|
|
|
+ 新增
|
|
|
</Button>
|
|
|
</Space>
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
<Table columns={columns} data={data} />
|
|
|
|
|
|
<AddModal
|
|
|
visible={visible}
|
|
|
envType={envType}
|
|
|
setVisible={setVisible}
|
|
|
onOk={(value) => {
|
|
|
setEditingRecord(value);
|
|
|
getEnvList(); // 新增完成后刷新列表
|
|
|
}}
|
|
|
record={editingRecord}
|
|
|
/>
|
|
|
</div>
|
|
|
);
|
|
|
};
|
|
|
|
|
|
export default ComponentEnv;
|