feat: v2.1.0 界面与凭据改进 —— 单一 API/MCP Key、邮件 Markdown 正文、/inboxs 域名筛选、暗色主题

- 单一 Key:API 与 MCP 共用一个 wmh_ Key,凭据迁移至 settings 表(0004 删除 api_credentials)
- Markdown:入库时 HTML→Markdown(mailhook 同思路),webhook payload 新增 markdown 字段
- /emails 路由改为 /inboxs 并支持域名筛选;设置按钮移入头像下拉
- 主题切换按钮(头像左侧,亮/暗持久化);设置模态仅 全局 Webhook/账号密码 两 tab 且高度限屏
- 列表操作列按钮加 SVG 图标;mailboxes 去 Webhook 列;最近邮件加收件人列
This commit is contained in:
bigcode
2026-09-30 13:27:28 +08:00
parent fec96e49cc
commit 7370cce784
38 changed files with 1281 additions and 512 deletions
+29 -11
View File
@@ -1,10 +1,11 @@
/** 前端入口:antd v6 + react-router(Vite 构建) */
import React from "react";
/** 前端入口:antd v6 + react-router(Vite 构建);亮/暗主题状态在顶层持有 */
import React, { useEffect, useState } from "react";
import { createRoot } from "react-dom/client";
import { ConfigProvider, App as AntdApp } from "antd";
import zhCN from "antd/locale/zh_CN";
import { createBrowserRouter, RouterProvider } from "react-router-dom";
import { antdTheme } from "./theme.ts";
import { applyDarkMode, buildAntdTheme, loadDarkMode } from "./theme.ts";
import { ThemeContext } from "./theme-context.ts";
import "./styles.css";
import { App } from "./App.tsx";
import { LoginPage } from "./pages/Login.tsx";
@@ -13,10 +14,10 @@ import { DashboardPage } from "./pages/Dashboard.tsx";
import { AccountsPage } from "./pages/Accounts.tsx";
import { DomainsPage } from "./pages/Domains.tsx";
import { MailboxesPage } from "./pages/Mailboxes.tsx";
import { EmailsPage } from "./pages/Emails.tsx";
import { InboxPage } from "./pages/Inbox.tsx";
import { setUnauthorizedHandler } from "./api.ts";
/** # 成员变量: 路由表 **/
/** # 成员变量: 路由表(邮件页路由 /inboxs,v2.1.0) **/
const router = createBrowserRouter([
{ path: "/login", element: <LoginPage /> },
{ path: "/oauth/sim/authorize", element: <OAuthSimPage /> },
@@ -28,11 +29,32 @@ const router = createBrowserRouter([
{ path: "accounts", element: <AccountsPage /> },
{ path: "domains", element: <DomainsPage /> },
{ path: "mailboxes", element: <MailboxesPage /> },
{ path: "emails", element: <EmailsPage /> },
{ path: "inboxs", element: <InboxPage /> },
],
},
]);
/** # 函数
* 顶层壳:持有主题状态,注入 Context 与 ConfigProvider
*/
function Shell() {
const [dark, setDark] = useState(loadDarkMode);
useEffect(() => {
applyDarkMode(dark);
}, [dark]);
return (
<ThemeContext.Provider value={{ dark, toggle: () => setDark((v) => !v) }}>
<ConfigProvider locale={zhCN} theme={buildAntdTheme(dark)}>
<AntdApp>
<RouterProvider router={router} />
</AntdApp>
</ConfigProvider>
</ThemeContext.Provider>
);
}
/** 未登录统一跳登录页 */
setUnauthorizedHandler(() => {
if (!location.pathname.startsWith("/login")) {
@@ -42,10 +64,6 @@ setUnauthorizedHandler(() => {
createRoot(document.getElementById("root")!).render(
<React.StrictMode>
<ConfigProvider locale={zhCN} theme={antdTheme}>
<AntdApp>
<RouterProvider router={router} />
</AntdApp>
</ConfigProvider>
<Shell />
</React.StrictMode>,
);