diff --git a/src/Dashboard/index.tsx b/src/Dashboard/index.tsx index b410967..28c4d9e 100644 --- a/src/Dashboard/index.tsx +++ b/src/Dashboard/index.tsx @@ -1,4 +1,5 @@ import { Card } from '@arco-design/web-react'; +import { IconPlayCircle, IconUser, IconFile, IconCheckCircle } from '@arco-design/web-react/icon'; import { dramaApi, logApi, userApi } from '../api'; import { usePageData } from '../hooks/usePageData'; import { hasPermissions } from '../utils/permission'; @@ -6,8 +7,32 @@ import { NoAccessPage } from '../components/NoAccessPage'; import { RequestLogTable } from '../components/RequestLogTable'; import type { AppUser, DashboardPageProps, Drama, MetricCardProps, RequestLog } from './interface'; -function MetricCard({ label, value }: MetricCardProps) { - return
{label}
{value}
; +const METRIC_ICONS: Record = { + dramas: , + users: , + logs: , + status: , +}; + +const METRIC_COLORS: Record = { + dramas: 'from-brand/5 to-brand/10', + users: 'from-success/5 to-success/10', + logs: 'from-warning/5 to-warning/10', + status: 'from-success/5 to-success/10', +}; + +function MetricCard({ label, value, icon }: MetricCardProps & { icon: string }) { + return ( +
+
+
+ {METRIC_ICONS[icon]} +
+ {label} +
+
{value}
+
+ ); } function DashboardPage({ profile }: DashboardPageProps) { @@ -21,11 +46,11 @@ function DashboardPage({ profile }: DashboardPageProps) { return ( <> -
- {canReadDramas && } - {canReadUsers && } - {canReadLogs && } - +
+ {canReadDramas && } + {canReadUsers && } + {canReadLogs && } +
{canReadLogs ? ( diff --git a/src/Drama/components/DramaList.tsx b/src/Drama/components/DramaList.tsx index 46149ce..d4efabf 100644 --- a/src/Drama/components/DramaList.tsx +++ b/src/Drama/components/DramaList.tsx @@ -42,13 +42,16 @@ export function DramaList() { }; return ( -
- - +
+ } onClick={() => setVisible(true)}> + 新增短剧 + + } + > { return (
-
-
- CT -
-

后台登录

-

使用管理员账号进入控制台。

-
+
+
+

后台登录

+

使用管理员账号进入控制台

- } placeholder="admin" /> + } placeholder="请输入用户名" size="large" /> - } placeholder="admin123" /> + } placeholder="请输入密码" size="large" /> - -
API 服务:{apiBaseUrl}
); -} +}; diff --git a/src/Login/components/LoginVisual.tsx b/src/Login/components/LoginVisual.tsx index 3a56d93..98efef4 100644 --- a/src/Login/components/LoginVisual.tsx +++ b/src/Login/components/LoginVisual.tsx @@ -2,26 +2,26 @@ export function LoginVisual() { return (
- CT - cth-tk-admin + CT + cth-tk-admin
- TikTok 短剧运营后台 -

CTH TikTok 短剧管理后台

-

集中处理短剧内容、剧集发布、订单支付、播放日志和系统权限,帮助运营人员稳定管理短剧业务。

+ TikTok 短剧运营后台 +

CTH TikTok 短剧管理后台

+

集中处理短剧内容、剧集发布、订单支付、播放日志和系统权限,帮助运营人员稳定管理短剧业务。

-
-
- 内容 - 短剧与剧集管理 +
+
+ 内容 + 短剧与剧集管理
-
- 权限 - 角色化后台授权 +
+ 权限 + 角色化后台授权
-
- 日志 - 请求与播放追踪 +
+ 日志 + 请求与播放追踪
diff --git a/src/Profile/components/ProfileInfoList.tsx b/src/Profile/components/ProfileInfoList.tsx index c541b9c..626dfb7 100644 --- a/src/Profile/components/ProfileInfoList.tsx +++ b/src/Profile/components/ProfileInfoList.tsx @@ -13,9 +13,9 @@ export function ProfileInfoList({ profile }: ProfileInfoListProps) { function ProfileInfoItem({ label, value }: ProfileInfoItemProps) { return ( -
- {label} - {value} +
+ {label} + {value}
); } diff --git a/src/Profile/components/ProfileSummary.tsx b/src/Profile/components/ProfileSummary.tsx index bc714fb..a414a24 100644 --- a/src/Profile/components/ProfileSummary.tsx +++ b/src/Profile/components/ProfileSummary.tsx @@ -3,11 +3,13 @@ import type { ProfileSummaryProps } from "../interface"; export function ProfileSummary({ profile }: ProfileSummaryProps) { return ( -
- {profile?.username?.slice(0, 1).toUpperCase() || "A"} +
+ + {profile?.username?.slice(0, 1).toUpperCase() || "A"} +
-

{profile?.nickname || profile?.username || "管理员"}

-

{profile?.email || "未设置邮箱"}

+

{profile?.nickname || profile?.username || "管理员"}

+

{profile?.email || "未设置邮箱"}

); diff --git a/src/Profile/index.tsx b/src/Profile/index.tsx index bcecd53..5513a32 100644 --- a/src/Profile/index.tsx +++ b/src/Profile/index.tsx @@ -65,36 +65,38 @@ function ProfilePage() { }; return ( -
- - - - - -
- - - - - - - - -
- -
- - - - - - - - - - - -
+
+
+ + + + + +
+ + + + + + + + +
+ +
+ + + + + + + + + + + +
+
); } diff --git a/src/Role/components/PermissionTreePicker.tsx b/src/Role/components/PermissionTreePicker.tsx index 18bf0fd..4de7cb5 100644 --- a/src/Role/components/PermissionTreePicker.tsx +++ b/src/Role/components/PermissionTreePicker.tsx @@ -117,7 +117,7 @@ export function PermissionTreePicker({ permissions, value, onChange }: Permissio const checkedKeys = value.map((id) => permissionKey(id)); return ( -
+
- 当前账号没有访问该功能的权限,请联系系统管理员分配角色。 +
+
+ +
+ 当前账号没有访问该功能的权限,请联系系统管理员分配角色。 +
); } diff --git a/src/index.css b/src/index.css index 4a774fa..0382008 100644 --- a/src/index.css +++ b/src/index.css @@ -2,9 +2,27 @@ @tailwind components; @tailwind utilities; +@layer base { + * { + @apply transition-colors duration-200; + } + + ::-webkit-scrollbar { + @apply w-1.5 h-1.5; + } + + ::-webkit-scrollbar-track { + @apply bg-transparent; + } + + ::-webkit-scrollbar-thumb { + @apply rounded-full bg-line hover:bg-muted; + } +} + @layer components { .section-card { - @apply rounded-lg; + @apply rounded-xl border border-line/60 bg-white shadow-sm; } .page-stack { @@ -22,4 +40,82 @@ .form-help { @apply -mt-3 mb-[18px] text-[13px] leading-[1.6] text-muted; } + + .stat-card { + @apply rounded-xl border border-line/60 bg-white p-5 shadow-sm transition-all duration-300 hover:shadow-md hover:-translate-y-0.5; + } +} + +.arco-layout-sider { + transition: width 0.2s cubic-bezier(0.2, 0, 0, 1) !important; +} + +.arco-layout-sider .arco-menu { + border-right: none !important; +} + +.arco-card { + border-radius: 0.75rem !important; + border: 1px solid rgba(229, 230, 235, 0.6) !important; + box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.04) !important; +} + +.arco-table-container { + border-radius: 0.5rem; + overflow: hidden; +} + +.arco-table-th { + background-color: #fafbfc !important; + font-weight: 600 !important; + color: #4e5969 !important; +} + +.arco-table-tr:hover .arco-table-td { + background-color: #f7f8fa !important; +} + +.arco-btn-primary { + box-shadow: 0 2px 6px rgba(22, 93, 251, 0.3) !important; +} + +.arco-btn-primary:hover { + box-shadow: 0 4px 12px rgba(22, 93, 251, 0.4) !important; +} + +.arco-modal { + border-radius: 0.75rem !important; + overflow: hidden; +} + +.arco-modal-header { + border-bottom: 1px solid rgba(229, 230, 235, 0.6) !important; + padding: 16px 24px !important; +} + +.arco-modal-body { + padding: 24px !important; +} + +.arco-input-wrapper { + border-radius: 0.5rem !important; + transition: all 0.2s !important; +} + +.arco-input-wrapper:hover { + border-color: #c9cdd4 !important; +} + +.arco-input-wrapper.arco-input-focus { + border-color: #165dff !important; + box-shadow: 0 0 0 2px rgba(22, 93, 251, 0.1) !important; +} + +.arco-select-view { + border-radius: 0.5rem !important; +} + +.arco-form-item-label { + font-weight: 500 !important; + color: #4e5969 !important; } diff --git a/src/layout/index.tsx b/src/layout/index.tsx index 245cda4..8c0bc11 100644 --- a/src/layout/index.tsx +++ b/src/layout/index.tsx @@ -48,50 +48,56 @@ export function AdminLayout() { }; return ( - - -
- TK - {!collapsed && TK短剧管理后台} + + +
+ TK + {!collapsed && TK短剧管理后台}
navigate(key)} onClickSubMenu={(_, openKeys) => setOpenMenuKeys(openKeys)} + className="!border-none" > {visibleMenuItems.map((item) => renderMenuItem(item))}
-
+
-
- + } />