docs: 添加前端开发规范文档和 OpenCode 配置
- 创建 AGENTS.md(前端编码规范、开发流程、Git 提交规范) - 创建 .opencode/workspace/frontend.json(前端工作区配置) - 更新 .gitignore
This commit is contained in:
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"name": "rui-frontend",
|
||||||
|
"description": "睿核科技前端开发会话 - 负责 rui-frontend 目录下的前端代码",
|
||||||
|
"scope": ["admin-ui/**", "cashier-mobile/**", "customer-mobile/**"],
|
||||||
|
"readonly": [],
|
||||||
|
"prompt": "你是 rui 前端开发助手。\n\n## 工作范围\n你只能修改 rui-frontend/ 目录下的前端代码。\n\n## 技术栈\n- Vue 3 + TypeScript\n- Element Plus(admin-ui)\n- Vite\n- pnpm workspace\n\n## 编码规范\n1. 使用 `<script setup lang=\"ts\">`\n2. Props 和 Emit 必须定义类型\n3. API 服务层封装在 service/ 目录\n4. 状态管理使用 Pinia(Setup Store 风格)\n5. 样式使用 UnoCSS + SCSS\n\n## 协作规则\n1. 需要后端接口时,提醒用户创建 Gitee Issue\n2. 不修改后端代码(backend/、app/)\n3. 遵循 AGENTS.md 规范\n\n## 常用命令\n- pnpm dev:admin - 启动管理后台\n- pnpm build:admin - 构建管理后台\n- pnpm install - 安装依赖",
|
||||||
|
"git": {
|
||||||
|
"defaultBranch": "main",
|
||||||
|
"commitMessageFormat": "type(scope): 中文描述"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,541 @@
|
|||||||
|
# rui-frontend AGENTS.md
|
||||||
|
|
||||||
|
> **睿核科技前端项目** — Vue 3 + TypeScript 前端工程
|
||||||
|
> **版本**: v1.0
|
||||||
|
> **更新日期**: 2026-06-04
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 一、项目概览
|
||||||
|
|
||||||
|
### 1.1 项目信息
|
||||||
|
|
||||||
|
| 属性 | 内容 |
|
||||||
|
|------|------|
|
||||||
|
| **项目名称** | rui-frontend |
|
||||||
|
| **项目类型** | Vue 3 前端工程(多项目管理)|
|
||||||
|
| **仓库地址** | https://gitee.com/rui/rui-frontend |
|
||||||
|
| **包管理器** | pnpm |
|
||||||
|
| **构建工具** | Vite |
|
||||||
|
|
||||||
|
### 1.2 仓库结构
|
||||||
|
|
||||||
|
```
|
||||||
|
rui-frontend/
|
||||||
|
├── admin-ui/ # 管理后台系统
|
||||||
|
│ ├── src/
|
||||||
|
│ │ ├── api/ # API 接口
|
||||||
|
│ │ ├── assets/ # 静态资源
|
||||||
|
│ │ ├── components/ # 公共组件
|
||||||
|
│ │ ├── composables/ # 组合式函数
|
||||||
|
│ │ ├── layouts/ # 布局组件
|
||||||
|
│ │ ├── locales/ # 国际化
|
||||||
|
│ │ ├── router/ # 路由配置
|
||||||
|
│ │ ├── service/ # 服务层(API 调用)
|
||||||
|
│ │ ├── stores/ # Pinia 状态管理
|
||||||
|
│ │ ├── styles/ # 全局样式
|
||||||
|
│ │ ├── types/ # 类型定义
|
||||||
|
│ │ ├── utils/ # 工具函数
|
||||||
|
│ │ └── views/ # 页面视图
|
||||||
|
│ ├── package.json
|
||||||
|
│ └── vite.config.ts
|
||||||
|
│
|
||||||
|
├── cashier-mobile/ # 收银系统移动端(待开发)
|
||||||
|
├── customer-mobile/ # 收银系统顾客端(待开发)
|
||||||
|
├── package.json # 根 package.json
|
||||||
|
├── pnpm-workspace.yaml # pnpm 工作区配置
|
||||||
|
└── README.md # 项目说明
|
||||||
|
```
|
||||||
|
|
||||||
|
### 1.3 技术栈
|
||||||
|
|
||||||
|
| 组件 | 版本 | 说明 |
|
||||||
|
|------|------|------|
|
||||||
|
| Vue | 3.5+ | 前端框架 |
|
||||||
|
| TypeScript | 5.4+ | 类型系统 |
|
||||||
|
| Vite | 5.x | 构建工具 |
|
||||||
|
| Element Plus | 2.9+ | UI 组件库(admin-ui)|
|
||||||
|
| Pinia | 2.2+ | 状态管理 |
|
||||||
|
| Vue Router | 4.4+ | 路由管理 |
|
||||||
|
| Axios | 1.7+ | HTTP 客户端 |
|
||||||
|
| pnpm | 8.x | 包管理器 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 二、编码规范
|
||||||
|
|
||||||
|
### 2.1 命名规范
|
||||||
|
|
||||||
|
| 类型 | 规范 | 示例 |
|
||||||
|
|------|------|------|
|
||||||
|
| **组件文件** | PascalCase | `UserForm.vue`, `OrderList.vue` |
|
||||||
|
| **组合式函数** | camelCase, use 前缀 | `useUser.ts`, `usePermission.ts` |
|
||||||
|
| **工具函数** | camelCase | `formatDate.ts`, `deepClone.ts` |
|
||||||
|
| **常量** | UPPER_SNAKE_CASE | `API_BASE_URL`, `DEFAULT_PAGE_SIZE` |
|
||||||
|
| **类型定义** | PascalCase, 后缀 Type | `UserType`, `OrderFormType` |
|
||||||
|
| **接口定义** | PascalCase, 前缀 I | `IUser`, `IOrder` |
|
||||||
|
| **枚举** | PascalCase, 后缀 Enum | `StatusEnum`, `GenderEnum` |
|
||||||
|
|
||||||
|
### 2.2 Vue 组件规范
|
||||||
|
|
||||||
|
#### 文件结构
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<script setup lang="ts">
|
||||||
|
// 1. 类型导入
|
||||||
|
import type { UserType } from '@/types'
|
||||||
|
|
||||||
|
// 2. Vue 核心导入
|
||||||
|
import { ref, computed, onMounted } from 'vue'
|
||||||
|
|
||||||
|
// 3. 第三方库
|
||||||
|
import { ElMessage } from 'element-plus'
|
||||||
|
|
||||||
|
// 4. 本地模块
|
||||||
|
import { useUserStore } from '@/stores/user'
|
||||||
|
import { formatDate } from '@/utils/date'
|
||||||
|
|
||||||
|
// 5. 组合式函数
|
||||||
|
const userStore = useUserStore()
|
||||||
|
|
||||||
|
// 6. 类型定义
|
||||||
|
interface Props {
|
||||||
|
userId: number
|
||||||
|
}
|
||||||
|
|
||||||
|
// 7. Props & Emits
|
||||||
|
const props = defineProps<Props>()
|
||||||
|
const emit = defineEmits<{
|
||||||
|
submit: [data: UserType]
|
||||||
|
}>()
|
||||||
|
|
||||||
|
// 8. 响应式数据
|
||||||
|
const userList = ref<UserType[]>([])
|
||||||
|
const loading = ref(false)
|
||||||
|
|
||||||
|
// 9. 计算属性
|
||||||
|
const userCount = computed(() => userList.value.length)
|
||||||
|
|
||||||
|
// 10. 方法
|
||||||
|
async function fetchUserList() {
|
||||||
|
loading.value = true
|
||||||
|
try {
|
||||||
|
// API 调用
|
||||||
|
} catch (error) {
|
||||||
|
ElMessage.error('获取用户列表失败')
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 11. 生命周期
|
||||||
|
onMounted(() => {
|
||||||
|
fetchUserList()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="user-list">
|
||||||
|
<!-- 模板内容 -->
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.user-list {
|
||||||
|
// 样式
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 组件编写原则
|
||||||
|
|
||||||
|
- **使用 `<script setup>`**:简洁、类型友好
|
||||||
|
- **使用 TypeScript**:所有组件必须 `lang="ts"`
|
||||||
|
- ** Props 必须定义类型**:使用 `defineProps<Props>()`
|
||||||
|
- **Emit 必须定义类型**:使用 `defineEmits<{}>()`
|
||||||
|
- **避免直接使用 any**:必须定义类型
|
||||||
|
|
||||||
|
### 2.3 API 服务层规范
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// service/userService.ts
|
||||||
|
import request from '@/utils/request'
|
||||||
|
import type { UserType, PageResult } from '@/types'
|
||||||
|
|
||||||
|
export const UserService = {
|
||||||
|
// 查询列表
|
||||||
|
getList(params: PageParams) {
|
||||||
|
return request.get<PageResult<UserType>>('/user/admin/list', { params })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 查询详情
|
||||||
|
getById(id: number) {
|
||||||
|
return request.get<UserType>(`/user/admin/${id}`)
|
||||||
|
},
|
||||||
|
|
||||||
|
// 新增
|
||||||
|
create(data: UserFormType) {
|
||||||
|
return request.post('/user/admin', data)
|
||||||
|
},
|
||||||
|
|
||||||
|
// 修改
|
||||||
|
update(id: number, data: UserFormType) {
|
||||||
|
return request.put(`/user/admin/${id}`, data)
|
||||||
|
},
|
||||||
|
|
||||||
|
// 删除
|
||||||
|
delete(id: number) {
|
||||||
|
return request.delete(`/user/admin/${id}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**原则**:
|
||||||
|
- 使用对象封装相关 API
|
||||||
|
- 返回类型必须明确
|
||||||
|
- 统一错误处理在 request 拦截器中
|
||||||
|
|
||||||
|
### 2.4 请求工具封装
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// utils/request.ts
|
||||||
|
import axios from 'axios'
|
||||||
|
import { ElMessage } from 'element-plus'
|
||||||
|
|
||||||
|
const request = axios.create({
|
||||||
|
baseURL: import.meta.env.VITE_API_BASE_URL,
|
||||||
|
timeout: 10000
|
||||||
|
})
|
||||||
|
|
||||||
|
// 请求拦截器
|
||||||
|
request.interceptors.request.use(
|
||||||
|
(config) => {
|
||||||
|
const token = localStorage.getItem('token')
|
||||||
|
if (token) {
|
||||||
|
config.headers.Authorization = `Bearer ${token}`
|
||||||
|
}
|
||||||
|
return config
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// 响应拦截器
|
||||||
|
request.interceptors.response.use(
|
||||||
|
(response) => {
|
||||||
|
const { code, msg, data } = response.data
|
||||||
|
if (code === 200) {
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
ElMessage.error(msg || '请求失败')
|
||||||
|
return Promise.reject(new Error(msg))
|
||||||
|
},
|
||||||
|
(error) => {
|
||||||
|
ElMessage.error(error.message || '网络错误')
|
||||||
|
return Promise.reject(error)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
export default request
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.5 状态管理(Pinia)
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// stores/user.ts
|
||||||
|
import { defineStore } from 'pinia'
|
||||||
|
import { ref, computed } from 'vue'
|
||||||
|
import type { UserType } from '@/types'
|
||||||
|
|
||||||
|
export const useUserStore = defineStore('user', () => {
|
||||||
|
// State
|
||||||
|
const userInfo = ref<UserType | null>(null)
|
||||||
|
const token = ref('')
|
||||||
|
|
||||||
|
// Getters
|
||||||
|
const isLoggedIn = computed(() => !!token.value)
|
||||||
|
|
||||||
|
// Actions
|
||||||
|
function setUserInfo(user: UserType) {
|
||||||
|
userInfo.value = user
|
||||||
|
}
|
||||||
|
|
||||||
|
function logout() {
|
||||||
|
userInfo.value = null
|
||||||
|
token.value = ''
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
userInfo,
|
||||||
|
token,
|
||||||
|
isLoggedIn,
|
||||||
|
setUserInfo,
|
||||||
|
logout
|
||||||
|
}
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
**原则**:
|
||||||
|
- 使用 Setup Store 风格(函数式)
|
||||||
|
- State 使用 `ref()`
|
||||||
|
- Getters 使用 `computed()`
|
||||||
|
- Actions 使用普通函数
|
||||||
|
|
||||||
|
### 2.6 样式规范
|
||||||
|
|
||||||
|
- 使用 **UnoCSS** 原子化 CSS(已配置)
|
||||||
|
- 复杂样式使用 **SCSS**
|
||||||
|
- 组件样式使用 `<style scoped>`
|
||||||
|
- 全局样式放在 `styles/` 目录
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<!-- 推荐:原子化 CSS -->
|
||||||
|
<template>
|
||||||
|
<div class="flex items-center justify-between p-4 bg-white rounded">
|
||||||
|
<span class="text-lg font-bold">标题</span>
|
||||||
|
<el-button type="primary">按钮</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 复杂组件使用 SCSS -->
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.user-form {
|
||||||
|
&__header {
|
||||||
|
@apply flex items-center justify-between;
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 三、目录规范
|
||||||
|
|
||||||
|
### 3.1 新增页面步骤
|
||||||
|
|
||||||
|
1. 在 `views/` 下创建目录和文件
|
||||||
|
2. 在 `router/` 下添加路由配置
|
||||||
|
3. 在 `service/` 下添加 API(如需要)
|
||||||
|
4. 在 `types/` 下添加类型(如需要)
|
||||||
|
|
||||||
|
### 3.2 组件分类
|
||||||
|
|
||||||
|
| 位置 | 用途 | 示例 |
|
||||||
|
|------|------|------|
|
||||||
|
| `components/common/` | 全局通用组件 | `RuiTable.vue`, `IconPicker.vue` |
|
||||||
|
| `views/{module}/` | 页面级组件 | `views/user/Index.vue` |
|
||||||
|
| `views/{module}/components/` | 页面私有组件 | `views/user/components/UserForm.vue` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 四、开发流程
|
||||||
|
|
||||||
|
### 4.1 新增功能流程
|
||||||
|
|
||||||
|
```
|
||||||
|
1. 确认后端接口已就绪(Swagger 文档)
|
||||||
|
2. 创建类型定义(types/)
|
||||||
|
3. 创建 API 服务(service/)
|
||||||
|
4. 创建页面组件(views/)
|
||||||
|
5. 配置路由(router/)
|
||||||
|
6. 联调测试
|
||||||
|
7. 提交代码
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.2 与后端协作
|
||||||
|
|
||||||
|
1. **需要新接口**:
|
||||||
|
- 在 spring-ai 仓库创建 `[API-REQ]` Issue
|
||||||
|
- 等待后端实现并回复 Swagger 地址
|
||||||
|
- 根据 Swagger 开发前端
|
||||||
|
|
||||||
|
2. **接口变更**:
|
||||||
|
- 关注后端 Issue 更新
|
||||||
|
- 及时更新前端 service/
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 五、Git 提交规范
|
||||||
|
|
||||||
|
### 5.1 提交格式
|
||||||
|
|
||||||
|
```
|
||||||
|
type(scope): 中文描述
|
||||||
|
|
||||||
|
示例:
|
||||||
|
feat(user): 添加用户列表页面
|
||||||
|
fix(order): 修复订单金额显示错误
|
||||||
|
docs(readme): 更新项目说明
|
||||||
|
style(css): 优化表格样式
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5.2 Type 类型
|
||||||
|
|
||||||
|
| 类型 | 说明 |
|
||||||
|
|------|------|
|
||||||
|
| `feat` | 新功能 |
|
||||||
|
| `fix` | 修复 Bug |
|
||||||
|
| `docs` | 文档更新 |
|
||||||
|
| `style` | 代码格式(不影响功能)|
|
||||||
|
| `refactor` | 重构 |
|
||||||
|
| `perf` | 性能优化 |
|
||||||
|
| `test` | 测试相关 |
|
||||||
|
| `chore` | 构建/工具链 |
|
||||||
|
|
||||||
|
### 5.3 Scope 范围
|
||||||
|
|
||||||
|
| Scope | 说明 |
|
||||||
|
|-------|------|
|
||||||
|
| `admin-ui` | 管理后台 |
|
||||||
|
| `cashier` | 收银系统 |
|
||||||
|
| `common` | 公共代码 |
|
||||||
|
| `deps` | 依赖更新 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 六、环境配置
|
||||||
|
|
||||||
|
### 6.1 环境变量
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# .env.development
|
||||||
|
VITE_API_BASE_URL=http://localhost:8080
|
||||||
|
VITE_APP_TITLE=睿核管理系统
|
||||||
|
|
||||||
|
# .env.production
|
||||||
|
VITE_API_BASE_URL=https://api.vifo.cc
|
||||||
|
VITE_APP_TITLE=睿核管理系统
|
||||||
|
```
|
||||||
|
|
||||||
|
### 6.2 代理配置
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// vite.config.ts
|
||||||
|
server: {
|
||||||
|
proxy: {
|
||||||
|
'/api': {
|
||||||
|
target: 'http://localhost:8080',
|
||||||
|
changeOrigin: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 七、性能优化
|
||||||
|
|
||||||
|
### 7.1 代码分割
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// 路由懒加载
|
||||||
|
const UserList = () => import('@/views/user/Index.vue')
|
||||||
|
|
||||||
|
// 组件懒加载
|
||||||
|
const Dialog = defineAsyncComponent(() => import('./Dialog.vue'))
|
||||||
|
```
|
||||||
|
|
||||||
|
### 7.2 资源优化
|
||||||
|
|
||||||
|
- 图片使用 WebP 格式
|
||||||
|
- 大组件使用异步加载
|
||||||
|
- 使用 CDN 加载第三方库(生产环境)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 八、测试规范
|
||||||
|
|
||||||
|
### 8.1 单元测试
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 待配置 Vitest
|
||||||
|
```
|
||||||
|
|
||||||
|
### 8.2 E2E 测试
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 待配置 Playwright
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 九、OpenCode 使用规范
|
||||||
|
|
||||||
|
### 9.1 启动方式
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /Users/zhangsheng/rhkj/rui-frontend
|
||||||
|
opencode
|
||||||
|
```
|
||||||
|
|
||||||
|
### 9.2 启动提示词
|
||||||
|
|
||||||
|
```
|
||||||
|
你现在进入【前端开发模式】。
|
||||||
|
|
||||||
|
工作目录:/Users/zhangsheng/rhkj/rui-frontend
|
||||||
|
技术栈:Vue 3、TypeScript、Element Plus、Vite、pnpm
|
||||||
|
规则:
|
||||||
|
1. 只能修改前端项目目录下的代码
|
||||||
|
2. 需要后端接口时,提醒用户创建 Gitee Issue
|
||||||
|
3. 遵循本文档的编码规范
|
||||||
|
4. 使用 pnpm,不要混用 npm/yarn
|
||||||
|
|
||||||
|
当前任务:【描述具体任务】
|
||||||
|
```
|
||||||
|
|
||||||
|
### 9.3 禁止事项
|
||||||
|
|
||||||
|
- ❌ 修改 backend/ 或 app/ 目录下的代码
|
||||||
|
- ❌ 使用 npm/yarn(必须使用 pnpm)
|
||||||
|
- ❌ 提交 node_modules/ 到 Git
|
||||||
|
- ❌ 在代码中写死 API 地址(使用环境变量)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 十、相关文档
|
||||||
|
|
||||||
|
- [项目 README](../README.md)
|
||||||
|
- [后端项目规范](../../spring-ai/AGENTS.md)
|
||||||
|
- [跨团队协作规范](../../spring-ai/docs/cross-team-workflow.md)
|
||||||
|
- [OpenCode 操作指南](../../spring-ai/docs/opencode-workflow.md)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 十一、附录
|
||||||
|
|
||||||
|
### 11.1 常用命令
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 安装依赖
|
||||||
|
pnpm install
|
||||||
|
|
||||||
|
# 启动开发服务器
|
||||||
|
pnpm dev:admin
|
||||||
|
|
||||||
|
# 构建
|
||||||
|
pnpm build:admin
|
||||||
|
|
||||||
|
# 类型检查
|
||||||
|
pnpm type-check
|
||||||
|
|
||||||
|
# 代码检查
|
||||||
|
pnpm lint
|
||||||
|
|
||||||
|
# 安装子项目依赖
|
||||||
|
cd admin-ui && pnpm install
|
||||||
|
```
|
||||||
|
|
||||||
|
### 11.2 错误码对照
|
||||||
|
|
||||||
|
| 错误码 | 说明 |
|
||||||
|
|--------|------|
|
||||||
|
| 200 | 成功 |
|
||||||
|
| 400 | 请求参数错误 |
|
||||||
|
| 401 | 未授权 |
|
||||||
|
| 403 | 无权限 |
|
||||||
|
| 404 | 资源不存在 |
|
||||||
|
| 500 | 服务器内部错误 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
> **提示**:本文档是活文档,根据项目发展持续更新。如有建议请提交 PR。
|
||||||
Reference in New Issue
Block a user