- 左上角名称改为火炬VOD管理器 - 登录页使用渐变背景、LOGO、圆角卡片 - 视频列表、操作日志默认每页 10 条 - 布局增加底部版权信息 © meshel.cn · MIT 开源
This commit is contained in:
@@ -9,7 +9,7 @@ import {
|
|||||||
import { Outlet, useLocation, useNavigate } from 'react-router-dom';
|
import { Outlet, useLocation, useNavigate } from 'react-router-dom';
|
||||||
import { useAuthStore } from '../store/auth';
|
import { useAuthStore } from '../store/auth';
|
||||||
|
|
||||||
const { Header, Sider, Content } = AntLayout;
|
const { Header, Sider, Content, Footer } = AntLayout;
|
||||||
|
|
||||||
export default function Layout() {
|
export default function Layout() {
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
@@ -54,7 +54,7 @@ export default function Layout() {
|
|||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
VOD 管理器
|
火炬VOD管理器
|
||||||
</div>
|
</div>
|
||||||
<Menu
|
<Menu
|
||||||
mode="inline"
|
mode="inline"
|
||||||
@@ -87,6 +87,16 @@ export default function Layout() {
|
|||||||
>
|
>
|
||||||
<Outlet />
|
<Outlet />
|
||||||
</Content>
|
</Content>
|
||||||
|
<Footer
|
||||||
|
style={{
|
||||||
|
textAlign: 'center',
|
||||||
|
background: colorBgContainer,
|
||||||
|
color: '#888',
|
||||||
|
fontSize: 13,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
© {new Date().getFullYear()} meshel.cn · 火炬VOD管理器 · MIT 开源
|
||||||
|
</Footer>
|
||||||
</AntLayout>
|
</AntLayout>
|
||||||
</AntLayout>
|
</AntLayout>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { Form, Input, Button, Card, message } from 'antd';
|
import { Form, Input, Button, Card, message, Typography, Space } from 'antd';
|
||||||
|
import { VideoCameraOutlined, LockOutlined, UserOutlined } from '@ant-design/icons';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { useAuthStore } from '../store/auth';
|
import { useAuthStore } from '../store/auth';
|
||||||
import { login } from '../api/auth';
|
import { login } from '../api/auth';
|
||||||
|
|
||||||
|
const { Title, Text } = Typography;
|
||||||
|
|
||||||
export default function LoginPage() {
|
export default function LoginPage() {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const setAuth = useAuthStore((state) => state.setAuth);
|
const setAuth = useAuthStore((state) => state.setAuth);
|
||||||
@@ -30,32 +33,77 @@ export default function LoginPage() {
|
|||||||
display: 'flex',
|
display: 'flex',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
background: '#f0f2f5',
|
background: 'linear-gradient(135deg, #1677ff 0%, #0958d9 100%)',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Card title="阿里云 VOD 媒体库管理器" style={{ width: 400 }}>
|
<Card
|
||||||
|
style={{
|
||||||
|
width: 420,
|
||||||
|
borderRadius: 16,
|
||||||
|
boxShadow: '0 20px 50px rgba(0, 0, 0, 0.15)',
|
||||||
|
overflow: 'hidden',
|
||||||
|
}}
|
||||||
|
bodyStyle={{ padding: '40px 32px' }}
|
||||||
|
>
|
||||||
|
<Space direction="vertical" align="center" style={{ width: '100%', marginBottom: 32 }}>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
width: 64,
|
||||||
|
height: 64,
|
||||||
|
borderRadius: '50%',
|
||||||
|
background: 'linear-gradient(135deg, #1677ff 0%, #0958d9 100%)',
|
||||||
|
display: 'flex',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<VideoCameraOutlined style={{ fontSize: 32, color: '#fff' }} />
|
||||||
|
</div>
|
||||||
|
<Title level={3} style={{ margin: 0 }}>火炬VOD管理器</Title>
|
||||||
|
<Text type="secondary">阿里云视频点播媒体资源管理后台</Text>
|
||||||
|
</Space>
|
||||||
|
|
||||||
<Form name="login" onFinish={handleSubmit} autoComplete="off" layout="vertical">
|
<Form name="login" onFinish={handleSubmit} autoComplete="off" layout="vertical">
|
||||||
<Form.Item
|
<Form.Item
|
||||||
label="用户名"
|
|
||||||
name="username"
|
name="username"
|
||||||
rules={[{ required: true, message: '请输入用户名' }]}
|
rules={[{ required: true, message: '请输入用户名' }]}
|
||||||
>
|
>
|
||||||
<Input placeholder="admin" />
|
<Input
|
||||||
|
prefix={<UserOutlined />}
|
||||||
|
placeholder="用户名"
|
||||||
|
size="large"
|
||||||
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
<Form.Item
|
<Form.Item
|
||||||
label="密码"
|
|
||||||
name="password"
|
name="password"
|
||||||
rules={[{ required: true, message: '请输入密码' }]}
|
rules={[{ required: true, message: '请输入密码' }]}
|
||||||
>
|
>
|
||||||
<Input.Password placeholder="admin" />
|
<Input.Password
|
||||||
|
prefix={<LockOutlined />}
|
||||||
|
placeholder="密码"
|
||||||
|
size="large"
|
||||||
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
<Form.Item>
|
<Form.Item style={{ marginBottom: 12 }}>
|
||||||
<Button type="primary" htmlType="submit" loading={loading} block>
|
<Button
|
||||||
|
type="primary"
|
||||||
|
htmlType="submit"
|
||||||
|
loading={loading}
|
||||||
|
size="large"
|
||||||
|
block
|
||||||
|
style={{ borderRadius: 8 }}
|
||||||
|
>
|
||||||
登录
|
登录
|
||||||
</Button>
|
</Button>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
|
<div style={{ textAlign: 'center' }}>
|
||||||
|
<Text type="secondary" style={{ fontSize: 12 }}>
|
||||||
|
默认账号:admin / admin
|
||||||
|
</Text>
|
||||||
|
</div>
|
||||||
</Form>
|
</Form>
|
||||||
</Card>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ export default function LogsPage() {
|
|||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [total, setTotal] = useState(0);
|
const [total, setTotal] = useState(0);
|
||||||
const [pageNo, setPageNo] = useState(1);
|
const [pageNo, setPageNo] = useState(1);
|
||||||
const [pageSize, setPageSize] = useState(20);
|
const [pageSize, setPageSize] = useState(10);
|
||||||
|
|
||||||
const fetchLogs = async (page: number, size: number) => {
|
const fetchLogs = async (page: number, size: number) => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ export default function VideosPage() {
|
|||||||
const [selectedRows, setSelectedRows] = useState<VideoItem[]>([]);
|
const [selectedRows, setSelectedRows] = useState<VideoItem[]>([]);
|
||||||
const [total, setTotal] = useState(0);
|
const [total, setTotal] = useState(0);
|
||||||
const [pageNo, setPageNo] = useState(1);
|
const [pageNo, setPageNo] = useState(1);
|
||||||
const [pageSize, setPageSize] = useState(20);
|
const [pageSize, setPageSize] = useState(10);
|
||||||
const [categories, setCategories] = useState<Record<string, unknown>[]>([]);
|
const [categories, setCategories] = useState<Record<string, unknown>[]>([]);
|
||||||
const [detail, setDetail] = useState<VideoItem | null>(null);
|
const [detail, setDetail] = useState<VideoItem | null>(null);
|
||||||
const [drawerOpen, setDrawerOpen] = useState(false);
|
const [drawerOpen, setDrawerOpen] = useState(false);
|
||||||
|
|||||||
Reference in New Issue
Block a user