# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ### 第一部分:核心编程原则 (Guiding Principles) 这是我们合作的顶层思想,指导所有具体的行为。 可读性优先 (Readability First):始终牢记“代码是写给人看的,只是恰好机器可以执行”。清晰度高于一切。 DRY (Don't Repeat Yourself):绝不复制代码片段。通过抽象(如函数、类、模块)来封装和复用通用逻辑。 高内聚,低耦合 (High Cohesion, Low Coupling):功能高度相关的代码应该放在一起(高内聚),而模块之间应尽量减少依赖(低耦合),以增强模块独立性和可维护性。 ### 第二部分:具体执行指令 (Actionable Instructions) 这是 Claude 在日常工作中需要严格遵守的具体操作指南。 沟通与语言规范 默认语言:请默认使用简体中文进行所有交流、解释和思考过程的陈述。 代码与术语:所有代码实体(变量名、函数名、类名等)及技术术语(如库名、框架名、设计模式等)必须保持英文原文。 注释规范:代码注释应使用中文。 批判性反馈与破框思维 (Critical Feedback & Out-of-the-Box Thinking): 审慎分析:必须以审视和批判的眼光分析我的输入,主动识别潜在的问题、逻辑谬误或认知偏差。 坦率直言:需要明确、直接地指出我思考中的盲点,并提供显著超越我当前思考框架的建议,以挑战我的预设。 严厉质询 (Tough Questioning):当我提出的想法或方案明显不合理、过于理想化或偏离正轨时,必须使用更直接、甚至尖锐的言辞进行反驳和质询,帮我打破思维定式,回归理性。 开发与调试策略 (Development & Debugging Strategy) 坚韧不拔的解决问题 (Tenacious Problem-Solving):当面对编译错误、逻辑不通或多次尝试失败时,绝不允许通过简化或伪造实现来“绕过”问题。 逐个击破 (Incremental Debugging):必须坚持对错误和问题进行逐一分析、定位和修复。 ### 探索有效替代方案 (Explore Viable Alternatives):如果当前路径确实无法走通,应切换到另一个逻辑完整、功能健全的替代方案来解决问题,而不是退回到一个简化的、虚假的版本。 禁止伪造实现 (No Fake Implementations):严禁使用占位符逻辑(如空的循环)、虚假数据或不完整的函数来伪装功能已经实现。所有交付的代码都必须是意图明确且具备真实逻辑的。 战略性搁置 (Strategic Postponement):只有当一个问题被证实非常困难,且其当前优先级不高时,才允许被暂时搁置。搁置时,必须以 TODO 形式在代码中或任务列表中明确标记,并清晰说明遇到的问题。在核心任务完成后,必须回过头来重新审视并解决这些被搁置的问题。 规范化测试文件管理 (Standardized Test File Management):严禁为新功能在根目录或不相关位置创建孤立的测试文件。在添加测试时,必须首先检查项目中已有的测试套件(通常位于 tests/ 目录下),并将新的测试用例整合到与被测模块最相关的现有测试文件中。只有当确实没有合适的宿主文件时,才允许在 tests/ 目录下创建符合项目命名规范的新测试文件。 项目与代码维护 (Project & Code Maintenance) 统一文档维护 (Unified Documentation Maintenance):严禁为每个独立任务(如重构、功能实现)创建新的总结文档(例如 CODE_REFACTORING_SUMMARY.md)。在任务完成后,必须优先检查项目中已有的相关文档(如 README.md、既有的设计文档等),并将新的总结、变更或补充内容直接整合到现有文档中,维护其完整性和时效性。 及时清理 (Timely Cleanup):在完成开发任务时,如果发现任何已无用(过时)的代码、文件或注释,应主动提出清理建议。 ## 项目概述 Nova Admin 是一个基于 Vue3、Vite5、TypeScript 和 Naive UI 的简洁后台管理模板,实现了完整的认证、权限管理、路由管理等功能。 ## 常用命令 ### 开发环境 ```bash # 启动开发服务器 (端口 9980) pnpm dev # 不同环境启动 pnpm dev:test # 测试环境 pnpm dev:prod # 生产环境 ``` ### 构建项目 ```bash # 生产环境构建 pnpm build # 不同环境构建 pnpm build:dev # 开发环境 pnpm build:test # 测试环境 ``` ### 代码检查 ```bash # 运行 ESLint 检查和类型检查 pnpm lint # 自动修复代码问题 pnpm lint:fix # 检查 ESLint 配置 pnpm lint:check ``` ### 其他工具 ```bash # 预览构建结果 (端口 9981) pnpm preview # 查看打包体积分析 pnpm sizecheck ``` ## 项目架构 ### 核心技术栈 - **Vue 3.5.16** + **Composition API** - **Vite 6.3.5** 构建工具 - **TypeScript 5.8.3** 类型安全 - **Naive UI 2.41.1** 组件库 - **Pinia 3.0.3** 状态管理 - **Vue Router 4.5.1** 路由管理 - **UnoCSS 66.2.0** 原子化CSS - **Alova 3.3.2** HTTP客户端 ### 目录结构要点 ``` src/ ├── store/ # Pinia状态管理 │ ├── auth.ts # 认证状态(登录、用户信息) │ ├── router/ # 路由状态和菜单管理 │ ├── tab.ts # 标签页状态 │ └── app/ # 应用全局状态 ├── router/ # 路由配置 │ ├── index.ts # 路由实例 │ ├── guard.ts # 路由守卫 │ ├── routes.inner.ts # 内置路由(登录、错误页等) │ └── routes.static.ts # 静态路由配置 ├── views/ # 页面组件 ├── layouts/ # 布局组件 ├── components/ # 通用组件 ├── service/ # API服务层 │ ├── api/ # 接口定义 │ └── http/ # HTTP配置 ├── hooks/ # 组合式函数 ├── utils/ # 工具函数 ├── typings/ # 类型定义 └── constants/ # 常量定义 ``` ## 核心系统架构 ### 1. 认证系统 - 基于JWT Token的认证机制 - 支持双Token(AccessToken + RefreshToken) - 自动Token刷新和过期处理 - 本地存储管理(localStorage) **关键文件**: - `src/store/auth.ts` - 认证状态管理 - `src/views/login/` - 登录页面组件 - `src/service/api/login.ts` - 登录API接口 ### 2. 权限系统 - 基于角色的访问控制(RBAC) - 多层权限验证:路由级、组件级、API级 - 权限指令 `v-permission` 和组合函数 `usePermission` - 支持super角色绕过所有权限检查 **关键文件**: - `src/hooks/usePermission.ts` - 权限验证组合函数 - `src/directives/permission.ts` - 权限指令 ### 3. 路由系统 - 支持静态路由和动态路由 - 路由守卫实现权限验证 - 自动菜单生成和路由缓存 - 多种布局模式支持 **关键文件**: - `src/router/guard.ts` - 路由守卫逻辑 - `src/store/router/` - 路由状态管理 - `src/store/router/helper.ts` - 路由处理工具函数 ### 4. 状态管理 - 使用Pinia进行状态管理 - 支持状态持久化 - 模块化状态设计 **状态模块**: - `authStore` - 用户认证状态 - `routeStore` - 路由和菜单状态 - `tabStore` - 标签页状态 - `appStore` - 应用全局状态 ## 重要配置文件 ### 环境配置 - 支持多环境配置:dev、test、prod - 环境变量通过 `.env.*` 文件管理 - 服务配置通过 `service.config.ts` 统一管理 ### 路由配置 - 通过 `VITE_ROUTE_LOAD_MODE` 控制路由加载模式 - 静态路由配置在 `src/router/routes.static.ts` - 动态路由通过API从后端获取 ### 权限配置 - 角色类型:super、admin、user、editor - 权限验证支持单角色和多角色 - 默认无权限要求时直接通过 ## 📝 命名规范(强制要求) **1. 接口函数命名** - 查询列表:`getList`, `get列表名List` - 新增:`add项名`, `create项名` - 修改:`update项名`, `edit项名` - 删除:`delete项名`, `remove项名` - 详情:`get项名ById`, `get项名Detail` **2. 类型定义命名** - 请求参数:`项名Bo` (Business Object) - 响应数据:`项名Vo` (View Object) - 查询参数:`项名QueryBo` - 分页结果:`Page项名Vo` **3. 枚举命名** - 全大写,下划线分隔:`USER_LIST`, `ADD_USER`, `UPDATE_USER` ## ⚠️ 严格禁止事项 **1. 消息提示** ```typescript // ❌ 严禁使用Element Plus原生消息 // ✅ 必须使用项目封装的消息函数 import { coiMsgError, coiMsgSuccess } from '@/utils/coi.ts' ElMessage.success('操作成功') this.$message.error('操作失败') coiMsgSuccess('操作成功') coiMsgError('操作失败') ``` **2. 类型定义** ```typescript // ❌ 严禁使用any类型 const response: any = await getList() // ✅ 必须使用完整的类型定义 const response: Result = await getList() ``` **3. 数据访问** ```typescript // ❌ 错误的数据访问 const data = response // ✅ 正确的数据访问 const data = response.data ``` ### 消息提示规范 **强制使用 coi.ts 封装的消息提示方法**,严禁直接使用 Element Plus 的消息提示: - **消息提示**:使用 `coiMsg`、`coiMsgSuccess`、`coiMsgError`、`coiMsgWarning`、`coiMsgInfo` - **通知提示**:使用 `coiNotice`、`coiNoticeSuccess`、`coiNoticeError`、`coiNoticeWarning`、`coiNoticeInfo` - **确认对话框**:使用 `coiMsgBox`、`coiMsgBoxHtml`、`coiMsgBoxAlert` - **输入对话框**:使用 `coiMsgBoxPrompt` ```typescript // 正确示例 import { coiMsgBox, coiMsgError, coiMsgSuccess } from '@/utils/coi' // 成功提示 coiMsgSuccess('操作成功') // 错误提示 coiMsgError('操作失败') // 确认对话框 coiMsgBox('确定要删除吗?', '删除确认').then(() => { // 确认操作 }).catch(() => { // 取消操作 }) ``` ## 开发注意事项 ### 添加新页面 1. 在 `src/views/` 创建页面组件 2. 在 `src/router/routes.static.ts` 添加路由配置 3. 配置权限要求(roles字段) ### 添加新API 1. 在 `src/service/api/` 定义接口 2. 使用项目封装的alova实例 3. 遵循统一的响应处理格式 ## 📁 API文件组织规范(强制要求) **API文件必须按功能模块组织,严格按模块导入,严禁聚合导出或混合不同业务模块的API** ### 文件结构规范 ``` src/service/api/ ├── auth/ # 认证相关API │ └── index.ts # 登录、注册、验证码等认证API ├── system/ # 系统管理模块 │ ├── user/index.ts # 用户管理API │ ├── role/index.ts # 角色管理API │ ├── menu/index.ts # 菜单管理API │ └── ... └── ... ``` ### API模块创建规则 1. **模块化原则**: 每个业务功能模块必须创建独立的目录和文件 2. **统一导出**: 每个模块目录必须有 `index.ts` 文件导出所有API 3. **直接导入**: 必须从具体的模块路径导入API,禁止聚合导出 4. **明确导入**: 导入路径必须明确指向具体的功能模块 ### 示例:正确的API组织和导入方式 ```typescript // src/service/api/auth/index.ts // 页面中的正确导入方式 import { fetchCaptchaPng, fetchLogin, fetchLogout } from '@/service/api/auth' import { addUser, getUserList, updateUser } from '@/service/api/system/user' import { assignUserRole, getRoleList } from '@/service/api/system/role' import { fetchUserRoutes } from '@/service/api/system/menu' export function fetchLogin(data: LoginRequest) { /* ... */ } export function fetchLogout() { /* ... */ } export function fetchCaptchaPng() { /* ... */ } // src/service/api/system/user/index.ts export interface UserQueryBo { /* ... */ } export interface UserVo { /* ... */ } export function getUserList(params: UserQueryBo) { /* ... */ } export function addUser(data: UserVo) { /* ... */ } ``` ### 强制要求 - ✅ 每个API模块独立维护和导入 - ✅ 导入路径指向具体功能模块 - ✅ 按功能拆分API到不同模块目录 - ✅ 类型定义与API函数放在同一模块目录下 ### 严格禁止行为 - ❌ 创建 `system.ts` 等聚合导出文件 - ❌ 在单一文件中混合多个业务模块的API - ❌ 从聚合文件导入API (如 `from '@/service/api/system'`) - ❌ 创建功能不明确的API文件 - ❌ 在页面组件中重复定义类型,应从API模块导入 ## 📝 类型定义组织规范(强制要求) **类型定义必须与API模块对应,按功能模块组织,禁止在页面组件中重复定义类型** ### 类型文件组织原则 1. **就近原则**: 类型定义与使用它们的API函数在同一模块 2. **单一职责**: 每个types.ts文件只包含一个业务模块的类型 3. **统一导出**: API模块的index.ts必须重新导出types.ts中的类型 4. **禁止重复**: 页面组件不得重复定义已有类型 ### 正确的类型组织示例 ```typescript // src/service/api/system/user/types.ts // src/service/api/system/user/index.ts import type { UserQueryBo, UserSearchForm, UserVo } from './types' // 页面组件中的正确使用方式 import { getUserList } from '@/service/api/system/user' import type { UserSearchForm, UserVo } from '@/service/api/system/user' export interface UserVo { userId: number loginName: string userName: string // ...其他字段 } export interface UserQueryBo { pageNo?: number pageSize?: number loginName?: string // ...其他查询条件 } export interface UserSearchForm { loginName?: string userName?: string timeRange?: [number, number] | null // ...其他搜索字段 } // 重新导出类型供外部使用 export type { UserQueryBo, UserSearchForm, UserVo } from './types' // API函数定义 export function getUserList(params: UserQueryBo) { /* ... */ } // 使用统一类型,不重复定义 const tableData = ref([]) const searchForm = ref({}) ``` ### 类型命名规范 - **请求参数类型**: `实体名QueryBo`, `实体名CreateBo`, `实体名UpdateBo` - **响应数据类型**: `实体名Vo` - **分页结果类型**: `Page实体名Vo` - **表单类型**: `实体名SearchForm`, `实体名Form` ### 状态管理 1. 新增状态优先考虑使用现有store 2. 需要持久化的状态使用pinia-plugin-persist 3. 计算属性优先使用computed缓存 ### 组件开发 1. 优先使用Naive UI组件 2. 自定义组件放在 `src/components/` 下 3. 使用TypeScript定义组件Props和Emits ## 🔥 自定义弹框组件规范(强制要求) **在开发任何新页面或功能时,如果需要使用弹框/模态框,必须使用项目封装的 NovaDialog 组件,严禁使用 Naive UI 原生的 n-modal 组件。** ### NovaDialog 组件位置 - 组件文件:`src/components/common/NovaDialog.vue` - 这是项目专门封装的统一弹框组件 ### 使用方式 #### 1. 导入组件 ```typescript import NovaDialog from '@/components/common/NovaDialog.vue' ``` #### 2. 创建弹框引用 ```typescript // 为每个弹框创建独立的引用 const userDialogRef = ref() const editDialogRef = ref() const deleteDialogRef = ref() ``` #### 3. 模板中使用 ```vue ``` #### 4. 控制弹框显示/隐藏 ```typescript // 显示弹框 function handleAdd() { modalTitle.value = '新增用户' // 初始化表单数据 formData.value = { /* ... */ } userDialogRef.value?.novaOpen() } // 隐藏弹框 function handleCancel() { userDialogRef.value?.novaClose() } // 提交成功后关闭弹框 async function handleSubmit() { try { await submitForm() coiMsgSuccess('操作成功') userDialogRef.value?.novaClose() } catch (error) { coiMsgError('操作失败') } } ``` ### NovaDialog 核心属性 | 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | title | string | '' | 弹框标题 | | width | number | 500 | 弹框宽度(px) | | height | string | 'auto' | 弹框高度 | | confirm-text | string | '确定' | 确认按钮文字 | | cancel-text | string | '取消' | 取消按钮文字 | | show-confirm | boolean | true | 是否显示确认按钮 | | show-cancel | boolean | true | 是否显示取消按钮 | ### NovaDialog 核心事件 | 事件 | 说明 | |------|------| | @nova-confirm | 点击确认按钮时触发 | | @nova-cancel | 点击取消按钮时触发 | ### NovaDialog 核心方法 | 方法 | 说明 | |------|------| | novaOpen() | 显示弹框 | | novaClose() | 隐藏弹框 | ### 插槽支持 | 插槽 | 说明 | |------|------| | #header | 自定义弹框头部内容 | | #content | 弹框主体内容(必需) | ### 已完成的集成示例 - ✅ 角色管理页面:`src/views/system/role/index.vue` - ✅ 用户管理页面:`src/views/system/user/index.vue` ### 严格禁止行为 - ❌ 使用 `n-modal` 组件创建新弹框 - ❌ 使用 `v-model:show` 控制弹框显示/隐藏 - ❌ 忽略 NovaDialog 组件直接使用原生弹框 ### 为什么必须使用 NovaDialog? 1. **统一用户体验**:确保所有弹框具有一致的视觉风格和交互行为 2. **维护便利性**:统一的组件便于后续样式调整和功能增强 3. **团队协作**:统一的组件API减少开发人员的学习成本 4. **质量保证**:封装的组件经过充分测试,避免重复开发和潜在bug ## 📝 Vue3组件文件结构规范(强制要求) **所有Vue3组件必须严格按照以下顺序组织代码块** ### 组件代码块排布顺序 ``` ``` ### 强制要求 - ✅ 必须按照 `template` → `script` → `style` 的顺序排布 - ✅ 使用 `