feat: 实现前端管理后台(React + Vite + Ant Design + Zustand)
This commit is contained in:
@@ -0,0 +1,162 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import {
|
||||
Table,
|
||||
Button,
|
||||
Space,
|
||||
Modal,
|
||||
Form,
|
||||
Input,
|
||||
message,
|
||||
Tag,
|
||||
Popconfirm,
|
||||
} from 'antd';
|
||||
import { PlusOutlined } from '@ant-design/icons';
|
||||
import {
|
||||
listAccounts,
|
||||
createAccount,
|
||||
deleteAccount,
|
||||
switchAccount,
|
||||
Account,
|
||||
AccountInput,
|
||||
} from '../api/accounts';
|
||||
|
||||
export default function AccountsPage() {
|
||||
const [accounts, setAccounts] = useState<Account[]>([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [modalOpen, setModalOpen] = useState(false);
|
||||
const [form] = Form.useForm();
|
||||
|
||||
const fetchAccounts = async () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const data = await listAccounts();
|
||||
setAccounts(data);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
fetchAccounts();
|
||||
}, []);
|
||||
|
||||
const handleSubmit = async (values: AccountInput) => {
|
||||
try {
|
||||
await createAccount(values);
|
||||
message.success('账号添加成功');
|
||||
setModalOpen(false);
|
||||
form.resetFields();
|
||||
fetchAccounts();
|
||||
} catch (error) {
|
||||
message.error('添加失败');
|
||||
}
|
||||
};
|
||||
|
||||
const handleDelete = async (id: string) => {
|
||||
try {
|
||||
await deleteAccount(id);
|
||||
message.success('已删除');
|
||||
fetchAccounts();
|
||||
} catch (error) {
|
||||
message.error('删除失败');
|
||||
}
|
||||
};
|
||||
|
||||
const handleSwitch = async (id: string) => {
|
||||
try {
|
||||
await switchAccount(id);
|
||||
message.success('已切换当前账号');
|
||||
fetchAccounts();
|
||||
} catch (error) {
|
||||
message.error('切换失败');
|
||||
}
|
||||
};
|
||||
|
||||
const columns = [
|
||||
{ title: '名称', dataIndex: 'name' },
|
||||
{ title: 'AccessKey ID', dataIndex: 'accessKeyId', ellipsis: true },
|
||||
{ title: 'Region', dataIndex: 'region' },
|
||||
{
|
||||
title: '状态',
|
||||
dataIndex: 'isActive',
|
||||
render: (isActive: number) =>
|
||||
isActive ? <Tag color="green">当前使用</Tag> : <Tag>备用</Tag>,
|
||||
},
|
||||
{
|
||||
title: '操作',
|
||||
key: 'action',
|
||||
render: (_: unknown, record: Account) => (
|
||||
<Space>
|
||||
{!record.isActive && (
|
||||
<Button type="link" onClick={() => handleSwitch(record.id)}>
|
||||
切换
|
||||
</Button>
|
||||
)}
|
||||
<Popconfirm title="确认删除?" onConfirm={() => handleDelete(record.id)}>
|
||||
<Button type="link" danger>
|
||||
删除
|
||||
</Button>
|
||||
</Popconfirm>
|
||||
</Space>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div style={{ marginBottom: 16 }}>
|
||||
<Button type="primary" icon={<PlusOutlined />} onClick={() => setModalOpen(true)}>
|
||||
添加账号
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<Table rowKey="id" columns={columns} dataSource={accounts} loading={loading} />
|
||||
|
||||
<Modal
|
||||
title="添加阿里云 VOD 账号"
|
||||
open={modalOpen}
|
||||
onCancel={() => setModalOpen(false)}
|
||||
footer={null}
|
||||
>
|
||||
<Form form={form} layout="vertical" onFinish={handleSubmit}>
|
||||
<Form.Item
|
||||
label="名称"
|
||||
name="name"
|
||||
rules={[{ required: true, message: '请输入名称' }]}
|
||||
>
|
||||
<Input placeholder="用于区分不同账号" />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label="AccessKey ID"
|
||||
name="accessKeyId"
|
||||
rules={[{ required: true, message: '请输入 AccessKey ID' }]}
|
||||
>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label="AccessKey Secret"
|
||||
name="accessKeySecret"
|
||||
rules={[{ required: true, message: '请输入 AccessKey Secret' }]}
|
||||
>
|
||||
<Input.Password />
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
label="Region"
|
||||
name="region"
|
||||
rules={[{ required: true, message: '请输入 Region' }]}
|
||||
>
|
||||
<Input placeholder="如 cn-shanghai" />
|
||||
</Form.Item>
|
||||
<Form.Item label="Endpoint(可选)" name="endpoint">
|
||||
<Input placeholder="默认 vod.{region}.aliyuncs.com" />
|
||||
</Form.Item>
|
||||
<Form.Item>
|
||||
<Button type="primary" htmlType="submit" block>
|
||||
保存
|
||||
</Button>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</Modal>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user