From d6ba26fd3937de56215750fd6c1b21a2909dc9d5 Mon Sep 17 00:00:00 2001 From: xiongxiao Date: Tue, 24 Mar 2026 13:04:47 +0800 Subject: [PATCH] Auto commit: 2026-03-24 13:04 --- AGENTS.md | 22 +- package.json | 22 +- src/components/a/Sidebar.tsx | 23 ++- src/modules/mark-api.ts | 378 +++++++++++++++++++++++++++++++++++ 4 files changed, 418 insertions(+), 27 deletions(-) create mode 100644 src/modules/mark-api.ts diff --git a/AGENTS.md b/AGENTS.md index 6b64f68..b74a037 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -30,23 +30,20 @@ pages/page-app/ └── store/ # 模块状态管理(Zustand) ``` -### hooks/ 文件夹说明 +### api 请求 -每个模块的 `hooks/` 文件夹用于封装与该模块相关的 React Query hooks: +`modules/*-api.ts` 文件用于封装 API 请求函数,使用 `@kevisual/query` 进行底层请求处理。 + +参考示例 +```ts +// src/modules/mark-api.ts +import { queryApi as markApi } from '@/modules/mark-api.ts'; -- **use-api-query.ts**: 使用 `@tanstack/react-query` 的 `useQuery` 封装 API 调用 - - 定义 `queryKeys` 常量用于缓存标识 - - 封装 `useQuery` hooks 用于数据获取(GET 请求) - - 封装 `useMutation` hooks 用于数据修改(POST/PUT/DELETE 请求) - - 支持预取(prefetch)和无限滚动(infinite query) -- **index.ts**: 导出模块所有 hooks,便于统一导入使用 +const res = await markApi.mark.list({ page: 1, pageSize: 10 }); +``` ### 状态和数据获取 -- **@tanstack/react-query** 用于数据获取、缓存和状态管理 - - 在模块的 `hooks/` 文件夹中封装 API 调用 - - QueryClient 实例位于 `src/modules/query.ts` - - 在 `src/routes/__root.tsx` 中通过 `QueryClientProvider` 提供 - **Zustand** 用于全局状态管理 - **@kevisual/query** 用于底层 API 请求封装 - **React Hook Form** 用于表单管理 @@ -54,7 +51,6 @@ pages/page-app/ ## 核心依赖 - **@base-ui/react**: Headless UI 基础组件 -- **@tanstack/react-query**: 数据获取、缓存和状态管理(配合 hooks/ 使用) - **@tanstack/react-router**: 基于 TanStack Router 插件的文件路由 - **class-variance-authority**: 基于变体的样式系统 - **clsx + tailwind-merge**: 通过 `cn()` 提供 className 工具函数 diff --git a/package.json b/package.json index 584fdce..c608f22 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "vite-react", + "name": "@kevisual/app", "private": true, "version": "0.0.1", "type": "module", @@ -9,6 +9,7 @@ "build": "vite build", "preview": "vite preview", "ui": "bunx shadcn@latest add ", + "template": "ev deploy . -k vite-react-template -v 0.0.1 -y y -u", "pub": "envision deploy ./dist -k vite-react -v 0.0.1 -y y -u" }, "files": [ @@ -20,9 +21,9 @@ "@base-ui/react": "^1.3.0", "@kevisual/api": "^0.0.65", "@kevisual/context": "^0.0.8", - "@kevisual/router": "0.1.6", - "@tanstack/react-query": "^5.91.3", - "@tanstack/react-router": "^1.168.1", + "@kevisual/router": "0.2.2", + "@tanstack/react-query": "^5.95.2", + "@tanstack/react-router": "^1.168.3", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "cmdk": "^1.1.1", @@ -30,12 +31,12 @@ "dayjs": "^1.11.20", "es-toolkit": "^1.45.1", "fuse.js": "^7.1.0", - "lucide-react": "^0.577.0", + "lucide-react": "^1.0.1", "nanoid": "^5.1.7", "next-themes": "^0.4.6", "react": "^19.2.4", "react-dom": "^19.2.4", - "react-hook-form": "^7.71.2", + "react-hook-form": "^7.72.0", "sonner": "^2.0.7", "zustand": "^5.0.12" }, @@ -49,18 +50,19 @@ "@kevisual/types": "^0.0.12", "@kevisual/vite-html-plugin": "^0.0.1", "@tailwindcss/vite": "^4.2.2", - "@tanstack/react-router-devtools": "^1.166.10", - "@tanstack/router-plugin": "^1.167.2", + "@tanstack/react-router-devtools": "^1.166.11", + "@tanstack/router-plugin": "^1.167.4", "@types/node": "^25.5.0", "@types/react": "^19.2.14", "@types/react-dom": "^19.2.3", "@vitejs/plugin-react": "^6.0.1", "dotenv": "^17.3.1", + "re-resizable": "^6.11.2", "tailwind-merge": "^3.5.0", "tailwindcss": "^4.2.2", "tw-animate-css": "^1.4.0", - "typescript": "^5.9.3", - "vite": "v8.0.1", + "typescript": "^6.0.2", + "vite": "v8.0.2", "vite-plugin-pwa": "^1.2.0" } } \ No newline at end of file diff --git a/src/components/a/Sidebar.tsx b/src/components/a/Sidebar.tsx index 31a177f..b9715ef 100644 --- a/src/components/a/Sidebar.tsx +++ b/src/components/a/Sidebar.tsx @@ -32,6 +32,7 @@ export interface SidebarProps { children?: React.ReactNode logo?: React.ReactNode title?: React.ReactNode + footer?: React.ReactNode defaultCollapsed?: boolean defaultWidth?: number minWidth?: number @@ -44,6 +45,7 @@ export function Sidebar({ children, logo, title, + footer, defaultCollapsed = false, defaultWidth = 208, minWidth = 120, @@ -80,7 +82,7 @@ export function Sidebar({ if (item.isDeveloping) { setDevelopingDialog({ open: true, title: item.title }) - } else if (item.external && item.path.startsWith('http')) { + } else if (item.external) { window.open(item.path, '_blank') } else if (item.path.startsWith('/')) { navigate({ to: item.path }) @@ -172,7 +174,6 @@ export function Sidebar({ ) } - return ( <>
@@ -194,7 +195,7 @@ export function Sidebar({ > ) : ( // 收起状态 -