4da6832b44
- 命名重构:tenant → customer(对齐后端 R1 重构) - Tenant → Customer / tenant_id → customerId - tenantStore → customerStore / getTenant/setTenant → getCustomer/setCustomer - cookie key tenant → customer, HTTP header tenantId → customerId - 后端契约更新:AuthResponse 加 sub 字段 - 接口 URL 修复:/auth/oidc/callback → /api/v1/auth/oidc/callback - 依赖升级:vue 3.5 / element-plus 2.8 / vite 5 / typescript 5.6 / sass 1.79 - 删 node-sass / scss / sass-loader / moment / mock/index.ts - 配置文件拆分:.env.development / .env.production / .env.example - 删除冗余 view/auth/auth/callback.vue 副本 - .gitignore 增加 dist / .opencode / tmp - 新增 AGENT.md 与后端风格对齐
211 lines
7.7 KiB
Markdown
211 lines
7.7 KiB
Markdown
# AGENT.md — violin-home
|
||
|
||
> 面向 AI agent 的工程导览:模块关系、路由约定、与后端的契约、扩展点。
|
||
> 代码即事实,本文件是索引;如代码与本文档冲突,**以代码为准**。
|
||
|
||
---
|
||
|
||
## 项目定位
|
||
|
||
violin-home 是 **violin 微服务套件的统一前端门户**,部署在 `https://www.violin-home.cn/`。
|
||
|
||
- 认证:**Authentik OIDC**,回调路径 `/auth/callback`,前端把 code POST 到 `violin-auth` 服务换 token
|
||
- 后端:依赖 violin-auth(认证)/ violin-bookmark(书签)/ violin-calendar(日历)/ violin-onenote / violin-cloud / 等子服务
|
||
- 域名:生产 `https://www.violin-home.cn/`;本地 dev 走 `.env.development` 的 `VITE_APP_URL`
|
||
|
||
---
|
||
|
||
## 技术栈
|
||
|
||
| 维度 | 选型 |
|
||
|------|------|
|
||
| 框架 | Vue 3.5 + Composition API (`<script setup>`) |
|
||
| 构建 | Vite 5 |
|
||
| 语言 | TypeScript 5.6 |
|
||
| UI | Element Plus 2.8 + Icons |
|
||
| 状态 | Pinia 2.2 |
|
||
| 路由 | vue-router 4.4(**memory history**,不是 hash / web) |
|
||
| HTTP | axios 1.7 |
|
||
| 图表 | ECharts 5 |
|
||
| Markdown | md-editor-v3 4 |
|
||
| 日期 | dayjs(**已废弃 moment**) |
|
||
| Mock | vite-plugin-mock 3(**仅 dev 启用**) |
|
||
| 拖拽 | vuedraggable 4 |
|
||
| 样式 | SCSS(Dart Sass 1.79,**已删除 node-sass**) |
|
||
|
||
---
|
||
|
||
## 目录结构
|
||
|
||
```
|
||
violin-home/
|
||
├── public/ 静态资源(不打包)
|
||
│ ├── blog/*.ts 博客元数据(按业务模块拆分)
|
||
│ └── reset/ Authentik reset 入口(reset.html 等)
|
||
├── src/
|
||
│ ├── api/ axios 接口封装(每个业务一个文件)
|
||
│ ├── components/ 公共组件
|
||
│ │ ├── common/ 通用组件
|
||
│ │ ├── layout/ 顶层布局
|
||
│ │ ├── login/ 登录 / 注册 / sorryPage
|
||
│ │ ├── cloud/ 云盘 + aplayer 音乐
|
||
│ │ ├── illustration/ 插画
|
||
│ │ ├── customPic/ 自定义图片
|
||
│ │ └── operate/ 操作组件
|
||
│ ├── const/ 全局常量
|
||
│ ├── entity/ 实体类型(TypeScript interface)
|
||
│ ├── router/ 路由表(**统一指向 @/view/**)
|
||
│ ├── service/ 服务层(独立于 axios 的工具服务)
|
||
│ ├── store/ Pinia stores
|
||
│ ├── style/ 全局样式(mixin.scss 在 vite.config.ts 里自动注入)
|
||
│ ├── types/ 类型声明(*.d.ts)
|
||
│ ├── utils/ 工具函数(auth 令牌管理、request axios 封装、date、number)
|
||
│ ├── view/ **页面视图(业务页)** — 单数 view
|
||
│ ├── App.vue
|
||
│ ├── env.d.ts
|
||
│ ├── main.ts
|
||
│ └── permission.ts 路由守卫
|
||
├── mock/ vite-plugin-mock 的 mock 数据
|
||
├── authentik-deploy/ Authentik 部署相关(helm values、reset 脚本)
|
||
├── .env.development 本地开发
|
||
├── .env.test 测试环境
|
||
├── .env.production 生产环境
|
||
├── Dockerfile
|
||
├── Jenkinsfile
|
||
├── nginx.conf
|
||
├── vite.config.ts
|
||
└── tsconfig.json
|
||
```
|
||
|
||
---
|
||
|
||
## 路由约定
|
||
|
||
**全部路由指向 `@/view/`**(单数),包括 `/auth/callback`:
|
||
- `router/index.ts` 是**唯一**的路由表
|
||
- 路由 meta.name 是侧边栏展示的中文名
|
||
- `/auth/callback` 由 `view/auth/callback.vue` 处理 OIDC 回调(拿 code → POST `/auth/oidc/callback` 到 violin-auth → 存 token)
|
||
|
||
**禁止**新建 `views/`(复数)目录。
|
||
|
||
---
|
||
|
||
## 认证流程(OIDC)
|
||
|
||
```
|
||
浏览器 → Authentik 登录页(不在本工程)
|
||
↓ 回调到 https://www.violin-home.cn/auth/callback?code=...&state=...
|
||
↓
|
||
view/auth/callback.vue
|
||
↓ POST { code, redirect_uri } → VITE_APP_URL + '/auth/oidc/callback'
|
||
↓
|
||
violin-auth 服务(cn.violin.auth.service.OAuthService.oidcAuthorize)
|
||
↓ 返回 { token, user_id, name }
|
||
↓
|
||
utils/auth.setToken / setTenant 存到 cookie + localStorage
|
||
↓ 跳到 /
|
||
```
|
||
|
||
**关键约定**:
|
||
- `redirect_uri` 必须和 Authentik 应用的配置完全一致(`VITE_OIDC_REDIRECT_URI`)
|
||
- `state` 必须校验(防 CSRF),前后端都用 `sessionStorage.oidc_state` 缓存
|
||
- token 由 `setToken()` 存到 cookie(`js-cookie`),后续 axios 请求拦截器自动加 `Authorization: Bearer <token>`
|
||
|
||
---
|
||
|
||
## HTTP 封装(utils/request.ts)
|
||
|
||
- `baseURL` = `import.meta.env.VITE_APP_URL`
|
||
- 请求拦截器:从 `js-cookie` 读 token,加到 header
|
||
- 响应拦截器:401 → 跳 `/login`;5xx → ElMessage 报错
|
||
|
||
每个业务模块在 `src/api/` 下有自己的文件(如 `api/bookmark.ts`),导出按业务分组的函数:
|
||
```ts
|
||
import { service } from '@/utils/request'
|
||
export const getBookmarks = (params: PageQuery) =>
|
||
service({ url: '/api/v1/bookmark', method: 'get', params })
|
||
```
|
||
|
||
---
|
||
|
||
## 状态管理(Pinia)
|
||
|
||
`src/store/` 下每个业务一个 store(settings、strategy、table、tenant)。**禁止**把所有状态塞进一个 store。
|
||
|
||
- `tenant` store 管当前 customer(对应后端的 customerId)
|
||
- `settings` store 管用户偏好
|
||
- `strategy` store 管 CTA 策略模板
|
||
- `table` store 管通用表格筛选/分页状态
|
||
|
||
---
|
||
|
||
## 与后端子服务的对应
|
||
|
||
| 路径前缀 | 后端服务 | 端口(K8s 内) |
|
||
|---------|---------|--------------|
|
||
| `/auth/**` | violin-auth | 8080 |
|
||
| `/api/v1/bookmark/**` | violin-bookmark | 8081 |
|
||
| `/api/v1/calendar/**` | violin-calendar | 8082 |
|
||
| `/api/v1/onenote/**` | violin-onenote | 8083 |
|
||
| `/api/v1/cloud/**` | violin-cloud | 8084 |
|
||
| `/api/v1/trader/**` | violin-trader | 8085 |
|
||
| `/api/v1/user/**` | violin-auth(user 模块) | 8080 |
|
||
|
||
路由由 K8s ingress 统一反向代理;前端只关心 `VITE_APP_URL` 单一域名。
|
||
|
||
---
|
||
|
||
## 构建与运行
|
||
|
||
```bash
|
||
# 安装依赖(推荐 pnpm,yarn 也行)
|
||
npm install
|
||
|
||
# 本地 dev(启动 mock)
|
||
npm run dev
|
||
|
||
# 生产构建(先类型检查,再打包)
|
||
npm run build
|
||
|
||
# 测试环境构建
|
||
npm run build:test
|
||
|
||
# 预览构建产物
|
||
npm run preview
|
||
```
|
||
|
||
Node:v18+(**不要**用 v14/16,老的 sass-loader/node-sass 不兼容)。
|
||
|
||
---
|
||
|
||
## 已知坑(不要"清理"它们)
|
||
|
||
### 1. `view/` 单数 vs `views/` 复数
|
||
|
||
**永远只创建 `view/` 单数目录**。`views/` 是历史遗物,已删除过又留下空目录。
|
||
|
||
### 2. node-sass 已废弃
|
||
|
||
`package.json` 里**没有** `node-sass`。如果你看到 `npm install` 报 `node-sass` 相关错误,是因为旧依赖被缓存,**不要**手动加回 `node-sass`,用 Dart Sass(`sass: ^1.79`)即可。
|
||
|
||
### 3. axios 0.x → 1.x
|
||
|
||
升级到 axios 1.7 后,`axios.create()` 配置有少量变化(如 `paramsSerializer`)。如果你看到 `interceptor is not a function` 之类的报错,看下拦截器是否还兼容旧签名。
|
||
|
||
### 4. Vue Router 4 用 memory history
|
||
|
||
`createMemoryHistory()` 而非 `createWebHistory()` / `createWebHashHistory()`。刷新页面会丢路由——如果要做刷新保留路由,需要切到 `createWebHistory()` 并配合 K8s ingress 重写。
|
||
|
||
### 5. vite-plugin-mock 仅 dev 启用
|
||
|
||
生产构建不会带 mock(`localEnabled: command === 'serve'`)。如果发现生产缺数据,看下是不是依赖了 mock。
|
||
|
||
---
|
||
|
||
## 相关项目
|
||
|
||
- `violin-auth` — 认证服务(OIDC + JWT 签发)
|
||
- `violin-bookmark` / `violin-calendar` / `violin-onenote` / `violin-cloud` / `violin-trader` — 业务子服务
|
||
- `violin-common` / `violin-core` — 后端共享框架
|
||
- `violin-parent` — 后端父 POM
|