mirror of
https://github.com/whyour/qinglong.git
synced 2025-07-28 15:36:07 +08:00
增加环境变量批量导入导出功能
This commit is contained in:
parent
6f93219c44
commit
75012189c3
277
src/pages/env/index.tsx
vendored
277
src/pages/env/index.tsx
vendored
|
@ -9,11 +9,15 @@ import {
|
||||||
Typography,
|
Typography,
|
||||||
Tooltip,
|
Tooltip,
|
||||||
Input,
|
Input,
|
||||||
|
Form,
|
||||||
|
notification,
|
||||||
} from 'antd';
|
} from 'antd';
|
||||||
import {
|
import {
|
||||||
EditOutlined,
|
EditOutlined,
|
||||||
DeleteOutlined,
|
DeleteOutlined,
|
||||||
SyncOutlined,
|
SyncOutlined,
|
||||||
|
ClockCircleOutlined,
|
||||||
|
CloseCircleOutlined,
|
||||||
CheckCircleOutlined,
|
CheckCircleOutlined,
|
||||||
StopOutlined,
|
StopOutlined,
|
||||||
} from '@ant-design/icons';
|
} from '@ant-design/icons';
|
||||||
|
@ -26,9 +30,10 @@ import { DndProvider, useDrag, useDrop } from 'react-dnd';
|
||||||
import { HTML5Backend } from 'react-dnd-html5-backend';
|
import { HTML5Backend } from 'react-dnd-html5-backend';
|
||||||
import './index.less';
|
import './index.less';
|
||||||
import { getTableScroll } from '@/utils/index';
|
import { getTableScroll } from '@/utils/index';
|
||||||
|
import { doc } from 'prettier';
|
||||||
|
|
||||||
const { Text } = Typography;
|
const { Text } = Typography;
|
||||||
const { Search } = Input;
|
const { Search, TextArea } = Input;
|
||||||
|
|
||||||
enum Status {
|
enum Status {
|
||||||
'已启用',
|
'已启用',
|
||||||
|
@ -462,6 +467,188 @@ const Env = ({ headerStyle, isPhone, theme }: any) => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const [importForm] = Form.useForm();
|
||||||
|
|
||||||
|
const operateImport = () => {
|
||||||
|
const importList: Array<any> = [
|
||||||
|
// {
|
||||||
|
// index: 1,
|
||||||
|
// name: '',
|
||||||
|
// icon: '',
|
||||||
|
// color: ''
|
||||||
|
// }
|
||||||
|
];
|
||||||
|
let importRes: any;
|
||||||
|
|
||||||
|
const insertOneEnv = async (values: any) => {
|
||||||
|
const { value, split, name, remarks } = values;
|
||||||
|
const method = 'post';
|
||||||
|
let payload;
|
||||||
|
if (split === '1') {
|
||||||
|
const symbol = value.includes('&') ? '&' : '\n';
|
||||||
|
payload = value.split(symbol).map((x: any) => {
|
||||||
|
return {
|
||||||
|
name: name,
|
||||||
|
value: x,
|
||||||
|
remarks: remarks,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
payload = [{ value, name, remarks }];
|
||||||
|
}
|
||||||
|
const { code, data } = await request[method](`${config.apiPrefix}envs`, {
|
||||||
|
data: payload,
|
||||||
|
});
|
||||||
|
return { code, data };
|
||||||
|
};
|
||||||
|
|
||||||
|
const submitImport = async (value: string) => {
|
||||||
|
let now_at: any = '';
|
||||||
|
try {
|
||||||
|
setLoading(true);
|
||||||
|
const dataList = JSON.parse(value); // 是一个数组
|
||||||
|
|
||||||
|
for (const [index, item] of dataList.entries()) {
|
||||||
|
importList.push({
|
||||||
|
index: index,
|
||||||
|
name: item.name,
|
||||||
|
icon: <SyncOutlined />,
|
||||||
|
color: 'default',
|
||||||
|
text: '等待中',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const [index, item] of dataList.entries()) {
|
||||||
|
Object.assign(importList[index], {
|
||||||
|
icon: <ClockCircleOutlined />,
|
||||||
|
color: 'processing',
|
||||||
|
text: '进行中',
|
||||||
|
});
|
||||||
|
now_at = importList[index];
|
||||||
|
const { code = 0 } = await insertOneEnv(item);
|
||||||
|
if (code === 200) {
|
||||||
|
Object.assign(importList[index], {
|
||||||
|
icon: <CheckCircleOutlined />,
|
||||||
|
color: 'success',
|
||||||
|
text: '成功',
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
Object.assign(importList[index], {
|
||||||
|
icon: <CloseCircleOutlined />,
|
||||||
|
color: 'error',
|
||||||
|
text: '失败',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
importRes = importList.map((one) => {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
第${one.index + 1}个变量 - ${one.name}{' '}
|
||||||
|
<Tag icon={one.icon} color={one.color}>
|
||||||
|
更新成功
|
||||||
|
</Tag>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
const count_success = importList.filter(
|
||||||
|
(one) => one.color === 'success',
|
||||||
|
).length;
|
||||||
|
const count_failed = importList.filter(
|
||||||
|
(one) => one.color === 'error',
|
||||||
|
).length;
|
||||||
|
|
||||||
|
notification.success({
|
||||||
|
message: '导入完成',
|
||||||
|
description: `成功导入${count_success}个,失败${count_failed}个`,
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
} catch (e) {
|
||||||
|
if (e.message.includes('JSON')) {
|
||||||
|
message.error('数据格式有问题,请检查并更正json格式');
|
||||||
|
} else {
|
||||||
|
message.error(
|
||||||
|
`导入第 ${now_at.index + 1} 个数据 ${
|
||||||
|
now_at.name
|
||||||
|
} 失败,请检查是否存在相同变量`,
|
||||||
|
);
|
||||||
|
console.log(e);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
Modal.confirm({
|
||||||
|
title: `环境变量配置数据-导入-请手动粘贴`,
|
||||||
|
okText: '导入',
|
||||||
|
content: (
|
||||||
|
<div>
|
||||||
|
<Form form={importForm} layout="vertical" name="form_in_modal">
|
||||||
|
<Form.Item name="envs" label="环境变量">
|
||||||
|
<TextArea
|
||||||
|
placeholder="请粘贴导入的环境变量"
|
||||||
|
style={{ height: 120, marginTop: '20px' }}
|
||||||
|
autoFocus
|
||||||
|
></TextArea>
|
||||||
|
</Form.Item>
|
||||||
|
</Form>
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
async onOk() {
|
||||||
|
const values = await importForm.validateFields();
|
||||||
|
const { envs }: { envs: string } = values;
|
||||||
|
const isOk = await submitImport(envs);
|
||||||
|
if (isOk) {
|
||||||
|
setTimeout(() => {
|
||||||
|
location.reload();
|
||||||
|
}, 1000);
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
return Promise.reject('');
|
||||||
|
},
|
||||||
|
onCancel() {
|
||||||
|
importForm.resetFields();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const operateExport = () => {
|
||||||
|
const result = [...value];
|
||||||
|
const selectItems = result
|
||||||
|
.filter((one) => selectedRowIds.includes(one.id))
|
||||||
|
.map((one) => {
|
||||||
|
return {
|
||||||
|
name: one.name,
|
||||||
|
value: one.value,
|
||||||
|
split: one.split,
|
||||||
|
remarks: one.remarks,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const resJson = JSON.stringify(selectItems, function (key: any, val: any) {
|
||||||
|
console.log(val);
|
||||||
|
if (val) return val;
|
||||||
|
});
|
||||||
|
|
||||||
|
Modal.confirm({
|
||||||
|
title: `环境变量配置数据-导出-请手动复制`,
|
||||||
|
content: (
|
||||||
|
<TextArea
|
||||||
|
style={{ height: 120, marginTop: '20px' }}
|
||||||
|
value={resJson}
|
||||||
|
autoFocus
|
||||||
|
></TextArea>
|
||||||
|
),
|
||||||
|
onOk() {
|
||||||
|
console.log('Ok');
|
||||||
|
},
|
||||||
|
onCancel() {
|
||||||
|
console.log('Cancel');
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const modifyName = () => {
|
const modifyName = () => {
|
||||||
setIsEditNameModalVisible(true);
|
setIsEditNameModalVisible(true);
|
||||||
};
|
};
|
||||||
|
@ -500,42 +687,58 @@ const Env = ({ headerStyle, isPhone, theme }: any) => {
|
||||||
style: headerStyle,
|
style: headerStyle,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{selectedRowIds.length > 0 && (
|
<div style={{ marginBottom: 16, display: 'flex' }}>
|
||||||
<div style={{ marginBottom: 16 }}>
|
<Button
|
||||||
<Button
|
type="primary"
|
||||||
type="primary"
|
style={{ marginBottom: 5 }}
|
||||||
style={{ marginBottom: 5 }}
|
onClick={operateImport}
|
||||||
onClick={modifyName}
|
>
|
||||||
>
|
批量导入
|
||||||
批量修改变量名称
|
</Button>
|
||||||
</Button>
|
{selectedRowIds.length > 0 && (
|
||||||
<Button
|
<div>
|
||||||
type="primary"
|
<Button
|
||||||
style={{ marginBottom: 5, marginLeft: 8 }}
|
type="primary"
|
||||||
onClick={delEnvs}
|
style={{ marginBottom: 5, marginLeft: 8 }}
|
||||||
>
|
onClick={operateExport}
|
||||||
批量删除
|
>
|
||||||
</Button>
|
批量导出
|
||||||
<Button
|
</Button>
|
||||||
type="primary"
|
<Button
|
||||||
onClick={() => operateEnvs(0)}
|
type="primary"
|
||||||
style={{ marginLeft: 8, marginBottom: 5 }}
|
style={{ marginBottom: 5, marginLeft: 8 }}
|
||||||
>
|
onClick={modifyName}
|
||||||
批量启用
|
>
|
||||||
</Button>
|
批量修改变量名称
|
||||||
<Button
|
</Button>
|
||||||
type="primary"
|
<Button
|
||||||
onClick={() => operateEnvs(1)}
|
type="primary"
|
||||||
style={{ marginLeft: 8, marginRight: 8 }}
|
style={{ marginBottom: 5, marginLeft: 8 }}
|
||||||
>
|
onClick={delEnvs}
|
||||||
批量禁用
|
>
|
||||||
</Button>
|
批量删除
|
||||||
<span style={{ marginLeft: 8 }}>
|
</Button>
|
||||||
已选择
|
<Button
|
||||||
<a>{selectedRowIds?.length}</a>项
|
type="primary"
|
||||||
</span>
|
onClick={() => operateEnvs(0)}
|
||||||
</div>
|
style={{ marginLeft: 8, marginBottom: 5 }}
|
||||||
)}
|
>
|
||||||
|
批量启用
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
onClick={() => operateEnvs(1)}
|
||||||
|
style={{ marginLeft: 8, marginRight: 8 }}
|
||||||
|
>
|
||||||
|
批量禁用
|
||||||
|
</Button>
|
||||||
|
<span style={{ marginLeft: 8 }}>
|
||||||
|
已选择
|
||||||
|
<a>{selectedRowIds?.length}</a>项
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
<DndProvider backend={HTML5Backend}>
|
<DndProvider backend={HTML5Backend}>
|
||||||
<Table
|
<Table
|
||||||
columns={columns}
|
columns={columns}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user