refactor(layout): 重构应用布局结构和全局副作用处理

- 移除 AppShell 组件,将布局逻辑直接集成到各层级 layout
- 提取全局 Provider 到 AppProviders 组件统一管理
- 移除独立的 ThemeSync 和 QueryProvider 组件
- 将 AntThemeProvider 功能整合到 AppProviders
- 更新用户状态和主题相关的 prop 传递方式
- 优化管理后台菜单结构为全局常量定义
- 迁移页面私有 hooks 到对应页面目录下
- 提取通用 UI 副作用动作为全局 hooks 以减少重复代码
This commit is contained in:
HouYunFei
2026-05-21 11:42:22 +08:00
parent dce6ab2282
commit 603deee962
25 changed files with 151 additions and 257 deletions
+5 -10
View File
@@ -2,12 +2,12 @@
import { CopyOutlined, DeleteOutlined, EditOutlined, EyeOutlined, PlusOutlined, ReloadOutlined, SearchOutlined } from "@ant-design/icons";
import { ProTable, type ProColumns } from "@ant-design/pro-components";
import { App, Button, Card, Col, Flex, Form, Image, Input, Modal, Row, Select, Space, Tag, Tooltip, Typography } from "antd";
import { Button, Card, Col, Flex, Form, Image, Input, Modal, Row, Select, Space, Tag, Tooltip, Typography } from "antd";
import { useEffect, useState } from "react";
import copy from "copy-to-clipboard";
import { useCopyText } from "@/hooks/use-copy-text";
import type { AdminAsset } from "@/services/api/admin";
import { useAdminAssets } from "../hooks/use-admin-assets";
import { useAdminAssets } from "./use-admin-assets";
type AssetFormValues = Partial<AdminAsset> & { tagText?: string };
@@ -21,7 +21,7 @@ const editTypeOptions = typeOptions.slice(1);
export default function AdminAssetsPage() {
const { assets, tags, keyword, kind, tag, page, pageSize, total, isLoading, searchAssets, changeKind, changeTag, changePage, changePageSize, resetFilters, refreshAssets, saveAsset: saveAdminAsset, deleteAsset } = useAdminAssets();
const { message } = App.useApp();
const copyText = useCopyText();
const [form] = Form.useForm<AssetFormValues>();
const [editingAsset, setEditingAsset] = useState<Partial<AdminAsset> | null>(null);
const [detailAsset, setDetailAsset] = useState<AdminAsset | null>(null);
@@ -33,11 +33,6 @@ export default function AdminAssetsPage() {
if (editingAsset) form.setFieldsValue({ ...editingAsset, tagText: editingAsset.tags?.join(", ") || "" });
}, [editingAsset, form]);
const copyValue = async (value: string) => {
copy(value);
message.success("已复制");
};
const saveAsset = async () => {
const value = await form.validateFields();
const nextType = value.type || "text";
@@ -150,7 +145,7 @@ export default function AdminAssetsPage() {
</Flex>
{detailAsset.description ? <Typography.Paragraph type="secondary" style={{ margin: 0 }}>{detailAsset.description}</Typography.Paragraph> : null}
<Input.TextArea value={detailAsset.type === "image" ? detailAsset.url || detailAsset.coverUrl : detailAsset.content} rows={7} readOnly />
<Button icon={<CopyOutlined />} onClick={() => void copyValue(detailAsset.type === "image" ? detailAsset.url || detailAsset.coverUrl : detailAsset.content)}></Button>
<Button icon={<CopyOutlined />} onClick={() => copyText(detailAsset.type === "image" ? detailAsset.url || detailAsset.coverUrl : detailAsset.content)}></Button>
</Flex>
) : null}
</Modal>