From 8dc6a046fa6858f8e229f900337ab557388c81c5 Mon Sep 17 00:00:00 2001 From: weizwz <1124725517@qq.com> Date: Wed, 19 Nov 2025 22:03:31 +0800 Subject: [PATCH 1/8] =?UTF-8?q?=E4=BC=98=E5=8C=96=E7=A7=BB=E5=8A=A8?= =?UTF-8?q?=E7=AB=AF=E7=9A=84=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/layout/Header.tsx | 40 ++++++--------------- components/layout/ThemeToggle.tsx | 6 +--- components/modals/EditLinkModal.tsx | 56 ++++++++++++++--------------- 3 files changed, 39 insertions(+), 63 deletions(-) diff --git a/components/layout/Header.tsx b/components/layout/Header.tsx index c82b8d1..2f45f67 100644 --- a/components/layout/Header.tsx +++ b/components/layout/Header.tsx @@ -3,7 +3,7 @@ import React, { memo, useCallback } from 'react'; import { useRouter } from 'next/navigation'; import { Button, Tooltip } from 'antd'; -import { EditOutlined, MenuOutlined, GithubOutlined } from '@ant-design/icons'; +import { MenuOutlined, GithubOutlined, SettingOutlined } from '@ant-design/icons'; import SearchBar from './SearchBar'; import ThemeToggle from './ThemeToggle'; @@ -58,36 +58,28 @@ const Header = memo(function Header({ onMenuClick }: HeaderProps) { {/* 右侧工具栏 */} -
+
@@ -107,21 +99,17 @@ const Header = memo(function Header({ onMenuClick }: HeaderProps) { 唯知导航
-
+
{onMenuClick && (
diff --git a/components/layout/ThemeToggle.tsx b/components/layout/ThemeToggle.tsx index d3988e9..fb29e0b 100644 --- a/components/layout/ThemeToggle.tsx +++ b/components/layout/ThemeToggle.tsx @@ -76,16 +76,12 @@ export default function ThemeToggle() { -
- - - - {/* 导入导出工具栏 */} -
-
-
- - - 已选择 {selectedRowKeys.length} 项 - +
+ {/* 页头 */} +
+
+
+ {/* Logo/标题 */} +
+ 网站Logo +

+ 数据管理 +

-
- - - +
+
+
+ {/* 数据表格 */} +
+
+ {/* 导入导出工具栏 */} +
+
+
+ + + 已选择 {selectedRowKeys.length} 项 + +
+
+ - - - + + + + + +
-
- {/* 数据表格 */} -
- + +
+ + {/* 编辑链接弹窗 */} + + + {/* 编辑分类弹窗 */} + { + setCategoryEditModalOpen(false); + setCurrentCategory(null); + }} + onSubmit={handleCategorySubmit} + /> + + {/* 重置数据确认对话框 */} + -
- {/* 编辑链接弹窗 */} - - - {/* 编辑分类弹窗 */} - { - setCategoryEditModalOpen(false); - setCurrentCategory(null); - }} - onSubmit={handleCategorySubmit} - /> - - {/* 重置数据确认对话框 */} - - - {/* 批量分类弹窗 */} - setBatchCategoryModalOpen(false)} - onSubmit={handleBatchCategorySubmit} - /> + {/* 批量分类弹窗 */} + setBatchCategoryModalOpen(false)} + onSubmit={handleBatchCategorySubmit} + /> +
); From c4dda42f541fe02381a3019f7104c55f6280a01c Mon Sep 17 00:00:00 2001 From: weizwz <1124725517@qq.com> Date: Thu, 20 Nov 2025 10:22:14 +0800 Subject: [PATCH 5/8] =?UTF-8?q?=E4=BC=98=E5=8C=96=E8=A1=A8=E6=A0=BC?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=B1=95=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/globals.css | 17 ----- components/management/DataTable.tsx | 111 +++++++++++++++------------- 2 files changed, 59 insertions(+), 69 deletions(-) diff --git a/app/globals.css b/app/globals.css index 00b37cc..d13c46d 100644 --- a/app/globals.css +++ b/app/globals.css @@ -322,23 +322,6 @@ select:focus-visible { transition: none; } -/* DataTable 分类行样式 */ -.category-row > td { - background-color: #eff6ff !important; -} - -.dark .category-row > td { - background-color: rgba(30, 58, 138, 0.3) !important; -} - -.category-row:hover > td { - background-color: #dbeafe !important; -} - -.dark .category-row:hover > td { - background-color: rgba(30, 64, 175, 0.4) !important; -} - /* PWA 安装提示动画 */ @keyframes slide-up { from { diff --git a/components/management/DataTable.tsx b/components/management/DataTable.tsx index cc92a15..bc0d1dc 100644 --- a/components/management/DataTable.tsx +++ b/components/management/DataTable.tsx @@ -2,7 +2,7 @@ import React, { useState, useMemo, useEffect } from 'react'; import { Table, Button, Space, Popconfirm } from 'antd'; -import { EditOutlined, DeleteOutlined } from '@ant-design/icons'; +import { EditOutlined, DeleteOutlined, RightOutlined, DownOutlined } from '@ant-design/icons'; import type { ColumnsType } from 'antd/es/table'; import { Link } from '@/types/link'; import { Category } from '@/types/category'; @@ -59,18 +59,19 @@ export const DataTable: React.FC = ({ const categories = useAppSelector((state) => state.categories.items); // 使用外部传入的 selectedRowKeys 或内部状态 - const selectedRowKeys = externalSelectedRowKeys !== undefined ? externalSelectedRowKeys : internalSelectedRowKeys; + const selectedRowKeys = + externalSelectedRowKeys !== undefined ? externalSelectedRowKeys : internalSelectedRowKeys; // 构建树形数据结构 const treeData = useMemo(() => { const tree: TreeNode[] = []; // 按分类组织链接 - categories.forEach(category => { + categories.forEach((category) => { const categoryLinks = links - .filter(link => link.category === category.name) + .filter((link) => link.category === category.name) .sort((a, b) => a.order - b.order) - .map(link => ({ + .map((link) => ({ key: link.id, id: link.id, name: link.name, @@ -101,9 +102,9 @@ export const DataTable: React.FC = ({ // 添加未分类节点(如果有未分类的链接) const uncategorizedLinks = links - .filter(link => !link.category || link.category === '') + .filter((link) => !link.category || link.category === '') .sort((a, b) => a.order - b.order) - .map(link => ({ + .map((link) => ({ key: link.id, id: link.id, name: link.name, @@ -136,16 +137,13 @@ export const DataTable: React.FC = ({ return tree.sort((a, b) => a.order - b.order); }, [links, categories]); - // 默认展开所有分类(包括未分类) + // 默认展开第一个分类 useEffect(() => { - const allCategoryKeys = categories.map(cat => `category-${cat.id}`); - // 如果有未分类链接,也展开未分类节点 - const hasUncategorized = links.some(link => !link.category || link.category === ''); - if (hasUncategorized) { - allCategoryKeys.push('category-uncategorized'); + if (categories.length > 0) { + const firstCategoryKey = `category-${categories[0].id}`; + setExpandedRowKeys([firstCategoryKey]); } - setExpandedRowKeys(allCategoryKeys); - }, [categories, links]); + }, [categories]); // 表格列定义 const columns: ColumnsType = [ @@ -153,25 +151,48 @@ export const DataTable: React.FC = ({ title: '名称', dataIndex: 'name', key: 'name', - width: 160, + width: 120, ellipsis: true, - render: (name: string, record: TreeNode) => ( - - {name} - - ), + render: (name: string, record: TreeNode) => + record.isCategory ? ( + {name} + ) : record.icon ? ( +
+
+ 图标 { + e.currentTarget.style.display = 'none'; + }} + /> +
+ {name} +
+ ) : ( + {name} + ), }, { title: '地址', dataIndex: 'url', key: 'url', - width: 200, + width: 180, ellipsis: true, - render: (url: string, record: TreeNode) => + render: (url: string, record: TreeNode) => record.isCategory ? ( - ) : url ? ( - + {url} ) : null, @@ -180,9 +201,9 @@ export const DataTable: React.FC = ({ title: '描述', dataIndex: 'description', key: 'description', - width: 300, + width: 240, ellipsis: true, - render: (description: string, record: TreeNode) => + render: (description: string, record: TreeNode) => record.isCategory ? ( 共 {record.children?.length || 0} 条链接 ) : ( @@ -190,11 +211,11 @@ export const DataTable: React.FC = ({ ), }, { - title: '背景颜色', + title: '背景', dataIndex: 'backgroundColor', key: 'backgroundColor', width: 100, - render: (color: string, record: TreeNode) => + render: (color: string, record: TreeNode) => record.isCategory ? ( - ) : ( @@ -210,7 +231,7 @@ export const DataTable: React.FC = ({ { title: '操作', key: 'action', - width: 150, + width: 120, fixed: 'right', render: (_, record: TreeNode) => { if (record.isCategory) { @@ -218,7 +239,7 @@ export const DataTable: React.FC = ({ if (record.id === 'uncategorized') { return -; } - + // 分类节点的操作 const category: Category = { id: record.id, @@ -228,7 +249,7 @@ export const DataTable: React.FC = ({ createdAt: record.createdAt, updatedAt: record.updatedAt, }; - + return ( ); } - + // 链接节点的操作 return ( @@ -280,12 +296,7 @@ export const DataTable: React.FC = ({ okText="确定" cancelText="取消" > - @@ -300,7 +311,7 @@ export const DataTable: React.FC = ({ selectedRowKeys, onChange: (newSelectedRowKeys: React.Key[]) => { // 过滤掉分类节点 - const linkKeys = newSelectedRowKeys.filter(key => !String(key).startsWith('category-')); + const linkKeys = newSelectedRowKeys.filter((key) => !String(key).startsWith('category-')); if (onSelectionChange) { onSelectionChange(linkKeys); } else { @@ -321,15 +332,12 @@ export const DataTable: React.FC = ({ rowKey="key" size="middle" rowSelection={rowSelection} - rowClassName={(record) => - record.isCategory - ? 'category-row' - : '' - } + rowClassName={(record) => (record.isCategory ? 'category-row' : '')} expandable={{ expandedRowKeys, + indentSize: 0, onExpandedRowsChange: (keys) => setExpandedRowKeys([...keys]), - defaultExpandAllRows: true, + // defaultExpandAllRows: true, }} pagination={{ current: currentPage, @@ -347,7 +355,6 @@ export const DataTable: React.FC = ({ pageSizeOptions: ['10', '20', '50', '100'], }} scroll={{ x: 1200 }} - className="[&_.ant-empty]:z-0 [&_.category-row>td]:bg-blue-50! [&_.category-row>td]:dark:bg-blue-900/30! [&_.category-row:hover>td]:bg-blue-100! [&_.category-row:hover>td]:dark:bg-blue-800/40!" />
); From bfaccda189931e84978c0a26aff4ea1b17db7446 Mon Sep 17 00:00:00 2001 From: weizwz <1124725517@qq.com> Date: Thu, 20 Nov 2025 10:22:37 +0800 Subject: [PATCH 6/8] =?UTF-8?q?=E5=88=A0=E9=99=A4=E6=97=A0=E7=94=A8?= =?UTF-8?q?=E5=BC=95=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/management/DataTable.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/management/DataTable.tsx b/components/management/DataTable.tsx index bc0d1dc..a206e44 100644 --- a/components/management/DataTable.tsx +++ b/components/management/DataTable.tsx @@ -2,7 +2,7 @@ import React, { useState, useMemo, useEffect } from 'react'; import { Table, Button, Space, Popconfirm } from 'antd'; -import { EditOutlined, DeleteOutlined, RightOutlined, DownOutlined } from '@ant-design/icons'; +import { EditOutlined, DeleteOutlined } from '@ant-design/icons'; import type { ColumnsType } from 'antd/es/table'; import { Link } from '@/types/link'; import { Category } from '@/types/category'; From 5a6b86f2a51d8b190d8476cdc74e278a82b490f6 Mon Sep 17 00:00:00 2001 From: weizwz <1124725517@qq.com> Date: Thu, 20 Nov 2025 10:48:49 +0800 Subject: [PATCH 7/8] =?UTF-8?q?=E4=BC=98=E5=8C=96=E8=A1=A8=E6=A0=BC?= =?UTF-8?q?=E7=BB=86=E8=8A=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/management/DataTable.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/management/DataTable.tsx b/components/management/DataTable.tsx index a206e44..af93b33 100644 --- a/components/management/DataTable.tsx +++ b/components/management/DataTable.tsx @@ -224,7 +224,7 @@ export const DataTable: React.FC = ({ className="w-6 h-6 rounded border border-gray-300" style={{ backgroundColor: color || '#d9d9d9' }} /> - {color || '#d9d9d9'} + {color || '#d9d9d9'} ), }, From a2e027b3213fd4d3480ef9c3c58dc14c937c72e9 Mon Sep 17 00:00:00 2001 From: weizwz <1124725517@qq.com> Date: Thu, 20 Nov 2025 11:01:41 +0800 Subject: [PATCH 8/8] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=9C=80=E6=96=B0?= =?UTF-8?q?=E9=A2=84=E8=A7=88=E5=9B=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 14e6b05..f16b892 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@
-![](https://p.weizwz.com/nav/20251119_170634_d89c36024f0efbc4.webp) +![](https://p.weizwz.com/nav/20251120_110028_78c15d3713752f31.webp) 现代化的个人前端导航网站,为开发者提供高效、美观的资源导航体验