diff --git a/.mimocode/plans/1783060688305-neon-meadow.md b/.mimocode/plans/1783060688305-neon-meadow.md
new file mode 100644
index 0000000..198609a
--- /dev/null
+++ b/.mimocode/plans/1783060688305-neon-meadow.md
@@ -0,0 +1,125 @@
+# 后台样式统一优化计划
+
+## 问题总结
+
+经过全面审查,发现以下风格不一致和突兀的地方:
+
+| # | 问题 | 严重度 | 涉及文件 |
+|---|------|--------|----------|
+| 1 | CSS 中大量使用硬编码十六进制颜色,未引用 Tailwind 语义 token | 高 | `index.css` |
+| 2 | `stat-card` 悬浮效果(上移+大阴影)与 `section-card`(仅阴影)风格差异大 | 中 | `index.css` |
+| 3 | 主按钮悬浮时 `translateY(-1px)` 在管理后台中显得突兀 | 中 | `index.css` |
+| 4 | `blue-600` 应为 `brand` 的渐变色在布局和头像中混用 | 中 | `layout/index.tsx`, `ProfileSummary.tsx` |
+| 5 | 登录页使用 `#f7f8fa` 而非 `canvas` token | 低 | `Login/index.tsx`, `LoginPanel.tsx` |
+| 6 | Role/Personnel 页面缺少 `page-stack` 包裹 | 中 | `Role/index.tsx`, `Personnel/index.tsx` |
+| 7 | Modal 宽度不一致(640/720/默认520) | 中 | `Channel`, `DramaList`, `DramaDetail`, `Role`, `Personnel` |
+| 8 | 分页配置不一致(部分有 sizeCanChange/showTotal,部分没有) | 中 | 多个页面 |
+| 9 | 状态标签颜色不一致(禁用:红色 vs 灰色) | 低 | `User`, `Personnel` vs `Channel`, `Drama` |
+| 10 | DramaList 的"新增短剧"按钮用绿色,其他页面用蓝色 | 低 | `DramaList.tsx` |
+| 11 | InputNumber 宽度不一致(固定180px vs 100%) | 低 | `Channel` vs `Drama` |
+
+## 实施方案
+
+### 步骤 1:统一 CSS 中的颜色引用 (`index.css`)
+
+将所有硬编码颜色替换为 Tailwind 语义化写法:
+
+```css
+/* 之前 */
+background-color: #f2f3f5 !important; /* canvas */
+color: #165dff !important; /* brand */
+background-color: #e8f3ff !important; /* brand-light */
+color: #4e5969 !important; /* 无对应token,新增 secondary */
+background-color: #fafbfc !important; /* 无对应token,新增 header-bg */
+color: #1d2129 !important; /* ink */
+color: #86909c !important; /* muted */
+border-color: #c9cdd4 !important; /* 无对应token,新增 border-hover */
+background-color: #f7f8fa !important; /* 无对应token,新增 row-hover */
+color: #fff !important; /* white */
+```
+
+新增 tailwind.config.js token:
+- `secondary: '#4e5969'` — 表头、表单标签等次级文字
+- `header-bg: '#fafbfc'` — 表头、描述标签背景
+- `row-hover: '#f7f8fa'` — 表格行悬浮背景
+- `border-hover: '#c9cdd4'` — 输入框悬浮边框
+
+CSS 改用 `theme()` 函数引用:
+```css
+background-color: theme('colors.canvas') !important;
+color: theme('colors.brand') !important;
+```
+
+### 步骤 2:统一悬浮效果 (`index.css`)
+
+- 移除 `stat-card` 的 `hover:-translate-y-0.5`,改为与 `section-card` 一致的仅阴影变化
+- 移除 `.arco-btn-primary:hover` 的 `transform: translateY(-1px)`
+- 统一所有悬浮阴影为同一级别
+
+### 步骤 3:修复渐变色 (`layout/index.tsx`, `ProfileSummary.tsx`)
+
+将 `to-blue-600` 改为 `to-brand`:
+- `layout/index.tsx` 行 61:Logo 渐变
+- `layout/index.tsx` 行 103:Avatar 渐变
+- `ProfileSummary.tsx` 行 7:Avatar 渐变
+
+### 步骤 4:修复登录页背景色 (`Login/index.tsx`, `LoginPanel.tsx`)
+
+将 `bg-[#f7f8fa]` 改为 `bg-canvas`
+
+### 步骤 5:统一页面结构 (`Role/index.tsx`, `Personnel/index.tsx`)
+
+为 Role 和 Personnel 页面添加 `page-stack` 包裹:
+```tsx
+return (
+
+
+```
+
+### 步骤 6:统一 Modal 宽度
+
+所有包含表单的 Modal 统一使用 `style={{ width: 640 }}`:
+- `Role/index.tsx`:新增角色 Modal 添加宽度
+- `Personnel/index.tsx`:新增人员 Modal、分配角色 Modal 添加宽度
+
+### 步骤 7:统一分页配置
+
+所有 Table 的 pagination 统一添加 `sizeCanChange: true` 和 `showTotal: true`:
+- `User/index.tsx`
+- `Role/index.tsx`
+- `Personnel/index.tsx`
+- `Data/index.tsx`(3个表格)
+
+### 步骤 8:统一状态标签颜色
+
+禁用/停用状态统一使用 `gray` 而非 `red`:
+- `User/index.tsx`:将 `'red'` 改为 `'gray'`
+- `Personnel/index.tsx`:将 `'red'` 改为 `'gray'`
+
+### 步骤 9:统一"新增"按钮颜色
+
+`DramaList.tsx` 的"新增短剧"按钮移除 `status="success"`,使用默认蓝色主按钮。
+
+### 步骤 10:统一 InputNumber 宽度
+
+`Channel/index.tsx` 的 InputNumber 从 `style={{ width: 180 }}` 改为 `style={{ width: 200 }}`,与 Select 保持一致。
+
+## 涉及文件清单
+
+1. `tailwind.config.js` — 新增 secondary/header-bg/row-hover/border-hover token
+2. `src/index.css` — 统一颜色引用、统一悬浮效果
+3. `src/layout/index.tsx` — 修复渐变色 blue-600 → brand
+4. `src/Profile/components/ProfileSummary.tsx` — 修复渐变色
+5. `src/Login/index.tsx` — 背景色 canvas
+6. `src/Login/components/LoginPanel.tsx` — 背景色 canvas
+7. `src/Role/index.tsx` — 添加 page-stack、Modal 宽度、分页配置
+8. `src/Personnel/index.tsx` — 添加 page-stack、Modal 宽度、分页配置、状态标签颜色
+9. `src/User/index.tsx` — 分页配置、状态标签颜色
+10. `src/Data/index.tsx` — 分页配置(3个表格)
+11. `src/Drama/components/DramaList.tsx` — 按钮颜色
+
+## 验证方式
+
+1. `pnpm lint` — TypeScript 类型检查通过
+2. `pnpm build` — 构建成功
+3. 视觉检查:各页面悬浮效果、颜色、间距保持一致
diff --git a/src/Channel/index.tsx b/src/Channel/index.tsx
index 0e7a08d..53b7c18 100644
--- a/src/Channel/index.tsx
+++ b/src/Channel/index.tsx
@@ -84,10 +84,10 @@ export default function ChannelPage() {
-
+
-
-
-
-
- } onClick={() => setVisible(true)}>新增短剧}>
+ } onClick={() => setVisible(true)}>新增短剧}>
短剧标题
diff --git a/src/Login/components/LoginPanel.tsx b/src/Login/components/LoginPanel.tsx
index 477ac88..43fc5b0 100644
--- a/src/Login/components/LoginPanel.tsx
+++ b/src/Login/components/LoginPanel.tsx
@@ -4,7 +4,7 @@ import type { LoginPanelProps } from "../interface";
export const LoginPanel = ({ loading, onSubmit }: LoginPanelProps) => {
return (
-
+
后台登录
diff --git a/src/Login/index.tsx b/src/Login/index.tsx
index 3bfeed2..0d51ae3 100644
--- a/src/Login/index.tsx
+++ b/src/Login/index.tsx
@@ -23,7 +23,7 @@ function LoginPage() {
};
return (
-
+
diff --git a/src/Personnel/index.tsx b/src/Personnel/index.tsx
index b2921f3..9394870 100644
--- a/src/Personnel/index.tsx
+++ b/src/Personnel/index.tsx
@@ -66,14 +66,15 @@ function PersonnelPage() {
));
return (
+
} onClick={openCreate}>新增人员} noPadding>
-
{record.isSuperAdmin ? 超级管理员 : record.roles.map((role) => {role.name})} },
- { title: '状态', dataIndex: 'status', width: 120, render: (status) => {status === 'active' ? '启用' : '禁用'} },
+ { title: '状态', dataIndex: 'status', width: 120, render: (status) => {status === 'active' ? '启用' : '禁用'} },
{ title: '创建时间', dataIndex: 'createdAt', width: 190 },
{
title: '操作',
@@ -88,7 +89,7 @@ function PersonnelPage() {
),
},
]} />
- setCreateVisible(false)} footer={null}>
+ setCreateVisible(false)} footer={null} style={{ width: 640 }}>
@@ -119,6 +120,7 @@ function PersonnelPage() {
confirmLoading={assigning}
onOk={saveAssignedRoles}
onCancel={() => setAssignVisible(false)}
+ style={{ width: 640 }}
>
+
);
}
diff --git a/src/Profile/components/ProfileSummary.tsx b/src/Profile/components/ProfileSummary.tsx
index 016f58c..d0ae181 100644
--- a/src/Profile/components/ProfileSummary.tsx
+++ b/src/Profile/components/ProfileSummary.tsx
@@ -4,7 +4,7 @@ import type { ProfileSummaryProps } from "../interface";
export function ProfileSummary({ profile }: ProfileSummaryProps) {
return (
-
+
{profile?.username?.slice(0, 1).toUpperCase() || "A"}
diff --git a/src/Role/index.tsx b/src/Role/index.tsx
index e0406c4..e25b250 100644
--- a/src/Role/index.tsx
+++ b/src/Role/index.tsx
@@ -62,6 +62,7 @@ function RolesPage() {
};
return (
+
);
}
diff --git a/src/User/index.tsx b/src/User/index.tsx
index 9e2d053..3641798 100644
--- a/src/User/index.tsx
+++ b/src/User/index.tsx
@@ -15,11 +15,11 @@ function UsersPage() {
return (
- {status === 'active' ? '启用' : '禁用'} },
+ { title: '状态', dataIndex: 'status', width: 120, render: (status) => {status === 'active' ? '启用' : '禁用'} },
{ title: '操作', width: 160, render: (_, record: AppUser) => },
]} />
diff --git a/src/index.css b/src/index.css
index e69fdae..c630804 100644
--- a/src/index.css
+++ b/src/index.css
@@ -26,7 +26,7 @@
}
.section-card:hover {
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
+ box-shadow: theme('boxShadow.card-hover');
}
.page-stack {
@@ -38,7 +38,7 @@
}
.form-label {
- @apply mb-2 text-sm font-medium text-ink;
+ @apply mb-2 text-sm font-medium;
}
.form-help {
@@ -46,7 +46,7 @@
}
.stat-card {
- @apply rounded-xl border border-line/60 bg-white p-5 shadow-sm transition-all duration-300 hover:shadow-lg hover:-translate-y-0.5 cursor-default;
+ @apply rounded-xl border border-line/60 bg-white p-5 shadow-sm transition-shadow duration-300 hover:shadow-card-hover cursor-default;
}
}
@@ -66,12 +66,12 @@
}
.arco-menu-item:hover {
- background-color: #f2f3f5 !important;
+ background-color: theme('colors.canvas') !important;
}
.arco-menu-item.arco-menu-selected {
- background-color: #e8f3ff !important;
- color: #165dff !important;
+ background-color: theme('colors.brand-light') !important;
+ color: theme('colors.brand') !important;
font-weight: 600 !important;
}
@@ -80,29 +80,29 @@
}
.arco-menu-inline-header:hover {
- background-color: #f2f3f5 !important;
+ background-color: theme('colors.canvas') !important;
}
/* ── Card ───────────────────────────────────────────── */
.arco-card {
- border: 1px solid rgba(229, 230, 235, 0.6) !important;
- box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.04) !important;
+ border: 1px solid theme('colors.line / 60%') !important;
+ box-shadow: theme('boxShadow.card') !important;
transition: box-shadow 0.3s ease !important;
}
.arco-card:hover {
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06) !important;
+ box-shadow: theme('boxShadow.card-hover') !important;
}
.arco-card-header {
- border-bottom: 1px solid rgba(229, 230, 235, 0.5) !important;
+ border-bottom: 1px solid theme('colors.line / 50%') !important;
padding: 14px 20px !important;
}
.arco-card-header-title {
font-weight: 600 !important;
font-size: 15px !important;
- color: #1d2129 !important;
+ color: theme('colors.ink') !important;
}
/* ── Table ──────────────────────────────────────────── */
@@ -111,12 +111,12 @@
}
.arco-table-th {
- background-color: #fafbfc !important;
+ background-color: theme('colors.header-bg') !important;
font-weight: 600 !important;
- color: #4e5969 !important;
+ color: theme('colors.secondary') !important;
font-size: 13px !important;
letter-spacing: 0.01em;
- border-bottom: 1px solid rgba(229, 230, 235, 0.8) !important;
+ border-bottom: 1px solid theme('colors.line / 80%') !important;
}
.arco-table-td {
@@ -124,7 +124,7 @@
}
.arco-table-tr:hover .arco-table-td {
- background-color: #f7f8fa !important;
+ background-color: theme('colors.row-hover') !important;
}
.arco-table-sticky-header .arco-table-container {
@@ -142,16 +142,16 @@
}
.arco-pagination-item:hover {
- background-color: #e8f3ff !important;
- color: #165dff !important;
- border-color: #bedaff !important;
+ background-color: theme('colors.brand-light') !important;
+ color: theme('colors.brand') !important;
+ border-color: theme('colors.brand / 40%') !important;
}
.arco-pagination-item-active {
- background-color: #165dff !important;
- border-color: #165dff !important;
+ background-color: theme('colors.brand') !important;
+ border-color: theme('colors.brand') !important;
color: #fff !important;
- box-shadow: 0 2px 6px rgba(22, 93, 251, 0.3) !important;
+ box-shadow: 0 2px 6px theme('colors.brand / 30%') !important;
}
/* ── Button ─────────────────────────────────────────── */
@@ -161,25 +161,24 @@
}
.arco-btn-primary {
- box-shadow: 0 2px 6px rgba(22, 93, 251, 0.3) !important;
+ box-shadow: 0 2px 6px theme('colors.brand / 30%') !important;
}
.arco-btn-primary:hover {
- box-shadow: 0 4px 12px rgba(22, 93, 251, 0.4) !important;
- transform: translateY(-1px);
+ box-shadow: 0 4px 12px theme('colors.brand / 40%') !important;
}
.arco-btn-secondary:not(.arco-btn-disabled):hover {
- background-color: #f2f3f5 !important;
- border-color: #c9cdd4 !important;
+ background-color: theme('colors.canvas') !important;
+ border-color: theme('colors.line-hover') !important;
}
.arco-btn-text:not(.arco-btn-disabled):hover {
- background-color: #f2f3f5 !important;
+ background-color: theme('colors.canvas') !important;
}
.arco-btn-text-danger:not(.arco-btn-disabled):hover {
- background-color: #fff1f0 !important;
+ background-color: theme('colors.danger-light') !important;
}
/* ── Modal ──────────────────────────────────────────── */
@@ -188,7 +187,7 @@
}
.arco-modal-header {
- border-bottom: 1px solid rgba(229, 230, 235, 0.6) !important;
+ border-bottom: 1px solid theme('colors.line / 60%') !important;
padding: 16px 24px !important;
}
@@ -202,7 +201,7 @@
}
.arco-modal-footer {
- border-top: 1px solid rgba(229, 230, 235, 0.6) !important;
+ border-top: 1px solid theme('colors.line / 60%') !important;
padding: 12px 24px !important;
}
@@ -212,12 +211,12 @@
}
.arco-input-wrapper:hover {
- border-color: #c9cdd4 !important;
+ border-color: theme('colors.line-hover') !important;
}
.arco-input-wrapper.arco-input-focus {
- border-color: #165dff !important;
- box-shadow: 0 0 0 2px rgba(22, 93, 251, 0.1) !important;
+ border-color: theme('colors.brand') !important;
+ box-shadow: 0 0 0 2px theme('colors.brand / 10%') !important;
}
.arco-select-view {
@@ -225,12 +224,12 @@
}
.arco-select-view:hover {
- border-color: #c9cdd4 !important;
+ border-color: theme('colors.line-hover') !important;
}
.arco-select-view.arco-select-view-focus {
- border-color: #165dff !important;
- box-shadow: 0 0 0 2px rgba(22, 93, 251, 0.1) !important;
+ border-color: theme('colors.brand') !important;
+ box-shadow: 0 0 0 2px theme('colors.brand / 10%') !important;
}
.arco-textarea-wrapper {
@@ -238,18 +237,18 @@
}
.arco-textarea-wrapper:hover {
- border-color: #c9cdd4 !important;
+ border-color: theme('colors.line-hover') !important;
}
.arco-textarea-focus {
- border-color: #165dff !important;
- box-shadow: 0 0 0 2px rgba(22, 93, 251, 0.1) !important;
+ border-color: theme('colors.brand') !important;
+ box-shadow: 0 0 0 2px theme('colors.brand / 10%') !important;
}
/* ── Form ───────────────────────────────────────────── */
.arco-form-item-label {
font-weight: 500 !important;
- color: #4e5969 !important;
+ color: theme('colors.secondary') !important;
font-size: 13px !important;
}
@@ -262,12 +261,12 @@
/* ── Descriptions ───────────────────────────────────── */
.arco-descriptions-item-label {
font-weight: 500 !important;
- color: #86909c !important;
- background-color: #fafbfc !important;
+ color: theme('colors.muted') !important;
+ background-color: theme('colors.header-bg') !important;
}
.arco-descriptions-item-value {
- color: #1d2129 !important;
+ color: theme('colors.ink') !important;
}
/* ── Dropdown ───────────────────────────────────────── */
@@ -280,7 +279,7 @@
}
.arco-dropdown-menu-item:hover {
- background-color: #f2f3f5 !important;
+ background-color: theme('colors.canvas') !important;
}
/* ── Switch ─────────────────────────────────────────── */
@@ -289,5 +288,5 @@
}
.arco-switch-checked {
- box-shadow: 0 2px 4px rgba(22, 93, 251, 0.3) !important;
+ box-shadow: 0 2px 4px theme('colors.brand / 30%') !important;
}
diff --git a/src/layout/index.tsx b/src/layout/index.tsx
index a7a19b0..428c47f 100644
--- a/src/layout/index.tsx
+++ b/src/layout/index.tsx
@@ -58,7 +58,7 @@ export function AdminLayout() {
trigger={null}
>
- TK
+ TK
{!collapsed && TK短剧管理后台}
@@ -99,8 +99,8 @@ export function AdminLayout() {
}
>
-