# CLAUDE.md - GPU Guard 前端

## 项目概述

GPU Guard 前端 - 基于 Vue 3 + Cool Admin UI 的 GPU 智能监控平台前端。

**技术栈**: Vue 3.5 + TypeScript 5.5 + Vite 5.4 + Element Plus 2.9 + Pinia
**端口**: 9001
**包管理器**: pnpm (必须)
**后端代理**: `/dev/` → `http://127.0.0.1:8003`

## 重要规定

1. **所有回答用中文**
2. **遵循 Cool Admin 前端约定**

## 常用命令

```bash
pnpm i                    # 安装依赖
pnpm dev                  # 启动开发服务器 (端口 9001)
pnpm build                # 生产构建
pnpm type-check           # TypeScript 类型检查
pnpm lint                 # ESLint 检查
```

## Cool Admin 前端开发规范

### 模块配置 (ModuleConfig)

每个模块必须有 `config.ts`：

```typescript
// src/modules/{模块名}/config.ts
export default (): ModuleConfig => {
  return {
    name: 'project',           // 模块标识
    label: '项目管理',          // 显示名称
    order: 50,                 // 菜单排序
    views: [                   // 路由定义
      {
        path: '/project/list',
        meta: { label: '项目列表' },
        component: () => import('./views/list.vue')
      },
    ]
  };
};
```

### Service 代理 (核心机制)

Cool Admin 根据后端 Controller 文件名自动生成 service 代理：

```typescript
const { service } = useCool();

// 后端 controller 文件: modules/project/controller/admin/info.ts
service.project.info.page({ page: 1, size: 10 })  // POST /admin/project/info/page
service.project.info.add({ name: '新项目' })       // POST /admin/project/info/add
service.project.info.update({ id: 1, name: '改' }) // POST /admin/project/info/update
service.project.info.delete({ ids: [1, 2] })       // POST /admin/project/info/delete
service.project.info.info({ id: 1 })               // GET  /admin/project/info/info?id=1
```

**重要规则:**
- service 路径由后端 controller 文件名决定
- 下划线文件名 `time_log.ts` → `service.project.time_log`（不是 timeLog）
- 自定义接口用 `service.request()`: `service.request({ url: '/admin/project/task/ganttData' })`

### 动态路由机制

路由来源（优先级从高到低）：
1. 已注册的静态路由
2. 后端 `base_sys_menu` 表中的菜单路由
3. 模块 `config.ts` 中定义的 views

**菜单驱动路由:** 前端根据 `base_sys_menu` 表的 `viewPath` 字段动态加载组件。`viewPath` 格式为 `modules/project/views/list.vue`（相对于 `src/`）。

### 请求拦截器

位于 `src/cool/service/request.ts`：
- 自动添加 JWT Token 到 `Authorization` header
- Token 过期自动刷新（refreshToken 机制）
- 响应格式: `{ code: 1000, data: ..., message: '...' }`
- code 1000 = 成功，其他 = 失败

### 路径别名

- `/@/` → `./src/`
- `/$*/` → `./src/modules/`

## 模块清单

| 模块 | 路由前缀 | 关键页面 |
|------|---------|---------|
| **base** | `/` | 登录(Canvas星河动画)、首页、用户管理、角色管理、菜单管理、部门管理 |
| **agent** | `/agent/*` | 智能体对话(WebSocket)、智能体管理、技能管理、模型渠道管理、检测结果 |
| **project** | `/project/*` | 项目列表、项目详情(甘特图/日历/看板/列表四视图) |
| **data** | `/data/*` | 商业健康险创新药、医保药品管理 |
| **dict** | `/dict/*` | 字典管理 |
| **task** | `/task/*` | 定时任务管理 |
| **space** | `/space/*` | 文件空间管理 |
| **user** | `/user/*` | 应用用户管理 |
| **ontology** | `/ontology/*` | 本体论可视化 |
| **demo** | `/demo/*` | 演示页面 |

## Agent 模块详情

### 页面
| 页面 | 路由 | 说明 |
|-----|------|------|
| Agent 对话 | `/agent/chat` | WebSocket 流式对话 + 会话管理 + Skill 进度 + thinking 折叠 |
| Agent 管理 | `/agent/agents` | 卡片网格 + CRUD + 发布/取消 |
| Agent 编辑 | `/agent/agent-edit` | 5个Tab(基本信息/Skill选择/提示词/模型渠道/接口配置) |
| Skill 管理 | `/agent/skills` | 卡片列表 + 启停 + 详情(配置/提示词/模型) |
| 模型渠道管理 | `/agent/model-channel` | 渠道CRUD + 模型配置 + 连通性测试 |

### 核心逻辑
| 文件 | 用途 |
|-----|------|
| `store/chat.ts` | Pinia Store (WebSocket连接 + token统计 + Skill结果) |
| `hooks/chat.ts` | 对话核心Hook (消息管理/thinking/token_update) |
| `hooks/realtime-voice.ts` | 实时语音交互 (Socket.IO + AudioWorklet) |
| `components/model-channel-selector.vue` | 渠道级联选择器组件 |

## Project 模块详情

### 页面
| 页面 | 路由 | 说明 |
|-----|------|------|
| 项目列表 | `/project/list` | 卡片网格 + 筛选 + 新建/编辑弹窗 |
| 项目详情 | `/project/detail` | Tab切换: 甘特图/日历/看板/列表 |

### 组件
| 组件 | 说明 |
|-----|------|
| `gantt.vue` | dhtmlx-gantt 甘特图 + 拖拽更新 |
| `calendar.vue` | FullCalendar 日历视图 |
| `table.vue` | Element Plus 表格列表 |
| `kanban.vue` | vuedraggable 看板拖拽 |
| `task-drawer.vue` | 任务详情抽屉 + 工时记录 |
| `phase-manager.vue` | 阶段管理弹窗 |
| `time-log-dialog.vue` | 工时记录弹窗 |

## 开发规范

- **组件**: Vue 3 Composition API (`<script lang="ts" setup>`)
- **状态管理**: Pinia
- **样式**: Sass + scoped
- **代码风格**: ESLint + Prettier (tab缩进, 单引号)
- **v-model 双向绑定**: 使用 `computed({ get, set })` 模式，避免双 watch 递归
- **el-tab-pane 懒加载**: 使用 `lazy` 属性，不要用 `v-if` 控制 tab 内容显隐
