From 5f19fc6aa5ba745bf677ac68f6f7cfeb02c2102c Mon Sep 17 00:00:00 2001 From: admin Date: Mon, 10 Aug 2026 14:40:58 +0800 Subject: [PATCH] =?UTF-8?q?=E5=93=81=E7=89=8C=E5=8C=96=E9=87=8D=E6=9E=84:?= =?UTF-8?q?=20StreamCore=20+=20=E7=8E=B0=E4=BB=A3UI=E4=B8=BB=E9=A2=98=20+?= =?UTF-8?q?=20=E8=8B=B1=E6=96=87=E7=95=8C=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 移除所有emoji (HomePage中的🎬改为VideoCameraOutlined图标) - 主题重设计: 深蓝色系主色(#1E3A5F),系统sans-serif字体 白色/浅灰背景,现代卡片阴影和圆角,完全去除复古感 - 首页移除管理入口,纯观众视角(渐变横幅+卡片列表) - 统一品牌名称 StreamCore (替换LiveStream) - 全部界面英文(antd默认locale,去除zhCN) - 登录页渐变+卡片居中布局 --- backend/main.py | 2 +- frontend/index.html | 5 +- frontend/src/App.tsx | 3 +- frontend/src/admin/AdminLayout.tsx | 28 +++++--- frontend/src/admin/LoginPage.tsx | 18 ++--- frontend/src/admin/pages/Dashboard.tsx | 45 ++++++------ frontend/src/admin/pages/NodeManager.tsx | 55 +++++++-------- frontend/src/admin/pages/Settings.tsx | 34 ++++----- frontend/src/admin/pages/StreamForm.tsx | 48 ++++++------- frontend/src/admin/pages/StreamList.tsx | 49 ++++++------- frontend/src/global.css | 3 +- frontend/src/theme/anthropic.ts | 61 ++++++++++------- frontend/src/viewer/pages/HomePage.tsx | 87 ++++++++++++------------ frontend/src/viewer/pages/WatchPage.tsx | 40 ++++++----- 14 files changed, 253 insertions(+), 225 deletions(-) diff --git a/backend/main.py b/backend/main.py index a83b80b..99eaea5 100644 --- a/backend/main.py +++ b/backend/main.py @@ -19,7 +19,7 @@ async def lifespan(app: FastAPI): transcode_mgr.stop_all() -app = FastAPI(title="LiveStream Platform", lifespan=lifespan) +app = FastAPI(title="StreamCore", lifespan=lifespan) app.add_middleware( CORSMiddleware, diff --git a/frontend/index.html b/frontend/index.html index bdb7cf8..77805a7 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -3,10 +3,7 @@ - LiveStream Platform - - - + StreamCore
diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 63854ff..0ea8dbb 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -1,7 +1,6 @@ import { useState, useEffect } from 'react' import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom' import { ConfigProvider } from 'antd' -import zhCN from 'antd/locale/zh_CN' import theme from './theme/anthropic' import AdminLayout from './admin/AdminLayout' import LoginPage from './admin/LoginPage' @@ -31,7 +30,7 @@ function AdminGuard({ children }: { children: React.ReactNode }) { export default function App() { return ( - + } /> diff --git a/frontend/src/admin/AdminLayout.tsx b/frontend/src/admin/AdminLayout.tsx index 9d8f7b8..5a6b73a 100644 --- a/frontend/src/admin/AdminLayout.tsx +++ b/frontend/src/admin/AdminLayout.tsx @@ -15,11 +15,11 @@ const { Sider, Content, Header } = Layout const { Text } = Typography const menuItems = [ - { key: '/admin', icon: , label: '概览' }, - { key: '/admin/streams', icon: , label: '直播列表' }, - { key: '/admin/streams/new', icon: , label: '创建直播' }, - { key: '/admin/nodes', icon: , label: '边缘节点' }, - { key: '/admin/settings', icon: , label: '系统设置' }, + { key: '/admin', icon: , label: 'Dashboard' }, + { key: '/admin/streams', icon: , label: 'Streams' }, + { key: '/admin/streams/new', icon: , label: 'New Stream' }, + { key: '/admin/nodes', icon: , label: 'Nodes' }, + { key: '/admin/settings', icon: , label: 'Settings' }, ] export default function AdminLayout() { @@ -44,7 +44,7 @@ export default function AdminLayout() { onCollapse={setCollapsed} width={220} style={{ - borderRight: '1px solid #E8E4DD', + borderRight: '1px solid #E8ECF1', background: '#FFFFFF', }} > @@ -53,10 +53,16 @@ export default function AdminLayout() { display: 'flex', alignItems: 'center', justifyContent: 'center', - borderBottom: '1px solid #E8E4DD', + borderBottom: '1px solid #E8ECF1', + background: '#1E3A5F', + color: '#FFFFFF', }}> - - {collapsed ? 'LS' : 'LiveStream'} + + {collapsed ? 'SC' : 'StreamCore'}
} onClick={handleLogout} > - 退出登录 + Logout
diff --git a/frontend/src/admin/LoginPage.tsx b/frontend/src/admin/LoginPage.tsx index 6613f08..f3d1750 100644 --- a/frontend/src/admin/LoginPage.tsx +++ b/frontend/src/admin/LoginPage.tsx @@ -14,10 +14,10 @@ export default function LoginPage() { setLoading(true) try { await login(values.password) - message.success('登录成功') + message.success('Login successful') navigate('/admin') } catch { - message.error('密码错误') + message.error('Invalid password') } finally { setLoading(false) } @@ -29,28 +29,28 @@ export default function LoginPage() { display: 'flex', alignItems: 'center', justifyContent: 'center', - background: '#FAF8F5', + background: 'linear-gradient(135deg, #1E3A5F 0%, #2D5F8A 50%, #F5F6FA 50%)', }}> - +
- LiveStream - 管理后台 + StreamCore + Admin Console
} - placeholder="密码" + placeholder="Password" size="large" />
diff --git a/frontend/src/admin/pages/Dashboard.tsx b/frontend/src/admin/pages/Dashboard.tsx index e33a4f7..03b5d23 100644 --- a/frontend/src/admin/pages/Dashboard.tsx +++ b/frontend/src/admin/pages/Dashboard.tsx @@ -1,9 +1,9 @@ import { useState, useEffect } from 'react' import { Row, Col, Card, Statistic, Typography, Table, Tag, Space } from 'antd' -import { VideoCameraOutlined, EyeOutlined, SignalFilled } from '@ant-design/icons' +import { VideoCameraOutlined, SignalFilled, PlayCircleOutlined } from '@ant-design/icons' import { fetchStreams, type StreamInfo } from '../../api/streams' -const { Title } = Typography +const { Title, Text } = Typography export default function Dashboard() { const [streams, setStreams] = useState([]) @@ -27,60 +27,65 @@ export default function Dashboard() { const pendingCount = streams.filter((s) => s.status === 'pending').length const statusMap: Record = { - pending: { color: 'blue', label: '待开播' }, - live: { color: 'green', label: '直播中' }, - ended: { color: 'default', label: '已结束' }, - cancelled: { color: 'red', label: '已取消' }, + pending: { color: 'blue', label: 'Scheduled' }, + live: { color: 'green', label: 'Live' }, + ended: { color: 'default', label: 'Ended' }, + cancelled: { color: 'red', label: 'Cancelled' }, } const recentColumns = [ - { title: '标题', dataIndex: 'title', key: 'title', ellipsis: true }, + { title: 'Title', dataIndex: 'title', key: 'title', ellipsis: true }, { - title: '状态', dataIndex: 'status', key: 'status', + title: 'Status', dataIndex: 'status', key: 'status', render: (status: string) => { const s = statusMap[status] || { color: 'default', label: status } return {s.label} }, + width: 110, + }, + { + title: 'Created', dataIndex: 'created_at', key: 'created_at', + render: (v: string) => v?.slice(0, 16), + width: 170, }, - { title: '创建时间', dataIndex: 'created_at', key: 'created_at', render: (v: string) => v?.slice(0, 16) }, ] return (
- 概览 + Overview - + } + prefix={} loading={loading} /> - + } + prefix={} loading={loading} /> - + } + prefix={} loading={loading} /> - + = { - 'round-robin': '轮询', - 'weighted': '权重', - 'least-conn': '最少连接', + 'round-robin': 'Round-Robin', + 'weighted': 'Weighted', + 'least-conn': 'Least-Conn', } export default function NodeManager() { @@ -45,15 +45,15 @@ export default function NodeManager() { ]) setNodes(nodesRes.data) setStrategy(strategyRes.data) - } catch { message.error('加载失败') } + } catch { message.error('Failed to load') } setLoading(false) } async function updateWeight(nodeId: string, weight: number) { try { await api.put(`/nodes/${nodeId}`, { weight }) - message.success('已更新') - } catch { message.error('更新失败') } + message.success('Updated') + } catch { message.error('Failed') } } async function toggleNode(nodeId: string, enabled: boolean) { @@ -62,17 +62,17 @@ export default function NodeManager() { try { await api.put(`/nodes/${nodeId}`, { weight: node.weight, enabled }) setNodes((prev) => prev.map((n) => (n.id === nodeId ? { ...n, enabled } : n))) - message.success('已更新') - } catch { message.error('更新失败') } + message.success('Updated') + } catch { message.error('Failed') } } const columns = [ - { title: '名称', dataIndex: 'name', key: 'name' }, - { title: '主机', dataIndex: 'host', key: 'host' }, - { title: 'HLS 端口', dataIndex: 'hls_port', key: 'hls_port', width: 100 }, - { title: 'API 端口', dataIndex: 'api_port', key: 'api_port', width: 100 }, + { title: 'Name', dataIndex: 'name', key: 'name' }, + { title: 'Host', dataIndex: 'host', key: 'host' }, + { title: 'HLS Port', dataIndex: 'hls_port', key: 'hls_port', width: 100 }, + { title: 'API Port', dataIndex: 'api_port', key: 'api_port', width: 100 }, { - title: '权重', dataIndex: 'weight', key: 'weight', width: 140, + title: 'Weight', dataIndex: 'weight', key: 'weight', width: 140, render: (_: number, record: NodeInfo) => ( ( } color="success">在线, + title: 'Health', key: 'health', width: 100, + render: () => } color="success">Online, }, ] return (
- 边缘节点管理 + Edge Nodes {strategy && (
- + - + - - + + )} } onClick={loadData}>刷新} + title="Node List" + extra={} + style={{ borderRadius: 12 }} >
- 系统设置 + System Settings - - - + + + + - -