{"owner":"vbenjs","repo":"vue-vben-admin","hasSkills":true,"totalSkillsCount":19,"totalTokensCount":5640,"categories":["plugin-manifest"],"hasMcp":false,"mcpConfig":null,"found":["internal/vite-config/src/plugins/inject-app-loading/README.md","packages/@core/README.md","packages/@core/base/README.md","packages/@core/base/shared/src/cache/README.md","packages/@core/composables/src/use-simple-locale/README.md","packages/@core/ui-kit/README.md","packages/@core/ui-kit/menu-ui/README.md","packages/constants/README.md","packages/effects/README.md","packages/effects/hooks/README.md","packages/effects/layouts/src/basic/README.md","packages/effects/plugins/README.md","packages/effects/plugins/src/echarts/README.md","packages/effects/plugins/src/motion/README.md","packages/effects/plugins/src/vxe-table/README.md","packages/icons/README.md","packages/styles/README.md","packages/types/README.md","packages/utils/README.md"],"skills":{"internal/vite-config/src/plugins/inject-app-loading/README.md":"# inject-app-loading\n\n用于在应用加载时显示加载动画的插件，可自行选择加载动画的样式。\n","packages/@core/README.md":"# @vben-core\n\n系统一些比较基础的SDK和UI组件库，该目录后续完善后，可能会迁移出去或者发布到npm，请勿将任何业务逻辑和业务包放在该目录。\n","packages/@core/base/README.md":"# base\n\n基础共享包，请勿引入 workspace 依赖\n\n-\n","packages/@core/base/shared/src/cache/README.md":"# Cache 模块\n\n基于**策略模式**的异步存储管理方案，支持多种存储后端（localStorage、IndexedDB、Memory），提供统一的 API 接口。\n\n## 架构设计\n\n```shell\n┌───────────────────────────────────────────────┐\n│             StorageManager                    │\n│  ┌─────────────┐  ┌───────────────────────┐   │\n│  │ Prefix 隔离 │   │   TTL 过期管理        │   │\n│  └─────────────┘  └───────────────────────┘   │\n├───────────────────────────────────────────────┤\n│             IStorageDriver                    │\n├──────────┬─────────────────┬──────────────────┤\n│  Local   │   IndexedDB     │     Memory       │\n│  Storage │   Driver        │     Driver       │\n│  Driver  │                 │                  │\n└──────────┴─────────────────┴──────────────────┘\n```\n\n**分层职责：**\n\n| 层级             | 职责                                         |\n| ---------------- | -------------------------------------------- |\n| `StorageManager` | 命名空间前缀隔离、TTL 过期检查、统一对外 API |\n| `IStorageDriver` | 纯粹的 KV 存取抽象接口                       |\n| 各 Driver 实现   | 对接具体存储引擎，不感知前缀和 TTL           |\n\n---\n\n## 快速开始\n\n### 基本使用（默认 localStorage）\n\n```typescript\nimport { StorageManager } from '@vben-core/shared/cache';\n\nconst cache = new StorageManager({ prefix: 'myapp' });\n// 使用 IndexedDB\n//new StorageManager({ driver: new IndexedDBDriver(), prefix: 'app' });\n\n// 使用 sessionStorage\n//new StorageManager({ driver: new LocalStorageDriver({ storageType: 'sessionStorage' }), prefix: 'app' });\n\n// 测试环境\n//new StorageManager({ driver: new MemoryStorageDriver(), prefix: 'test' });\n\n// 存储数据\nawait cache.setItem('user', { name: '张三', age: 28 });\n\n// 读取数据\nconst user = await cache.getItem('user');\n// => { name: '张三', age: 28 }\n\n// 带默认值读取\nconst settings = await cache.getItem('settings', { theme: 'light' });\n// 如果不存在，返回 { theme: 'light' }\n\n// 删除数据\nawait cache.removeItem('user');\n\n// 清除当前前缀下所有数据\nawait cache.clear();\n```\n\n### 带 TTL 过期\n\n```typescript\nconst cache = new StorageManager({ prefix: 'session' });\n\n// 设置 5 分钟后过期（TTL 单位为毫秒）\nawait cache.setItem('token', 'abc123', 5 * 60 * 1000);\n\n// 5 分钟内可以正常读取\nconst token = await cache.getItem('token');\n// => 'abc123'\n\n// 5 分钟后自动返回 null（惰性删除）\nconst expiredToken = await cache.getItem('token');\n// => null\n\n// 主动清理所有过期项\nawait cache.clearExpiredItems();\n```\n\n---\n\n## 存储驱动\n\n### LocalStorageDriver（默认）\n\n基于浏览器 `localStorage` 或 `sessionStorage`，数据持久化存储。\n\n```typescript\nimport { LocalStorageDriver, StorageManager } from '@vben-core/shared/cache';\n\n// 使用 localStorage（默认）\nconst cache = new StorageManager({\n  driver: new LocalStorageDriver(),\n  prefix: 'app',\n});\n\n// 使用 sessionStorage\nconst sessionCache = new StorageManager({\n  driver: new LocalStorageDriver({ storageType: 'sessionStorage' }),\n  prefix: 'app',\n});\n```\n\n**特点：**\n\n- 同步 API 用 async 包装，保持接口统一\n- 自动处理 JSON 序列化/反序列化\n- 数据损坏时自动清除并返回 null\n- 存储上限约 5-10MB（视浏览器而定）\n\n**适用场景：** 用户偏好设置、小型配置数据、Token 存储\n\n---\n\n### IndexedDBDriver\n\n基于浏览器 IndexedDB，支持大容量结构化数据存储。\n\n```typescript\nimport {IndexedDBDriver, StorageManager} from '@vben-core/shared/cache';\n\nconst cache = new StorageManager({\n  driver: new IndexedDBDriver({\n    dbName: 'my-app-db',     // 数据库名称，默认 'vben-storage'\n    dbVersion: 1,            // 数据库版本，默认 1\n    storeName: 'cache-store', // 对象存储名称，默认 'kv-store'\n  }),\n  prefix: 'data',\n});\n\n// 存储大量数据\nawait cache.setItem('table-data', largeDataArray);\n\n// 存储二进制友好的结构（IndexedDB 原生支持）\nawait cache.setItem('config', {\n  columns: [...],\n  filters: [...],\n  pagination: {page: 1, size: 20},\n});\n```\n\n**特点：**\n\n- 懒初始化：首次操作时自动打开数据库，无需手动调用 `init()`\n- 存储容量大（通常数百 MB 到 GB 级别）\n- 支持结构化克隆（可存储 Date、RegExp、Blob 等复杂类型）\n- 天然异步，不阻塞主线程\n\n**适用场景：** 离线数据缓存、大型表格数据、文件/图片缓存、复杂业务数据\n\n---\n\n### MemoryStorageDriver\n\n基于内存 Map，数据不持久化，页面刷新即丢失。\n\n```typescript\nimport { MemoryStorageDriver, StorageManager } from '@vben-core/shared/cache';\n\nconst cache = new StorageManager({\n  driver: new MemoryStorageDriver(),\n  prefix: 'test',\n});\n```\n\n**特点：**\n\n- 读写速度最快\n- 无浏览器 API 依赖\n- 数据随页面生命周期销毁\n\n**适用场景：** 单元测试、SSR 服务端渲染、临时运行时缓存\n\n---\n\n## API 参考\n\n### StorageManager\n\n#### 构造函数\n\n```typescript\nnew StorageManager(options?: StorageManagerOptions)\n```\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `driver` | `IStorageDriver` | `new LocalStorageDriver()` | 存储驱动实例 |\n| `prefix` | `string` | `''` | 键前缀，用于命名空间隔离 |\n\n#### 方法\n\n| 方法 | 签名 | 说明 |\n| --- | --- | --- |\n| `getItem` | `getItem<T>(key: string, defaultValue?: T \\| null): Promise<T \\| null>` | 获取存储项，过期或不存在返回默认值 |\n| `setItem` | `setItem<T>(key: string, value: T, ttl?: number): Promise<void>` | 设置存储项，可选 TTL（毫秒） |\n| `removeItem` | `removeItem(key: string): Promise<void>` | 删除指定存储项 |\n| `clear` | `clear(): Promise<void>` | 清除当前前缀下所有存储项 |\n| `clearExpiredItems` | `clearExpiredItems(): Promise<void>` | 主动清理所有过期项 |\n\n---\n\n### IStorageDriver 接口\n\n自定义驱动需要实现此接口：\n\n```typescript\ninterface IStorageDriver {\n  clear(): Promise<void>;\n\n  getItem<T>(key: string): Promise<null | T>;\n\n  keys(): Promise<string[]>;\n\n  removeItem(key: string): Promise<void>;\n\n  setItem<T>(key: string, value: T): Promise<void>;\n}\n```\n\n---\n\n## 高级用法\n\n### 自定义 Driver\n\n```typescript\nimport type { IStorageDriver } from '@vben-core/shared/cache';\n\nclass CookieStorageDriver implements IStorageDriver {\n  async getItem<T>(key: string): Promise<null | T> {\n    const value = getCookie(key);\n    return value ? JSON.parse(value) : null;\n  }\n\n  async setItem<T>(key: string, value: T): Promise<void> {\n    setCookie(key, JSON.stringify(value));\n  }\n\n  async removeItem(key: string): Promise<void> {\n    deleteCookie(key);\n  }\n\n  async clear(): Promise<void> {\n    clearAllCookies();\n  }\n\n  async keys(): Promise<string[]> {\n    return getAllCookieNames();\n  }\n}\n\n// 使用自定义 Driver\nconst cache = new StorageManager({\n  driver: new CookieStorageDriver(),\n  prefix: 'ck',\n});\n```\n\n### 根据环境动态选择 Driver\n\n```typescript\nimport {\n  IndexedDBDriver,\n  LocalStorageDriver,\n  MemoryStorageDriver,\n  StorageManager,\n} from '@vben-core/shared/cache';\n\nfunction createStorageManager(prefix: string) {\n  // SSR 环境使用内存驱动\n  if (typeof window === 'undefined') {\n    return new StorageManager({\n      driver: new MemoryStorageDriver(),\n      prefix,\n    });\n  }\n\n  // 大数据场景使用 IndexedDB\n  if (needsLargeStorage()) {\n    return new StorageManager({\n      driver: new IndexedDBDriver({ dbName: `${prefix}-db` }),\n      prefix,\n    });\n  }\n\n  // 默认使用 localStorage\n  return new StorageManager({ prefix });\n}\n```\n\n### 命名空间隔离\n\n```typescript\n// 不同模块使用不同前缀，互不干扰\nconst userCache = new StorageManager({ prefix: 'user' });\nconst configCache = new StorageManager({ prefix: 'config' });\n\nawait userCache.setItem('profile', { name: '张三' });\nawait configCache.setItem('profile', { theme: 'dark' });\n\n// 各自独立\nawait userCache.getItem('profile'); // => { name: '张三' }\nawait configCache.getItem('profile'); // => { theme: 'dark' }\n\n// 只清除 user 前缀的数据\nawait userCache.clear();\nawait configCache.getItem('profile'); // => { theme: 'dark' }（不受影响）\n```\n\n### 定时清理过期数据\n\n```typescript\nconst cache = new StorageManager({ prefix: 'app' });\n\n// 应用启动时清理一次\nawait cache.clearExpiredItems();\n\n// 或者定时清理（每 10 分钟）\nsetInterval(\n  async () => {\n    await cache.clearExpiredItems();\n  },\n  10 * 60 * 1000,\n);\n```\n\n---\n\n## 数据存储格式\n\n`StorageManager` 在 Driver 层存储的数据结构为：\n\n```typescript\ninterface StorageItem<T> {\n  expiry?: number; // 过期时间戳（毫秒），undefined 表示永不过期\n  value: T; // 实际业务数据\n}\n```\n\n实际存储的 key 格式为：`{prefix}-{key}`\n\n例如 `prefix = 'app'`，`key = 'user'`，则实际存储键为 `app-user`。\n\n---\n\n## 过期策略\n\n采用**惰性删除 + 主动清理**双重策略：\n\n| 策略 | 触发时机 | 说明 |\n| --- | --- | --- |\n| 惰性删除 | 调用 `getItem` 时 | 读取时检查过期，过期则删除并返回默认值 |\n| 主动清理 | 调用 `clearExpiredItems` 时 | 遍历所有带前缀的 key，删除已过期项 |\n\n---\n\n## 各 Driver 对比\n\n| 特性       | LocalStorageDriver  | IndexedDBDriver  | MemoryStorageDriver |\n| ---------- | ------------------- | ---------------- | ------------------- |\n| 持久化     | ✅                  | ✅               | ❌                  |\n| 容量       | 5-10 MB             | 数百 MB+         | 受内存限制          |\n| 速度       | 快（同步）          | 中等（异步 I/O） | 最快                |\n| 数据类型   | 仅 JSON 可序列化    | 结构化克隆       | 任意 JS 对象        |\n| 浏览器支持 | 所有现代浏览器      | 所有现代浏览器   | 任意环境            |\n| 阻塞主线程 | 是                  | 否               | 否                  |\n| 适用场景   | 配置、Token、小数据 | 离线缓存、大数据 | 测试、SSR           |\n\n---\n\n## 在项目中的使用\n\n本项目中 `StorageManager` 主要被 `PreferenceManager` 消费，用于持久化用户偏好设置：\n\n```typescript\n// packages/@core/preferences/src/preferences.ts\nclass PreferenceManager {\n  private cache: StorageManager;\n\n  constructor() {\n    this.cache = new StorageManager();\n    this.state = reactive<Preferences>({ ...defaultPreferences });\n  }\n\n  initPreferences = async ({ namespace }) => {\n    // 用应用命名空间重新初始化\n    this.cache = new StorageManager({ prefix: namespace });\n\n    // 从缓存加载偏好设置\n    const cached = await this.cache.getItem<Preferences>('preferences');\n    // ...\n  };\n}\n```\n\n---\n\n## 注意事项\n\n1. **所有方法都是异步的** — 即使底层是同步的 localStorage，API 也返回 Promise，确保切换 Driver 时无需改动调用方。\n\n2. **TTL 单位是毫秒** — `setItem('key', value, 60000)` 表示 60 秒后过期。\n\n3. **IndexedDB 懒初始化** — 不需要手动调用 `init()` 或 `open()`，首次操作时自动打开数据库连接并复用。\n\n4. **前缀隔离是逻辑隔离** — `clear()` 只清除当前前缀下的数据，不影响其他前缀或无前缀的数据。\n\n5. **错误处理** — LocalStorageDriver 在 JSON 解析失败时自动清除损坏数据； `PreferenceManager.saveToCache` 内部 try-catch 防止未捕获异常。\n\n6. **IndexedDB 版本升级** — 如果需要修改 objectStore 结构，需要递增 `dbVersion`。当前实现在 `upgradeneeded` 事件中自动创建 objectStore。\n","packages/@core/composables/src/use-simple-locale/README.md":"# Simple i18n\n\nSimple i18 implementation\n","packages/@core/ui-kit/README.md":"# ui-kit\n\n用于管理公共组件、不同UI组件库封装的组件\n","packages/@core/ui-kit/menu-ui/README.md":"# 菜单组件\n","packages/constants/README.md":"# @vben/constants\n\n用于多个 `app` 公用的常量，继承了 `@vben-core/shared/constants` 的所有能力。业务上有通用常量可以放在这里。\n\n## 用法\n\n### 添加依赖\n\n```bash\n# 进入目标应用目录，例如 apps/xxxx-app\n# cd apps/xxxx-app\npnpm add @vben/constants\n```\n\n### 使用\n\n```ts\nimport { LOGIN_PATH } from '@vben/constants';\n```\n","packages/effects/README.md":"## Effects 目录\n\n`effects` 目录专门用于存放与轻微耦合相关的代码和逻辑。如果你的包具有以下特点，建议将其放置在 `effects` 目录下：\n\n- **状态管理**：使用状态管理框架 `pinia`，并包含处理副作用（如异步操作、API 调用）的部分。\n- **用户偏好设置**：使用 `@vben-core/preferences` 处理用户偏好设置，涉及本地存储或浏览器缓存逻辑（如使用 `localStorage`）。\n- **导航和路由**：处理导航、页面跳转等场景，需要管理路由变化的逻辑。\n- **组件库依赖**：包含与特定组件库紧密耦合或依赖大型仓库的部分。\n\n通过将相关代码归类到 `effects` 目录，可以使项目结构更加清晰，便于维护和扩展。\n","packages/effects/hooks/README.md":"# @vben/hooks\n\n用于多个 `app` 公用的 hook，继承了 `@vben/hooks` 的所有能力。业务上有通用 hooks 可以放在这里。\n\n## 用法\n\n### 添加依赖\n\n```bash\n# 进入目标应用目录，例如 apps/xxxx-app\n# cd apps/xxxx-app\npnpm add @vben/hooks\n```\n\n### 使用\n\n```ts\nimport { useNamespace } from '@vben/hooks';\n```\n","packages/effects/layouts/src/basic/README.md":"## layout\n\n### header\n\n- 支持N个自定义插槽，命名方式：header-right-n，header-left-n\n- header-left-n ，排序方式：0-19 ,breadcrumb 21-x\n- header-right-n ，排序方式：0-49，global-search，51-59，theme-toggle，61-69，language-toggle，71-79，fullscreen，81-89，notification，91-149，user-dropdown，151-x\n","packages/effects/plugins/README.md":"# @vben/plugins\n\n该目录用于存放项目中集成的第三方库及其相关插件。每个插件都包含了可重用的逻辑、配置和组件，方便在项目中进行统一管理和调用。\n\n## 注意\n\n所有的第三方插件都必须以 `subpath` 形式引入，例：\n\n以 `echarts` 为例，引入方式如下：\n\n**packages.json**\n\n```json\n\"exports\": {\n    \"./echarts\": {\n      \"types\": \"./src/echarts/index.ts\",\n      \"default\": \"./src/echarts/index.ts\"\n    }\n  }\n```\n\n**使用方式**\n\n```ts\nimport { useEcharts } from '@vben/plugins/echarts';\n```\n\n这样做的好处是，应用可以自行选择是否使用插件，而不会因为插件的引入及副作用而导致打包体积增大，只引入需要的插件即可。\n","packages/effects/plugins/src/echarts/README.md":"# ECharts Plugin\n\nECharts 图表插件，预置常用组件和图表类型。\n\n## 导出\n\n| 导出         | 类型 | 说明         |\n| ------------ | ---- | ------------ |\n| `default`    | 对象 | echarts 实例 |\n| `EchartsUI`  | 组件 | 图表容器组件 |\n| `ECOption`   | 类型 | 图表配置类型 |\n| `useEcharts` | 函数 | 组合式函数   |\n\n## 使用\n\n```ts\nimport { EchartsUI, useEcharts, ECOption } from '@vben/plugins/echarts';\n```\n\n## 类型\n\n```ts\nimport type { ECOption } from '@vben/plugins/echarts';\n```\n\n## 预置组件\n\n- TitleComponent\n- TooltipComponent\n- GridComponent\n- LegendComponent\n- ToolboxComponent\n- DatasetComponent\n- TransformComponent\n\n## 预置图表\n\n- BarChart\n- LineChart\n- PieChart\n- RadarChart\n","packages/effects/plugins/src/motion/README.md":"# Motion Plugin\n\n基于 @vueuse/motion 的动画插件。\n\n## 导出\n\n| 导出              | 类型 | 说明       |\n| ----------------- | ---- | ---------- |\n| `Motion`          | 组件 | 动画组件   |\n| `MotionGroup`     | 组件 | 动画组组件 |\n| `MotionDirective` | 指令 | 动画指令   |\n| `MotionPlugin`    | 插件 | Vue 插件   |\n\n## 使用\n\n```ts\nimport { MotionPlugin, Motion, MotionDirective } from '@vben/plugins/motion';\n\napp.use(MotionPlugin);\n```\n\n## 类型\n\n```ts\nimport type { MotionOptions, MotionVariants } from '@vben/plugins/motion';\n```\n","packages/effects/plugins/src/vxe-table/README.md":"# VXE Table Plugin\n\n基于 vxe-table 和 vxe-pc-ui 的表格组件插件。\n\n## 导出\n\n| 导出                  | 类型 | 说明           |\n| --------------------- | ---- | -------------- |\n| `setupVbenVxeTable`   | 函数 | 初始化配置函数 |\n| `useVbenVxeGrid`      | 函数 | 表格组合式函数 |\n| `VbenVxeGrid`         | 组件 | 表格组件       |\n| `VxeTableGridColumns` | 类型 | 表格列类型     |\n| `VxeTableGridOptions` | 类型 | 表格配置类型   |\n| `VxeGridProps`        | 类型 | 表格 Props     |\n| `VxeGridListeners`    | 类型 | 表格事件类型   |\n\n## 使用\n\n```ts\nimport {\n  setupVbenVxeTable,\n  useVbenVxeGrid,\n  VbenVxeGrid,\n} from '@vben/plugins/vxe-table';\n```\n\n## 初始化\n\n在应用入口处调用：\n\n```ts\nimport { setupVbenVxeTable } from '@vben/plugins/vxe-table';\nimport { useVbenForm } from '@vben-core/form-ui';\n\nsetupVbenVxeTable({\n  configVxeTable: (vxeUI) => {\n    // 配置 VXE Table\n  },\n  useVbenForm,\n});\n```\n\n## 类型\n\n```ts\nimport type {\n  VxeTableGridOptions,\n  VxeGridProps,\n} from '@vben/plugins/vxe-table';\n```\n","packages/icons/README.md":"# @vben/icons\n\n用于多个 `app` 公用的图标文件，继承了 `@vben-core/icons` 的所有能力。业务上有通用图标可以放在这里。\n\n## 用法\n\n### 添加依赖\n\n```bash\n# 进入目标应用目录，例如 apps/xxxx-app\n# cd apps/xxxx-app\npnpm add @vben/icons\n```\n\n### 使用\n\n```ts\nimport { X } from '@vben/icons';\n```\n","packages/styles/README.md":"# @vben/styles\n\n用于多个 `app` 公用的样式文件，继承了 `@vben-core/design` 的所有能力。业务上有通用的样式文件可以放在这里。\n\n## 用法\n\n### 添加依赖\n\n```bash\n# 进入目标应用目录，例如 apps/xxxx-app\n# cd apps/xxxx-app\npnpm add @vben/styles\n```\n\n### 使用\n\n```ts\nimport '@vben/styles';\n```\n","packages/types/README.md":"# @vben/types\n\n用于多个 `app` 公用的工具类型，继承了 `@vben-core/typings` 的所有能力。业务上有通用的类型定义可以放在这里。\n\n## 用法\n\n### 添加依赖\n\n```bash\n# 进入目标应用目录，例如 apps/xxxx-app\n# cd apps/xxxx-app\npnpm add @vben/types\n```\n\n### 使用\n\n```ts\n// 推荐加上 type\nimport type { SelectOption } from '@vben/types';\n```\n","packages/utils/README.md":"# @vben/utils\n\n用于多个 `app` 公用的工具包，继承了 `@vben-core/shared/utils` 的所有能力。业务上有通用的工具函数可以放在这里。\n\n## 用法\n\n### 添加依赖\n\n```bash\n# 进入目标应用目录，例如 apps/xxxx-app\n# cd apps/xxxx-app\npnpm add @vben/utils\n```\n\n### 使用\n\n```ts\nimport { isString } from '@vben/utils';\n```\n"},"files":{"internal/vite-config/src/plugins/inject-app-loading/README.md":"# inject-app-loading\n\n用于在应用加载时显示加载动画的插件，可自行选择加载动画的样式。\n","packages/@core/README.md":"# @vben-core\n\n系统一些比较基础的SDK和UI组件库，该目录后续完善后，可能会迁移出去或者发布到npm，请勿将任何业务逻辑和业务包放在该目录。\n","packages/@core/base/README.md":"# base\n\n基础共享包，请勿引入 workspace 依赖\n\n-\n","packages/@core/base/shared/src/cache/README.md":"# Cache 模块\n\n基于**策略模式**的异步存储管理方案，支持多种存储后端（localStorage、IndexedDB、Memory），提供统一的 API 接口。\n\n## 架构设计\n\n```shell\n┌───────────────────────────────────────────────┐\n│             StorageManager                    │\n│  ┌─────────────┐  ┌───────────────────────┐   │\n│  │ Prefix 隔离 │   │   TTL 过期管理        │   │\n│  └─────────────┘  └───────────────────────┘   │\n├───────────────────────────────────────────────┤\n│             IStorageDriver                    │\n├──────────┬─────────────────┬──────────────────┤\n│  Local   │   IndexedDB     │     Memory       │\n│  Storage │   Driver        │     Driver       │\n│  Driver  │                 │                  │\n└──────────┴─────────────────┴──────────────────┘\n```\n\n**分层职责：**\n\n| 层级             | 职责                                         |\n| ---------------- | -------------------------------------------- |\n| `StorageManager` | 命名空间前缀隔离、TTL 过期检查、统一对外 API |\n| `IStorageDriver` | 纯粹的 KV 存取抽象接口                       |\n| 各 Driver 实现   | 对接具体存储引擎，不感知前缀和 TTL           |\n\n---\n\n## 快速开始\n\n### 基本使用（默认 localStorage）\n\n```typescript\nimport { StorageManager } from '@vben-core/shared/cache';\n\nconst cache = new StorageManager({ prefix: 'myapp' });\n// 使用 IndexedDB\n//new StorageManager({ driver: new IndexedDBDriver(), prefix: 'app' });\n\n// 使用 sessionStorage\n//new StorageManager({ driver: new LocalStorageDriver({ storageType: 'sessionStorage' }), prefix: 'app' });\n\n// 测试环境\n//new StorageManager({ driver: new MemoryStorageDriver(), prefix: 'test' });\n\n// 存储数据\nawait cache.setItem('user', { name: '张三', age: 28 });\n\n// 读取数据\nconst user = await cache.getItem('user');\n// => { name: '张三', age: 28 }\n\n// 带默认值读取\nconst settings = await cache.getItem('settings', { theme: 'light' });\n// 如果不存在，返回 { theme: 'light' }\n\n// 删除数据\nawait cache.removeItem('user');\n\n// 清除当前前缀下所有数据\nawait cache.clear();\n```\n\n### 带 TTL 过期\n\n```typescript\nconst cache = new StorageManager({ prefix: 'session' });\n\n// 设置 5 分钟后过期（TTL 单位为毫秒）\nawait cache.setItem('token', 'abc123', 5 * 60 * 1000);\n\n// 5 分钟内可以正常读取\nconst token = await cache.getItem('token');\n// => 'abc123'\n\n// 5 分钟后自动返回 null（惰性删除）\nconst expiredToken = await cache.getItem('token');\n// => null\n\n// 主动清理所有过期项\nawait cache.clearExpiredItems();\n```\n\n---\n\n## 存储驱动\n\n### LocalStorageDriver（默认）\n\n基于浏览器 `localStorage` 或 `sessionStorage`，数据持久化存储。\n\n```typescript\nimport { LocalStorageDriver, StorageManager } from '@vben-core/shared/cache';\n\n// 使用 localStorage（默认）\nconst cache = new StorageManager({\n  driver: new LocalStorageDriver(),\n  prefix: 'app',\n});\n\n// 使用 sessionStorage\nconst sessionCache = new StorageManager({\n  driver: new LocalStorageDriver({ storageType: 'sessionStorage' }),\n  prefix: 'app',\n});\n```\n\n**特点：**\n\n- 同步 API 用 async 包装，保持接口统一\n- 自动处理 JSON 序列化/反序列化\n- 数据损坏时自动清除并返回 null\n- 存储上限约 5-10MB（视浏览器而定）\n\n**适用场景：** 用户偏好设置、小型配置数据、Token 存储\n\n---\n\n### IndexedDBDriver\n\n基于浏览器 IndexedDB，支持大容量结构化数据存储。\n\n```typescript\nimport {IndexedDBDriver, StorageManager} from '@vben-core/shared/cache';\n\nconst cache = new StorageManager({\n  driver: new IndexedDBDriver({\n    dbName: 'my-app-db',     // 数据库名称，默认 'vben-storage'\n    dbVersion: 1,            // 数据库版本，默认 1\n    storeName: 'cache-store', // 对象存储名称，默认 'kv-store'\n  }),\n  prefix: 'data',\n});\n\n// 存储大量数据\nawait cache.setItem('table-data', largeDataArray);\n\n// 存储二进制友好的结构（IndexedDB 原生支持）\nawait cache.setItem('config', {\n  columns: [...],\n  filters: [...],\n  pagination: {page: 1, size: 20},\n});\n```\n\n**特点：**\n\n- 懒初始化：首次操作时自动打开数据库，无需手动调用 `init()`\n- 存储容量大（通常数百 MB 到 GB 级别）\n- 支持结构化克隆（可存储 Date、RegExp、Blob 等复杂类型）\n- 天然异步，不阻塞主线程\n\n**适用场景：** 离线数据缓存、大型表格数据、文件/图片缓存、复杂业务数据\n\n---\n\n### MemoryStorageDriver\n\n基于内存 Map，数据不持久化，页面刷新即丢失。\n\n```typescript\nimport { MemoryStorageDriver, StorageManager } from '@vben-core/shared/cache';\n\nconst cache = new StorageManager({\n  driver: new MemoryStorageDriver(),\n  prefix: 'test',\n});\n```\n\n**特点：**\n\n- 读写速度最快\n- 无浏览器 API 依赖\n- 数据随页面生命周期销毁\n\n**适用场景：** 单元测试、SSR 服务端渲染、临时运行时缓存\n\n---\n\n## API 参考\n\n### StorageManager\n\n#### 构造函数\n\n```typescript\nnew StorageManager(options?: StorageManagerOptions)\n```\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `driver` | `IStorageDriver` | `new LocalStorageDriver()` | 存储驱动实例 |\n| `prefix` | `string` | `''` | 键前缀，用于命名空间隔离 |\n\n#### 方法\n\n| 方法 | 签名 | 说明 |\n| --- | --- | --- |\n| `getItem` | `getItem<T>(key: string, defaultValue?: T \\| null): Promise<T \\| null>` | 获取存储项，过期或不存在返回默认值 |\n| `setItem` | `setItem<T>(key: string, value: T, ttl?: number): Promise<void>` | 设置存储项，可选 TTL（毫秒） |\n| `removeItem` | `removeItem(key: string): Promise<void>` | 删除指定存储项 |\n| `clear` | `clear(): Promise<void>` | 清除当前前缀下所有存储项 |\n| `clearExpiredItems` | `clearExpiredItems(): Promise<void>` | 主动清理所有过期项 |\n\n---\n\n### IStorageDriver 接口\n\n自定义驱动需要实现此接口：\n\n```typescript\ninterface IStorageDriver {\n  clear(): Promise<void>;\n\n  getItem<T>(key: string): Promise<null | T>;\n\n  keys(): Promise<string[]>;\n\n  removeItem(key: string): Promise<void>;\n\n  setItem<T>(key: string, value: T): Promise<void>;\n}\n```\n\n---\n\n## 高级用法\n\n### 自定义 Driver\n\n```typescript\nimport type { IStorageDriver } from '@vben-core/shared/cache';\n\nclass CookieStorageDriver implements IStorageDriver {\n  async getItem<T>(key: string): Promise<null | T> {\n    const value = getCookie(key);\n    return value ? JSON.parse(value) : null;\n  }\n\n  async setItem<T>(key: string, value: T): Promise<void> {\n    setCookie(key, JSON.stringify(value));\n  }\n\n  async removeItem(key: string): Promise<void> {\n    deleteCookie(key);\n  }\n\n  async clear(): Promise<void> {\n    clearAllCookies();\n  }\n\n  async keys(): Promise<string[]> {\n    return getAllCookieNames();\n  }\n}\n\n// 使用自定义 Driver\nconst cache = new StorageManager({\n  driver: new CookieStorageDriver(),\n  prefix: 'ck',\n});\n```\n\n### 根据环境动态选择 Driver\n\n```typescript\nimport {\n  IndexedDBDriver,\n  LocalStorageDriver,\n  MemoryStorageDriver,\n  StorageManager,\n} from '@vben-core/shared/cache';\n\nfunction createStorageManager(prefix: string) {\n  // SSR 环境使用内存驱动\n  if (typeof window === 'undefined') {\n    return new StorageManager({\n      driver: new MemoryStorageDriver(),\n      prefix,\n    });\n  }\n\n  // 大数据场景使用 IndexedDB\n  if (needsLargeStorage()) {\n    return new StorageManager({\n      driver: new IndexedDBDriver({ dbName: `${prefix}-db` }),\n      prefix,\n    });\n  }\n\n  // 默认使用 localStorage\n  return new StorageManager({ prefix });\n}\n```\n\n### 命名空间隔离\n\n```typescript\n// 不同模块使用不同前缀，互不干扰\nconst userCache = new StorageManager({ prefix: 'user' });\nconst configCache = new StorageManager({ prefix: 'config' });\n\nawait userCache.setItem('profile', { name: '张三' });\nawait configCache.setItem('profile', { theme: 'dark' });\n\n// 各自独立\nawait userCache.getItem('profile'); // => { name: '张三' }\nawait configCache.getItem('profile'); // => { theme: 'dark' }\n\n// 只清除 user 前缀的数据\nawait userCache.clear();\nawait configCache.getItem('profile'); // => { theme: 'dark' }（不受影响）\n```\n\n### 定时清理过期数据\n\n```typescript\nconst cache = new StorageManager({ prefix: 'app' });\n\n// 应用启动时清理一次\nawait cache.clearExpiredItems();\n\n// 或者定时清理（每 10 分钟）\nsetInterval(\n  async () => {\n    await cache.clearExpiredItems();\n  },\n  10 * 60 * 1000,\n);\n```\n\n---\n\n## 数据存储格式\n\n`StorageManager` 在 Driver 层存储的数据结构为：\n\n```typescript\ninterface StorageItem<T> {\n  expiry?: number; // 过期时间戳（毫秒），undefined 表示永不过期\n  value: T; // 实际业务数据\n}\n```\n\n实际存储的 key 格式为：`{prefix}-{key}`\n\n例如 `prefix = 'app'`，`key = 'user'`，则实际存储键为 `app-user`。\n\n---\n\n## 过期策略\n\n采用**惰性删除 + 主动清理**双重策略：\n\n| 策略 | 触发时机 | 说明 |\n| --- | --- | --- |\n| 惰性删除 | 调用 `getItem` 时 | 读取时检查过期，过期则删除并返回默认值 |\n| 主动清理 | 调用 `clearExpiredItems` 时 | 遍历所有带前缀的 key，删除已过期项 |\n\n---\n\n## 各 Driver 对比\n\n| 特性       | LocalStorageDriver  | IndexedDBDriver  | MemoryStorageDriver |\n| ---------- | ------------------- | ---------------- | ------------------- |\n| 持久化     | ✅                  | ✅               | ❌                  |\n| 容量       | 5-10 MB             | 数百 MB+         | 受内存限制          |\n| 速度       | 快（同步）          | 中等（异步 I/O） | 最快                |\n| 数据类型   | 仅 JSON 可序列化    | 结构化克隆       | 任意 JS 对象        |\n| 浏览器支持 | 所有现代浏览器      | 所有现代浏览器   | 任意环境            |\n| 阻塞主线程 | 是                  | 否               | 否                  |\n| 适用场景   | 配置、Token、小数据 | 离线缓存、大数据 | 测试、SSR           |\n\n---\n\n## 在项目中的使用\n\n本项目中 `StorageManager` 主要被 `PreferenceManager` 消费，用于持久化用户偏好设置：\n\n```typescript\n// packages/@core/preferences/src/preferences.ts\nclass PreferenceManager {\n  private cache: StorageManager;\n\n  constructor() {\n    this.cache = new StorageManager();\n    this.state = reactive<Preferences>({ ...defaultPreferences });\n  }\n\n  initPreferences = async ({ namespace }) => {\n    // 用应用命名空间重新初始化\n    this.cache = new StorageManager({ prefix: namespace });\n\n    // 从缓存加载偏好设置\n    const cached = await this.cache.getItem<Preferences>('preferences');\n    // ...\n  };\n}\n```\n\n---\n\n## 注意事项\n\n1. **所有方法都是异步的** — 即使底层是同步的 localStorage，API 也返回 Promise，确保切换 Driver 时无需改动调用方。\n\n2. **TTL 单位是毫秒** — `setItem('key', value, 60000)` 表示 60 秒后过期。\n\n3. **IndexedDB 懒初始化** — 不需要手动调用 `init()` 或 `open()`，首次操作时自动打开数据库连接并复用。\n\n4. **前缀隔离是逻辑隔离** — `clear()` 只清除当前前缀下的数据，不影响其他前缀或无前缀的数据。\n\n5. **错误处理** — LocalStorageDriver 在 JSON 解析失败时自动清除损坏数据； `PreferenceManager.saveToCache` 内部 try-catch 防止未捕获异常。\n\n6. **IndexedDB 版本升级** — 如果需要修改 objectStore 结构，需要递增 `dbVersion`。当前实现在 `upgradeneeded` 事件中自动创建 objectStore。\n","packages/@core/composables/src/use-simple-locale/README.md":"# Simple i18n\n\nSimple i18 implementation\n","packages/@core/ui-kit/README.md":"# ui-kit\n\n用于管理公共组件、不同UI组件库封装的组件\n","packages/@core/ui-kit/menu-ui/README.md":"# 菜单组件\n","packages/constants/README.md":"# @vben/constants\n\n用于多个 `app` 公用的常量，继承了 `@vben-core/shared/constants` 的所有能力。业务上有通用常量可以放在这里。\n\n## 用法\n\n### 添加依赖\n\n```bash\n# 进入目标应用目录，例如 apps/xxxx-app\n# cd apps/xxxx-app\npnpm add @vben/constants\n```\n\n### 使用\n\n```ts\nimport { LOGIN_PATH } from '@vben/constants';\n```\n","packages/effects/README.md":"## Effects 目录\n\n`effects` 目录专门用于存放与轻微耦合相关的代码和逻辑。如果你的包具有以下特点，建议将其放置在 `effects` 目录下：\n\n- **状态管理**：使用状态管理框架 `pinia`，并包含处理副作用（如异步操作、API 调用）的部分。\n- **用户偏好设置**：使用 `@vben-core/preferences` 处理用户偏好设置，涉及本地存储或浏览器缓存逻辑（如使用 `localStorage`）。\n- **导航和路由**：处理导航、页面跳转等场景，需要管理路由变化的逻辑。\n- **组件库依赖**：包含与特定组件库紧密耦合或依赖大型仓库的部分。\n\n通过将相关代码归类到 `effects` 目录，可以使项目结构更加清晰，便于维护和扩展。\n","packages/effects/hooks/README.md":"# @vben/hooks\n\n用于多个 `app` 公用的 hook，继承了 `@vben/hooks` 的所有能力。业务上有通用 hooks 可以放在这里。\n\n## 用法\n\n### 添加依赖\n\n```bash\n# 进入目标应用目录，例如 apps/xxxx-app\n# cd apps/xxxx-app\npnpm add @vben/hooks\n```\n\n### 使用\n\n```ts\nimport { useNamespace } from '@vben/hooks';\n```\n","packages/effects/layouts/src/basic/README.md":"## layout\n\n### header\n\n- 支持N个自定义插槽，命名方式：header-right-n，header-left-n\n- header-left-n ，排序方式：0-19 ,breadcrumb 21-x\n- header-right-n ，排序方式：0-49，global-search，51-59，theme-toggle，61-69，language-toggle，71-79，fullscreen，81-89，notification，91-149，user-dropdown，151-x\n","packages/effects/plugins/README.md":"# @vben/plugins\n\n该目录用于存放项目中集成的第三方库及其相关插件。每个插件都包含了可重用的逻辑、配置和组件，方便在项目中进行统一管理和调用。\n\n## 注意\n\n所有的第三方插件都必须以 `subpath` 形式引入，例：\n\n以 `echarts` 为例，引入方式如下：\n\n**packages.json**\n\n```json\n\"exports\": {\n    \"./echarts\": {\n      \"types\": \"./src/echarts/index.ts\",\n      \"default\": \"./src/echarts/index.ts\"\n    }\n  }\n```\n\n**使用方式**\n\n```ts\nimport { useEcharts } from '@vben/plugins/echarts';\n```\n\n这样做的好处是，应用可以自行选择是否使用插件，而不会因为插件的引入及副作用而导致打包体积增大，只引入需要的插件即可。\n","packages/effects/plugins/src/echarts/README.md":"# ECharts Plugin\n\nECharts 图表插件，预置常用组件和图表类型。\n\n## 导出\n\n| 导出         | 类型 | 说明         |\n| ------------ | ---- | ------------ |\n| `default`    | 对象 | echarts 实例 |\n| `EchartsUI`  | 组件 | 图表容器组件 |\n| `ECOption`   | 类型 | 图表配置类型 |\n| `useEcharts` | 函数 | 组合式函数   |\n\n## 使用\n\n```ts\nimport { EchartsUI, useEcharts, ECOption } from '@vben/plugins/echarts';\n```\n\n## 类型\n\n```ts\nimport type { ECOption } from '@vben/plugins/echarts';\n```\n\n## 预置组件\n\n- TitleComponent\n- TooltipComponent\n- GridComponent\n- LegendComponent\n- ToolboxComponent\n- DatasetComponent\n- TransformComponent\n\n## 预置图表\n\n- BarChart\n- LineChart\n- PieChart\n- RadarChart\n","packages/effects/plugins/src/motion/README.md":"# Motion Plugin\n\n基于 @vueuse/motion 的动画插件。\n\n## 导出\n\n| 导出              | 类型 | 说明       |\n| ----------------- | ---- | ---------- |\n| `Motion`          | 组件 | 动画组件   |\n| `MotionGroup`     | 组件 | 动画组组件 |\n| `MotionDirective` | 指令 | 动画指令   |\n| `MotionPlugin`    | 插件 | Vue 插件   |\n\n## 使用\n\n```ts\nimport { MotionPlugin, Motion, MotionDirective } from '@vben/plugins/motion';\n\napp.use(MotionPlugin);\n```\n\n## 类型\n\n```ts\nimport type { MotionOptions, MotionVariants } from '@vben/plugins/motion';\n```\n","packages/effects/plugins/src/vxe-table/README.md":"# VXE Table Plugin\n\n基于 vxe-table 和 vxe-pc-ui 的表格组件插件。\n\n## 导出\n\n| 导出                  | 类型 | 说明           |\n| --------------------- | ---- | -------------- |\n| `setupVbenVxeTable`   | 函数 | 初始化配置函数 |\n| `useVbenVxeGrid`      | 函数 | 表格组合式函数 |\n| `VbenVxeGrid`         | 组件 | 表格组件       |\n| `VxeTableGridColumns` | 类型 | 表格列类型     |\n| `VxeTableGridOptions` | 类型 | 表格配置类型   |\n| `VxeGridProps`        | 类型 | 表格 Props     |\n| `VxeGridListeners`    | 类型 | 表格事件类型   |\n\n## 使用\n\n```ts\nimport {\n  setupVbenVxeTable,\n  useVbenVxeGrid,\n  VbenVxeGrid,\n} from '@vben/plugins/vxe-table';\n```\n\n## 初始化\n\n在应用入口处调用：\n\n```ts\nimport { setupVbenVxeTable } from '@vben/plugins/vxe-table';\nimport { useVbenForm } from '@vben-core/form-ui';\n\nsetupVbenVxeTable({\n  configVxeTable: (vxeUI) => {\n    // 配置 VXE Table\n  },\n  useVbenForm,\n});\n```\n\n## 类型\n\n```ts\nimport type {\n  VxeTableGridOptions,\n  VxeGridProps,\n} from '@vben/plugins/vxe-table';\n```\n","packages/icons/README.md":"# @vben/icons\n\n用于多个 `app` 公用的图标文件，继承了 `@vben-core/icons` 的所有能力。业务上有通用图标可以放在这里。\n\n## 用法\n\n### 添加依赖\n\n```bash\n# 进入目标应用目录，例如 apps/xxxx-app\n# cd apps/xxxx-app\npnpm add @vben/icons\n```\n\n### 使用\n\n```ts\nimport { X } from '@vben/icons';\n```\n","packages/styles/README.md":"# @vben/styles\n\n用于多个 `app` 公用的样式文件，继承了 `@vben-core/design` 的所有能力。业务上有通用的样式文件可以放在这里。\n\n## 用法\n\n### 添加依赖\n\n```bash\n# 进入目标应用目录，例如 apps/xxxx-app\n# cd apps/xxxx-app\npnpm add @vben/styles\n```\n\n### 使用\n\n```ts\nimport '@vben/styles';\n```\n","packages/types/README.md":"# @vben/types\n\n用于多个 `app` 公用的工具类型，继承了 `@vben-core/typings` 的所有能力。业务上有通用的类型定义可以放在这里。\n\n## 用法\n\n### 添加依赖\n\n```bash\n# 进入目标应用目录，例如 apps/xxxx-app\n# cd apps/xxxx-app\npnpm add @vben/types\n```\n\n### 使用\n\n```ts\n// 推荐加上 type\nimport type { SelectOption } from '@vben/types';\n```\n","packages/utils/README.md":"# @vben/utils\n\n用于多个 `app` 公用的工具包，继承了 `@vben-core/shared/utils` 的所有能力。业务上有通用的工具函数可以放在这里。\n\n## 用法\n\n### 添加依赖\n\n```bash\n# 进入目标应用目录，例如 apps/xxxx-app\n# cd apps/xxxx-app\npnpm add @vben/utils\n```\n\n### 使用\n\n```ts\nimport { isString } from '@vben/utils';\n```\n"},"items":[{"name":"README.md","path":"internal/vite-config/src/plugins/inject-app-loading/README.md","rawUrl":"https://raw.githubusercontent.com/vbenjs/vue-vben-admin/HEAD/internal/vite-config/src/plugins/inject-app-loading/README.md","title":"inject-app-loading Documentation","category":"plugin-manifest","format":"markdown","content":"# inject-app-loading\n\n用于在应用加载时显示加载动画的插件，可自行选择加载动画的样式。\n","isInternal":false,"tokens":32,"sizeBytes":116},{"name":"README.md","path":"packages/@core/base/README.md","rawUrl":"https://raw.githubusercontent.com/vbenjs/vue-vben-admin/HEAD/packages/@core/base/README.md","title":"base Documentation","category":"plugin-manifest","format":"markdown","content":"# base\n\n基础共享包，请勿引入 workspace 依赖\n\n-\n","isInternal":false,"tokens":22,"sizeBytes":59},{"name":"README.md","path":"packages/@core/base/shared/src/cache/README.md","rawUrl":"https://raw.githubusercontent.com/vbenjs/vue-vben-admin/HEAD/packages/@core/base/shared/src/cache/README.md","title":"cache Documentation","category":"plugin-manifest","format":"markdown","content":"# Cache 模块\n\n基于**策略模式**的异步存储管理方案，支持多种存储后端（localStorage、IndexedDB、Memory），提供统一的 API 接口。\n\n## 架构设计\n\n```shell\n┌───────────────────────────────────────────────┐\n│             StorageManager                    │\n│  ┌─────────────┐  ┌───────────────────────┐   │\n│  │ Prefix 隔离 │   │   TTL 过期管理        │   │\n│  └─────────────┘  └───────────────────────┘   │\n├───────────────────────────────────────────────┤\n│             IStorageDriver                    │\n├──────────┬─────────────────┬──────────────────┤\n│  Local   │   IndexedDB     │     Memory       │\n│  Storage │   Driver        │     Driver       │\n│  Driver  │                 │                  │\n└──────────┴─────────────────┴──────────────────┘\n```\n\n**分层职责：**\n\n| 层级             | 职责                                         |\n| ---------------- | -------------------------------------------- |\n| `StorageManager` | 命名空间前缀隔离、TTL 过期检查、统一对外 API |\n| `IStorageDriver` | 纯粹的 KV 存取抽象接口                       |\n| 各 Driver 实现   | 对接具体存储引擎，不感知前缀和 TTL           |\n\n---\n\n## 快速开始\n\n### 基本使用（默认 localStorage）\n\n```typescript\nimport { StorageManager } from '@vben-core/shared/cache';\n\nconst cache = new StorageManager({ prefix: 'myapp' });\n// 使用 IndexedDB\n//new StorageManager({ driver: new IndexedDBDriver(), prefix: 'app' });\n\n// 使用 sessionStorage\n//new StorageManager({ driver: new LocalStorageDriver({ storageType: 'sessionStorage' }), prefix: 'app' });\n\n// 测试环境\n//new StorageManager({ driver: new MemoryStorageDriver(), prefix: 'test' });\n\n// 存储数据\nawait cache.setItem('user', { name: '张三', age: 28 });\n\n// 读取数据\nconst user = await cache.getItem('user');\n// => { name: '张三', age: 28 }\n\n// 带默认值读取\nconst settings = await cache.getItem('settings', { theme: 'light' });\n// 如果不存在，返回 { theme: 'light' }\n\n// 删除数据\nawait cache.removeItem('user');\n\n// 清除当前前缀下所有数据\nawait cache.clear();\n```\n\n### 带 TTL 过期\n\n```typescript\nconst cache = new StorageManager({ prefix: 'session' });\n\n// 设置 5 分钟后过期（TTL 单位为毫秒）\nawait cache.setItem('token', 'abc123', 5 * 60 * 1000);\n\n// 5 分钟内可以正常读取\nconst token = await cache.getItem('token');\n// => 'abc123'\n\n// 5 分钟后自动返回 null（惰性删除）\nconst expiredToken = await cache.getItem('token');\n// => null\n\n// 主动清理所有过期项\nawait cache.clearExpiredItems();\n```\n\n---\n\n## 存储驱动\n\n### LocalStorageDriver（默认）\n\n基于浏览器 `localStorage` 或 `sessionStorage`，数据持久化存储。\n\n```typescript\nimport { LocalStorageDriver, StorageManager } from '@vben-core/shared/cache';\n\n// 使用 localStorage（默认）\nconst cache = new StorageManager({\n  driver: new LocalStorageDriver(),\n  prefix: 'app',\n});\n\n// 使用 sessionStorage\nconst sessionCache = new StorageManager({\n  driver: new LocalStorageDriver({ storageType: 'sessionStorage' }),\n  prefix: 'app',\n});\n```\n\n**特点：**\n\n- 同步 API 用 async 包装，保持接口统一\n- 自动处理 JSON 序列化/反序列化\n- 数据损坏时自动清除并返回 null\n- 存储上限约 5-10MB（视浏览器而定）\n\n**适用场景：** 用户偏好设置、小型配置数据、Token 存储\n\n---\n\n### IndexedDBDriver\n\n基于浏览器 IndexedDB，支持大容量结构化数据存储。\n\n```typescript\nimport {IndexedDBDriver, StorageManager} from '@vben-core/shared/cache';\n\nconst cache = new StorageManager({\n  driver: new IndexedDBDriver({\n    dbName: 'my-app-db',     // 数据库名称，默认 'vben-storage'\n    dbVersion: 1,            // 数据库版本，默认 1\n    storeName: 'cache-store', // 对象存储名称，默认 'kv-store'\n  }),\n  prefix: 'data',\n});\n\n// 存储大量数据\nawait cache.setItem('table-data', largeDataArray);\n\n// 存储二进制友好的结构（IndexedDB 原生支持）\nawait cache.setItem('config', {\n  columns: [...],\n  filters: [...],\n  pagination: {page: 1, size: 20},\n});\n```\n\n**特点：**\n\n- 懒初始化：首次操作时自动打开数据库，无需手动调用 `init()`\n- 存储容量大（通常数百 MB 到 GB 级别）\n- 支持结构化克隆（可存储 Date、RegExp、Blob 等复杂类型）\n- 天然异步，不阻塞主线程\n\n**适用场景：** 离线数据缓存、大型表格数据、文件/图片缓存、复杂业务数据\n\n---\n\n### MemoryStorageDriver\n\n基于内存 Map，数据不持久化，页面刷新即丢失。\n\n```typescript\nimport { MemoryStorageDriver, StorageManager } from '@vben-core/shared/cache';\n\nconst cache = new StorageManager({\n  driver: new MemoryStorageDriver(),\n  prefix: 'test',\n});\n```\n\n**特点：**\n\n- 读写速度最快\n- 无浏览器 API 依赖\n- 数据随页面生命周期销毁\n\n**适用场景：** 单元测试、SSR 服务端渲染、临时运行时缓存\n\n---\n\n## API 参考\n\n### StorageManager\n\n#### 构造函数\n\n```typescript\nnew StorageManager(options?: StorageManagerOptions)\n```\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `driver` | `IStorageDriver` | `new LocalStorageDriver()` | 存储驱动实例 |\n| `prefix` | `string` | `''` | 键前缀，用于命名空间隔离 |\n\n#### 方法\n\n| 方法 | 签名 | 说明 |\n| --- | --- | --- |\n| `getItem` | `getItem<T>(key: string, defaultValue?: T \\| null): Promise<T \\| null>` | 获取存储项，过期或不存在返回默认值 |\n| `setItem` | `setItem<T>(key: string, value: T, ttl?: number): Promise<void>` | 设置存储项，可选 TTL（毫秒） |\n| `removeItem` | `removeItem(key: string): Promise<void>` | 删除指定存储项 |\n| `clear` | `clear(): Promise<void>` | 清除当前前缀下所有存储项 |\n| `clearExpiredItems` | `clearExpiredItems(): Promise<void>` | 主动清理所有过期项 |\n\n---\n\n### IStorageDriver 接口\n\n自定义驱动需要实现此接口：\n\n```typescript\ninterface IStorageDriver {\n  clear(): Promise<void>;\n\n  getItem<T>(key: string): Promise<null | T>;\n\n  keys(): Promise<string[]>;\n\n  removeItem(key: string): Promise<void>;\n\n  setItem<T>(key: string, value: T): Promise<void>;\n}\n```\n\n---\n\n## 高级用法\n\n### 自定义 Driver\n\n```typescript\nimport type { IStorageDriver } from '@vben-core/shared/cache';\n\nclass CookieStorageDriver implements IStorageDriver {\n  async getItem<T>(key: string): Promise<null | T> {\n    const value = getCookie(key);\n    return value ? JSON.parse(value) : null;\n  }\n\n  async setItem<T>(key: string, value: T): Promise<void> {\n    setCookie(key, JSON.stringify(value));\n  }\n\n  async removeItem(key: string): Promise<void> {\n    deleteCookie(key);\n  }\n\n  async clear(): Promise<void> {\n    clearAllCookies();\n  }\n\n  async keys(): Promise<string[]> {\n    return getAllCookieNames();\n  }\n}\n\n// 使用自定义 Driver\nconst cache = new StorageManager({\n  driver: new CookieStorageDriver(),\n  prefix: 'ck',\n});\n```\n\n### 根据环境动态选择 Driver\n\n```typescript\nimport {\n  IndexedDBDriver,\n  LocalStorageDriver,\n  MemoryStorageDriver,\n  StorageManager,\n} from '@vben-core/shared/cache';\n\nfunction createStorageManager(prefix: string) {\n  // SSR 环境使用内存驱动\n  if (typeof window === 'undefined') {\n    return new StorageManager({\n      driver: new MemoryStorageDriver(),\n      prefix,\n    });\n  }\n\n  // 大数据场景使用 IndexedDB\n  if (needsLargeStorage()) {\n    return new StorageManager({\n      driver: new IndexedDBDriver({ dbName: `${prefix}-db` }),\n      prefix,\n    });\n  }\n\n  // 默认使用 localStorage\n  return new StorageManager({ prefix });\n}\n```\n\n### 命名空间隔离\n\n```typescript\n// 不同模块使用不同前缀，互不干扰\nconst userCache = new StorageManager({ prefix: 'user' });\nconst configCache = new StorageManager({ prefix: 'config' });\n\nawait userCache.setItem('profile', { name: '张三' });\nawait configCache.setItem('profile', { theme: 'dark' });\n\n// 各自独立\nawait userCache.getItem('profile'); // => { name: '张三' }\nawait configCache.getItem('profile'); // => { theme: 'dark' }\n\n// 只清除 user 前缀的数据\nawait userCache.clear();\nawait configCache.getItem('profile'); // => { theme: 'dark' }（不受影响）\n```\n\n### 定时清理过期数据\n\n```typescript\nconst cache = new StorageManager({ prefix: 'app' });\n\n// 应用启动时清理一次\nawait cache.clearExpiredItems();\n\n// 或者定时清理（每 10 分钟）\nsetInterval(\n  async () => {\n    await cache.clearExpiredItems();\n  },\n  10 * 60 * 1000,\n);\n```\n\n---\n\n## 数据存储格式\n\n`StorageManager` 在 Driver 层存储的数据结构为：\n\n```typescript\ninterface StorageItem<T> {\n  expiry?: number; // 过期时间戳（毫秒），undefined 表示永不过期\n  value: T; // 实际业务数据\n}\n```\n\n实际存储的 key 格式为：`{prefix}-{key}`\n\n例如 `prefix = 'app'`，`key = 'user'`，则实际存储键为 `app-user`。\n\n---\n\n## 过期策略\n\n采用**惰性删除 + 主动清理**双重策略：\n\n| 策略 | 触发时机 | 说明 |\n| --- | --- | --- |\n| 惰性删除 | 调用 `getItem` 时 | 读取时检查过期，过期则删除并返回默认值 |\n| 主动清理 | 调用 `clearExpiredItems` 时 | 遍历所有带前缀的 key，删除已过期项 |\n\n---\n\n## 各 Driver 对比\n\n| 特性       | LocalStorageDriver  | IndexedDBDriver  | MemoryStorageDriver |\n| ---------- | ------------------- | ---------------- | ------------------- |\n| 持久化     | ✅                  | ✅               | ❌                  |\n| 容量       | 5-10 MB             | 数百 MB+         | 受内存限制          |\n| 速度       | 快（同步）          | 中等（异步 I/O） | 最快                |\n| 数据类型   | 仅 JSON 可序列化    | 结构化克隆       | 任意 JS 对象        |\n| 浏览器支持 | 所有现代浏览器      | 所有现代浏览器   | 任意环境            |\n| 阻塞主线程 | 是                  | 否               | 否                  |\n| 适用场景   | 配置、Token、小数据 | 离线缓存、大数据 | 测试、SSR           |\n\n---\n\n## 在项目中的使用\n\n本项目中 `StorageManager` 主要被 `PreferenceManager` 消费，用于持久化用户偏好设置：\n\n```typescript\n// packages/@core/preferences/src/preferences.ts\nclass PreferenceManager {\n  private cache: StorageManager;\n\n  constructor() {\n    this.cache = new StorageManager();\n    this.state = reactive<Preferences>({ ...defaultPreferences });\n  }\n\n  initPreferences = async ({ namespace }) => {\n    // 用应用命名空间重新初始化\n    this.cache = new StorageManager({ prefix: namespace });\n\n    // 从缓存加载偏好设置\n    const cached = await this.cache.getItem<Preferences>('preferences');\n    // ...\n  };\n}\n```\n\n---\n\n## 注意事项\n\n1. **所有方法都是异步的** — 即使底层是同步的 localStorage，API 也返回 Promise，确保切换 Driver 时无需改动调用方。\n\n2. **TTL 单位是毫秒** — `setItem('key', value, 60000)` 表示 60 秒后过期。\n\n3. **IndexedDB 懒初始化** — 不需要手动调用 `init()` 或 `open()`，首次操作时自动打开数据库连接并复用。\n\n4. **前缀隔离是逻辑隔离** — `clear()` 只清除当前前缀下的数据，不影响其他前缀或无前缀的数据。\n\n5. **错误处理** — LocalStorageDriver 在 JSON 解析失败时自动清除损坏数据； `PreferenceManager.saveToCache` 内部 try-catch 防止未捕获异常。\n\n6. **IndexedDB 版本升级** — 如果需要修改 objectStore 结构，需要递增 `dbVersion`。当前实现在 `upgradeneeded` 事件中自动创建 objectStore。\n","isInternal":false,"tokens":3388,"sizeBytes":12269},{"name":"README.md","path":"packages/@core/composables/src/use-simple-locale/README.md","rawUrl":"https://raw.githubusercontent.com/vbenjs/vue-vben-admin/HEAD/packages/@core/composables/src/use-simple-locale/README.md","title":"use-simple-locale Documentation","category":"plugin-manifest","format":"markdown","content":"# Simple i18n\n\nSimple i18 implementation\n","isInternal":false,"tokens":11,"sizeBytes":41},{"name":"README.md","path":"packages/@core/README.md","rawUrl":"https://raw.githubusercontent.com/vbenjs/vue-vben-admin/HEAD/packages/@core/README.md","title":"@core Documentation","category":"plugin-manifest","format":"markdown","content":"# @vben-core\n\n系统一些比较基础的SDK和UI组件库，该目录后续完善后，可能会迁移出去或者发布到npm，请勿将任何业务逻辑和业务包放在该目录。\n","isInternal":false,"tokens":67,"sizeBytes":188},{"name":"README.md","path":"packages/@core/ui-kit/menu-ui/README.md","rawUrl":"https://raw.githubusercontent.com/vbenjs/vue-vben-admin/HEAD/packages/@core/ui-kit/menu-ui/README.md","title":"menu-ui Documentation","category":"plugin-manifest","format":"markdown","content":"# 菜单组件\n","isInternal":false,"tokens":8,"sizeBytes":15},{"name":"README.md","path":"packages/@core/ui-kit/README.md","rawUrl":"https://raw.githubusercontent.com/vbenjs/vue-vben-admin/HEAD/packages/@core/ui-kit/README.md","title":"ui-kit Documentation","category":"plugin-manifest","format":"markdown","content":"# ui-kit\n\n用于管理公共组件、不同UI组件库封装的组件\n","isInternal":false,"tokens":25,"sizeBytes":70},{"name":"README.md","path":"packages/constants/README.md","rawUrl":"https://raw.githubusercontent.com/vbenjs/vue-vben-admin/HEAD/packages/constants/README.md","title":"constants Documentation","category":"plugin-manifest","format":"markdown","content":"# @vben/constants\n\n用于多个 `app` 公用的常量，继承了 `@vben-core/shared/constants` 的所有能力。业务上有通用常量可以放在这里。\n\n## 用法\n\n### 添加依赖\n\n```bash\n# 进入目标应用目录，例如 apps/xxxx-app\n# cd apps/xxxx-app\npnpm add @vben/constants\n```\n\n### 使用\n\n```ts\nimport { LOGIN_PATH } from '@vben/constants';\n```\n","isInternal":false,"tokens":120,"sizeBytes":365},{"name":"README.md","path":"packages/effects/hooks/README.md","rawUrl":"https://raw.githubusercontent.com/vbenjs/vue-vben-admin/HEAD/packages/effects/hooks/README.md","title":"hooks Documentation","category":"plugin-manifest","format":"markdown","content":"# @vben/hooks\n\n用于多个 `app` 公用的 hook，继承了 `@vben/hooks` 的所有能力。业务上有通用 hooks 可以放在这里。\n\n## 用法\n\n### 添加依赖\n\n```bash\n# 进入目标应用目录，例如 apps/xxxx-app\n# cd apps/xxxx-app\npnpm add @vben/hooks\n```\n\n### 使用\n\n```ts\nimport { useNamespace } from '@vben/hooks';\n```\n","isInternal":false,"tokens":118,"sizeBytes":339},{"name":"README.md","path":"packages/effects/layouts/src/basic/README.md","rawUrl":"https://raw.githubusercontent.com/vbenjs/vue-vben-admin/HEAD/packages/effects/layouts/src/basic/README.md","title":"basic Documentation","category":"plugin-manifest","format":"markdown","content":"## layout\n\n### header\n\n- 支持N个自定义插槽，命名方式：header-right-n，header-left-n\n- header-left-n ，排序方式：0-19 ,breadcrumb 21-x\n- header-right-n ，排序方式：0-49，global-search，51-59，theme-toggle，61-69，language-toggle，71-79，fullscreen，81-89，notification，91-149，user-dropdown，151-x\n","isInternal":false,"tokens":100,"sizeBytes":337},{"name":"README.md","path":"packages/effects/plugins/README.md","rawUrl":"https://raw.githubusercontent.com/vbenjs/vue-vben-admin/HEAD/packages/effects/plugins/README.md","title":"plugins Documentation","category":"plugin-manifest","format":"markdown","content":"# @vben/plugins\n\n该目录用于存放项目中集成的第三方库及其相关插件。每个插件都包含了可重用的逻辑、配置和组件，方便在项目中进行统一管理和调用。\n\n## 注意\n\n所有的第三方插件都必须以 `subpath` 形式引入，例：\n\n以 `echarts` 为例，引入方式如下：\n\n**packages.json**\n\n```json\n\"exports\": {\n    \"./echarts\": {\n      \"types\": \"./src/echarts/index.ts\",\n      \"default\": \"./src/echarts/index.ts\"\n    }\n  }\n```\n\n**使用方式**\n\n```ts\nimport { useEcharts } from '@vben/plugins/echarts';\n```\n\n这样做的好处是，应用可以自行选择是否使用插件，而不会因为插件的引入及副作用而导致打包体积增大，只引入需要的插件即可。\n","isInternal":false,"tokens":239,"sizeBytes":742},{"name":"README.md","path":"packages/effects/plugins/src/echarts/README.md","rawUrl":"https://raw.githubusercontent.com/vbenjs/vue-vben-admin/HEAD/packages/effects/plugins/src/echarts/README.md","title":"echarts Documentation","category":"plugin-manifest","format":"markdown","content":"# ECharts Plugin\n\nECharts 图表插件，预置常用组件和图表类型。\n\n## 导出\n\n| 导出         | 类型 | 说明         |\n| ------------ | ---- | ------------ |\n| `default`    | 对象 | echarts 实例 |\n| `EchartsUI`  | 组件 | 图表容器组件 |\n| `ECOption`   | 类型 | 图表配置类型 |\n| `useEcharts` | 函数 | 组合式函数   |\n\n## 使用\n\n```ts\nimport { EchartsUI, useEcharts, ECOption } from '@vben/plugins/echarts';\n```\n\n## 类型\n\n```ts\nimport type { ECOption } from '@vben/plugins/echarts';\n```\n\n## 预置组件\n\n- TitleComponent\n- TooltipComponent\n- GridComponent\n- LegendComponent\n- ToolboxComponent\n- DatasetComponent\n- TransformComponent\n\n## 预置图表\n\n- BarChart\n- LineChart\n- PieChart\n- RadarChart\n","isInternal":false,"tokens":227,"sizeBytes":741},{"name":"README.md","path":"packages/effects/plugins/src/motion/README.md","rawUrl":"https://raw.githubusercontent.com/vbenjs/vue-vben-admin/HEAD/packages/effects/plugins/src/motion/README.md","title":"motion Documentation","category":"plugin-manifest","format":"markdown","content":"# Motion Plugin\n\n基于 @vueuse/motion 的动画插件。\n\n## 导出\n\n| 导出              | 类型 | 说明       |\n| ----------------- | ---- | ---------- |\n| `Motion`          | 组件 | 动画组件   |\n| `MotionGroup`     | 组件 | 动画组组件 |\n| `MotionDirective` | 指令 | 动画指令   |\n| `MotionPlugin`    | 插件 | Vue 插件   |\n\n## 使用\n\n```ts\nimport { MotionPlugin, Motion, MotionDirective } from '@vben/plugins/motion';\n\napp.use(MotionPlugin);\n```\n\n## 类型\n\n```ts\nimport type { MotionOptions, MotionVariants } from '@vben/plugins/motion';\n```\n","isInternal":false,"tokens":173,"sizeBytes":572},{"name":"README.md","path":"packages/effects/plugins/src/vxe-table/README.md","rawUrl":"https://raw.githubusercontent.com/vbenjs/vue-vben-admin/HEAD/packages/effects/plugins/src/vxe-table/README.md","title":"vxe-table Documentation","category":"plugin-manifest","format":"markdown","content":"# VXE Table Plugin\n\n基于 vxe-table 和 vxe-pc-ui 的表格组件插件。\n\n## 导出\n\n| 导出                  | 类型 | 说明           |\n| --------------------- | ---- | -------------- |\n| `setupVbenVxeTable`   | 函数 | 初始化配置函数 |\n| `useVbenVxeGrid`      | 函数 | 表格组合式函数 |\n| `VbenVxeGrid`         | 组件 | 表格组件       |\n| `VxeTableGridColumns` | 类型 | 表格列类型     |\n| `VxeTableGridOptions` | 类型 | 表格配置类型   |\n| `VxeGridProps`        | 类型 | 表格 Props     |\n| `VxeGridListeners`    | 类型 | 表格事件类型   |\n\n## 使用\n\n```ts\nimport {\n  setupVbenVxeTable,\n  useVbenVxeGrid,\n  VbenVxeGrid,\n} from '@vben/plugins/vxe-table';\n```\n\n## 初始化\n\n在应用入口处调用：\n\n```ts\nimport { setupVbenVxeTable } from '@vben/plugins/vxe-table';\nimport { useVbenForm } from '@vben-core/form-ui';\n\nsetupVbenVxeTable({\n  configVxeTable: (vxeUI) => {\n    // 配置 VXE Table\n  },\n  useVbenForm,\n});\n```\n\n## 类型\n\n```ts\nimport type {\n  VxeTableGridOptions,\n  VxeGridProps,\n} from '@vben/plugins/vxe-table';\n```\n","isInternal":false,"tokens":354,"sizeBytes":1088},{"name":"README.md","path":"packages/effects/README.md","rawUrl":"https://raw.githubusercontent.com/vbenjs/vue-vben-admin/HEAD/packages/effects/README.md","title":"effects Documentation","category":"plugin-manifest","format":"markdown","content":"## Effects 目录\n\n`effects` 目录专门用于存放与轻微耦合相关的代码和逻辑。如果你的包具有以下特点，建议将其放置在 `effects` 目录下：\n\n- **状态管理**：使用状态管理框架 `pinia`，并包含处理副作用（如异步操作、API 调用）的部分。\n- **用户偏好设置**：使用 `@vben-core/preferences` 处理用户偏好设置，涉及本地存储或浏览器缓存逻辑（如使用 `localStorage`）。\n- **导航和路由**：处理导航、页面跳转等场景，需要管理路由变化的逻辑。\n- **组件库依赖**：包含与特定组件库紧密耦合或依赖大型仓库的部分。\n\n通过将相关代码归类到 `effects` 目录，可以使项目结构更加清晰，便于维护和扩展。\n","isInternal":false,"tokens":265,"sizeBytes":772},{"name":"README.md","path":"packages/icons/README.md","rawUrl":"https://raw.githubusercontent.com/vbenjs/vue-vben-admin/HEAD/packages/icons/README.md","title":"icons Documentation","category":"plugin-manifest","format":"markdown","content":"# @vben/icons\n\n用于多个 `app` 公用的图标文件，继承了 `@vben-core/icons` 的所有能力。业务上有通用图标可以放在这里。\n\n## 用法\n\n### 添加依赖\n\n```bash\n# 进入目标应用目录，例如 apps/xxxx-app\n# cd apps/xxxx-app\npnpm add @vben/icons\n```\n\n### 使用\n\n```ts\nimport { X } from '@vben/icons';\n```\n","isInternal":false,"tokens":119,"sizeBytes":339},{"name":"README.md","path":"packages/styles/README.md","rawUrl":"https://raw.githubusercontent.com/vbenjs/vue-vben-admin/HEAD/packages/styles/README.md","title":"styles Documentation","category":"plugin-manifest","format":"markdown","content":"# @vben/styles\n\n用于多个 `app` 公用的样式文件，继承了 `@vben-core/design` 的所有能力。业务上有通用的样式文件可以放在这里。\n\n## 用法\n\n### 添加依赖\n\n```bash\n# 进入目标应用目录，例如 apps/xxxx-app\n# cd apps/xxxx-app\npnpm add @vben/styles\n```\n\n### 使用\n\n```ts\nimport '@vben/styles';\n```\n","isInternal":false,"tokens":117,"sizeBytes":341},{"name":"README.md","path":"packages/types/README.md","rawUrl":"https://raw.githubusercontent.com/vbenjs/vue-vben-admin/HEAD/packages/types/README.md","title":"types Documentation","category":"plugin-manifest","format":"markdown","content":"# @vben/types\n\n用于多个 `app` 公用的工具类型，继承了 `@vben-core/typings` 的所有能力。业务上有通用的类型定义可以放在这里。\n\n## 用法\n\n### 添加依赖\n\n```bash\n# 进入目标应用目录，例如 apps/xxxx-app\n# cd apps/xxxx-app\npnpm add @vben/types\n```\n\n### 使用\n\n```ts\n// 推荐加上 type\nimport type { SelectOption } from '@vben/types';\n```\n","isInternal":false,"tokens":132,"sizeBytes":387},{"name":"README.md","path":"packages/utils/README.md","rawUrl":"https://raw.githubusercontent.com/vbenjs/vue-vben-admin/HEAD/packages/utils/README.md","title":"utils Documentation","category":"plugin-manifest","format":"markdown","content":"# @vben/utils\n\n用于多个 `app` 公用的工具包，继承了 `@vben-core/shared/utils` 的所有能力。业务上有通用的工具函数可以放在这里。\n\n## 用法\n\n### 添加依赖\n\n```bash\n# 进入目标应用目录，例如 apps/xxxx-app\n# cd apps/xxxx-app\npnpm add @vben/utils\n```\n\n### 使用\n\n```ts\nimport { isString } from '@vben/utils';\n```\n","isInternal":false,"tokens":123,"sizeBytes":359}],"systemPromptSnippet":"<yakaai_skills repo=\"vbenjs/vue-vben-admin\">\n<!-- File: internal/vite-config/src/plugins/inject-app-loading/README.md (Tokens: ~32 | Category: plugin-manifest) -->\n# inject-app-loading\n\n用于在应用加载时显示加载动画的插件，可自行选择加载动画的样式。\n\n<!-- File: packages/@core/base/README.md (Tokens: ~22 | Category: plugin-manifest) -->\n# base\n\n基础共享包，请勿引入 workspace 依赖\n\n-\n\n<!-- File: packages/@core/base/shared/src/cache/README.md (Tokens: ~3388 | Category: plugin-manifest) -->\n# Cache 模块\n\n基于**策略模式**的异步存储管理方案，支持多种存储后端（localStorage、IndexedDB、Memory），提供统一的 API 接口。\n\n## 架构设计\n\n```shell\n┌───────────────────────────────────────────────┐\n│             StorageManager                    │\n│  ┌─────────────┐  ┌───────────────────────┐   │\n│  │ Prefix 隔离 │   │   TTL 过期管理        │   │\n│  └─────────────┘  └───────────────────────┘   │\n├───────────────────────────────────────────────┤\n│             IStorageDriver                    │\n├──────────┬─────────────────┬──────────────────┤\n│  Local   │   IndexedDB     │     Memory       │\n│  Storage │   Driver        │     Driver       │\n│  Driver  │                 │                  │\n└──────────┴─────────────────┴──────────────────┘\n```\n\n**分层职责：**\n\n| 层级             | 职责                                         |\n| ---------------- | -------------------------------------------- |\n| `StorageManager` | 命名空间前缀隔离、TTL 过期检查、统一对外 API |\n| `IStorageDriver` | 纯粹的 KV 存取抽象接口                       |\n| 各 Driver 实现   | 对接具体存储引擎，不感知前缀和 TTL           |\n\n---\n\n## 快速开始\n\n### 基本使用（默认 localStorage）\n\n```typescript\nimport { StorageManager } from '@vben-core/shared/cache';\n\nconst cache = new StorageManager({ prefix: 'myapp' });\n// 使用 IndexedDB\n//new StorageManager({ driver: new IndexedDBDriver(), prefix: 'app' });\n\n// 使用 sessionStorage\n//new StorageManager({ driver: new LocalStorageDriver({ storageType: 'sessionStorage' }), prefix: 'app' });\n\n// 测试环境\n//new StorageManager({ driver: new MemoryStorageDriver(), prefix: 'test' });\n\n// 存储数据\nawait cache.setItem('user', { name: '张三', age: 28 });\n\n// 读取数据\nconst user = await cache.getItem('user');\n// => { name: '张三', age: 28 }\n\n// 带默认值读取\nconst settings = await cache.getItem('settings', { theme: 'light' });\n// 如果不存在，返回 { theme: 'light' }\n\n// 删除数据\nawait cache.removeItem('user');\n\n// 清除当前前缀下所有数据\nawait cache.clear();\n```\n\n### 带 TTL 过期\n\n```typescript\nconst cache = new StorageManager({ prefix: 'session' });\n\n// 设置 5 分钟后过期（TTL 单位为毫秒）\nawait cache.setItem('token', 'abc123', 5 * 60 * 1000);\n\n// 5 分钟内可以正常读取\nconst token = await cache.getItem('token');\n// => 'abc123'\n\n// 5 分钟后自动返回 null（惰性删除）\nconst expiredToken = await cache.getItem('token');\n// => null\n\n// 主动清理所有过期项\nawait cache.clearExpiredItems();\n```\n\n---\n\n## 存储驱动\n\n### LocalStorageDriver（默认）\n\n基于浏览器 `localStorage` 或 `sessionStorage`，数据持久化存储。\n\n```typescript\nimport { LocalStorageDriver, StorageManager } from '@vben-core/shared/cache';\n\n// 使用 localStorage（默认）\nconst cache = new StorageManager({\n  driver: new LocalStorageDriver(),\n  prefix: 'app',\n});\n\n// 使用 sessionStorage\nconst sessionCache = new StorageManager({\n  driver: new LocalStorageDriver({ storageType: 'sessionStorage' }),\n  prefix: 'app',\n});\n```\n\n**特点：**\n\n- 同步 API 用 async 包装，保持接口统一\n- 自动处理 JSON 序列化/反序列化\n- 数据损坏时自动清除并返回 null\n- 存储上限约 5-10MB（视浏览器而定）\n\n**适用场景：** 用户偏好设置、小型配置数据、Token 存储\n\n---\n\n### IndexedDBDriver\n\n基于浏览器 IndexedDB，支持大容量结构化数据存储。\n\n```typescript\nimport {IndexedDBDriver, StorageManager} from '@vben-core/shared/cache';\n\nconst cache = new StorageManager({\n  driver: new IndexedDBDriver({\n    dbName: 'my-app-db',     // 数据库名称，默认 'vben-storage'\n    dbVersion: 1,            // 数据库版本，默认 1\n    storeName: 'cache-store', // 对象存储名称，默认 'kv-store'\n  }),\n  prefix: 'data',\n});\n\n// 存储大量数据\nawait cache.setItem('table-data', largeDataArray);\n\n// 存储二进制友好的结构（IndexedDB 原生支持）\nawait cache.setItem('config', {\n  columns: [...],\n  filters: [...],\n  pagination: {page: 1, size: 20},\n});\n```\n\n**特点：**\n\n- 懒初始化：首次操作时自动打开数据库，无需手动调用 `init()`\n- 存储容量大（通常数百 MB 到 GB 级别）\n- 支持结构化克隆（可存储 Date、RegExp、Blob 等复杂类型）\n- 天然异步，不阻塞主线程\n\n**适用场景：** 离线数据缓存、大型表格数据、文件/图片缓存、复杂业务数据\n\n---\n\n### MemoryStorageDriver\n\n基于内存 Map，数据不持久化，页面刷新即丢失。\n\n```typescript\nimport { MemoryStorageDriver, StorageManager } from '@vben-core/shared/cache';\n\nconst cache = new StorageManager({\n  driver: new MemoryStorageDriver(),\n  prefix: 'test',\n});\n```\n\n**特点：**\n\n- 读写速度最快\n- 无浏览器 API 依赖\n- 数据随页面生命周期销毁\n\n**适用场景：** 单元测试、SSR 服务端渲染、临时运行时缓存\n\n---\n\n## API 参考\n\n### StorageManager\n\n#### 构造函数\n\n```typescript\nnew StorageManager(options?: StorageManagerOptions)\n```\n\n| 参数 | 类型 | 默认值 | 说明 |\n| --- | --- | --- | --- |\n| `driver` | `IStorageDriver` | `new LocalStorageDriver()` | 存储驱动实例 |\n| `prefix` | `string` | `''` | 键前缀，用于命名空间隔离 |\n\n#### 方法\n\n| 方法 | 签名 | 说明 |\n| --- | --- | --- |\n| `getItem` | `getItem<T>(key: string, defaultValue?: T \\| null): Promise<T \\| null>` | 获取存储项，过期或不存在返回默认值 |\n| `setItem` | `setItem<T>(key: string, value: T, ttl?: number): Promise<void>` | 设置存储项，可选 TTL（毫秒） |\n| `removeItem` | `removeItem(key: string): Promise<void>` | 删除指定存储项 |\n| `clear` | `clear(): Promise<void>` | 清除当前前缀下所有存储项 |\n| `clearExpiredItems` | `clearExpiredItems(): Promise<void>` | 主动清理所有过期项 |\n\n---\n\n### IStorageDriver 接口\n\n自定义驱动需要实现此接口：\n\n```typescript\ninterface IStorageDriver {\n  clear(): Promise<void>;\n\n  getItem<T>(key: string): Promise<null | T>;\n\n  keys(): Promise<string[]>;\n\n  removeItem(key: string): Promise<void>;\n\n  setItem<T>(key: string, value: T): Promise<void>;\n}\n```\n\n---\n\n## 高级用法\n\n### 自定义 Driver\n\n```typescript\nimport type { IStorageDriver } from '@vben-core/shared/cache';\n\nclass CookieStorageDriver implements IStorageDriver {\n  async getItem<T>(key: string): Promise<null | T> {\n    const value = getCookie(key);\n    return value ? JSON.parse(value) : null;\n  }\n\n  async setItem<T>(key: string, value: T): Promise<void> {\n    setCookie(key, JSON.stringify(value));\n  }\n\n  async removeItem(key: string): Promise<void> {\n    deleteCookie(key);\n  }\n\n  async clear(): Promise<void> {\n    clearAllCookies();\n  }\n\n  async keys(): Promise<string[]> {\n    return getAllCookieNames();\n  }\n}\n\n// 使用自定义 Driver\nconst cache = new StorageManager({\n  driver: new CookieStorageDriver(),\n  prefix: 'ck',\n});\n```\n\n### 根据环境动态选择 Driver\n\n```typescript\nimport {\n  IndexedDBDriver,\n  LocalStorageDriver,\n  MemoryStorageDriver,\n  StorageManager,\n} from '@vben-core/shared/cache';\n\nfunction createStorageManager(prefix: string) {\n  // SSR 环境使用内存驱动\n  if (typeof window === 'undefined') {\n    return new StorageManager({\n      driver: new MemoryStorageDriver(),\n      prefix,\n    });\n  }\n\n  // 大数据场景使用 IndexedDB\n  if (needsLargeStorage()) {\n    return new StorageManager({\n      driver: new IndexedDBDriver({ dbName: `${prefix}-db` }),\n      prefix,\n    });\n  }\n\n  // 默认使用 localStorage\n  return new StorageManager({ prefix });\n}\n```\n\n### 命名空间隔离\n\n```typescript\n// 不同模块使用不同前缀，互不干扰\nconst userCache = new StorageManager({ prefix: 'user' });\nconst configCache = new StorageManager({ prefix: 'config' });\n\nawait userCache.setItem('profile', { name: '张三' });\nawait configCache.setItem('profile', { theme: 'dark' });\n\n// 各自独立\nawait userCache.getItem('profile'); // => { name: '张三' }\nawait configCache.getItem('profile'); // => { theme: 'dark' }\n\n// 只清除 user 前缀的数据\nawait userCache.clear();\nawait configCache.getItem('profile'); // => { theme: 'dark' }（不受影响）\n```\n\n### 定时清理过期数据\n\n```typescript\nconst cache = new StorageManager({ prefix: 'app' });\n\n// 应用启动时清理一次\nawait cache.clearExpiredItems();\n\n// 或者定时清理（每 10 分钟）\nsetInterval(\n  async () => {\n    await cache.clearExpiredItems();\n  },\n  10 * 60 * 1000,\n);\n```\n\n---\n\n## 数据存储格式\n\n`StorageManager` 在 Driver 层存储的数据结构为：\n\n```typescript\ninterface StorageItem<T> {\n  expiry?: number; // 过期时间戳（毫秒），undefined 表示永不过期\n  value: T; // 实际业务数据\n}\n```\n\n实际存储的 key 格式为：`{prefix}-{key}`\n\n例如 `prefix = 'app'`，`key = 'user'`，则实际存储键为 `app-user`。\n\n---\n\n## 过期策略\n\n采用**惰性删除 + 主动清理**双重策略：\n\n| 策略 | 触发时机 | 说明 |\n| --- | --- | --- |\n| 惰性删除 | 调用 `getItem` 时 | 读取时检查过期，过期则删除并返回默认值 |\n| 主动清理 | 调用 `clearExpiredItems` 时 | 遍历所有带前缀的 key，删除已过期项 |\n\n---\n\n## 各 Driver 对比\n\n| 特性       | LocalStorageDriver  | IndexedDBDriver  | MemoryStorageDriver |\n| ---------- | ------------------- | ---------------- | ------------------- |\n| 持久化     | ✅                  | ✅               | ❌                  |\n| 容量       | 5-10 MB             | 数百 MB+         | 受内存限制          |\n| 速度       | 快（同步）          | 中等（异步 I/O） | 最快                |\n| 数据类型   | 仅 JSON 可序列化    | 结构化克隆       | 任意 JS 对象        |\n| 浏览器支持 | 所有现代浏览器      | 所有现代浏览器   | 任意环境            |\n| 阻塞主线程 | 是                  | 否               | 否                  |\n| 适用场景   | 配置、Token、小数据 | 离线缓存、大数据 | 测试、SSR           |\n\n---\n\n## 在项目中的使用\n\n本项目中 `StorageManager` 主要被 `PreferenceManager` 消费，用于持久化用户偏好设置：\n\n```typescript\n// packages/@core/preferences/src/preferences.ts\nclass PreferenceManager {\n  private cache: StorageManager;\n\n  constructor() {\n    this.cache = new StorageManager();\n    this.state = reactive<Preferences>({ ...defaultPreferences });\n  }\n\n  initPreferences = async ({ namespace }) => {\n    // 用应用命名空间重新初始化\n    this.cache = new StorageManager({ prefix: namespace });\n\n    // 从缓存加载偏好设置\n    const cached = await this.cache.getItem<Preferences>('preferences');\n    // ...\n  };\n}\n```\n\n---\n\n## 注意事项\n\n1. **所有方法都是异步的** — 即使底层是同步的 localStorage，API 也返回 Promise，确保切换 Driver 时无需改动调用方。\n\n2. **TTL 单位是毫秒** — `setItem('key', value, 60000)` 表示 60 秒后过期。\n\n3. **IndexedDB 懒初始化** — 不需要手动调用 `init()` 或 `open()`，首次操作时自动打开数据库连接并复用。\n\n4. **前缀隔离是逻辑隔离** — `clear()` 只清除当前前缀下的数据，不影响其他前缀或无前缀的数据。\n\n5. **错误处理** — LocalStorageDriver 在 JSON 解析失败时自动清除损坏数据； `PreferenceManager.saveToCache` 内部 try-catch 防止未捕获异常。\n\n6. **IndexedDB 版本升级** — 如果需要修改 objectStore 结构，需要递增 `dbVersion`。当前实现在 `upgradeneeded` 事件中自动创建 objectStore。\n\n<!-- File: packages/@core/composables/src/use-simple-locale/README.md (Tokens: ~11 | Category: plugin-manifest) -->\n# Simple i18n\n\nSimple i18 implementation\n\n<!-- File: packages/@core/README.md (Tokens: ~67 | Category: plugin-manifest) -->\n# @vben-core\n\n系统一些比较基础的SDK和UI组件库，该目录后续完善后，可能会迁移出去或者发布到npm，请勿将任何业务逻辑和业务包放在该目录。\n\n<!-- File: packages/@core/ui-kit/menu-ui/README.md (Tokens: ~8 | Category: plugin-manifest) -->\n# 菜单组件\n\n<!-- File: packages/@core/ui-kit/README.md (Tokens: ~25 | Category: plugin-manifest) -->\n# ui-kit\n\n用于管理公共组件、不同UI组件库封装的组件\n\n<!-- File: packages/constants/README.md (Tokens: ~120 | Category: plugin-manifest) -->\n# @vben/constants\n\n用于多个 `app` 公用的常量，继承了 `@vben-core/shared/constants` 的所有能力。业务上有通用常量可以放在这里。\n\n## 用法\n\n### 添加依赖\n\n```bash\n# 进入目标应用目录，例如 apps/xxxx-app\n# cd apps/xxxx-app\npnpm add @vben/constants\n```\n\n### 使用\n\n```ts\nimport { LOGIN_PATH } from '@vben/constants';\n```\n\n<!-- File: packages/effects/hooks/README.md (Tokens: ~118 | Category: plugin-manifest) -->\n# @vben/hooks\n\n用于多个 `app` 公用的 hook，继承了 `@vben/hooks` 的所有能力。业务上有通用 hooks 可以放在这里。\n\n## 用法\n\n### 添加依赖\n\n```bash\n# 进入目标应用目录，例如 apps/xxxx-app\n# cd apps/xxxx-app\npnpm add @vben/hooks\n```\n\n### 使用\n\n```ts\nimport { useNamespace } from '@vben/hooks';\n```\n\n<!-- File: packages/effects/layouts/src/basic/README.md (Tokens: ~100 | Category: plugin-manifest) -->\n## layout\n\n### header\n\n- 支持N个自定义插槽，命名方式：header-right-n，header-left-n\n- header-left-n ，排序方式：0-19 ,breadcrumb 21-x\n- header-right-n ，排序方式：0-49，global-search，51-59，theme-toggle，61-69，language-toggle，71-79，fullscreen，81-89，notification，91-149，user-dropdown，151-x\n\n<!-- File: packages/effects/plugins/README.md (Tokens: ~239 | Category: plugin-manifest) -->\n# @vben/plugins\n\n该目录用于存放项目中集成的第三方库及其相关插件。每个插件都包含了可重用的逻辑、配置和组件，方便在项目中进行统一管理和调用。\n\n## 注意\n\n所有的第三方插件都必须以 `subpath` 形式引入，例：\n\n以 `echarts` 为例，引入方式如下：\n\n**packages.json**\n\n```json\n\"exports\": {\n    \"./echarts\": {\n      \"types\": \"./src/echarts/index.ts\",\n      \"default\": \"./src/echarts/index.ts\"\n    }\n  }\n```\n\n**使用方式**\n\n```ts\nimport { useEcharts } from '@vben/plugins/echarts';\n```\n\n这样做的好处是，应用可以自行选择是否使用插件，而不会因为插件的引入及副作用而导致打包体积增大，只引入需要的插件即可。\n\n<!-- File: packages/effects/plugins/src/echarts/README.md (Tokens: ~227 | Category: plugin-manifest) -->\n# ECharts Plugin\n\nECharts 图表插件，预置常用组件和图表类型。\n\n## 导出\n\n| 导出         | 类型 | 说明         |\n| ------------ | ---- | ------------ |\n| `default`    | 对象 | echarts 实例 |\n| `EchartsUI`  | 组件 | 图表容器组件 |\n| `ECOption`   | 类型 | 图表配置类型 |\n| `useEcharts` | 函数 | 组合式函数   |\n\n## 使用\n\n```ts\nimport { EchartsUI, useEcharts, ECOption } from '@vben/plugins/echarts';\n```\n\n## 类型\n\n```ts\nimport type { ECOption } from '@vben/plugins/echarts';\n```\n\n## 预置组件\n\n- TitleComponent\n- TooltipComponent\n- GridComponent\n- LegendComponent\n- ToolboxComponent\n- DatasetComponent\n- TransformComponent\n\n## 预置图表\n\n- BarChart\n- LineChart\n- PieChart\n- RadarChart\n\n<!-- File: packages/effects/plugins/src/motion/README.md (Tokens: ~173 | Category: plugin-manifest) -->\n# Motion Plugin\n\n基于 @vueuse/motion 的动画插件。\n\n## 导出\n\n| 导出              | 类型 | 说明       |\n| ----------------- | ---- | ---------- |\n| `Motion`          | 组件 | 动画组件   |\n| `MotionGroup`     | 组件 | 动画组组件 |\n| `MotionDirective` | 指令 | 动画指令   |\n| `MotionPlugin`    | 插件 | Vue 插件   |\n\n## 使用\n\n```ts\nimport { MotionPlugin, Motion, MotionDirective } from '@vben/plugins/motion';\n\napp.use(MotionPlugin);\n```\n\n## 类型\n\n```ts\nimport type { MotionOptions, MotionVariants } from '@vben/plugins/motion';\n```\n\n<!-- File: packages/effects/plugins/src/vxe-table/README.md (Tokens: ~354 | Category: plugin-manifest) -->\n# VXE Table Plugin\n\n基于 vxe-table 和 vxe-pc-ui 的表格组件插件。\n\n## 导出\n\n| 导出                  | 类型 | 说明           |\n| --------------------- | ---- | -------------- |\n| `setupVbenVxeTable`   | 函数 | 初始化配置函数 |\n| `useVbenVxeGrid`      | 函数 | 表格组合式函数 |\n| `VbenVxeGrid`         | 组件 | 表格组件       |\n| `VxeTableGridColumns` | 类型 | 表格列类型     |\n| `VxeTableGridOptions` | 类型 | 表格配置类型   |\n| `VxeGridProps`        | 类型 | 表格 Props     |\n| `VxeGridListeners`    | 类型 | 表格事件类型   |\n\n## 使用\n\n```ts\nimport {\n  setupVbenVxeTable,\n  useVbenVxeGrid,\n  VbenVxeGrid,\n} from '@vben/plugins/vxe-table';\n```\n\n## 初始化\n\n在应用入口处调用：\n\n```ts\nimport { setupVbenVxeTable } from '@vben/plugins/vxe-table';\nimport { useVbenForm } from '@vben-core/form-ui';\n\nsetupVbenVxeTable({\n  configVxeTable: (vxeUI) => {\n    // 配置 VXE Table\n  },\n  useVbenForm,\n});\n```\n\n## 类型\n\n```ts\nimport type {\n  VxeTableGridOptions,\n  VxeGridProps,\n} from '@vben/plugins/vxe-table';\n```\n\n<!-- File: packages/effects/README.md (Tokens: ~265 | Category: plugin-manifest) -->\n## Effects 目录\n\n`effects` 目录专门用于存放与轻微耦合相关的代码和逻辑。如果你的包具有以下特点，建议将其放置在 `effects` 目录下：\n\n- **状态管理**：使用状态管理框架 `pinia`，并包含处理副作用（如异步操作、API 调用）的部分。\n- **用户偏好设置**：使用 `@vben-core/preferences` 处理用户偏好设置，涉及本地存储或浏览器缓存逻辑（如使用 `localStorage`）。\n- **导航和路由**：处理导航、页面跳转等场景，需要管理路由变化的逻辑。\n- **组件库依赖**：包含与特定组件库紧密耦合或依赖大型仓库的部分。\n\n通过将相关代码归类到 `effects` 目录，可以使项目结构更加清晰，便于维护和扩展。\n\n<!-- File: packages/icons/README.md (Tokens: ~119 | Category: plugin-manifest) -->\n# @vben/icons\n\n用于多个 `app` 公用的图标文件，继承了 `@vben-core/icons` 的所有能力。业务上有通用图标可以放在这里。\n\n## 用法\n\n### 添加依赖\n\n```bash\n# 进入目标应用目录，例如 apps/xxxx-app\n# cd apps/xxxx-app\npnpm add @vben/icons\n```\n\n### 使用\n\n```ts\nimport { X } from '@vben/icons';\n```\n\n<!-- File: packages/styles/README.md (Tokens: ~117 | Category: plugin-manifest) -->\n# @vben/styles\n\n用于多个 `app` 公用的样式文件，继承了 `@vben-core/design` 的所有能力。业务上有通用的样式文件可以放在这里。\n\n## 用法\n\n### 添加依赖\n\n```bash\n# 进入目标应用目录，例如 apps/xxxx-app\n# cd apps/xxxx-app\npnpm add @vben/styles\n```\n\n### 使用\n\n```ts\nimport '@vben/styles';\n```\n\n<!-- File: packages/types/README.md (Tokens: ~132 | Category: plugin-manifest) -->\n# @vben/types\n\n用于多个 `app` 公用的工具类型，继承了 `@vben-core/typings` 的所有能力。业务上有通用的类型定义可以放在这里。\n\n## 用法\n\n### 添加依赖\n\n```bash\n# 进入目标应用目录，例如 apps/xxxx-app\n# cd apps/xxxx-app\npnpm add @vben/types\n```\n\n### 使用\n\n```ts\n// 推荐加上 type\nimport type { SelectOption } from '@vben/types';\n```\n\n<!-- File: packages/utils/README.md (Tokens: ~123 | Category: plugin-manifest) -->\n# @vben/utils\n\n用于多个 `app` 公用的工具包，继承了 `@vben-core/shared/utils` 的所有能力。业务上有通用的工具函数可以放在这里。\n\n## 用法\n\n### 添加依赖\n\n```bash\n# 进入目标应用目录，例如 apps/xxxx-app\n# cd apps/xxxx-app\npnpm add @vben/utils\n```\n\n### 使用\n\n```ts\nimport { isString } from '@vben/utils';\n```\n</yakaai_skills>"}