Compare commits
10 Commits
b11fe9916f
...
6b83b7cbc9
| Author | SHA1 | Date | |
|---|---|---|---|
| 6b83b7cbc9 | |||
| 106e1c14fe | |||
| a7e056643e | |||
| a8d6fafb71 | |||
| 509812e9b0 | |||
| 7e59bfa2f6 | |||
| fbb8381f8f | |||
| 805804177a | |||
| 5ad113bb85 | |||
| 6c4cccc0fc |
+1
@@ -1,5 +1,6 @@
|
|||||||
<component name="InspectionProjectProfileManager">
|
<component name="InspectionProjectProfileManager">
|
||||||
<profile version="1.0">
|
<profile version="1.0">
|
||||||
<option name="myName" value="Project Default" />
|
<option name="myName" value="Project Default" />
|
||||||
|
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
|
||||||
</profile>
|
</profile>
|
||||||
</component>
|
</component>
|
||||||
Generated
+3
@@ -1,5 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
|
<component name="ProjectRootManager" version="2" project-jdk-name="openjdk-26" project-jdk-type="JavaSDK">
|
||||||
|
<output url="file://$PROJECT_DIR$/out" />
|
||||||
|
</component>
|
||||||
<component name="SshConsoleOptionsProvider">
|
<component name="SshConsoleOptionsProvider">
|
||||||
<option name="myEncoding" value="UTF-8" />
|
<option name="myEncoding" value="UTF-8" />
|
||||||
<option name="myConnectionType" value="NONE" />
|
<option name="myConnectionType" value="NONE" />
|
||||||
|
|||||||
Generated
+8
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ProjectModuleManager">
|
||||||
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/.idea/rui-frontend.iml" filepath="$PROJECT_DIR$/.idea/rui-frontend.iml" />
|
||||||
|
</modules>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
Generated
+9
@@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="JAVA_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||||
|
<exclude-output />
|
||||||
|
<content url="file://$MODULE_DIR$" />
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
||||||
Generated
+6
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="" vcs="Git" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
@@ -1,541 +1,99 @@
|
|||||||
# rui-frontend AGENTS.md
|
# AI 开发边界配置 - 前端仓库
|
||||||
|
|
||||||
> **睿核科技前端项目** — Vue 3 + TypeScript 前端工程
|
> **警告**:本文件定义 AI 的开发边界,AI 必须严格遵守!
|
||||||
> **版本**: v1.0
|
|
||||||
> **更新日期**: 2026-06-04
|
|
||||||
|
|
||||||
---
|
## 🎯 本仓库职责
|
||||||
|
|
||||||
## 一、项目概览
|
**rui-frontend** 是睿核科技的前端工程集合,包含:
|
||||||
|
- `admin-ui` - 管理后台(Vue3 + TypeScript + Vite)
|
||||||
|
- `cashier-mobile` - 收银移动端(技术栈待定,可能是 uni-app、React Native 等)
|
||||||
|
- `cashier-customer` - 顾客移动端(技术栈待定,可能是 uni-app、React Native 等)
|
||||||
|
|
||||||
### 1.1 项目信息
|
## 🚫 绝对禁止
|
||||||
|
|
||||||
| 属性 | 内容 |
|
1. **禁止修改后端代码** - 本仓库只有前端代码
|
||||||
|------|------|
|
2. **禁止修改 API 接口定义** - 接口定义在后端仓库
|
||||||
| **项目名称** | rui-frontend |
|
3. **禁止直接访问数据库** - 必须通过 REST API
|
||||||
| **项目类型** | Vue 3 前端工程(多项目管理)|
|
4. **禁止引入后端依赖** - 如 Spring, MyBatis 等
|
||||||
| **仓库地址** | https://gitee.com/rui/rui-frontend |
|
|
||||||
| **包管理器** | pnpm |
|
|
||||||
| **构建工具** | Vite |
|
|
||||||
|
|
||||||
### 1.2 仓库结构
|
## ✅ 允许范围
|
||||||
|
|
||||||
```
|
```
|
||||||
rui-frontend/
|
rui-frontend/
|
||||||
├── admin-ui/ # 管理后台系统
|
├── admin-ui/ ✅ 可修改(Vue3 管理后台)
|
||||||
│ ├── src/
|
├── cashier-mobile/ ✅ 可修改(收银移动端)
|
||||||
│ │ ├── api/ # API 接口
|
├── cashier-customer/ ✅ 可修改(顾客移动端)
|
||||||
│ │ ├── assets/ # 静态资源
|
├── package.json ✅ 可修改(根配置)
|
||||||
│ │ ├── components/ # 公共组件
|
└── pnpm-workspace.yaml ✅ 可修改
|
||||||
│ │ ├── 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 技术栈
|
## 🔗 与后端通信规范
|
||||||
|
|
||||||
| 组件 | 版本 | 说明 |
|
### 1. API 调用方式
|
||||||
|------|------|------|
|
- 使用 **Axios**、**Fetch** 或各框架提供的 HTTP 客户端发送请求
|
||||||
| Vue | 3.5+ | 前端框架 |
|
- 禁止直接引用后端 Java 类
|
||||||
| 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. 接口地址规范
|
||||||
|
```typescript
|
||||||
|
// 正确示例(axios)
|
||||||
|
const API_BASE = '/api'; // 通过网关转发
|
||||||
|
const userApi = {
|
||||||
|
getList: () => axios.get(`${API_BASE}/user/list`),
|
||||||
|
create: (data) => axios.post(`${API_BASE}/user`, data)
|
||||||
|
};
|
||||||
|
|
||||||
## 二、编码规范
|
// 正确示例(uni-app)
|
||||||
|
const userApi = {
|
||||||
### 2.1 命名规范
|
getList: () => uni.request({ url: `${API_BASE}/user/list` }),
|
||||||
|
create: (data) => uni.request({ url: `${API_BASE}/user`, method: 'POST', data })
|
||||||
| 类型 | 规范 | 示例 |
|
};
|
||||||
|------|------|------|
|
|
||||||
| **组件文件** | 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>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 组件编写原则
|
### 3. 数据类型定义
|
||||||
|
- 前端自行定义 TypeScript 接口或各框架的类型定义
|
||||||
- **使用 `<script setup>`**:简洁、类型友好
|
- 与后端 DTO 保持一致(但不直接引用)
|
||||||
- **使用 TypeScript**:所有组件必须 `lang="ts"`
|
|
||||||
- ** Props 必须定义类型**:使用 `defineProps<Props>()`
|
|
||||||
- **Emit 必须定义类型**:使用 `defineEmits<{}>()`
|
|
||||||
- **避免直接使用 any**:必须定义类型
|
|
||||||
|
|
||||||
### 2.3 API 服务层规范
|
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
// service/userService.ts
|
// 前端自定义类型
|
||||||
import request from '@/utils/request'
|
interface UserDTO {
|
||||||
import type { UserType, PageResult } from '@/types'
|
id: number;
|
||||||
|
username: string;
|
||||||
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 请求工具封装
|
### admin-ui(管理后台)
|
||||||
|
- **框架**:Vue 3 + TypeScript + Vite
|
||||||
|
- **包管理器**:pnpm(强制使用)
|
||||||
|
- **组件规范**:组合式 API(setup 语法)
|
||||||
|
|
||||||
```typescript
|
### cashier-mobile / cashier-customer(移动端)
|
||||||
// utils/request.ts
|
- **框架**:uni-app(Vue3)
|
||||||
import axios from 'axios'
|
- **支持平台**:小程序、H5、App
|
||||||
import { ElMessage } from 'element-plus'
|
- **包管理器**:pnpm(推荐)或 npm
|
||||||
|
- **UI 框架**:uni-ui 或 uview-plus
|
||||||
|
|
||||||
const request = axios.create({
|
### 通用规范
|
||||||
baseURL: import.meta.env.VITE_API_BASE_URL,
|
1. **代码风格**:遵循项目现有 ESLint/Prettier 配置
|
||||||
timeout: 10000
|
2. **HTTP 客户端**:统一封装请求拦截器(处理 Token、错误等)
|
||||||
})
|
3. **路由管理**:各项目自行管理前端路由
|
||||||
|
4. **状态管理**:根据框架选择(Pinia、Vuex、Redux、Zustand 等)
|
||||||
|
|
||||||
// 请求拦截器
|
## 🔔 当需要后端支持时
|
||||||
request.interceptors.request.use(
|
|
||||||
(config) => {
|
|
||||||
const token = localStorage.getItem('token')
|
|
||||||
if (token) {
|
|
||||||
config.headers.Authorization = `Bearer ${token}`
|
|
||||||
}
|
|
||||||
return config
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
// 响应拦截器
|
如果前端需要新的 API 接口:
|
||||||
request.interceptors.response.use(
|
1. **不要自己创建后端代码**
|
||||||
(response) => {
|
2. 在后端仓库的 Issue 中提需求
|
||||||
const { code, msg, data } = response.data
|
3. 等待后端提供接口后再联调
|
||||||
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)
|
- **前端 AI**:只负责 rui-frontend 仓库
|
||||||
|
- **后端 AI**:负责 spring-ai 仓库提供 API
|
||||||
```typescript
|
- **沟通方式**:通过 Gitea Issue / 钉钉通知
|
||||||
// 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>
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 三、目录规范
|
> **最后提醒**:AI 必须严格限制在本仓库范围内开发,禁止跨仓库修改代码!
|
||||||
|
|
||||||
### 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。
|
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
调试测试 07:34:22
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
最终测试 2026-06-04 07:30:33
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
Markdown测试 07:28:00
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
最终验证 2026-06-04 07:43:19
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
<script setup>
|
||||||
|
import { onLaunch, onShow, onHide } from '@dcloudio/uni-app'
|
||||||
|
|
||||||
|
onLaunch(() => {
|
||||||
|
console.log('顾客端启动')
|
||||||
|
})
|
||||||
|
|
||||||
|
onShow(() => {
|
||||||
|
console.log('顾客端显示')
|
||||||
|
})
|
||||||
|
|
||||||
|
onHide(() => {
|
||||||
|
console.log('顾客端隐藏')
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* 全局样式 */
|
||||||
|
page {
|
||||||
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
import { createSSRApp } from 'vue'
|
||||||
|
import App from './App.vue'
|
||||||
|
|
||||||
|
export function createApp() {
|
||||||
|
const app = createSSRApp(App)
|
||||||
|
return {
|
||||||
|
app
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
{
|
||||||
|
"name": "收银顾客端",
|
||||||
|
"appid": "__UNI__CUSTOMER001",
|
||||||
|
"description": "睿核科技顾客端移动端",
|
||||||
|
"versionName": "1.0.0",
|
||||||
|
"versionCode": "100",
|
||||||
|
"transformPx": false,
|
||||||
|
"app-plus": {
|
||||||
|
"usingComponents": true,
|
||||||
|
"splashscreen": {
|
||||||
|
"alwaysShowBeforeRender": true,
|
||||||
|
"waiting": true,
|
||||||
|
"autoclose": true,
|
||||||
|
"delay": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"mp-weixin": {
|
||||||
|
"appid": "",
|
||||||
|
"setting": {
|
||||||
|
"urlCheck": false
|
||||||
|
},
|
||||||
|
"usingComponents": true
|
||||||
|
},
|
||||||
|
"h5": {
|
||||||
|
"title": "顾客端",
|
||||||
|
"router": {
|
||||||
|
"mode": "hash"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"name": "cashier-customer",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "顾客端移动端 - uni-app",
|
||||||
|
"main": "main.js",
|
||||||
|
"scripts": {
|
||||||
|
"dev:h5": "uni",
|
||||||
|
"dev:mp-weixin": "uni --platform mp-weixin",
|
||||||
|
"dev:app": "uni --platform app",
|
||||||
|
"build:h5": "uni build",
|
||||||
|
"build:mp-weixin": "uni build --platform mp-weixin",
|
||||||
|
"build:app": "uni build --platform app"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@dcloudio/uni-app": "3.0.0",
|
||||||
|
"vue": "^3.3.0",
|
||||||
|
"vuex": "^4.1.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@dcloudio/types": "^3.3.0",
|
||||||
|
"@dcloudio/uni-cli-shared": "3.0.0",
|
||||||
|
"@dcloudio/vite-plugin-uni": "3.0.0",
|
||||||
|
"vite": "^4.4.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
{
|
||||||
|
"pages": [
|
||||||
|
{
|
||||||
|
"path": "pages/index/index",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "首页"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/order/order",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "我的订单"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/member/member",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "会员中心"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"globalStyle": {
|
||||||
|
"navigationBarTextStyle": "black",
|
||||||
|
"navigationBarTitleText": "顾客端",
|
||||||
|
"navigationBarBackgroundColor": "#F8F8F8",
|
||||||
|
"backgroundColor": "#F8F8F8"
|
||||||
|
},
|
||||||
|
"tabBar": {
|
||||||
|
"list": [
|
||||||
|
{
|
||||||
|
"pagePath": "pages/index/index",
|
||||||
|
"text": "首页"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pagePath": "pages/order/order",
|
||||||
|
"text": "订单"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pagePath": "pages/member/member",
|
||||||
|
"text": "我的"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
<template>
|
||||||
|
<view class="container">
|
||||||
|
<view class="header">
|
||||||
|
<text class="title">欢迎光临</text>
|
||||||
|
</view>
|
||||||
|
<view class="content">
|
||||||
|
<view class="menu-list">
|
||||||
|
<view v-for="item in menuList" :key="item.id" class="menu-item" @click="goToDetail(item)">
|
||||||
|
<image :src="item.image" class="menu-image" mode="aspectFill" />
|
||||||
|
<text class="menu-name">{{ item.name }}</text>
|
||||||
|
<text class="menu-price">¥{{ item.price }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
const menuList = ref([
|
||||||
|
{ id: 1, name: '招牌奶茶', price: '18.00', image: '/static/logo.png' },
|
||||||
|
{ id: 2, name: '美式咖啡', price: '22.00', image: '/static/logo.png' },
|
||||||
|
{ id: 3, name: '芝士蛋糕', price: '28.00', image: '/static/logo.png' }
|
||||||
|
])
|
||||||
|
|
||||||
|
const goToDetail = (item) => {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: `/pages/order/order?id=${item.id}`
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.container {
|
||||||
|
padding: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: 36rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-list {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-item {
|
||||||
|
width: calc(50% - 10rpx);
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 12rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
box-shadow: 0 2rpx 10rpx rgba(0,0,0,0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-image {
|
||||||
|
width: 100%;
|
||||||
|
height: 200rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-name {
|
||||||
|
display: block;
|
||||||
|
padding: 10rpx;
|
||||||
|
font-size: 28rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-price {
|
||||||
|
display: block;
|
||||||
|
padding: 0 10rpx 10rpx;
|
||||||
|
color: #ff0000;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
<template>
|
||||||
|
<view class="container">
|
||||||
|
<view class="header">
|
||||||
|
<text class="title">会员中心</text>
|
||||||
|
</view>
|
||||||
|
<view class="member-info">
|
||||||
|
<view class="avatar-section">
|
||||||
|
<image src="/static/logo.png" class="avatar" />
|
||||||
|
<text class="nickname">张三</text>
|
||||||
|
<text class="level">黄金会员</text>
|
||||||
|
</view>
|
||||||
|
<view class="stats">
|
||||||
|
<view class="stat-item">
|
||||||
|
<text class="stat-value">100</text>
|
||||||
|
<text class="stat-label">积分</text>
|
||||||
|
</view>
|
||||||
|
<view class="stat-item">
|
||||||
|
<text class="stat-value">5</text>
|
||||||
|
<text class="stat-label">优惠券</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
// 会员中心逻辑
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.container {
|
||||||
|
padding: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.member-info {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar-section {
|
||||||
|
margin-bottom: 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar {
|
||||||
|
width: 120rpx;
|
||||||
|
height: 120rpx;
|
||||||
|
border-radius: 60rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nickname {
|
||||||
|
display: block;
|
||||||
|
font-size: 32rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-bottom: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.level {
|
||||||
|
display: block;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stats {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
margin-top: 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-item {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-value {
|
||||||
|
display: block;
|
||||||
|
font-size: 36rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #007AFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-label {
|
||||||
|
display: block;
|
||||||
|
color: #999;
|
||||||
|
margin-top: 10rpx;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
<template>
|
||||||
|
<view class="container">
|
||||||
|
<view class="header">
|
||||||
|
<text class="title">我的订单</text>
|
||||||
|
</view>
|
||||||
|
<view class="order-list">
|
||||||
|
<view v-for="order in orders" :key="order.id" class="order-item">
|
||||||
|
<text class="order-no">{{ order.orderNo }}</text>
|
||||||
|
<text class="order-amount">¥{{ order.amount }}</text>
|
||||||
|
<text class="order-status">{{ order.status }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
const orders = ref([
|
||||||
|
{ id: 1, orderNo: 'O202401010001', amount: '199.99', status: '已完成' },
|
||||||
|
{ id: 2, orderNo: 'O202401010002', amount: '99.99', status: '待支付' }
|
||||||
|
])
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.container {
|
||||||
|
padding: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-list {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-item {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 20rpx;
|
||||||
|
border-bottom: 1rpx solid #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-amount {
|
||||||
|
color: #ff0000;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
<script setup>
|
||||||
|
import { onLaunch, onShow, onHide } from '@dcloudio/uni-app'
|
||||||
|
|
||||||
|
onLaunch(() => {
|
||||||
|
console.log('收银移动端启动')
|
||||||
|
})
|
||||||
|
|
||||||
|
onShow(() => {
|
||||||
|
console.log('收银移动端显示')
|
||||||
|
})
|
||||||
|
|
||||||
|
onHide(() => {
|
||||||
|
console.log('收银移动端隐藏')
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* 全局样式 */
|
||||||
|
page {
|
||||||
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
import { createSSRApp } from 'vue'
|
||||||
|
import App from './App.vue'
|
||||||
|
|
||||||
|
export function createApp() {
|
||||||
|
const app = createSSRApp(App)
|
||||||
|
return {
|
||||||
|
app
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
{
|
||||||
|
"name": "收银系统",
|
||||||
|
"appid": "__UNI__CASHIER001",
|
||||||
|
"description": "睿核科技收银系统移动端",
|
||||||
|
"versionName": "1.0.0",
|
||||||
|
"versionCode": "100",
|
||||||
|
"transformPx": false,
|
||||||
|
"app-plus": {
|
||||||
|
"usingComponents": true,
|
||||||
|
"splashscreen": {
|
||||||
|
"alwaysShowBeforeRender": true,
|
||||||
|
"waiting": true,
|
||||||
|
"autoclose": true,
|
||||||
|
"delay": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"mp-weixin": {
|
||||||
|
"appid": "",
|
||||||
|
"setting": {
|
||||||
|
"urlCheck": false
|
||||||
|
},
|
||||||
|
"usingComponents": true
|
||||||
|
},
|
||||||
|
"h5": {
|
||||||
|
"title": "收银系统",
|
||||||
|
"router": {
|
||||||
|
"mode": "hash"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+20
-10
@@ -1,15 +1,25 @@
|
|||||||
{
|
{
|
||||||
"name": "cashier-mobile",
|
"name": "cashier-mobile",
|
||||||
"version": "0.1.0",
|
"version": "1.0.0",
|
||||||
"description": "收银系统移动端",
|
"description": "收银系统移动端 - uni-app",
|
||||||
"private": true,
|
"main": "main.js",
|
||||||
"type": "module",
|
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "echo '待配置开发命令'",
|
"dev:h5": "uni",
|
||||||
"build": "echo '待配置构建命令'",
|
"dev:mp-weixin": "uni --platform mp-weixin",
|
||||||
"lint": "echo '待配置'",
|
"dev:app": "uni --platform app",
|
||||||
"type-check": "echo '待配置'"
|
"build:h5": "uni build",
|
||||||
|
"build:mp-weixin": "uni build --platform mp-weixin",
|
||||||
|
"build:app": "uni build --platform app"
|
||||||
},
|
},
|
||||||
"dependencies": {},
|
"dependencies": {
|
||||||
"devDependencies": {}
|
"@dcloudio/uni-app": "3.0.0",
|
||||||
|
"vue": "^3.3.0",
|
||||||
|
"vuex": "^4.1.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@dcloudio/types": "^3.3.0",
|
||||||
|
"@dcloudio/uni-cli-shared": "3.0.0",
|
||||||
|
"@dcloudio/vite-plugin-uni": "3.0.0",
|
||||||
|
"vite": "^4.4.0"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
{
|
||||||
|
"pages": [
|
||||||
|
{
|
||||||
|
"path": "pages/index/index",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "收银台"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/order/order",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "订单管理"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/member/member",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "会员管理"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"globalStyle": {
|
||||||
|
"navigationBarTextStyle": "black",
|
||||||
|
"navigationBarTitleText": "收银系统",
|
||||||
|
"navigationBarBackgroundColor": "#F8F8F8",
|
||||||
|
"backgroundColor": "#F8F8F8"
|
||||||
|
},
|
||||||
|
"tabBar": {
|
||||||
|
"list": [
|
||||||
|
{
|
||||||
|
"pagePath": "pages/index/index",
|
||||||
|
"text": "收银"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pagePath": "pages/order/order",
|
||||||
|
"text": "订单"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pagePath": "pages/member/member",
|
||||||
|
"text": "会员"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
<template>
|
||||||
|
<view class="container">
|
||||||
|
<view class="header">
|
||||||
|
<text class="title">收银台</text>
|
||||||
|
</view>
|
||||||
|
<view class="content">
|
||||||
|
<view class="input-area">
|
||||||
|
<input
|
||||||
|
v-model="amount"
|
||||||
|
type="digit"
|
||||||
|
placeholder="请输入金额"
|
||||||
|
class="amount-input"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
<button @click="createOrder" class="submit-btn">创建订单</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
const amount = ref('')
|
||||||
|
|
||||||
|
const createOrder = () => {
|
||||||
|
if (!amount.value) {
|
||||||
|
uni.showToast({ title: '请输入金额', icon: 'none' })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: 调用创建订单 API
|
||||||
|
uni.showLoading({ title: '创建中...' })
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
uni.hideLoading()
|
||||||
|
uni.showToast({ title: '创建成功', icon: 'success' })
|
||||||
|
amount.value = ''
|
||||||
|
}, 1000)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.container {
|
||||||
|
padding: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: 36rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-area {
|
||||||
|
margin-bottom: 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.amount-input {
|
||||||
|
height: 80rpx;
|
||||||
|
border: 2rpx solid #ddd;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
padding: 0 20rpx;
|
||||||
|
font-size: 32rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.submit-btn {
|
||||||
|
background-color: #007AFF;
|
||||||
|
color: white;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
<template>
|
||||||
|
<view class="container">
|
||||||
|
<view class="header">
|
||||||
|
<text class="title">会员管理</text>
|
||||||
|
</view>
|
||||||
|
<view class="member-list">
|
||||||
|
<view v-for="member in members" :key="member.id" class="member-item">
|
||||||
|
<text class="member-name">{{ member.name }}</text>
|
||||||
|
<text class="member-phone">{{ member.phone }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
const members = ref([
|
||||||
|
{ id: 1, name: '张三', phone: '138****8888' },
|
||||||
|
{ id: 2, name: '李四', phone: '139****9999' }
|
||||||
|
])
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.container {
|
||||||
|
padding: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.member-list {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.member-item {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 20rpx;
|
||||||
|
border-bottom: 1rpx solid #eee;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
<template>
|
||||||
|
<view class="container">
|
||||||
|
<view class="header">
|
||||||
|
<text class="title">订单列表</text>
|
||||||
|
</view>
|
||||||
|
<view class="order-list">
|
||||||
|
<view v-for="order in orders" :key="order.id" class="order-item">
|
||||||
|
<text class="order-no">{{ order.orderNo }}</text>
|
||||||
|
<text class="order-amount">¥{{ order.amount }}</text>
|
||||||
|
<text class="order-status">{{ order.status }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
const orders = ref([
|
||||||
|
{ id: 1, orderNo: 'O202401010001', amount: '199.99', status: '已完成' },
|
||||||
|
{ id: 2, orderNo: 'O202401010002', amount: '99.99', status: '待支付' }
|
||||||
|
])
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.container {
|
||||||
|
padding: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-list {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-item {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 20rpx;
|
||||||
|
border-bottom: 1rpx solid #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-amount {
|
||||||
|
color: #ff0000;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "customer-mobile",
|
|
||||||
"version": "0.1.0",
|
|
||||||
"description": "收银系统顾客端",
|
|
||||||
"private": true,
|
|
||||||
"type": "module",
|
|
||||||
"scripts": {
|
|
||||||
"dev": "echo '待配置开发命令'",
|
|
||||||
"build": "echo '待配置构建命令'",
|
|
||||||
"lint": "echo '待配置'",
|
|
||||||
"type-check": "echo '待配置'"
|
|
||||||
},
|
|
||||||
"dependencies": {},
|
|
||||||
"devDependencies": {}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
# rui-frontend 文档中心
|
||||||
|
|
||||||
|
> 本目录包含前端项目相关的设计文档、实施计划和开发规范。
|
||||||
|
> 文档来源:`spring-ai/docs`(后端仓库),定期同步更新。
|
||||||
|
|
||||||
|
## 📁 目录结构
|
||||||
|
|
||||||
|
```
|
||||||
|
docs/
|
||||||
|
├── design/ # 设计文档
|
||||||
|
│ ├── rui-admin功能设计文档.md
|
||||||
|
│ ├── cashier-design.md
|
||||||
|
│ └── admin-ui-module-build-design.md
|
||||||
|
├── plans/ # 实施计划
|
||||||
|
│ └── cashier-admin-implementation.md
|
||||||
|
├── standards/ # 开发规范
|
||||||
|
│ ├── 前端开发规则.md
|
||||||
|
│ └── API设计规范.md
|
||||||
|
└── README.md # 本文档
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📋 文档说明
|
||||||
|
|
||||||
|
### 设计文档(design/)
|
||||||
|
|
||||||
|
| 文档 | 说明 | 来源 |
|
||||||
|
|------|------|------|
|
||||||
|
| `rui-admin功能设计文档.md` | rui-admin 管理后台功能模块设计 | spring-ai/docs |
|
||||||
|
| `cashier-design.md` | 收银系统(POS)整体架构设计 | spring-ai/docs/superpowers/specs |
|
||||||
|
| `admin-ui-module-build-design.md` | Admin-UI 分模块打包功能设计 | spring-ai/docs/superpowers/specs |
|
||||||
|
|
||||||
|
### 实施计划(plans/)
|
||||||
|
|
||||||
|
| 文档 | 说明 | 来源 |
|
||||||
|
|------|------|------|
|
||||||
|
| `cashier-admin-implementation.md` | 收银系统后台管理功能完善实施计划 | spring-ai/docs/superpowers/plans |
|
||||||
|
|
||||||
|
### 开发规范(standards/)
|
||||||
|
|
||||||
|
| 文档 | 说明 | 来源 |
|
||||||
|
|------|------|------|
|
||||||
|
| `前端开发规则.md` | 前端编码规范、目录结构、命名约定 | spring-ai/docs |
|
||||||
|
| `API设计规范.md` | RESTful API 设计规范 | spring-ai/docs |
|
||||||
|
|
||||||
|
## 🔄 同步说明
|
||||||
|
|
||||||
|
当后端仓库 `spring-ai/docs` 中的文档更新时,前端仓库应同步更新副本:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 示例:同步收银系统设计文档
|
||||||
|
cp ~/rhkj/spring-ai/docs/superpowers/specs/2026-06-03-cashier-design.md \
|
||||||
|
~/rhkj/rui-frontend/docs/design/cashier-design.md
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📝 新增文档
|
||||||
|
|
||||||
|
如需新增前端专属文档,直接在此目录下创建,无需同步到后端仓库。
|
||||||
@@ -0,0 +1,371 @@
|
|||||||
|
# Admin-UI 分模块打包功能设计文档
|
||||||
|
|
||||||
|
> **设计日期**: 2026-06-04
|
||||||
|
> **版本**: v1.0
|
||||||
|
> **状态**: 已批准
|
||||||
|
> **目标**: 实现 Admin-UI 按系统配置分模块打包,支持不同租户类型输出不同产物包
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 一、背景与目标
|
||||||
|
|
||||||
|
### 1.1 现状分析
|
||||||
|
|
||||||
|
当前 Admin-UI 存在以下问题:
|
||||||
|
|
||||||
|
1. **路由硬编码**:所有页面路由集中在 `router/index.ts` 中硬编码,无法按模块裁剪
|
||||||
|
2. **构建产物单一**:无论服务哪个租户,都打包所有页面代码,产物体积大
|
||||||
|
3. **缺乏系统差异化**:Dashboard、登录页等核心页面无法根据不同系统定制
|
||||||
|
4. **模块管理已有雏形**:后端已支持租户模块配置(`ModuleDialog.vue`),但前端构建未与之配合
|
||||||
|
|
||||||
|
### 1.2 目标定义
|
||||||
|
|
||||||
|
1. **构建时分包**:根据 JSON 配置文件,构建时只打包指定模块的代码
|
||||||
|
2. **动态路由生成**:替换硬编码路由,构建时根据配置动态生成路由表
|
||||||
|
3. **系统差异化页面**:支持 Dashboard、登录页按系统配置加载不同子组件
|
||||||
|
4. **多产物输出**:不同系统输出到 `dist/{systemKey}/` 目录
|
||||||
|
5. **保持现有功能**:菜单 API 获取、权限控制、主题切换等功能不受影响
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 二、详细设计
|
||||||
|
|
||||||
|
### 2.1 整体架构
|
||||||
|
|
||||||
|
```
|
||||||
|
构建流程:
|
||||||
|
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
|
||||||
|
│ build-config/ │ │ Vite Plugin │ │ 构建产物 │
|
||||||
|
│ cashier.json │────→│ (module-build) │────→│ dist/cashier/ │
|
||||||
|
│ admin.json │ │ │ │ dist/admin/ │
|
||||||
|
│ super.json │ │ 1. 读取配置 │ │ dist/super/ │
|
||||||
|
└─────────────────┘ │ 2. 生成路由 │ │ │
|
||||||
|
│ 3. 注入配置 │ └─────────────────┘
|
||||||
|
│ 4. 配置输出 │
|
||||||
|
└──────────────────┘
|
||||||
|
|
||||||
|
运行时:
|
||||||
|
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
|
||||||
|
│ 统一入口页面 │────→│ 虚拟模块配置 │────→│ 系统特定子组件 │
|
||||||
|
│ Dashboard │ │ __SYSTEM_CONFIG__│ │ systems/ │
|
||||||
|
│ Login │ │ │ │ Cashier.vue │
|
||||||
|
└─────────────────┘ └──────────────────┘ │ Super.vue │
|
||||||
|
└─────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.2 核心组件
|
||||||
|
|
||||||
|
#### 2.2.1 配置文件(`build-config/`)
|
||||||
|
|
||||||
|
每个系统一个 JSON 配置文件:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
interface BuildConfig {
|
||||||
|
/** 系统唯一标识,产物目录名 */
|
||||||
|
key: string
|
||||||
|
/** 系统显示名称 */
|
||||||
|
name: string
|
||||||
|
/** 系统描述 */
|
||||||
|
description?: string
|
||||||
|
/** 包含的模块列表 */
|
||||||
|
modules: string[]
|
||||||
|
/** 登录页配置 */
|
||||||
|
login: {
|
||||||
|
/** 登录组件名(对应 views/login/systems/ 下的组件) */
|
||||||
|
component: string
|
||||||
|
/** 是否显示租户ID输入 */
|
||||||
|
showTenantInput: boolean
|
||||||
|
/** 页面标题 */
|
||||||
|
title: string
|
||||||
|
/** 副标题 */
|
||||||
|
subtitle?: string
|
||||||
|
/** 背景图路径 */
|
||||||
|
background?: string
|
||||||
|
/** Logo路径 */
|
||||||
|
logo?: string
|
||||||
|
}
|
||||||
|
/** Dashboard配置 */
|
||||||
|
dashboard: {
|
||||||
|
/** Dashboard组件名(对应 views/dashboard/systems/ 下的组件) */
|
||||||
|
component: string
|
||||||
|
/** 页面标题 */
|
||||||
|
title: string
|
||||||
|
}
|
||||||
|
/** 主题配置 */
|
||||||
|
theme: {
|
||||||
|
/** 主题色 */
|
||||||
|
primaryColor: string
|
||||||
|
/** 页面标题 */
|
||||||
|
title: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**示例配置:**
|
||||||
|
|
||||||
|
```json
|
||||||
|
// build-config/super.json
|
||||||
|
{
|
||||||
|
"key": "super",
|
||||||
|
"name": "超级管理后台",
|
||||||
|
"description": "超级租户专用,包含租户管理",
|
||||||
|
"modules": ["system", "user"],
|
||||||
|
"login": {
|
||||||
|
"component": "Super",
|
||||||
|
"showTenantInput": false,
|
||||||
|
"title": "睿核平台管理",
|
||||||
|
"subtitle": "超级管理员登录"
|
||||||
|
},
|
||||||
|
"dashboard": {
|
||||||
|
"component": "Super",
|
||||||
|
"title": "平台运营概览"
|
||||||
|
},
|
||||||
|
"theme": {
|
||||||
|
"primaryColor": "#722ed1",
|
||||||
|
"title": "睿核平台管理"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```json
|
||||||
|
// build-config/cashier.json
|
||||||
|
{
|
||||||
|
"key": "cashier",
|
||||||
|
"name": "收银系统",
|
||||||
|
"description": "面向收银场景的管理后台",
|
||||||
|
"modules": ["system", "user", "cms", "cashier"],
|
||||||
|
"login": {
|
||||||
|
"component": "Cashier",
|
||||||
|
"showTenantInput": true,
|
||||||
|
"title": "睿核收银",
|
||||||
|
"subtitle": "门店管理系统"
|
||||||
|
},
|
||||||
|
"dashboard": {
|
||||||
|
"component": "Cashier",
|
||||||
|
"title": "收银数据概览"
|
||||||
|
},
|
||||||
|
"theme": {
|
||||||
|
"primaryColor": "#1677ff",
|
||||||
|
"title": "睿核收银"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2.2.2 Vite 插件(`scripts/vite-plugin-module-build.ts`)
|
||||||
|
|
||||||
|
插件职责:
|
||||||
|
|
||||||
|
1. **解析命令行参数**:读取 `--system={key}` 参数
|
||||||
|
2. **加载配置**:读取 `build-config/{key}.json`
|
||||||
|
3. **生成虚拟路由模块**:`virtual:generated-routes`
|
||||||
|
- 根据 `config.modules` 从路由模板中组装路由表
|
||||||
|
- 只包含指定模块的路由 + 核心页面路由(登录、Dashboard入口、个人中心、设置)
|
||||||
|
4. **生成虚拟配置模块**:`virtual:system-config`
|
||||||
|
- 将配置对象注入为全局常量 `__SYSTEM_CONFIG__`
|
||||||
|
5. **配置构建输出**:
|
||||||
|
- `build.outDir = dist/${config.key}`
|
||||||
|
- `build.rollupOptions.treeshake = true` 确保未使用代码被移除
|
||||||
|
|
||||||
|
**路由生成逻辑:**
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// router/modules/system.ts
|
||||||
|
export const systemRoutes = [
|
||||||
|
{ path: 'system/menu', name: 'SystemMenu', component: () => import('@/views/system/menu/Index.vue'), meta: { i18n: 'menu.systemMenu' } },
|
||||||
|
{ path: 'system/role', name: 'SystemRole', component: () => import('@/views/system/role/Index.vue'), meta: { i18n: 'menu.systemRole' } },
|
||||||
|
// ...
|
||||||
|
]
|
||||||
|
|
||||||
|
// router/modules/user.ts
|
||||||
|
export const userRoutes = [
|
||||||
|
{ path: 'user/info', name: 'UserInfo', component: () => import('@/views/user/info/Index.vue'), meta: { i18n: 'menu.userInfo' } },
|
||||||
|
// ...
|
||||||
|
]
|
||||||
|
|
||||||
|
// 插件根据 config.modules 动态组装
|
||||||
|
const moduleRoutes = config.modules.flatMap(module => {
|
||||||
|
const routeModule = routeModules[module]
|
||||||
|
return routeModule ? routeModule.routes : []
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2.2.3 统一入口页面
|
||||||
|
|
||||||
|
**Dashboard 入口(`views/dashboard/Index.vue`):**
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { defineAsyncComponent } from 'vue'
|
||||||
|
import systemConfig from 'virtual:system-config'
|
||||||
|
|
||||||
|
// 动态加载系统特定的 Dashboard 组件
|
||||||
|
const dashboardComponent = defineAsyncComponent(() =>
|
||||||
|
import(`./systems/${systemConfig.dashboard.component}.vue`)
|
||||||
|
)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<component :is="dashboardComponent" />
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
**登录页入口(`views/login/Index.vue`):**
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { defineAsyncComponent } from 'vue'
|
||||||
|
import systemConfig from 'virtual:system-config'
|
||||||
|
|
||||||
|
// 动态加载系统特定的登录组件
|
||||||
|
const loginComponent = defineAsyncComponent(() =>
|
||||||
|
import(`./systems/${systemConfig.login.component}.vue`)
|
||||||
|
)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<component :is="loginComponent" :config="systemConfig.login" />
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.3 模块映射关系
|
||||||
|
|
||||||
|
建立 `src/views/` 下的页面目录与模块标识的映射:
|
||||||
|
|
||||||
|
| 模块标识 | 对应目录 | 包含页面 |
|
||||||
|
|---------|---------|---------|
|
||||||
|
| `system` | `views/system/*` | 菜单、角色、部门、岗位、字典、配置、日志、登录日志、租户、租户套餐、数据权限、OAuth2客户端 |
|
||||||
|
| `user` | `views/user/*` | 用户信息、用户详情、等级、等级日志、地址、账户 |
|
||||||
|
| `order` | `views/order/*` | 订单列表、退款记录 |
|
||||||
|
| `cms` | `views/cms/*` | 文章、分类、轮播图 |
|
||||||
|
| `marketing` | `views/marketing/*` | 优惠券、活动管理 |
|
||||||
|
| `demo` | `views/demo/*` | 图标演示、列表演示 |
|
||||||
|
| `cashier` | `views/cashier/*` | 门店、包间、定价、订单、商品、报表 |
|
||||||
|
|
||||||
|
**核心页面(所有系统默认包含,不依赖模块配置):**
|
||||||
|
- `views/login/Index.vue` - 登录页入口
|
||||||
|
- `views/login/systems/*.vue` - 系统特定登录组件
|
||||||
|
- `views/dashboard/Index.vue` - Dashboard 入口
|
||||||
|
- `views/dashboard/systems/*.vue` - 系统特定 Dashboard 组件
|
||||||
|
- `views/profile/Index.vue` - 个人中心
|
||||||
|
- `views/settings/Index.vue` - 系统设置
|
||||||
|
|
||||||
|
### 2.4 目录结构
|
||||||
|
|
||||||
|
```
|
||||||
|
admin-ui/
|
||||||
|
├── build-config/ # 系统打包配置
|
||||||
|
│ ├── cashier.json
|
||||||
|
│ ├── admin.json
|
||||||
|
│ ├── super.json
|
||||||
|
│ └── default.json # 默认配置(全模块,用于开发)
|
||||||
|
├── scripts/ # 构建脚本
|
||||||
|
│ └── vite-plugin-module-build.ts # Vite 插件
|
||||||
|
├── src/
|
||||||
|
│ ├── router/
|
||||||
|
│ │ ├── index.ts # 改造:使用虚拟路由模块
|
||||||
|
│ │ └── modules/ # 新增:按模块拆分路由配置
|
||||||
|
│ │ ├── core.ts # 核心路由(登录、Dashboard入口等)
|
||||||
|
│ │ ├── system.ts
|
||||||
|
│ │ ├── user.ts
|
||||||
|
│ │ ├── order.ts
|
||||||
|
│ │ ├── cms.ts
|
||||||
|
│ │ ├── marketing.ts
|
||||||
|
│ │ ├── demo.ts
|
||||||
|
│ │ └── cashier.ts
|
||||||
|
│ ├── views/
|
||||||
|
│ │ ├── login/
|
||||||
|
│ │ │ ├── Index.vue # 改造:统一入口
|
||||||
|
│ │ │ └── systems/ # 新增:系统特定登录组件
|
||||||
|
│ │ │ ├── Default.vue # 默认登录页
|
||||||
|
│ │ │ ├── Super.vue # 超级租户登录页
|
||||||
|
│ │ │ └── Cashier.vue # 收银系统登录页
|
||||||
|
│ │ ├── dashboard/
|
||||||
|
│ │ │ ├── Index.vue # 改造:统一入口
|
||||||
|
│ │ │ └── systems/ # 新增:系统特定 Dashboard
|
||||||
|
│ │ │ ├── Default.vue # 默认 Dashboard
|
||||||
|
│ │ │ ├── Cashier.vue # 收银系统 Dashboard
|
||||||
|
│ │ │ └── Super.vue # 超级租户 Dashboard
|
||||||
|
│ │ └── ... # 业务页面(保持现有结构)
|
||||||
|
│ ├── types/
|
||||||
|
│ │ └── system-config.d.ts # 系统配置类型定义
|
||||||
|
│ └── ...
|
||||||
|
├── package.json # 改造:添加构建命令
|
||||||
|
└── vite.config.ts # 改造:注册插件
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.5 构建命令
|
||||||
|
|
||||||
|
```json
|
||||||
|
// package.json
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite --port 3000",
|
||||||
|
"dev:cashier": "vite --port 3000 -- --system=cashier",
|
||||||
|
"dev:super": "vite --port 3000 -- --system=super",
|
||||||
|
"build": "vue-tsc && vite build",
|
||||||
|
"build:cashier": "vue-tsc && vite build -- --system=cashier",
|
||||||
|
"build:super": "vue-tsc && vite build -- --system=super",
|
||||||
|
"build:admin": "vue-tsc && vite build -- --system=admin",
|
||||||
|
"build:all": "pnpm build:cashier && pnpm build:super && pnpm build:admin"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**产物输出:**
|
||||||
|
|
||||||
|
```
|
||||||
|
dist/
|
||||||
|
├── cashier/ # 收银系统(system + user + cms + cashier)
|
||||||
|
├── super/ # 超级租户(system + user)
|
||||||
|
├── admin/ # 普通后台(system + user + order + cms + marketing)
|
||||||
|
└── default/ # 默认(全模块,用于开发测试)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.6 主题配置应用
|
||||||
|
|
||||||
|
系统配置中的 `theme` 字段在运行时应用:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// App.vue 或布局组件
|
||||||
|
import systemConfig from 'virtual:system-config'
|
||||||
|
|
||||||
|
// 设置页面标题
|
||||||
|
document.title = systemConfig.theme.title
|
||||||
|
|
||||||
|
// 设置主题色(Element Plus)
|
||||||
|
const el = document.documentElement
|
||||||
|
el.style.setProperty('--el-color-primary', systemConfig.theme.primaryColor)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 三、验收标准
|
||||||
|
|
||||||
|
- [ ] 执行 `pnpm build:super` 成功构建,产物输出到 `dist/super/`,只包含 system 和 user 模块的页面
|
||||||
|
- [ ] 执行 `pnpm build:cashier` 成功构建,产物输出到 `dist/cashier/`,包含 system、user、cms、cashier 模块的页面
|
||||||
|
- [ ] 不同系统的 Dashboard 显示不同的子组件内容
|
||||||
|
- [ ] 不同系统的登录页显示不同的子组件内容(超级租户无租户ID输入)
|
||||||
|
- [ ] 构建产物中不包含未配置模块的页面代码(Tree Shaking 生效)
|
||||||
|
- [ ] 现有菜单 API 获取、权限控制、主题切换功能正常
|
||||||
|
- [ ] 开发模式 `pnpm dev:cashier` 正常工作,热更新无问题
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 四、风险与依赖
|
||||||
|
|
||||||
|
| 风险 | 影响 | 缓解措施 |
|
||||||
|
|------|------|---------|
|
||||||
|
| Vite 插件开发复杂度 | 中 | 插件逻辑清晰拆分:配置读取、路由生成、虚拟模块、输出配置 |
|
||||||
|
| Tree Shaking 不彻底 | 中 | 使用 `import()` 动态导入,配合 Rollup 的 `treeshake` 配置,构建后检查产物 |
|
||||||
|
| 动态组件加载失败 | 低 | 添加错误处理,加载失败时回退到 Default 组件 |
|
||||||
|
| 现有功能回归 | 中 | 构建后逐一验证核心功能:登录、菜单、CRUD、主题切换 |
|
||||||
|
| 多人协作冲突 | 低 | 配置文件集中管理,模块路由独立文件,减少冲突 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 五、后续扩展
|
||||||
|
|
||||||
|
1. **国际化支持**:配置文件中可扩展 `locales` 字段,支持系统特定的翻译覆盖
|
||||||
|
2. **模块懒加载**:未来可考虑运行时动态加载模块(Module Federation)
|
||||||
|
3. **版本管理**:配置文件支持 `version` 字段,用于产物版本控制
|
||||||
|
4. **CI/CD 集成**:构建命令可直接接入 Jenkins/GitHub Actions,参数化构建不同系统
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,268 @@
|
|||||||
|
# rui-admin 功能设计文档
|
||||||
|
|
||||||
|
## 1. 项目概述
|
||||||
|
|
||||||
|
rui-admin 是睿核通用平台框架的后台管理前端系统,基于 Vue 3 + Element Plus + UnoCSS 构建,提供完整的系统管理、用户管理、内容管理、订单管理、营销管理等功能。
|
||||||
|
|
||||||
|
## 2. 功能模块划分
|
||||||
|
|
||||||
|
### 2.1 系统管理(system)- 核心模块
|
||||||
|
|
||||||
|
| 功能 | 状态 | 后端API | 说明 |
|
||||||
|
|------|------|---------|------|
|
||||||
|
| 菜单管理 | ✅ 已完成 | SysMenuController | 树形结构、图标修复 |
|
||||||
|
| 角色管理 | ✅ 已完成 | SysRoleController | CRUD + 权限分配 |
|
||||||
|
| 部门管理 | ✅ 已完成 | SysDeptController | 树形表格 |
|
||||||
|
| 字典管理 | ✅ 已完成 | SysDictTypeController | 字典类型 + 字典项 |
|
||||||
|
| 参数配置 | ✅ 已完成 | SysConfigController | 系统参数维护 |
|
||||||
|
| 租户管理 | ✅ 已完成 | SysTenantController | 多租户管理 |
|
||||||
|
| **操作日志** | ⏳ 待开发 | 需新建 | 用户操作审计 |
|
||||||
|
| **登录日志** | ⏳ 待开发 | 需新建 | 登录行为记录 |
|
||||||
|
| **OAuth2客户端** | ⏳ 待开发 | SystemOAuth2ClientController | 客户端管理前端 |
|
||||||
|
|
||||||
|
### 2.2 用户中心(user)- 核心模块
|
||||||
|
|
||||||
|
| 功能 | 状态 | 后端API | 说明 |
|
||||||
|
|------|------|---------|------|
|
||||||
|
| 用户管理 | ✅ 已完成 | UserController | 用户CRUD |
|
||||||
|
| 用户等级 | ✅ 已完成 | UserLevelController | 等级体系管理 |
|
||||||
|
| **用户详情** | ⏳ 待开发 | UserDetailController | 用户详细信息 |
|
||||||
|
| **等级日志** | ⏳ 待开发 | UserLevelLogController | 等级变更记录 |
|
||||||
|
| **用户账户** | ⏳ 待开发 | 需评估 | 账户安全设置 |
|
||||||
|
| **用户地址** | ⏳ 待开发 | 需新建 | 收货地址管理 |
|
||||||
|
|
||||||
|
### 2.3 系统设置(settings)- 基础模块
|
||||||
|
|
||||||
|
| 功能 | 状态 | 后端API | 说明 |
|
||||||
|
|------|------|---------|------|
|
||||||
|
| **个人设置** | ⏳ 待开发 | 需评估 | 个人信息修改 |
|
||||||
|
| **系统设置** | ⏳ 待开发 | SysConfigController | 全局参数配置界面 |
|
||||||
|
| **密码修改** | ⏳ 待开发 | UserController | 修改登录密码 |
|
||||||
|
|
||||||
|
### 2.4 订单管理(order)- 业务模块
|
||||||
|
|
||||||
|
| 功能 | 状态 | 后端API | 说明 |
|
||||||
|
|------|------|---------|------|
|
||||||
|
| **订单列表** | ⏳ 预留 | 需新建服务 | 订单查询、状态管理 |
|
||||||
|
| **退款管理** | ⏳ 预留 | 需新建服务 | 退款申请处理 |
|
||||||
|
|
||||||
|
### 2.5 内容管理(cms)- 业务模块
|
||||||
|
|
||||||
|
| 功能 | 状态 | 后端API | 说明 |
|
||||||
|
|------|------|---------|------|
|
||||||
|
| **文章管理** | ⏳ 预留 | 需新建服务 | CMS文章CRUD |
|
||||||
|
| **分类管理** | ⏳ 预留 | 需新建服务 | 文章分类 |
|
||||||
|
| **轮播管理** | ⏳ 预留 | 需新建服务 | Banner管理 |
|
||||||
|
|
||||||
|
### 2.6 营销管理(marketing)- 业务模块
|
||||||
|
|
||||||
|
| 功能 | 状态 | 后端API | 说明 |
|
||||||
|
|------|------|---------|------|
|
||||||
|
| **优惠券** | ⏳ 预留 | 需新建服务 | 优惠券CRUD |
|
||||||
|
| **活动管理** | ⏳ 预留 | 需新建服务 | 营销活动 |
|
||||||
|
|
||||||
|
## 3. 开发优先级
|
||||||
|
|
||||||
|
### Phase 1:核心功能完善(立即开始)
|
||||||
|
|
||||||
|
1. **操作日志**(system/log)
|
||||||
|
- 后端:创建 OperLog 实体、Mapper、Service、Controller
|
||||||
|
- 前端:日志列表页、详情弹窗
|
||||||
|
- 优先级:🔴 高
|
||||||
|
|
||||||
|
2. **用户详情**(user/info/detail)
|
||||||
|
- 后端:UserDetailController 已有,补充前端
|
||||||
|
- 前端:用户详情查看/编辑
|
||||||
|
- 优先级:🔴 高
|
||||||
|
|
||||||
|
3. **等级日志**(user/level-log)
|
||||||
|
- 后端:UserLevelLogController 已有,补充前端
|
||||||
|
- 前端:等级变更记录列表
|
||||||
|
- 优先级:🟡 中
|
||||||
|
|
||||||
|
4. **系统设置**(settings)
|
||||||
|
- 后端:复用 SysConfigController
|
||||||
|
- 前端:参数配置界面(与 system/config 区别:更友好的展示)
|
||||||
|
- 优先级:🟡 中
|
||||||
|
|
||||||
|
### Phase 2:基础功能补充(近期)
|
||||||
|
|
||||||
|
5. **登录日志**(system/login-log)
|
||||||
|
- 后端:创建 LoginLog 实体、Mapper、Service、Controller
|
||||||
|
- 前端:登录记录列表
|
||||||
|
- 优先级:🟡 中
|
||||||
|
|
||||||
|
6. **OAuth2客户端管理**(system/client)
|
||||||
|
- 后端:SystemOAuth2ClientController 已有
|
||||||
|
- 前端:客户端CRUD
|
||||||
|
- 优先级:🟡 中
|
||||||
|
|
||||||
|
7. **个人中心**(profile)
|
||||||
|
- 后端:复用现有接口
|
||||||
|
- 前端:个人信息展示与修改
|
||||||
|
- 优先级:🟢 低
|
||||||
|
|
||||||
|
### Phase 3:业务模块(按需)
|
||||||
|
|
||||||
|
8. **订单管理** - 需新建 rui-service-order 服务
|
||||||
|
9. **CMS内容管理** - 需新建 rui-service-cms 服务
|
||||||
|
10. **营销管理** - 需新建 rui-service-marketing 服务
|
||||||
|
|
||||||
|
## 4. 技术规范
|
||||||
|
|
||||||
|
### 4.1 前端规范
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// 页面结构标准
|
||||||
|
views/
|
||||||
|
├── {module}/
|
||||||
|
│ ├── Index.vue # 列表页(必须)
|
||||||
|
│ ├── {Module}FormDialog.vue # 表单弹窗(新增/编辑)
|
||||||
|
│ └── {Module}DetailDialog.vue # 详情弹窗(可选)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.2 后端规范
|
||||||
|
|
||||||
|
```java
|
||||||
|
// Controller 标准结构
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/{模块}/admin/{功能}")
|
||||||
|
public class XxxController extends BaseController<IService, Entity> {
|
||||||
|
// 自动获得:page、list、getById、save、updateById、remove
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.3 API 路径规范
|
||||||
|
|
||||||
|
| 类型 | 路径前缀 | 示例 |
|
||||||
|
|------|---------|------|
|
||||||
|
| 对外管理 | `/{模块}/admin/{功能}` | `/system/admin/log` |
|
||||||
|
| 内部调用 | `/{模块}/inner/{功能}` | `/system/inner/client` |
|
||||||
|
| 对外入口 | `/{模块}/entry/{功能}` | `/auth/entry/login` |
|
||||||
|
|
||||||
|
## 5. 数据库设计(新增表)
|
||||||
|
|
||||||
|
### 5.1 操作日志表(rui_sys_oper_log)
|
||||||
|
|
||||||
|
```sql
|
||||||
|
CREATE TABLE rui_sys_oper_log (
|
||||||
|
id BIGINT NOT NULL,
|
||||||
|
tenant_id BIGINT NOT NULL DEFAULT 0,
|
||||||
|
oper_type TINYINT NOT NULL DEFAULT 1 COMMENT '操作类型 1:新增 2:修改 3:删除 4:查询 5:导出 6:登录 7:登出',
|
||||||
|
title VARCHAR(200) NOT NULL COMMENT '操作模块',
|
||||||
|
method VARCHAR(500) DEFAULT NULL COMMENT '请求方法',
|
||||||
|
request_url VARCHAR(500) DEFAULT NULL,
|
||||||
|
request_method VARCHAR(10) DEFAULT NULL COMMENT 'GET/POST/PUT/DELETE',
|
||||||
|
request_params TEXT DEFAULT NULL,
|
||||||
|
response_data TEXT DEFAULT NULL,
|
||||||
|
user_id BIGINT DEFAULT NULL,
|
||||||
|
user_name VARCHAR(100) DEFAULT NULL,
|
||||||
|
oper_ip VARCHAR(128) DEFAULT NULL,
|
||||||
|
oper_location VARCHAR(255) DEFAULT NULL,
|
||||||
|
status TINYINT NOT NULL DEFAULT 1 COMMENT '状态 0:失败 1:成功',
|
||||||
|
error_msg TEXT DEFAULT NULL,
|
||||||
|
cost_time BIGINT DEFAULT 0 COMMENT '耗时(ms)',
|
||||||
|
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||||
|
PRIMARY KEY (id),
|
||||||
|
INDEX idx_user (user_id),
|
||||||
|
INDEX idx_tenant (tenant_id),
|
||||||
|
INDEX idx_created (created_at)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='操作日志';
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5.2 登录日志表(rui_sys_login_log)
|
||||||
|
|
||||||
|
```sql
|
||||||
|
CREATE TABLE rui_sys_login_log (
|
||||||
|
id BIGINT NOT NULL,
|
||||||
|
tenant_id BIGINT NOT NULL DEFAULT 0,
|
||||||
|
user_id BIGINT DEFAULT NULL,
|
||||||
|
username VARCHAR(100) DEFAULT NULL,
|
||||||
|
login_type TINYINT NOT NULL DEFAULT 1 COMMENT '登录类型 1:密码 2:短信 3:微信',
|
||||||
|
client_id VARCHAR(100) DEFAULT NULL,
|
||||||
|
ip VARCHAR(128) DEFAULT NULL,
|
||||||
|
location VARCHAR(255) DEFAULT NULL,
|
||||||
|
browser VARCHAR(200) DEFAULT NULL,
|
||||||
|
os VARCHAR(200) DEFAULT NULL,
|
||||||
|
status TINYINT NOT NULL DEFAULT 1 COMMENT '状态 0:失败 1:成功',
|
||||||
|
msg VARCHAR(500) DEFAULT NULL,
|
||||||
|
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||||
|
PRIMARY KEY (id),
|
||||||
|
INDEX idx_user (user_id),
|
||||||
|
INDEX idx_tenant (tenant_id),
|
||||||
|
INDEX idx_created (created_at)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='登录日志';
|
||||||
|
```
|
||||||
|
|
||||||
|
## 6. 实施计划
|
||||||
|
|
||||||
|
### 第1周:Phase 1 核心功能
|
||||||
|
- [ ] 后端:操作日志 AOP 拦截 + API
|
||||||
|
- [ ] 前端:system/log 页面
|
||||||
|
- [ ] 前端:user/info 详情弹窗
|
||||||
|
- [ ] 前端:user/level-log 页面
|
||||||
|
|
||||||
|
### 第2周:Phase 2 基础功能
|
||||||
|
- [ ] 后端:登录日志 API
|
||||||
|
- [ ] 前端:system/login-log 页面
|
||||||
|
- [ ] 前端:settings 系统设置页
|
||||||
|
- [ ] 前端:profile 个人中心
|
||||||
|
|
||||||
|
### 第3周+:Phase 3 业务模块(按需)
|
||||||
|
- [ ] 订单服务 + 前端页面
|
||||||
|
- [ ] CMS服务 + 前端页面
|
||||||
|
- [ ] 营销服务 + 前端页面
|
||||||
|
|
||||||
|
## 7. 前端组件规划
|
||||||
|
|
||||||
|
### 7.1 复用组件
|
||||||
|
|
||||||
|
| 组件 | 用途 | 位置 |
|
||||||
|
|------|------|------|
|
||||||
|
| RuiTable | 通用表格 | components/RuiTable.vue |
|
||||||
|
| RuiIcon | 图标渲染 | components/RuiIcon.vue |
|
||||||
|
| IconPicker | 图标选择 | components/IconPicker.vue |
|
||||||
|
|
||||||
|
### 7.2 新增组件需求
|
||||||
|
|
||||||
|
| 组件 | 用途 | 优先级 |
|
||||||
|
|------|------|--------|
|
||||||
|
| LogDetailDialog | 日志详情展示 | 🔴 高 |
|
||||||
|
| UserDetailPanel | 用户信息卡片 | 🔴 高 |
|
||||||
|
| ConfigGroupPanel | 配置分组展示 | 🟡 中 |
|
||||||
|
|
||||||
|
## 8. 权限设计
|
||||||
|
|
||||||
|
### 8.1 菜单权限
|
||||||
|
|
||||||
|
```
|
||||||
|
system:menu:list - 菜单列表
|
||||||
|
system:menu:add - 新增菜单
|
||||||
|
system:menu:edit - 编辑菜单
|
||||||
|
system:menu:remove - 删除菜单
|
||||||
|
system:log:list - 日志列表
|
||||||
|
system:log:remove - 删除日志
|
||||||
|
```
|
||||||
|
|
||||||
|
### 8.2 数据权限
|
||||||
|
|
||||||
|
- 超级管理员:查看所有租户数据
|
||||||
|
- 租户管理员:仅查看本租户数据
|
||||||
|
- 普通用户:仅查看个人数据
|
||||||
|
|
||||||
|
## 9. 注意事项
|
||||||
|
|
||||||
|
1. **操作日志性能**:大量操作日志可能影响性能,建议:
|
||||||
|
- 异步写入(MQ或线程池)
|
||||||
|
- 定期归档(30天前的日志迁移到历史表)
|
||||||
|
- 提供日志清理功能
|
||||||
|
|
||||||
|
2. **登录日志安全**:
|
||||||
|
- 记录失败登录尝试,用于安全审计
|
||||||
|
- 支持 IP 黑名单
|
||||||
|
- 异常登录告警
|
||||||
|
|
||||||
|
3. **预留模块**:
|
||||||
|
- order/cms/marketing 为业务预留模块
|
||||||
|
- 需要时创建对应后端服务
|
||||||
|
- 前端页面保持占位状态即可
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,505 @@
|
|||||||
|
# API 设计规范
|
||||||
|
|
||||||
|
> 睿核科技通用平台框架 RESTful API 统一设计标准
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 一、接口分类
|
||||||
|
|
||||||
|
| 分类 | 路径前缀 | 认证 | 说明 |
|
||||||
|
|------|---------|------|------|
|
||||||
|
| **对外接口** | `/{模块}/api/**` | OAuth2 Token | 对外提供的业务接口 |
|
||||||
|
| **内部接口** | `/{模块}/inner/**` | `@Inner` + `INTERNAL_REQUEST` | 微服务间 Feign 调用 |
|
||||||
|
| **入口接口** | `/{模块}/entry/**` | 无需认证 | 对外入口(登录、注册) |
|
||||||
|
| **回调接口** | `/{模块}/notify/**` | 无需认证 | 第三方回调(支付、Webhook) |
|
||||||
|
| **管理接口** | `/{模块}/admin/**` | 需管理员权限 | 后台管理 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 二、URL 设计规范
|
||||||
|
|
||||||
|
### 2.1 对外接口(RESTful)
|
||||||
|
|
||||||
|
```
|
||||||
|
GET /{version}/{模块}/{资源} # 列表查询
|
||||||
|
GET /{version}/{模块}/{资源}/{id} # 详情查询
|
||||||
|
POST /{version}/{模块}/{资源} # 新增
|
||||||
|
PUT /{version}/{模块}/{资源}/{id} # 全量更新
|
||||||
|
PATCH /{version}/{模块}/{资源}/{id} # 局部更新
|
||||||
|
DELETE /{version}/{模块}/{资源}/{id} # 删除
|
||||||
|
```
|
||||||
|
|
||||||
|
**示例**:
|
||||||
|
```
|
||||||
|
GET /v1/user/users?page=1&size=10 # 查询用户列表
|
||||||
|
GET /v1/user/users/1001 # 查询用户详情
|
||||||
|
POST /v1/user/users # 新增用户
|
||||||
|
PUT /v1/user/users/1001 # 全量更新用户
|
||||||
|
PATCH /v1/user/users/1001 # 局部更新(如只改状态)
|
||||||
|
DELETE /v1/user/users/1001 # 删除用户
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.2 内部接口(Feign)
|
||||||
|
|
||||||
|
```
|
||||||
|
GET /{模块}/inner/{功能}/{方法}
|
||||||
|
```
|
||||||
|
|
||||||
|
**示例**:
|
||||||
|
```
|
||||||
|
GET /user/inner/auth/loadByUsername/{username}
|
||||||
|
GET /system/inner/client/getById/{clientId}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.3 版本控制
|
||||||
|
|
||||||
|
- **URI 版本**(推荐):`/v1/user/users`
|
||||||
|
- **Header 版本**(可选):`Accept: application/vnd.rui.v1+json`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 三、请求规范
|
||||||
|
|
||||||
|
### 3.1 HTTP 方法
|
||||||
|
|
||||||
|
| 方法 | 用途 | 幂等性 |
|
||||||
|
|------|------|--------|
|
||||||
|
| GET | 查询 | ✅ |
|
||||||
|
| POST | 新增/提交 | ❌ |
|
||||||
|
| PUT | 全量更新 | ✅ |
|
||||||
|
| PATCH | 局部更新 | ❌ |
|
||||||
|
| DELETE | 删除 | ✅ |
|
||||||
|
|
||||||
|
### 3.2 Content-Type
|
||||||
|
|
||||||
|
```
|
||||||
|
Content-Type: application/json; charset=utf-8
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.3 请求头规范
|
||||||
|
|
||||||
|
| Header | 必填 | 说明 |
|
||||||
|
|--------|------|------|
|
||||||
|
| Authorization | 是(除 entry/notify) | `Bearer {access_token}` |
|
||||||
|
| Content-Type | 是 | `application/json` |
|
||||||
|
| X-Request-Id | 否 | 请求追踪 ID(网关自动生成) |
|
||||||
|
| X-Tenant-Id | 否 | 租户 ID(后端自动注入) |
|
||||||
|
| Accept-Language | 否 | 语言偏好 `zh-CN` / `en-US` |
|
||||||
|
|
||||||
|
### 3.4 分页参数
|
||||||
|
|
||||||
|
```
|
||||||
|
GET /v1/user/users?page=1&size=10&sort=createdAt,desc
|
||||||
|
```
|
||||||
|
|
||||||
|
| 参数 | 类型 | 默认值 | 说明 |
|
||||||
|
|------|------|--------|------|
|
||||||
|
| page | int | 1 | 当前页码(从1开始) |
|
||||||
|
| size | int | 10 | 每页条数(最大100) |
|
||||||
|
| sort | string | createdAt,desc | 排序字段和方向 |
|
||||||
|
|
||||||
|
### 3.5 查询参数
|
||||||
|
|
||||||
|
```
|
||||||
|
GET /v1/user/users?username=admin&status=1&createdAt_start=2024-01-01&createdAt_end=2024-12-31
|
||||||
|
```
|
||||||
|
|
||||||
|
**规则**:
|
||||||
|
- 精确匹配:字段名直接等于值 `status=1`
|
||||||
|
- 模糊匹配:字段名加后缀 `_like` `username_like=admin`
|
||||||
|
- 范围查询:字段名加后缀 `_start` / `_end` `createdAt_start=2024-01-01`
|
||||||
|
- 多值查询:字段名加后缀 `_in` `status_in=1,2`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 四、响应规范
|
||||||
|
|
||||||
|
### 4.1 统一响应格式
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"msg": "操作成功",
|
||||||
|
"data": {}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.2 分页响应格式
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"msg": "操作成功",
|
||||||
|
"data": {
|
||||||
|
"records": [],
|
||||||
|
"total": 100,
|
||||||
|
"size": 10,
|
||||||
|
"current": 1,
|
||||||
|
"pages": 10
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.3 HTTP 状态码
|
||||||
|
|
||||||
|
| 状态码 | 含义 | 使用场景 |
|
||||||
|
|--------|------|---------|
|
||||||
|
| 200 | OK | 查询成功、更新成功 |
|
||||||
|
| 201 | Created | 新增成功 |
|
||||||
|
| 204 | No Content | 删除成功(无返回体) |
|
||||||
|
| 400 | Bad Request | 参数校验失败 |
|
||||||
|
| 401 | Unauthorized | 未登录/Token 过期 |
|
||||||
|
| 403 | Forbidden | 无权限访问 |
|
||||||
|
| 404 | Not Found | 资源不存在 |
|
||||||
|
| 409 | Conflict | 资源冲突(如重复提交) |
|
||||||
|
| 429 | Too Many Requests | 请求过于频繁 |
|
||||||
|
| 500 | Internal Server Error | 服务器内部错误 |
|
||||||
|
|
||||||
|
### 4.4 错误码规范
|
||||||
|
|
||||||
|
| 区间 | 模块 | 示例 |
|
||||||
|
|------|------|------|
|
||||||
|
| 1000-1999 | 通用 | 1001: 参数校验失败, 1002: 资源不存在 |
|
||||||
|
| 2000-2999 | 用户模块 | 2001: 用户名已存在, 2002: 密码错误 |
|
||||||
|
| 3000-3999 | 系统模块 | 3001: 字典不存在, 3002: 配置错误 |
|
||||||
|
| 4000-4999 | 认证模块 | 4001: Token 过期, 4002: 无权访问 |
|
||||||
|
| 5000-5999 | 文件模块 | 5001: 上传失败, 5002: 文件过大 |
|
||||||
|
| 6000-6999 | 消息模块 | 6001: 发送失败, 6002: 模板不存在 |
|
||||||
|
|
||||||
|
**错误响应示例**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 2001,
|
||||||
|
"msg": "用户名已存在",
|
||||||
|
"data": null
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 五、Controller 命名与路径映射
|
||||||
|
|
||||||
|
### 5.1 命名规则
|
||||||
|
|
||||||
|
| 类型 | Controller 命名 | 路径 | 说明 |
|
||||||
|
|------|----------------|------|------|
|
||||||
|
| 对外业务 | `UserController` | `/v1/user/users/**` | 常规 CRUD |
|
||||||
|
| 内部调用 | `UserInnerController` | `/user/inner/**` | Feign 调用 |
|
||||||
|
| 对外入口 | `UserEntryController` | `/user/entry/**` | 免认证入口 |
|
||||||
|
| 第三方回调 | `PayNotifyController` | `/pay/notify/**` | Webhook |
|
||||||
|
| 后台管理 | `UserAdminController` | `/v1/user/admin/**` | 管理接口 |
|
||||||
|
|
||||||
|
### 5.2 方法命名
|
||||||
|
|
||||||
|
| 操作 | 方法名 | HTTP | 路径 |
|
||||||
|
|------|--------|------|------|
|
||||||
|
| 列表 | `list` / `page` | GET | `/{资源}` |
|
||||||
|
| 详情 | `getById` | GET | `/{资源}/{id}` |
|
||||||
|
| 新增 | `add` / `save` | POST | `/{资源}` |
|
||||||
|
| 更新 | `update` / `edit` | PUT | `/{资源}/{id}` |
|
||||||
|
| 局部更新 | `patch` | PATCH | `/{资源}/{id}` |
|
||||||
|
| 删除 | `remove` / `delete` | DELETE | `/{资源}/{id}` |
|
||||||
|
| 批量删除 | `batchRemove` | DELETE | `/{资源}/batch` |
|
||||||
|
| 导出 | `export` | GET | `/{资源}/export` |
|
||||||
|
| 导入 | `import` | POST | `/{资源}/import` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 六、Swagger 注解规范
|
||||||
|
|
||||||
|
### 6.1 Controller 注解
|
||||||
|
|
||||||
|
```java
|
||||||
|
@Tag(name = "用户管理", description = "用户相关接口")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/v1/user/users")
|
||||||
|
public class UserController {
|
||||||
|
|
||||||
|
@Operation(summary = "查询用户列表", description = "支持分页、排序、条件查询")
|
||||||
|
@GetMapping
|
||||||
|
public Result<PageResult<UserVO>> list(
|
||||||
|
@Parameter(description = "页码") @RequestParam(defaultValue = "1") Integer page,
|
||||||
|
@Parameter(description = "每页条数") @RequestParam(defaultValue = "10") Integer size) {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "新增用户")
|
||||||
|
@PostMapping
|
||||||
|
public Result<Long> add(@RequestBody @Valid UserDTO dto) {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 6.2 DTO / VO 注解
|
||||||
|
|
||||||
|
```java
|
||||||
|
@Schema(description = "用户新增DTO")
|
||||||
|
@Data
|
||||||
|
public class UserDTO {
|
||||||
|
|
||||||
|
@Schema(description = "用户名", requiredMode = Schema.RequiredMode.REQUIRED, example = "admin")
|
||||||
|
@NotBlank(message = "用户名不能为空")
|
||||||
|
@Size(min = 2, max = 50, message = "用户名长度2-50字符")
|
||||||
|
private String username;
|
||||||
|
|
||||||
|
@Schema(description = "状态 0:禁用 1:启用", example = "1")
|
||||||
|
private Integer status;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 七、数据校验规范
|
||||||
|
|
||||||
|
### 7.1 分组校验
|
||||||
|
|
||||||
|
```java
|
||||||
|
public interface AddGroup {} // 新增分组
|
||||||
|
public interface UpdateGroup {} // 更新分组
|
||||||
|
```
|
||||||
|
|
||||||
|
### 7.2 使用示例
|
||||||
|
|
||||||
|
```java
|
||||||
|
@Data
|
||||||
|
public class UserDTO {
|
||||||
|
|
||||||
|
@NotNull(message = "ID不能为空", groups = UpdateGroup.class)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@NotBlank(message = "用户名不能为空", groups = {AddGroup.class, UpdateGroup.class})
|
||||||
|
private String username;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Controller
|
||||||
|
@PostMapping
|
||||||
|
public Result<Long> add(@RequestBody @Validated(AddGroup.class) UserDTO dto) {
|
||||||
|
// 新增
|
||||||
|
}
|
||||||
|
|
||||||
|
@PutMapping("/{id}")
|
||||||
|
public Result<Void> update(@RequestBody @Validated(UpdateGroup.class) UserDTO dto) {
|
||||||
|
// 更新
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 八、Feign 接口规范
|
||||||
|
|
||||||
|
### 8.1 接口定义
|
||||||
|
|
||||||
|
```java
|
||||||
|
/**
|
||||||
|
* 远程用户服务
|
||||||
|
*/
|
||||||
|
@Headers("INTERNAL_REQUEST: INTERNAL")
|
||||||
|
@FeignClient(
|
||||||
|
contextId = "remoteUserService",
|
||||||
|
value = "${feign.providers.user:rui-service-user}",
|
||||||
|
path = "/user/inner"
|
||||||
|
)
|
||||||
|
public interface RemoteUserService {
|
||||||
|
|
||||||
|
@GetMapping("/auth/loadByUsername/{username}")
|
||||||
|
Result<Map<String, Object>> loadUser(@PathVariable String username);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 8.2 调用规范
|
||||||
|
|
||||||
|
```java
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class UserRemoteService {
|
||||||
|
|
||||||
|
private final RemoteUserService remoteUserService;
|
||||||
|
|
||||||
|
public UserVO getUserById(Long userId) {
|
||||||
|
Result<UserVO> result = remoteUserService.getById(userId);
|
||||||
|
if (result.isSuccess()) {
|
||||||
|
return result.getData();
|
||||||
|
}
|
||||||
|
throw new BizException(result.getCode(), result.getMsg());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 九、文件上传接口规范
|
||||||
|
|
||||||
|
### 9.1 单文件上传
|
||||||
|
|
||||||
|
```
|
||||||
|
POST /v1/file/files/upload
|
||||||
|
Content-Type: multipart/form-data
|
||||||
|
|
||||||
|
file: [二进制文件]
|
||||||
|
module: user
|
||||||
|
bizId: 1001
|
||||||
|
```
|
||||||
|
|
||||||
|
**响应**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"msg": "上传成功",
|
||||||
|
"data": {
|
||||||
|
"fileId": "123456",
|
||||||
|
"fileName": "avatar.jpg",
|
||||||
|
"fileUrl": "https://oss.example.com/avatar/123456.jpg",
|
||||||
|
"fileSize": 102400
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 9.2 多文件上传
|
||||||
|
|
||||||
|
```
|
||||||
|
POST /v1/file/files/batchUpload
|
||||||
|
Content-Type: multipart/form-data
|
||||||
|
|
||||||
|
files: [文件1, 文件2, 文件3]
|
||||||
|
module: user
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 十、导出接口规范
|
||||||
|
|
||||||
|
### 10.1 Excel 导出
|
||||||
|
|
||||||
|
```
|
||||||
|
GET /v1/user/users/export?username=admin&status=1
|
||||||
|
Accept: application/vnd.ms-excel
|
||||||
|
```
|
||||||
|
|
||||||
|
**响应**:
|
||||||
|
```
|
||||||
|
Content-Type: application/vnd.ms-excel
|
||||||
|
Content-Disposition: attachment; filename="用户列表_20240101.xlsx"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 10.2 CSV 导出
|
||||||
|
|
||||||
|
```
|
||||||
|
GET /v1/user/users/export?format=csv
|
||||||
|
Accept: text/csv
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 十一、WebSocket 接口规范(预留)
|
||||||
|
|
||||||
|
```
|
||||||
|
ws://gateway:9300/ws/{模块}/{topic}
|
||||||
|
```
|
||||||
|
|
||||||
|
**示例**:
|
||||||
|
```
|
||||||
|
ws://localhost:9300/ws/msg/notification # 消息通知
|
||||||
|
ws://localhost:9300/ws/monitor/metrics # 实时监控
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 十二、接口文档生成
|
||||||
|
|
||||||
|
### 12.1 配置 SpringDoc
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
springdoc:
|
||||||
|
swagger-ui:
|
||||||
|
path: /swagger-ui.html
|
||||||
|
enabled: true
|
||||||
|
api-docs:
|
||||||
|
path: /v3/api-docs
|
||||||
|
enabled: true
|
||||||
|
group-configs:
|
||||||
|
- group: 用户服务
|
||||||
|
display-name: 用户服务 API
|
||||||
|
paths-to-match: /v1/user/**
|
||||||
|
- group: 系统服务
|
||||||
|
display-name: 系统服务 API
|
||||||
|
paths-to-match: /v1/system/**
|
||||||
|
```
|
||||||
|
|
||||||
|
### 12.2 访问地址
|
||||||
|
|
||||||
|
```
|
||||||
|
http://localhost:9300/swagger-ui.html # 网关聚合文档
|
||||||
|
http://localhost:9301/swagger-ui.html # 认证服务文档
|
||||||
|
http://localhost:9302/swagger-ui.html # 系统服务文档
|
||||||
|
http://localhost:9303/swagger-ui.html # 用户服务文档
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 十三、Postman / APIFox 集合规范
|
||||||
|
|
||||||
|
### 13.1 目录结构
|
||||||
|
|
||||||
|
```
|
||||||
|
睿核科技通用平台
|
||||||
|
├── 01-认证中心
|
||||||
|
│ ├── 获取Token
|
||||||
|
│ ├── 刷新Token
|
||||||
|
│ └── 退出登录
|
||||||
|
├── 02-用户中心
|
||||||
|
│ ├── 用户管理
|
||||||
|
│ ├── 等级管理
|
||||||
|
│ └── 用户查询
|
||||||
|
├── 03-系统管理
|
||||||
|
│ ├── 租户管理
|
||||||
|
│ ├── 菜单管理
|
||||||
|
│ ├── 角色管理
|
||||||
|
│ ├── 字典管理
|
||||||
|
│ └── 参数配置
|
||||||
|
├── 04-文件管理
|
||||||
|
│ ├── 文件上传
|
||||||
|
│ └── 文件下载
|
||||||
|
└── 99-内部接口(Feign)
|
||||||
|
├── 用户服务
|
||||||
|
└── 系统服务
|
||||||
|
```
|
||||||
|
|
||||||
|
### 13.2 环境变量
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"baseUrl": "http://localhost:9300",
|
||||||
|
"token": "{{login_response_token}}",
|
||||||
|
"tenantId": "1"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 十四、接口变更管理
|
||||||
|
|
||||||
|
### 14.1 变更类型
|
||||||
|
|
||||||
|
| 类型 | 说明 | 版本处理 |
|
||||||
|
|------|------|---------|
|
||||||
|
| 新增接口 | 新增资源/功能 | 当前版本可用 |
|
||||||
|
| 新增字段 | 请求/响应增加字段 | 当前版本可用(兼容) |
|
||||||
|
| 废弃字段 | 字段标记 deprecated | 当前版本可用,下版本移除 |
|
||||||
|
| 废弃接口 | 接口标记 deprecated | 保留至少2个版本后移除 |
|
||||||
|
| 破坏性变更 | 字段删除/类型变更 | 升级版本号(v1 → v2) |
|
||||||
|
|
||||||
|
### 14.2 版本迭代策略
|
||||||
|
|
||||||
|
```
|
||||||
|
v1.0 —— 初始版本
|
||||||
|
v1.1 —— 新增字段(兼容)
|
||||||
|
v1.2 —— 新增接口(兼容)
|
||||||
|
v2.0 —— 破坏性变更(不兼容)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
> **文档版本**: v1.0
|
||||||
|
> **创建日期**: 2026-05-28
|
||||||
|
> **适用范围**: 睿核科技通用平台框架所有 RESTful API
|
||||||
@@ -0,0 +1,111 @@
|
|||||||
|
# 前端开发规则
|
||||||
|
|
||||||
|
> 适用于 {root} 仓库下所有前端工程
|
||||||
|
|
||||||
|
## 技术栈
|
||||||
|
|
||||||
|
| 场景 | 框架 | UI 库 | CSS |
|
||||||
|
|------|------|------|-----|
|
||||||
|
| **管理后台 PC** | Vue 3 + TypeScript + Vite | Element Plus | UnoCSS |
|
||||||
|
| **移动端/小程序** | uniapp (Vue 3) + TypeScript | uView Plus | UnoCSS |
|
||||||
|
| **H5 官网** | Vue 3 + TypeScript + Vite | — | UnoCSS |
|
||||||
|
|
||||||
|
## 统一规范
|
||||||
|
|
||||||
|
### 必选
|
||||||
|
|
||||||
|
- **Vue 3** Composition API(`<script setup lang="ts">`)
|
||||||
|
- **TypeScript** 严格模式
|
||||||
|
- **UnoCSS** 原子化 CSS(替代 Tailwind / 手写 CSS)
|
||||||
|
- **pnpm** 包管理器
|
||||||
|
- **ESLint** + `@antfu/eslint-config`
|
||||||
|
- **Vite** 构建工具
|
||||||
|
|
||||||
|
### 推荐
|
||||||
|
|
||||||
|
- **Pinia** 状态管理
|
||||||
|
- **Vue Router** 路由
|
||||||
|
- **Axios** HTTP 请求(统一拦截器 + Token 刷新)
|
||||||
|
- **unplugin-auto-import** 自动导入 Vue/API
|
||||||
|
- **unplugin-vue-components** 自动导入组件
|
||||||
|
- **Vitest** 单元测试
|
||||||
|
|
||||||
|
### 禁止
|
||||||
|
|
||||||
|
- Vue 2 / Options API
|
||||||
|
- JavaScript(必须 TS)
|
||||||
|
- CSS 文件(使用 UnoCSS 原子类)
|
||||||
|
- npm/yarn(必须 pnpm)
|
||||||
|
- 多行 CSS 样式块(用 UnoCSS 属性化或原子类替代)
|
||||||
|
|
||||||
|
## 项目结构
|
||||||
|
|
||||||
|
```
|
||||||
|
admin-ui/(或 web-ui/)
|
||||||
|
├── package.json
|
||||||
|
├── vite.config.ts
|
||||||
|
├── uno.config.ts
|
||||||
|
├── tsconfig.json
|
||||||
|
├── index.html
|
||||||
|
├── src/
|
||||||
|
│ ├── App.vue
|
||||||
|
│ ├── main.ts
|
||||||
|
│ ├── router/
|
||||||
|
│ ├── stores/ # Pinia
|
||||||
|
│ ├── api/ # Axios 封装 + 接口
|
||||||
|
│ ├── views/ # 页面组件
|
||||||
|
│ ├── components/ # 公共组件
|
||||||
|
│ ├── composables/ # 组合函数
|
||||||
|
│ ├── utils/ # 工具函数
|
||||||
|
│ └── styles/ # 仅放 UnoCSS 快捷方式或极少全局样式
|
||||||
|
└── public/
|
||||||
|
```
|
||||||
|
|
||||||
|
## API 调用规范
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// api/user.ts
|
||||||
|
import { request } from '@/utils/request'
|
||||||
|
|
||||||
|
export interface UserInfo {
|
||||||
|
id: number
|
||||||
|
username: string
|
||||||
|
nickname: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export const userApi = {
|
||||||
|
page: (params: any) => request.get<PageResult<UserInfo>>('/user/info/page', { params }),
|
||||||
|
create: (data: UserInfo) => request.post('/user/info/create', data),
|
||||||
|
update: (data: UserInfo) => request.put('/user/info/update', data),
|
||||||
|
remove: (id: number) => request.delete(`/user/info/${id}`),
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## UnoCSS 使用
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<!-- 原子类 -->
|
||||||
|
<div class="flex items-center gap-4 p-4 bg-white rounded shadow">
|
||||||
|
<span class="text-lg font-bold text-primary">标题</span>
|
||||||
|
<el-button type="primary" class="ml-auto">
|
||||||
|
操作
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
// 仅极少情况下使用,优先用 UnoCSS 原子类或 shortcuts
|
||||||
|
</style>
|
||||||
|
```
|
||||||
|
|
||||||
|
## 命名规范
|
||||||
|
|
||||||
|
| 类型 | 规则 | 示例 |
|
||||||
|
|------|------|------|
|
||||||
|
| 文件名 | PascalCase | `UserList.vue`, `useTable.ts` |
|
||||||
|
| 目录名 | kebab-case | `user-info/`, `order-detail/` |
|
||||||
|
| 变量/函数 | camelCase | `userList`, `fetchData` |
|
||||||
|
| 组件 | PascalCase | `<UserCard />` |
|
||||||
|
| Pinia store | useXxxStore | `useUserStore` |
|
||||||
|
| 路径 | 小写短横线 | `/user/info`, `/order/detail` |
|
||||||
@@ -0,0 +1,371 @@
|
|||||||
|
# Admin-UI 分模块打包功能设计文档
|
||||||
|
|
||||||
|
> **设计日期**: 2026-06-04
|
||||||
|
> **版本**: v1.0
|
||||||
|
> **状态**: 已批准
|
||||||
|
> **目标**: 实现 Admin-UI 按系统配置分模块打包,支持不同租户类型输出不同产物包
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 一、背景与目标
|
||||||
|
|
||||||
|
### 1.1 现状分析
|
||||||
|
|
||||||
|
当前 Admin-UI 存在以下问题:
|
||||||
|
|
||||||
|
1. **路由硬编码**:所有页面路由集中在 `router/index.ts` 中硬编码,无法按模块裁剪
|
||||||
|
2. **构建产物单一**:无论服务哪个租户,都打包所有页面代码,产物体积大
|
||||||
|
3. **缺乏系统差异化**:Dashboard、登录页等核心页面无法根据不同系统定制
|
||||||
|
4. **模块管理已有雏形**:后端已支持租户模块配置(`ModuleDialog.vue`),但前端构建未与之配合
|
||||||
|
|
||||||
|
### 1.2 目标定义
|
||||||
|
|
||||||
|
1. **构建时分包**:根据 JSON 配置文件,构建时只打包指定模块的代码
|
||||||
|
2. **动态路由生成**:替换硬编码路由,构建时根据配置动态生成路由表
|
||||||
|
3. **系统差异化页面**:支持 Dashboard、登录页按系统配置加载不同子组件
|
||||||
|
4. **多产物输出**:不同系统输出到 `dist/{systemKey}/` 目录
|
||||||
|
5. **保持现有功能**:菜单 API 获取、权限控制、主题切换等功能不受影响
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 二、详细设计
|
||||||
|
|
||||||
|
### 2.1 整体架构
|
||||||
|
|
||||||
|
```
|
||||||
|
构建流程:
|
||||||
|
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
|
||||||
|
│ build-config/ │ │ Vite Plugin │ │ 构建产物 │
|
||||||
|
│ cashier.json │────→│ (module-build) │────→│ dist/cashier/ │
|
||||||
|
│ admin.json │ │ │ │ dist/admin/ │
|
||||||
|
│ super.json │ │ 1. 读取配置 │ │ dist/super/ │
|
||||||
|
└─────────────────┘ │ 2. 生成路由 │ │ │
|
||||||
|
│ 3. 注入配置 │ └─────────────────┘
|
||||||
|
│ 4. 配置输出 │
|
||||||
|
└──────────────────┘
|
||||||
|
|
||||||
|
运行时:
|
||||||
|
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
|
||||||
|
│ 统一入口页面 │────→│ 虚拟模块配置 │────→│ 系统特定子组件 │
|
||||||
|
│ Dashboard │ │ __SYSTEM_CONFIG__│ │ systems/ │
|
||||||
|
│ Login │ │ │ │ Cashier.vue │
|
||||||
|
└─────────────────┘ └──────────────────┘ │ Super.vue │
|
||||||
|
└─────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.2 核心组件
|
||||||
|
|
||||||
|
#### 2.2.1 配置文件(`build-config/`)
|
||||||
|
|
||||||
|
每个系统一个 JSON 配置文件:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
interface BuildConfig {
|
||||||
|
/** 系统唯一标识,产物目录名 */
|
||||||
|
key: string
|
||||||
|
/** 系统显示名称 */
|
||||||
|
name: string
|
||||||
|
/** 系统描述 */
|
||||||
|
description?: string
|
||||||
|
/** 包含的模块列表 */
|
||||||
|
modules: string[]
|
||||||
|
/** 登录页配置 */
|
||||||
|
login: {
|
||||||
|
/** 登录组件名(对应 views/login/systems/ 下的组件) */
|
||||||
|
component: string
|
||||||
|
/** 是否显示租户ID输入 */
|
||||||
|
showTenantInput: boolean
|
||||||
|
/** 页面标题 */
|
||||||
|
title: string
|
||||||
|
/** 副标题 */
|
||||||
|
subtitle?: string
|
||||||
|
/** 背景图路径 */
|
||||||
|
background?: string
|
||||||
|
/** Logo路径 */
|
||||||
|
logo?: string
|
||||||
|
}
|
||||||
|
/** Dashboard配置 */
|
||||||
|
dashboard: {
|
||||||
|
/** Dashboard组件名(对应 views/dashboard/systems/ 下的组件) */
|
||||||
|
component: string
|
||||||
|
/** 页面标题 */
|
||||||
|
title: string
|
||||||
|
}
|
||||||
|
/** 主题配置 */
|
||||||
|
theme: {
|
||||||
|
/** 主题色 */
|
||||||
|
primaryColor: string
|
||||||
|
/** 页面标题 */
|
||||||
|
title: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**示例配置:**
|
||||||
|
|
||||||
|
```json
|
||||||
|
// build-config/super.json
|
||||||
|
{
|
||||||
|
"key": "super",
|
||||||
|
"name": "超级管理后台",
|
||||||
|
"description": "超级租户专用,包含租户管理",
|
||||||
|
"modules": ["system", "user"],
|
||||||
|
"login": {
|
||||||
|
"component": "Super",
|
||||||
|
"showTenantInput": false,
|
||||||
|
"title": "睿核平台管理",
|
||||||
|
"subtitle": "超级管理员登录"
|
||||||
|
},
|
||||||
|
"dashboard": {
|
||||||
|
"component": "Super",
|
||||||
|
"title": "平台运营概览"
|
||||||
|
},
|
||||||
|
"theme": {
|
||||||
|
"primaryColor": "#722ed1",
|
||||||
|
"title": "睿核平台管理"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
```json
|
||||||
|
// build-config/cashier.json
|
||||||
|
{
|
||||||
|
"key": "cashier",
|
||||||
|
"name": "收银系统",
|
||||||
|
"description": "面向收银场景的管理后台",
|
||||||
|
"modules": ["system", "user", "cms", "cashier"],
|
||||||
|
"login": {
|
||||||
|
"component": "Cashier",
|
||||||
|
"showTenantInput": true,
|
||||||
|
"title": "睿核收银",
|
||||||
|
"subtitle": "门店管理系统"
|
||||||
|
},
|
||||||
|
"dashboard": {
|
||||||
|
"component": "Cashier",
|
||||||
|
"title": "收银数据概览"
|
||||||
|
},
|
||||||
|
"theme": {
|
||||||
|
"primaryColor": "#1677ff",
|
||||||
|
"title": "睿核收银"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2.2.2 Vite 插件(`scripts/vite-plugin-module-build.ts`)
|
||||||
|
|
||||||
|
插件职责:
|
||||||
|
|
||||||
|
1. **解析命令行参数**:读取 `--system={key}` 参数
|
||||||
|
2. **加载配置**:读取 `build-config/{key}.json`
|
||||||
|
3. **生成虚拟路由模块**:`virtual:generated-routes`
|
||||||
|
- 根据 `config.modules` 从路由模板中组装路由表
|
||||||
|
- 只包含指定模块的路由 + 核心页面路由(登录、Dashboard入口、个人中心、设置)
|
||||||
|
4. **生成虚拟配置模块**:`virtual:system-config`
|
||||||
|
- 将配置对象注入为全局常量 `__SYSTEM_CONFIG__`
|
||||||
|
5. **配置构建输出**:
|
||||||
|
- `build.outDir = dist/${config.key}`
|
||||||
|
- `build.rollupOptions.treeshake = true` 确保未使用代码被移除
|
||||||
|
|
||||||
|
**路由生成逻辑:**
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// router/modules/system.ts
|
||||||
|
export const systemRoutes = [
|
||||||
|
{ path: 'system/menu', name: 'SystemMenu', component: () => import('@/views/system/menu/Index.vue'), meta: { i18n: 'menu.systemMenu' } },
|
||||||
|
{ path: 'system/role', name: 'SystemRole', component: () => import('@/views/system/role/Index.vue'), meta: { i18n: 'menu.systemRole' } },
|
||||||
|
// ...
|
||||||
|
]
|
||||||
|
|
||||||
|
// router/modules/user.ts
|
||||||
|
export const userRoutes = [
|
||||||
|
{ path: 'user/info', name: 'UserInfo', component: () => import('@/views/user/info/Index.vue'), meta: { i18n: 'menu.userInfo' } },
|
||||||
|
// ...
|
||||||
|
]
|
||||||
|
|
||||||
|
// 插件根据 config.modules 动态组装
|
||||||
|
const moduleRoutes = config.modules.flatMap(module => {
|
||||||
|
const routeModule = routeModules[module]
|
||||||
|
return routeModule ? routeModule.routes : []
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2.2.3 统一入口页面
|
||||||
|
|
||||||
|
**Dashboard 入口(`views/dashboard/Index.vue`):**
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { defineAsyncComponent } from 'vue'
|
||||||
|
import systemConfig from 'virtual:system-config'
|
||||||
|
|
||||||
|
// 动态加载系统特定的 Dashboard 组件
|
||||||
|
const dashboardComponent = defineAsyncComponent(() =>
|
||||||
|
import(`./systems/${systemConfig.dashboard.component}.vue`)
|
||||||
|
)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<component :is="dashboardComponent" />
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
**登录页入口(`views/login/Index.vue`):**
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { defineAsyncComponent } from 'vue'
|
||||||
|
import systemConfig from 'virtual:system-config'
|
||||||
|
|
||||||
|
// 动态加载系统特定的登录组件
|
||||||
|
const loginComponent = defineAsyncComponent(() =>
|
||||||
|
import(`./systems/${systemConfig.login.component}.vue`)
|
||||||
|
)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<component :is="loginComponent" :config="systemConfig.login" />
|
||||||
|
</template>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.3 模块映射关系
|
||||||
|
|
||||||
|
建立 `src/views/` 下的页面目录与模块标识的映射:
|
||||||
|
|
||||||
|
| 模块标识 | 对应目录 | 包含页面 |
|
||||||
|
|---------|---------|---------|
|
||||||
|
| `system` | `views/system/*` | 菜单、角色、部门、岗位、字典、配置、日志、登录日志、租户、租户套餐、数据权限、OAuth2客户端 |
|
||||||
|
| `user` | `views/user/*` | 用户信息、用户详情、等级、等级日志、地址、账户 |
|
||||||
|
| `order` | `views/order/*` | 订单列表、退款记录 |
|
||||||
|
| `cms` | `views/cms/*` | 文章、分类、轮播图 |
|
||||||
|
| `marketing` | `views/marketing/*` | 优惠券、活动管理 |
|
||||||
|
| `demo` | `views/demo/*` | 图标演示、列表演示 |
|
||||||
|
| `cashier` | `views/cashier/*` | 门店、包间、定价、订单、商品、报表 |
|
||||||
|
|
||||||
|
**核心页面(所有系统默认包含,不依赖模块配置):**
|
||||||
|
- `views/login/Index.vue` - 登录页入口
|
||||||
|
- `views/login/systems/*.vue` - 系统特定登录组件
|
||||||
|
- `views/dashboard/Index.vue` - Dashboard 入口
|
||||||
|
- `views/dashboard/systems/*.vue` - 系统特定 Dashboard 组件
|
||||||
|
- `views/profile/Index.vue` - 个人中心
|
||||||
|
- `views/settings/Index.vue` - 系统设置
|
||||||
|
|
||||||
|
### 2.4 目录结构
|
||||||
|
|
||||||
|
```
|
||||||
|
admin-ui/
|
||||||
|
├── build-config/ # 系统打包配置
|
||||||
|
│ ├── cashier.json
|
||||||
|
│ ├── admin.json
|
||||||
|
│ ├── super.json
|
||||||
|
│ └── default.json # 默认配置(全模块,用于开发)
|
||||||
|
├── scripts/ # 构建脚本
|
||||||
|
│ └── vite-plugin-module-build.ts # Vite 插件
|
||||||
|
├── src/
|
||||||
|
│ ├── router/
|
||||||
|
│ │ ├── index.ts # 改造:使用虚拟路由模块
|
||||||
|
│ │ └── modules/ # 新增:按模块拆分路由配置
|
||||||
|
│ │ ├── core.ts # 核心路由(登录、Dashboard入口等)
|
||||||
|
│ │ ├── system.ts
|
||||||
|
│ │ ├── user.ts
|
||||||
|
│ │ ├── order.ts
|
||||||
|
│ │ ├── cms.ts
|
||||||
|
│ │ ├── marketing.ts
|
||||||
|
│ │ ├── demo.ts
|
||||||
|
│ │ └── cashier.ts
|
||||||
|
│ ├── views/
|
||||||
|
│ │ ├── login/
|
||||||
|
│ │ │ ├── Index.vue # 改造:统一入口
|
||||||
|
│ │ │ └── systems/ # 新增:系统特定登录组件
|
||||||
|
│ │ │ ├── Default.vue # 默认登录页
|
||||||
|
│ │ │ ├── Super.vue # 超级租户登录页
|
||||||
|
│ │ │ └── Cashier.vue # 收银系统登录页
|
||||||
|
│ │ ├── dashboard/
|
||||||
|
│ │ │ ├── Index.vue # 改造:统一入口
|
||||||
|
│ │ │ └── systems/ # 新增:系统特定 Dashboard
|
||||||
|
│ │ │ ├── Default.vue # 默认 Dashboard
|
||||||
|
│ │ │ ├── Cashier.vue # 收银系统 Dashboard
|
||||||
|
│ │ │ └── Super.vue # 超级租户 Dashboard
|
||||||
|
│ │ └── ... # 业务页面(保持现有结构)
|
||||||
|
│ ├── types/
|
||||||
|
│ │ └── system-config.d.ts # 系统配置类型定义
|
||||||
|
│ └── ...
|
||||||
|
├── package.json # 改造:添加构建命令
|
||||||
|
└── vite.config.ts # 改造:注册插件
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.5 构建命令
|
||||||
|
|
||||||
|
```json
|
||||||
|
// package.json
|
||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite --port 3000",
|
||||||
|
"dev:cashier": "vite --port 3000 -- --system=cashier",
|
||||||
|
"dev:super": "vite --port 3000 -- --system=super",
|
||||||
|
"build": "vue-tsc && vite build",
|
||||||
|
"build:cashier": "vue-tsc && vite build -- --system=cashier",
|
||||||
|
"build:super": "vue-tsc && vite build -- --system=super",
|
||||||
|
"build:admin": "vue-tsc && vite build -- --system=admin",
|
||||||
|
"build:all": "pnpm build:cashier && pnpm build:super && pnpm build:admin"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**产物输出:**
|
||||||
|
|
||||||
|
```
|
||||||
|
dist/
|
||||||
|
├── cashier/ # 收银系统(system + user + cms + cashier)
|
||||||
|
├── super/ # 超级租户(system + user)
|
||||||
|
├── admin/ # 普通后台(system + user + order + cms + marketing)
|
||||||
|
└── default/ # 默认(全模块,用于开发测试)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.6 主题配置应用
|
||||||
|
|
||||||
|
系统配置中的 `theme` 字段在运行时应用:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// App.vue 或布局组件
|
||||||
|
import systemConfig from 'virtual:system-config'
|
||||||
|
|
||||||
|
// 设置页面标题
|
||||||
|
document.title = systemConfig.theme.title
|
||||||
|
|
||||||
|
// 设置主题色(Element Plus)
|
||||||
|
const el = document.documentElement
|
||||||
|
el.style.setProperty('--el-color-primary', systemConfig.theme.primaryColor)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 三、验收标准
|
||||||
|
|
||||||
|
- [ ] 执行 `pnpm build:super` 成功构建,产物输出到 `dist/super/`,只包含 system 和 user 模块的页面
|
||||||
|
- [ ] 执行 `pnpm build:cashier` 成功构建,产物输出到 `dist/cashier/`,包含 system、user、cms、cashier 模块的页面
|
||||||
|
- [ ] 不同系统的 Dashboard 显示不同的子组件内容
|
||||||
|
- [ ] 不同系统的登录页显示不同的子组件内容(超级租户无租户ID输入)
|
||||||
|
- [ ] 构建产物中不包含未配置模块的页面代码(Tree Shaking 生效)
|
||||||
|
- [ ] 现有菜单 API 获取、权限控制、主题切换功能正常
|
||||||
|
- [ ] 开发模式 `pnpm dev:cashier` 正常工作,热更新无问题
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 四、风险与依赖
|
||||||
|
|
||||||
|
| 风险 | 影响 | 缓解措施 |
|
||||||
|
|------|------|---------|
|
||||||
|
| Vite 插件开发复杂度 | 中 | 插件逻辑清晰拆分:配置读取、路由生成、虚拟模块、输出配置 |
|
||||||
|
| Tree Shaking 不彻底 | 中 | 使用 `import()` 动态导入,配合 Rollup 的 `treeshake` 配置,构建后检查产物 |
|
||||||
|
| 动态组件加载失败 | 低 | 添加错误处理,加载失败时回退到 Default 组件 |
|
||||||
|
| 现有功能回归 | 中 | 构建后逐一验证核心功能:登录、菜单、CRUD、主题切换 |
|
||||||
|
| 多人协作冲突 | 低 | 配置文件集中管理,模块路由独立文件,减少冲突 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 五、后续扩展
|
||||||
|
|
||||||
|
1. **国际化支持**:配置文件中可扩展 `locales` 字段,支持系统特定的翻译覆盖
|
||||||
|
2. **模块懒加载**:未来可考虑运行时动态加载模块(Module Federation)
|
||||||
|
3. **版本管理**:配置文件支持 `version` 字段,用于产物版本控制
|
||||||
|
4. **CI/CD 集成**:构建命令可直接接入 Jenkins/GitHub Actions,参数化构建不同系统
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,268 @@
|
|||||||
|
# rui-admin 功能设计文档
|
||||||
|
|
||||||
|
## 1. 项目概述
|
||||||
|
|
||||||
|
rui-admin 是睿核通用平台框架的后台管理前端系统,基于 Vue 3 + Element Plus + UnoCSS 构建,提供完整的系统管理、用户管理、内容管理、订单管理、营销管理等功能。
|
||||||
|
|
||||||
|
## 2. 功能模块划分
|
||||||
|
|
||||||
|
### 2.1 系统管理(system)- 核心模块
|
||||||
|
|
||||||
|
| 功能 | 状态 | 后端API | 说明 |
|
||||||
|
|------|------|---------|------|
|
||||||
|
| 菜单管理 | ✅ 已完成 | SysMenuController | 树形结构、图标修复 |
|
||||||
|
| 角色管理 | ✅ 已完成 | SysRoleController | CRUD + 权限分配 |
|
||||||
|
| 部门管理 | ✅ 已完成 | SysDeptController | 树形表格 |
|
||||||
|
| 字典管理 | ✅ 已完成 | SysDictTypeController | 字典类型 + 字典项 |
|
||||||
|
| 参数配置 | ✅ 已完成 | SysConfigController | 系统参数维护 |
|
||||||
|
| 租户管理 | ✅ 已完成 | SysTenantController | 多租户管理 |
|
||||||
|
| **操作日志** | ⏳ 待开发 | 需新建 | 用户操作审计 |
|
||||||
|
| **登录日志** | ⏳ 待开发 | 需新建 | 登录行为记录 |
|
||||||
|
| **OAuth2客户端** | ⏳ 待开发 | SystemOAuth2ClientController | 客户端管理前端 |
|
||||||
|
|
||||||
|
### 2.2 用户中心(user)- 核心模块
|
||||||
|
|
||||||
|
| 功能 | 状态 | 后端API | 说明 |
|
||||||
|
|------|------|---------|------|
|
||||||
|
| 用户管理 | ✅ 已完成 | UserController | 用户CRUD |
|
||||||
|
| 用户等级 | ✅ 已完成 | UserLevelController | 等级体系管理 |
|
||||||
|
| **用户详情** | ⏳ 待开发 | UserDetailController | 用户详细信息 |
|
||||||
|
| **等级日志** | ⏳ 待开发 | UserLevelLogController | 等级变更记录 |
|
||||||
|
| **用户账户** | ⏳ 待开发 | 需评估 | 账户安全设置 |
|
||||||
|
| **用户地址** | ⏳ 待开发 | 需新建 | 收货地址管理 |
|
||||||
|
|
||||||
|
### 2.3 系统设置(settings)- 基础模块
|
||||||
|
|
||||||
|
| 功能 | 状态 | 后端API | 说明 |
|
||||||
|
|------|------|---------|------|
|
||||||
|
| **个人设置** | ⏳ 待开发 | 需评估 | 个人信息修改 |
|
||||||
|
| **系统设置** | ⏳ 待开发 | SysConfigController | 全局参数配置界面 |
|
||||||
|
| **密码修改** | ⏳ 待开发 | UserController | 修改登录密码 |
|
||||||
|
|
||||||
|
### 2.4 订单管理(order)- 业务模块
|
||||||
|
|
||||||
|
| 功能 | 状态 | 后端API | 说明 |
|
||||||
|
|------|------|---------|------|
|
||||||
|
| **订单列表** | ⏳ 预留 | 需新建服务 | 订单查询、状态管理 |
|
||||||
|
| **退款管理** | ⏳ 预留 | 需新建服务 | 退款申请处理 |
|
||||||
|
|
||||||
|
### 2.5 内容管理(cms)- 业务模块
|
||||||
|
|
||||||
|
| 功能 | 状态 | 后端API | 说明 |
|
||||||
|
|------|------|---------|------|
|
||||||
|
| **文章管理** | ⏳ 预留 | 需新建服务 | CMS文章CRUD |
|
||||||
|
| **分类管理** | ⏳ 预留 | 需新建服务 | 文章分类 |
|
||||||
|
| **轮播管理** | ⏳ 预留 | 需新建服务 | Banner管理 |
|
||||||
|
|
||||||
|
### 2.6 营销管理(marketing)- 业务模块
|
||||||
|
|
||||||
|
| 功能 | 状态 | 后端API | 说明 |
|
||||||
|
|------|------|---------|------|
|
||||||
|
| **优惠券** | ⏳ 预留 | 需新建服务 | 优惠券CRUD |
|
||||||
|
| **活动管理** | ⏳ 预留 | 需新建服务 | 营销活动 |
|
||||||
|
|
||||||
|
## 3. 开发优先级
|
||||||
|
|
||||||
|
### Phase 1:核心功能完善(立即开始)
|
||||||
|
|
||||||
|
1. **操作日志**(system/log)
|
||||||
|
- 后端:创建 OperLog 实体、Mapper、Service、Controller
|
||||||
|
- 前端:日志列表页、详情弹窗
|
||||||
|
- 优先级:🔴 高
|
||||||
|
|
||||||
|
2. **用户详情**(user/info/detail)
|
||||||
|
- 后端:UserDetailController 已有,补充前端
|
||||||
|
- 前端:用户详情查看/编辑
|
||||||
|
- 优先级:🔴 高
|
||||||
|
|
||||||
|
3. **等级日志**(user/level-log)
|
||||||
|
- 后端:UserLevelLogController 已有,补充前端
|
||||||
|
- 前端:等级变更记录列表
|
||||||
|
- 优先级:🟡 中
|
||||||
|
|
||||||
|
4. **系统设置**(settings)
|
||||||
|
- 后端:复用 SysConfigController
|
||||||
|
- 前端:参数配置界面(与 system/config 区别:更友好的展示)
|
||||||
|
- 优先级:🟡 中
|
||||||
|
|
||||||
|
### Phase 2:基础功能补充(近期)
|
||||||
|
|
||||||
|
5. **登录日志**(system/login-log)
|
||||||
|
- 后端:创建 LoginLog 实体、Mapper、Service、Controller
|
||||||
|
- 前端:登录记录列表
|
||||||
|
- 优先级:🟡 中
|
||||||
|
|
||||||
|
6. **OAuth2客户端管理**(system/client)
|
||||||
|
- 后端:SystemOAuth2ClientController 已有
|
||||||
|
- 前端:客户端CRUD
|
||||||
|
- 优先级:🟡 中
|
||||||
|
|
||||||
|
7. **个人中心**(profile)
|
||||||
|
- 后端:复用现有接口
|
||||||
|
- 前端:个人信息展示与修改
|
||||||
|
- 优先级:🟢 低
|
||||||
|
|
||||||
|
### Phase 3:业务模块(按需)
|
||||||
|
|
||||||
|
8. **订单管理** - 需新建 rui-service-order 服务
|
||||||
|
9. **CMS内容管理** - 需新建 rui-service-cms 服务
|
||||||
|
10. **营销管理** - 需新建 rui-service-marketing 服务
|
||||||
|
|
||||||
|
## 4. 技术规范
|
||||||
|
|
||||||
|
### 4.1 前端规范
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// 页面结构标准
|
||||||
|
views/
|
||||||
|
├── {module}/
|
||||||
|
│ ├── Index.vue # 列表页(必须)
|
||||||
|
│ ├── {Module}FormDialog.vue # 表单弹窗(新增/编辑)
|
||||||
|
│ └── {Module}DetailDialog.vue # 详情弹窗(可选)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.2 后端规范
|
||||||
|
|
||||||
|
```java
|
||||||
|
// Controller 标准结构
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/{模块}/admin/{功能}")
|
||||||
|
public class XxxController extends BaseController<IService, Entity> {
|
||||||
|
// 自动获得:page、list、getById、save、updateById、remove
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.3 API 路径规范
|
||||||
|
|
||||||
|
| 类型 | 路径前缀 | 示例 |
|
||||||
|
|------|---------|------|
|
||||||
|
| 对外管理 | `/{模块}/admin/{功能}` | `/system/admin/log` |
|
||||||
|
| 内部调用 | `/{模块}/inner/{功能}` | `/system/inner/client` |
|
||||||
|
| 对外入口 | `/{模块}/entry/{功能}` | `/auth/entry/login` |
|
||||||
|
|
||||||
|
## 5. 数据库设计(新增表)
|
||||||
|
|
||||||
|
### 5.1 操作日志表(rui_sys_oper_log)
|
||||||
|
|
||||||
|
```sql
|
||||||
|
CREATE TABLE rui_sys_oper_log (
|
||||||
|
id BIGINT NOT NULL,
|
||||||
|
tenant_id BIGINT NOT NULL DEFAULT 0,
|
||||||
|
oper_type TINYINT NOT NULL DEFAULT 1 COMMENT '操作类型 1:新增 2:修改 3:删除 4:查询 5:导出 6:登录 7:登出',
|
||||||
|
title VARCHAR(200) NOT NULL COMMENT '操作模块',
|
||||||
|
method VARCHAR(500) DEFAULT NULL COMMENT '请求方法',
|
||||||
|
request_url VARCHAR(500) DEFAULT NULL,
|
||||||
|
request_method VARCHAR(10) DEFAULT NULL COMMENT 'GET/POST/PUT/DELETE',
|
||||||
|
request_params TEXT DEFAULT NULL,
|
||||||
|
response_data TEXT DEFAULT NULL,
|
||||||
|
user_id BIGINT DEFAULT NULL,
|
||||||
|
user_name VARCHAR(100) DEFAULT NULL,
|
||||||
|
oper_ip VARCHAR(128) DEFAULT NULL,
|
||||||
|
oper_location VARCHAR(255) DEFAULT NULL,
|
||||||
|
status TINYINT NOT NULL DEFAULT 1 COMMENT '状态 0:失败 1:成功',
|
||||||
|
error_msg TEXT DEFAULT NULL,
|
||||||
|
cost_time BIGINT DEFAULT 0 COMMENT '耗时(ms)',
|
||||||
|
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||||
|
PRIMARY KEY (id),
|
||||||
|
INDEX idx_user (user_id),
|
||||||
|
INDEX idx_tenant (tenant_id),
|
||||||
|
INDEX idx_created (created_at)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='操作日志';
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5.2 登录日志表(rui_sys_login_log)
|
||||||
|
|
||||||
|
```sql
|
||||||
|
CREATE TABLE rui_sys_login_log (
|
||||||
|
id BIGINT NOT NULL,
|
||||||
|
tenant_id BIGINT NOT NULL DEFAULT 0,
|
||||||
|
user_id BIGINT DEFAULT NULL,
|
||||||
|
username VARCHAR(100) DEFAULT NULL,
|
||||||
|
login_type TINYINT NOT NULL DEFAULT 1 COMMENT '登录类型 1:密码 2:短信 3:微信',
|
||||||
|
client_id VARCHAR(100) DEFAULT NULL,
|
||||||
|
ip VARCHAR(128) DEFAULT NULL,
|
||||||
|
location VARCHAR(255) DEFAULT NULL,
|
||||||
|
browser VARCHAR(200) DEFAULT NULL,
|
||||||
|
os VARCHAR(200) DEFAULT NULL,
|
||||||
|
status TINYINT NOT NULL DEFAULT 1 COMMENT '状态 0:失败 1:成功',
|
||||||
|
msg VARCHAR(500) DEFAULT NULL,
|
||||||
|
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
||||||
|
PRIMARY KEY (id),
|
||||||
|
INDEX idx_user (user_id),
|
||||||
|
INDEX idx_tenant (tenant_id),
|
||||||
|
INDEX idx_created (created_at)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='登录日志';
|
||||||
|
```
|
||||||
|
|
||||||
|
## 6. 实施计划
|
||||||
|
|
||||||
|
### 第1周:Phase 1 核心功能
|
||||||
|
- [ ] 后端:操作日志 AOP 拦截 + API
|
||||||
|
- [ ] 前端:system/log 页面
|
||||||
|
- [ ] 前端:user/info 详情弹窗
|
||||||
|
- [ ] 前端:user/level-log 页面
|
||||||
|
|
||||||
|
### 第2周:Phase 2 基础功能
|
||||||
|
- [ ] 后端:登录日志 API
|
||||||
|
- [ ] 前端:system/login-log 页面
|
||||||
|
- [ ] 前端:settings 系统设置页
|
||||||
|
- [ ] 前端:profile 个人中心
|
||||||
|
|
||||||
|
### 第3周+:Phase 3 业务模块(按需)
|
||||||
|
- [ ] 订单服务 + 前端页面
|
||||||
|
- [ ] CMS服务 + 前端页面
|
||||||
|
- [ ] 营销服务 + 前端页面
|
||||||
|
|
||||||
|
## 7. 前端组件规划
|
||||||
|
|
||||||
|
### 7.1 复用组件
|
||||||
|
|
||||||
|
| 组件 | 用途 | 位置 |
|
||||||
|
|------|------|------|
|
||||||
|
| RuiTable | 通用表格 | components/RuiTable.vue |
|
||||||
|
| RuiIcon | 图标渲染 | components/RuiIcon.vue |
|
||||||
|
| IconPicker | 图标选择 | components/IconPicker.vue |
|
||||||
|
|
||||||
|
### 7.2 新增组件需求
|
||||||
|
|
||||||
|
| 组件 | 用途 | 优先级 |
|
||||||
|
|------|------|--------|
|
||||||
|
| LogDetailDialog | 日志详情展示 | 🔴 高 |
|
||||||
|
| UserDetailPanel | 用户信息卡片 | 🔴 高 |
|
||||||
|
| ConfigGroupPanel | 配置分组展示 | 🟡 中 |
|
||||||
|
|
||||||
|
## 8. 权限设计
|
||||||
|
|
||||||
|
### 8.1 菜单权限
|
||||||
|
|
||||||
|
```
|
||||||
|
system:menu:list - 菜单列表
|
||||||
|
system:menu:add - 新增菜单
|
||||||
|
system:menu:edit - 编辑菜单
|
||||||
|
system:menu:remove - 删除菜单
|
||||||
|
system:log:list - 日志列表
|
||||||
|
system:log:remove - 删除日志
|
||||||
|
```
|
||||||
|
|
||||||
|
### 8.2 数据权限
|
||||||
|
|
||||||
|
- 超级管理员:查看所有租户数据
|
||||||
|
- 租户管理员:仅查看本租户数据
|
||||||
|
- 普通用户:仅查看个人数据
|
||||||
|
|
||||||
|
## 9. 注意事项
|
||||||
|
|
||||||
|
1. **操作日志性能**:大量操作日志可能影响性能,建议:
|
||||||
|
- 异步写入(MQ或线程池)
|
||||||
|
- 定期归档(30天前的日志迁移到历史表)
|
||||||
|
- 提供日志清理功能
|
||||||
|
|
||||||
|
2. **登录日志安全**:
|
||||||
|
- 记录失败登录尝试,用于安全审计
|
||||||
|
- 支持 IP 黑名单
|
||||||
|
- 异常登录告警
|
||||||
|
|
||||||
|
3. **预留模块**:
|
||||||
|
- order/cms/marketing 为业务预留模块
|
||||||
|
- 需要时创建对应后端服务
|
||||||
|
- 前端页面保持占位状态即可
|
||||||
File diff suppressed because it is too large
Load Diff
+2
-2
@@ -7,10 +7,10 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"dev:admin": "pnpm --filter admin-ui dev",
|
"dev:admin": "pnpm --filter admin-ui dev",
|
||||||
"dev:cashier": "pnpm --filter cashier-mobile dev",
|
"dev:cashier": "pnpm --filter cashier-mobile dev",
|
||||||
"dev:customer": "pnpm --filter customer-mobile dev",
|
"dev:cashier-customer": "pnpm --filter cashier-customer dev",
|
||||||
"build:admin": "pnpm --filter admin-ui build",
|
"build:admin": "pnpm --filter admin-ui build",
|
||||||
"build:cashier": "pnpm --filter cashier-mobile build",
|
"build:cashier": "pnpm --filter cashier-mobile build",
|
||||||
"build:customer": "pnpm --filter customer-mobile build",
|
"build:cashier-customer": "pnpm --filter cashier-customer build",
|
||||||
"build:all": "pnpm -r build",
|
"build:all": "pnpm -r build",
|
||||||
"lint": "pnpm -r lint",
|
"lint": "pnpm -r lint",
|
||||||
"type-check": "pnpm -r type-check"
|
"type-check": "pnpm -r type-check"
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
packages:
|
packages:
|
||||||
- 'admin-ui'
|
- 'admin-ui'
|
||||||
- 'cashier-mobile'
|
- 'cashier-mobile'
|
||||||
- 'customer-mobile'
|
- 'cashier-customer'
|
||||||
|
|||||||
@@ -0,0 +1,505 @@
|
|||||||
|
# API 设计规范
|
||||||
|
|
||||||
|
> 睿核科技通用平台框架 RESTful API 统一设计标准
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 一、接口分类
|
||||||
|
|
||||||
|
| 分类 | 路径前缀 | 认证 | 说明 |
|
||||||
|
|------|---------|------|------|
|
||||||
|
| **对外接口** | `/{模块}/api/**` | OAuth2 Token | 对外提供的业务接口 |
|
||||||
|
| **内部接口** | `/{模块}/inner/**` | `@Inner` + `INTERNAL_REQUEST` | 微服务间 Feign 调用 |
|
||||||
|
| **入口接口** | `/{模块}/entry/**` | 无需认证 | 对外入口(登录、注册) |
|
||||||
|
| **回调接口** | `/{模块}/notify/**` | 无需认证 | 第三方回调(支付、Webhook) |
|
||||||
|
| **管理接口** | `/{模块}/admin/**` | 需管理员权限 | 后台管理 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 二、URL 设计规范
|
||||||
|
|
||||||
|
### 2.1 对外接口(RESTful)
|
||||||
|
|
||||||
|
```
|
||||||
|
GET /{version}/{模块}/{资源} # 列表查询
|
||||||
|
GET /{version}/{模块}/{资源}/{id} # 详情查询
|
||||||
|
POST /{version}/{模块}/{资源} # 新增
|
||||||
|
PUT /{version}/{模块}/{资源}/{id} # 全量更新
|
||||||
|
PATCH /{version}/{模块}/{资源}/{id} # 局部更新
|
||||||
|
DELETE /{version}/{模块}/{资源}/{id} # 删除
|
||||||
|
```
|
||||||
|
|
||||||
|
**示例**:
|
||||||
|
```
|
||||||
|
GET /v1/user/users?page=1&size=10 # 查询用户列表
|
||||||
|
GET /v1/user/users/1001 # 查询用户详情
|
||||||
|
POST /v1/user/users # 新增用户
|
||||||
|
PUT /v1/user/users/1001 # 全量更新用户
|
||||||
|
PATCH /v1/user/users/1001 # 局部更新(如只改状态)
|
||||||
|
DELETE /v1/user/users/1001 # 删除用户
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.2 内部接口(Feign)
|
||||||
|
|
||||||
|
```
|
||||||
|
GET /{模块}/inner/{功能}/{方法}
|
||||||
|
```
|
||||||
|
|
||||||
|
**示例**:
|
||||||
|
```
|
||||||
|
GET /user/inner/auth/loadByUsername/{username}
|
||||||
|
GET /system/inner/client/getById/{clientId}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.3 版本控制
|
||||||
|
|
||||||
|
- **URI 版本**(推荐):`/v1/user/users`
|
||||||
|
- **Header 版本**(可选):`Accept: application/vnd.rui.v1+json`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 三、请求规范
|
||||||
|
|
||||||
|
### 3.1 HTTP 方法
|
||||||
|
|
||||||
|
| 方法 | 用途 | 幂等性 |
|
||||||
|
|------|------|--------|
|
||||||
|
| GET | 查询 | ✅ |
|
||||||
|
| POST | 新增/提交 | ❌ |
|
||||||
|
| PUT | 全量更新 | ✅ |
|
||||||
|
| PATCH | 局部更新 | ❌ |
|
||||||
|
| DELETE | 删除 | ✅ |
|
||||||
|
|
||||||
|
### 3.2 Content-Type
|
||||||
|
|
||||||
|
```
|
||||||
|
Content-Type: application/json; charset=utf-8
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.3 请求头规范
|
||||||
|
|
||||||
|
| Header | 必填 | 说明 |
|
||||||
|
|--------|------|------|
|
||||||
|
| Authorization | 是(除 entry/notify) | `Bearer {access_token}` |
|
||||||
|
| Content-Type | 是 | `application/json` |
|
||||||
|
| X-Request-Id | 否 | 请求追踪 ID(网关自动生成) |
|
||||||
|
| X-Tenant-Id | 否 | 租户 ID(后端自动注入) |
|
||||||
|
| Accept-Language | 否 | 语言偏好 `zh-CN` / `en-US` |
|
||||||
|
|
||||||
|
### 3.4 分页参数
|
||||||
|
|
||||||
|
```
|
||||||
|
GET /v1/user/users?page=1&size=10&sort=createdAt,desc
|
||||||
|
```
|
||||||
|
|
||||||
|
| 参数 | 类型 | 默认值 | 说明 |
|
||||||
|
|------|------|--------|------|
|
||||||
|
| page | int | 1 | 当前页码(从1开始) |
|
||||||
|
| size | int | 10 | 每页条数(最大100) |
|
||||||
|
| sort | string | createdAt,desc | 排序字段和方向 |
|
||||||
|
|
||||||
|
### 3.5 查询参数
|
||||||
|
|
||||||
|
```
|
||||||
|
GET /v1/user/users?username=admin&status=1&createdAt_start=2024-01-01&createdAt_end=2024-12-31
|
||||||
|
```
|
||||||
|
|
||||||
|
**规则**:
|
||||||
|
- 精确匹配:字段名直接等于值 `status=1`
|
||||||
|
- 模糊匹配:字段名加后缀 `_like` `username_like=admin`
|
||||||
|
- 范围查询:字段名加后缀 `_start` / `_end` `createdAt_start=2024-01-01`
|
||||||
|
- 多值查询:字段名加后缀 `_in` `status_in=1,2`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 四、响应规范
|
||||||
|
|
||||||
|
### 4.1 统一响应格式
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"msg": "操作成功",
|
||||||
|
"data": {}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.2 分页响应格式
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"msg": "操作成功",
|
||||||
|
"data": {
|
||||||
|
"records": [],
|
||||||
|
"total": 100,
|
||||||
|
"size": 10,
|
||||||
|
"current": 1,
|
||||||
|
"pages": 10
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.3 HTTP 状态码
|
||||||
|
|
||||||
|
| 状态码 | 含义 | 使用场景 |
|
||||||
|
|--------|------|---------|
|
||||||
|
| 200 | OK | 查询成功、更新成功 |
|
||||||
|
| 201 | Created | 新增成功 |
|
||||||
|
| 204 | No Content | 删除成功(无返回体) |
|
||||||
|
| 400 | Bad Request | 参数校验失败 |
|
||||||
|
| 401 | Unauthorized | 未登录/Token 过期 |
|
||||||
|
| 403 | Forbidden | 无权限访问 |
|
||||||
|
| 404 | Not Found | 资源不存在 |
|
||||||
|
| 409 | Conflict | 资源冲突(如重复提交) |
|
||||||
|
| 429 | Too Many Requests | 请求过于频繁 |
|
||||||
|
| 500 | Internal Server Error | 服务器内部错误 |
|
||||||
|
|
||||||
|
### 4.4 错误码规范
|
||||||
|
|
||||||
|
| 区间 | 模块 | 示例 |
|
||||||
|
|------|------|------|
|
||||||
|
| 1000-1999 | 通用 | 1001: 参数校验失败, 1002: 资源不存在 |
|
||||||
|
| 2000-2999 | 用户模块 | 2001: 用户名已存在, 2002: 密码错误 |
|
||||||
|
| 3000-3999 | 系统模块 | 3001: 字典不存在, 3002: 配置错误 |
|
||||||
|
| 4000-4999 | 认证模块 | 4001: Token 过期, 4002: 无权访问 |
|
||||||
|
| 5000-5999 | 文件模块 | 5001: 上传失败, 5002: 文件过大 |
|
||||||
|
| 6000-6999 | 消息模块 | 6001: 发送失败, 6002: 模板不存在 |
|
||||||
|
|
||||||
|
**错误响应示例**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 2001,
|
||||||
|
"msg": "用户名已存在",
|
||||||
|
"data": null
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 五、Controller 命名与路径映射
|
||||||
|
|
||||||
|
### 5.1 命名规则
|
||||||
|
|
||||||
|
| 类型 | Controller 命名 | 路径 | 说明 |
|
||||||
|
|------|----------------|------|------|
|
||||||
|
| 对外业务 | `UserController` | `/v1/user/users/**` | 常规 CRUD |
|
||||||
|
| 内部调用 | `UserInnerController` | `/user/inner/**` | Feign 调用 |
|
||||||
|
| 对外入口 | `UserEntryController` | `/user/entry/**` | 免认证入口 |
|
||||||
|
| 第三方回调 | `PayNotifyController` | `/pay/notify/**` | Webhook |
|
||||||
|
| 后台管理 | `UserAdminController` | `/v1/user/admin/**` | 管理接口 |
|
||||||
|
|
||||||
|
### 5.2 方法命名
|
||||||
|
|
||||||
|
| 操作 | 方法名 | HTTP | 路径 |
|
||||||
|
|------|--------|------|------|
|
||||||
|
| 列表 | `list` / `page` | GET | `/{资源}` |
|
||||||
|
| 详情 | `getById` | GET | `/{资源}/{id}` |
|
||||||
|
| 新增 | `add` / `save` | POST | `/{资源}` |
|
||||||
|
| 更新 | `update` / `edit` | PUT | `/{资源}/{id}` |
|
||||||
|
| 局部更新 | `patch` | PATCH | `/{资源}/{id}` |
|
||||||
|
| 删除 | `remove` / `delete` | DELETE | `/{资源}/{id}` |
|
||||||
|
| 批量删除 | `batchRemove` | DELETE | `/{资源}/batch` |
|
||||||
|
| 导出 | `export` | GET | `/{资源}/export` |
|
||||||
|
| 导入 | `import` | POST | `/{资源}/import` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 六、Swagger 注解规范
|
||||||
|
|
||||||
|
### 6.1 Controller 注解
|
||||||
|
|
||||||
|
```java
|
||||||
|
@Tag(name = "用户管理", description = "用户相关接口")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/v1/user/users")
|
||||||
|
public class UserController {
|
||||||
|
|
||||||
|
@Operation(summary = "查询用户列表", description = "支持分页、排序、条件查询")
|
||||||
|
@GetMapping
|
||||||
|
public Result<PageResult<UserVO>> list(
|
||||||
|
@Parameter(description = "页码") @RequestParam(defaultValue = "1") Integer page,
|
||||||
|
@Parameter(description = "每页条数") @RequestParam(defaultValue = "10") Integer size) {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "新增用户")
|
||||||
|
@PostMapping
|
||||||
|
public Result<Long> add(@RequestBody @Valid UserDTO dto) {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 6.2 DTO / VO 注解
|
||||||
|
|
||||||
|
```java
|
||||||
|
@Schema(description = "用户新增DTO")
|
||||||
|
@Data
|
||||||
|
public class UserDTO {
|
||||||
|
|
||||||
|
@Schema(description = "用户名", requiredMode = Schema.RequiredMode.REQUIRED, example = "admin")
|
||||||
|
@NotBlank(message = "用户名不能为空")
|
||||||
|
@Size(min = 2, max = 50, message = "用户名长度2-50字符")
|
||||||
|
private String username;
|
||||||
|
|
||||||
|
@Schema(description = "状态 0:禁用 1:启用", example = "1")
|
||||||
|
private Integer status;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 七、数据校验规范
|
||||||
|
|
||||||
|
### 7.1 分组校验
|
||||||
|
|
||||||
|
```java
|
||||||
|
public interface AddGroup {} // 新增分组
|
||||||
|
public interface UpdateGroup {} // 更新分组
|
||||||
|
```
|
||||||
|
|
||||||
|
### 7.2 使用示例
|
||||||
|
|
||||||
|
```java
|
||||||
|
@Data
|
||||||
|
public class UserDTO {
|
||||||
|
|
||||||
|
@NotNull(message = "ID不能为空", groups = UpdateGroup.class)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@NotBlank(message = "用户名不能为空", groups = {AddGroup.class, UpdateGroup.class})
|
||||||
|
private String username;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Controller
|
||||||
|
@PostMapping
|
||||||
|
public Result<Long> add(@RequestBody @Validated(AddGroup.class) UserDTO dto) {
|
||||||
|
// 新增
|
||||||
|
}
|
||||||
|
|
||||||
|
@PutMapping("/{id}")
|
||||||
|
public Result<Void> update(@RequestBody @Validated(UpdateGroup.class) UserDTO dto) {
|
||||||
|
// 更新
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 八、Feign 接口规范
|
||||||
|
|
||||||
|
### 8.1 接口定义
|
||||||
|
|
||||||
|
```java
|
||||||
|
/**
|
||||||
|
* 远程用户服务
|
||||||
|
*/
|
||||||
|
@Headers("INTERNAL_REQUEST: INTERNAL")
|
||||||
|
@FeignClient(
|
||||||
|
contextId = "remoteUserService",
|
||||||
|
value = "${feign.providers.user:rui-service-user}",
|
||||||
|
path = "/user/inner"
|
||||||
|
)
|
||||||
|
public interface RemoteUserService {
|
||||||
|
|
||||||
|
@GetMapping("/auth/loadByUsername/{username}")
|
||||||
|
Result<Map<String, Object>> loadUser(@PathVariable String username);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 8.2 调用规范
|
||||||
|
|
||||||
|
```java
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class UserRemoteService {
|
||||||
|
|
||||||
|
private final RemoteUserService remoteUserService;
|
||||||
|
|
||||||
|
public UserVO getUserById(Long userId) {
|
||||||
|
Result<UserVO> result = remoteUserService.getById(userId);
|
||||||
|
if (result.isSuccess()) {
|
||||||
|
return result.getData();
|
||||||
|
}
|
||||||
|
throw new BizException(result.getCode(), result.getMsg());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 九、文件上传接口规范
|
||||||
|
|
||||||
|
### 9.1 单文件上传
|
||||||
|
|
||||||
|
```
|
||||||
|
POST /v1/file/files/upload
|
||||||
|
Content-Type: multipart/form-data
|
||||||
|
|
||||||
|
file: [二进制文件]
|
||||||
|
module: user
|
||||||
|
bizId: 1001
|
||||||
|
```
|
||||||
|
|
||||||
|
**响应**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"msg": "上传成功",
|
||||||
|
"data": {
|
||||||
|
"fileId": "123456",
|
||||||
|
"fileName": "avatar.jpg",
|
||||||
|
"fileUrl": "https://oss.example.com/avatar/123456.jpg",
|
||||||
|
"fileSize": 102400
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 9.2 多文件上传
|
||||||
|
|
||||||
|
```
|
||||||
|
POST /v1/file/files/batchUpload
|
||||||
|
Content-Type: multipart/form-data
|
||||||
|
|
||||||
|
files: [文件1, 文件2, 文件3]
|
||||||
|
module: user
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 十、导出接口规范
|
||||||
|
|
||||||
|
### 10.1 Excel 导出
|
||||||
|
|
||||||
|
```
|
||||||
|
GET /v1/user/users/export?username=admin&status=1
|
||||||
|
Accept: application/vnd.ms-excel
|
||||||
|
```
|
||||||
|
|
||||||
|
**响应**:
|
||||||
|
```
|
||||||
|
Content-Type: application/vnd.ms-excel
|
||||||
|
Content-Disposition: attachment; filename="用户列表_20240101.xlsx"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 10.2 CSV 导出
|
||||||
|
|
||||||
|
```
|
||||||
|
GET /v1/user/users/export?format=csv
|
||||||
|
Accept: text/csv
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 十一、WebSocket 接口规范(预留)
|
||||||
|
|
||||||
|
```
|
||||||
|
ws://gateway:9300/ws/{模块}/{topic}
|
||||||
|
```
|
||||||
|
|
||||||
|
**示例**:
|
||||||
|
```
|
||||||
|
ws://localhost:9300/ws/msg/notification # 消息通知
|
||||||
|
ws://localhost:9300/ws/monitor/metrics # 实时监控
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 十二、接口文档生成
|
||||||
|
|
||||||
|
### 12.1 配置 SpringDoc
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
springdoc:
|
||||||
|
swagger-ui:
|
||||||
|
path: /swagger-ui.html
|
||||||
|
enabled: true
|
||||||
|
api-docs:
|
||||||
|
path: /v3/api-docs
|
||||||
|
enabled: true
|
||||||
|
group-configs:
|
||||||
|
- group: 用户服务
|
||||||
|
display-name: 用户服务 API
|
||||||
|
paths-to-match: /v1/user/**
|
||||||
|
- group: 系统服务
|
||||||
|
display-name: 系统服务 API
|
||||||
|
paths-to-match: /v1/system/**
|
||||||
|
```
|
||||||
|
|
||||||
|
### 12.2 访问地址
|
||||||
|
|
||||||
|
```
|
||||||
|
http://localhost:9300/swagger-ui.html # 网关聚合文档
|
||||||
|
http://localhost:9301/swagger-ui.html # 认证服务文档
|
||||||
|
http://localhost:9302/swagger-ui.html # 系统服务文档
|
||||||
|
http://localhost:9303/swagger-ui.html # 用户服务文档
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 十三、Postman / APIFox 集合规范
|
||||||
|
|
||||||
|
### 13.1 目录结构
|
||||||
|
|
||||||
|
```
|
||||||
|
睿核科技通用平台
|
||||||
|
├── 01-认证中心
|
||||||
|
│ ├── 获取Token
|
||||||
|
│ ├── 刷新Token
|
||||||
|
│ └── 退出登录
|
||||||
|
├── 02-用户中心
|
||||||
|
│ ├── 用户管理
|
||||||
|
│ ├── 等级管理
|
||||||
|
│ └── 用户查询
|
||||||
|
├── 03-系统管理
|
||||||
|
│ ├── 租户管理
|
||||||
|
│ ├── 菜单管理
|
||||||
|
│ ├── 角色管理
|
||||||
|
│ ├── 字典管理
|
||||||
|
│ └── 参数配置
|
||||||
|
├── 04-文件管理
|
||||||
|
│ ├── 文件上传
|
||||||
|
│ └── 文件下载
|
||||||
|
└── 99-内部接口(Feign)
|
||||||
|
├── 用户服务
|
||||||
|
└── 系统服务
|
||||||
|
```
|
||||||
|
|
||||||
|
### 13.2 环境变量
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"baseUrl": "http://localhost:9300",
|
||||||
|
"token": "{{login_response_token}}",
|
||||||
|
"tenantId": "1"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 十四、接口变更管理
|
||||||
|
|
||||||
|
### 14.1 变更类型
|
||||||
|
|
||||||
|
| 类型 | 说明 | 版本处理 |
|
||||||
|
|------|------|---------|
|
||||||
|
| 新增接口 | 新增资源/功能 | 当前版本可用 |
|
||||||
|
| 新增字段 | 请求/响应增加字段 | 当前版本可用(兼容) |
|
||||||
|
| 废弃字段 | 字段标记 deprecated | 当前版本可用,下版本移除 |
|
||||||
|
| 废弃接口 | 接口标记 deprecated | 保留至少2个版本后移除 |
|
||||||
|
| 破坏性变更 | 字段删除/类型变更 | 升级版本号(v1 → v2) |
|
||||||
|
|
||||||
|
### 14.2 版本迭代策略
|
||||||
|
|
||||||
|
```
|
||||||
|
v1.0 —— 初始版本
|
||||||
|
v1.1 —— 新增字段(兼容)
|
||||||
|
v1.2 —— 新增接口(兼容)
|
||||||
|
v2.0 —— 破坏性变更(不兼容)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
> **文档版本**: v1.0
|
||||||
|
> **创建日期**: 2026-05-28
|
||||||
|
> **适用范围**: 睿核科技通用平台框架所有 RESTful API
|
||||||
@@ -0,0 +1,280 @@
|
|||||||
|
# 编码规范
|
||||||
|
|
||||||
|
## 🎯 通用原则
|
||||||
|
|
||||||
|
1. **可读性优先** - 代码是写给人看的,顺便给机器执行
|
||||||
|
2. **DRY 原则** - Don't Repeat Yourself
|
||||||
|
3. **单一职责** - 一个类/方法只做一件事
|
||||||
|
4. **开闭原则** - 对扩展开放,对修改关闭
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📝 Java 编码规范
|
||||||
|
|
||||||
|
### 命名规范
|
||||||
|
|
||||||
|
| 类型 | 规范 | 示例 |
|
||||||
|
|------|------|------|
|
||||||
|
| 类名 | 大驼峰 | `UserService`, `OrderController` |
|
||||||
|
| 方法名 | 小驼峰 | `getUserById()`, `createOrder()` |
|
||||||
|
| 变量名 | 小驼峰 | `userName`, `orderList` |
|
||||||
|
| 常量 | 全大写下划线 | `MAX_RETRY_COUNT`, `DEFAULT_TIMEOUT` |
|
||||||
|
| 包名 | 全小写 | `com.rui.service.user` |
|
||||||
|
|
||||||
|
### 代码格式
|
||||||
|
|
||||||
|
```java
|
||||||
|
// 正确的类定义
|
||||||
|
@Service
|
||||||
|
public class UserServiceImpl implements IUserService {
|
||||||
|
|
||||||
|
private final UserMapper userMapper;
|
||||||
|
private final RedisUtil redisUtil;
|
||||||
|
|
||||||
|
// 构造器注入(推荐)
|
||||||
|
public UserServiceImpl(UserMapper userMapper, RedisUtil redisUtil) {
|
||||||
|
this.userMapper = userMapper;
|
||||||
|
this.redisUtil = redisUtil;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 方法注释
|
||||||
|
/**
|
||||||
|
* 根据ID获取用户信息
|
||||||
|
* @param userId 用户ID
|
||||||
|
* @return 用户信息
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public UserDTO getUserById(Long userId) {
|
||||||
|
// 先查缓存
|
||||||
|
UserDTO user = redisUtil.get("user:" + userId);
|
||||||
|
if (user != null) {
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 再查数据库
|
||||||
|
User entity = userMapper.selectById(userId);
|
||||||
|
if (entity == null) {
|
||||||
|
throw new BizException("用户不存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 转换并缓存
|
||||||
|
user = convertToDTO(entity);
|
||||||
|
redisUtil.set("user:" + userId, user, 3600);
|
||||||
|
|
||||||
|
return user;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 注释规范
|
||||||
|
|
||||||
|
```java
|
||||||
|
/**
|
||||||
|
* 用户服务实现类
|
||||||
|
*
|
||||||
|
* @author pigeon
|
||||||
|
* @since 2024-01-01
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class UserServiceImpl {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取用户详情
|
||||||
|
*
|
||||||
|
* @param userId 用户ID,不能为空
|
||||||
|
* @return 用户详情DTO
|
||||||
|
* @throws BizException 用户不存在时抛出
|
||||||
|
*/
|
||||||
|
public UserDetailDTO getDetail(Long userId) {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🌐 TypeScript/Vue 编码规范
|
||||||
|
|
||||||
|
### 命名规范
|
||||||
|
|
||||||
|
| 类型 | 规范 | 示例 |
|
||||||
|
|------|------|------|
|
||||||
|
| 组件名 | 大驼峰 | `UserTable.vue`, `OrderForm.vue` |
|
||||||
|
| 组合式函数 | use前缀 | `useUser()`, `useOrder()` |
|
||||||
|
| 类型定义 | 大驼峰 | `UserDTO`, `OrderFormData` |
|
||||||
|
| 常量 | 全大写下划线 | `API_BASE_URL`, `PAGE_SIZE` |
|
||||||
|
| 变量/函数 | 小驼峰 | `userList`, `getUserList()` |
|
||||||
|
|
||||||
|
### 组件规范
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<script setup lang="ts">
|
||||||
|
/**
|
||||||
|
* 用户管理组件
|
||||||
|
*
|
||||||
|
* @description 展示用户列表,支持增删改查
|
||||||
|
* @author pigeon
|
||||||
|
*/
|
||||||
|
import { ref, onMounted } from 'vue'
|
||||||
|
import type { UserDTO } from '@/types'
|
||||||
|
|
||||||
|
// Props 定义
|
||||||
|
interface Props {
|
||||||
|
deptId?: number
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
|
deptId: undefined
|
||||||
|
})
|
||||||
|
|
||||||
|
// Emits 定义
|
||||||
|
const emit = defineEmits<{
|
||||||
|
refresh: []
|
||||||
|
}>()
|
||||||
|
|
||||||
|
// 响应式数据
|
||||||
|
const userList = ref<UserDTO[]>([])
|
||||||
|
const loading = ref(false)
|
||||||
|
|
||||||
|
// 方法
|
||||||
|
async function loadUserList() {
|
||||||
|
loading.value = true
|
||||||
|
try {
|
||||||
|
const res = await userApi.getList({ deptId: props.deptId })
|
||||||
|
userList.value = res.data
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生命周期
|
||||||
|
onMounted(() => {
|
||||||
|
loadUserList()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🗄️ 数据库规范
|
||||||
|
|
||||||
|
### 命名规范
|
||||||
|
|
||||||
|
| 类型 | 规范 | 示例 |
|
||||||
|
|------|------|------|
|
||||||
|
| 表名 | 下划线、复数 | `sys_user`, `cashier_order` |
|
||||||
|
| 字段名 | 下划线 | `user_name`, `created_at` |
|
||||||
|
| 索引名 | idx_前缀 | `idx_user_name` |
|
||||||
|
| 外键 | fk_前缀 | `fk_order_user` |
|
||||||
|
|
||||||
|
### 必备字段
|
||||||
|
|
||||||
|
```sql
|
||||||
|
-- 所有表必须包含以下字段
|
||||||
|
CREATE TABLE example_table (
|
||||||
|
id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '主键ID',
|
||||||
|
-- 业务字段
|
||||||
|
name VARCHAR(100) NOT NULL COMMENT '名称',
|
||||||
|
|
||||||
|
-- 审计字段(由框架自动填充)
|
||||||
|
create_by VARCHAR(64) COMMENT '创建者',
|
||||||
|
create_time DATETIME COMMENT '创建时间',
|
||||||
|
update_by VARCHAR(64) COMMENT '更新者',
|
||||||
|
update_time DATETIME COMMENT '更新时间',
|
||||||
|
deleted TINYINT DEFAULT 0 COMMENT '删除标志(0-正常,1-删除)',
|
||||||
|
tenant_id BIGINT COMMENT '租户ID',
|
||||||
|
|
||||||
|
-- 索引
|
||||||
|
INDEX idx_name (name)
|
||||||
|
) COMMENT='示例表';
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔒 安全规范
|
||||||
|
|
||||||
|
1. **SQL 注入防护** - 使用 MyBatis 参数绑定,禁止字符串拼接 SQL
|
||||||
|
2. **XSS 防护** - 前端转义输出,后端校验输入
|
||||||
|
3. **敏感信息** - 密码必须加密存储,日志中禁止输出敏感信息
|
||||||
|
4. **接口鉴权** - 所有接口必须校验权限(白名单除外)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🧪 测试规范
|
||||||
|
|
||||||
|
### Java 测试
|
||||||
|
|
||||||
|
```java
|
||||||
|
@SpringBootTest
|
||||||
|
class UserServiceTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IUserService userService;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("根据ID查询用户-正常情况")
|
||||||
|
void getUserById_Success() {
|
||||||
|
// Given
|
||||||
|
Long userId = 1L;
|
||||||
|
|
||||||
|
// When
|
||||||
|
UserDTO user = userService.getUserById(userId);
|
||||||
|
|
||||||
|
// Then
|
||||||
|
assertThat(user).isNotNull();
|
||||||
|
assertThat(user.getId()).isEqualTo(userId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@DisplayName("根据ID查询用户-用户不存在")
|
||||||
|
void getUserById_NotFound() {
|
||||||
|
// Given
|
||||||
|
Long userId = 999L;
|
||||||
|
|
||||||
|
// Then
|
||||||
|
assertThrows(BizException.class, () -> {
|
||||||
|
userService.getUserById(userId);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📝 Git 提交规范
|
||||||
|
|
||||||
|
```
|
||||||
|
<type>(<scope>): <subject>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<footer>
|
||||||
|
```
|
||||||
|
|
||||||
|
### Type 类型
|
||||||
|
|
||||||
|
| 类型 | 说明 |
|
||||||
|
|------|------|
|
||||||
|
| feat | 新功能 |
|
||||||
|
| fix | 修复 bug |
|
||||||
|
| docs | 文档更新 |
|
||||||
|
| style | 代码格式(不影响功能) |
|
||||||
|
| refactor | 重构 |
|
||||||
|
| test | 测试相关 |
|
||||||
|
| chore | 构建/工具相关 |
|
||||||
|
|
||||||
|
### 示例
|
||||||
|
|
||||||
|
```bash
|
||||||
|
feat(cashier): 添加订单退款功能
|
||||||
|
|
||||||
|
- 支持部分退款
|
||||||
|
- 支持原路退回
|
||||||
|
- 添加退款记录表
|
||||||
|
|
||||||
|
Closes #123
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
> **最后提醒**:编码规范是为了团队协作,请务必遵守!
|
||||||
@@ -0,0 +1,111 @@
|
|||||||
|
# 前端开发规则
|
||||||
|
|
||||||
|
> 适用于 {root} 仓库下所有前端工程
|
||||||
|
|
||||||
|
## 技术栈
|
||||||
|
|
||||||
|
| 场景 | 框架 | UI 库 | CSS |
|
||||||
|
|------|------|------|-----|
|
||||||
|
| **管理后台 PC** | Vue 3 + TypeScript + Vite | Element Plus | UnoCSS |
|
||||||
|
| **移动端/小程序** | uniapp (Vue 3) + TypeScript | uView Plus | UnoCSS |
|
||||||
|
| **H5 官网** | Vue 3 + TypeScript + Vite | — | UnoCSS |
|
||||||
|
|
||||||
|
## 统一规范
|
||||||
|
|
||||||
|
### 必选
|
||||||
|
|
||||||
|
- **Vue 3** Composition API(`<script setup lang="ts">`)
|
||||||
|
- **TypeScript** 严格模式
|
||||||
|
- **UnoCSS** 原子化 CSS(替代 Tailwind / 手写 CSS)
|
||||||
|
- **pnpm** 包管理器
|
||||||
|
- **ESLint** + `@antfu/eslint-config`
|
||||||
|
- **Vite** 构建工具
|
||||||
|
|
||||||
|
### 推荐
|
||||||
|
|
||||||
|
- **Pinia** 状态管理
|
||||||
|
- **Vue Router** 路由
|
||||||
|
- **Axios** HTTP 请求(统一拦截器 + Token 刷新)
|
||||||
|
- **unplugin-auto-import** 自动导入 Vue/API
|
||||||
|
- **unplugin-vue-components** 自动导入组件
|
||||||
|
- **Vitest** 单元测试
|
||||||
|
|
||||||
|
### 禁止
|
||||||
|
|
||||||
|
- Vue 2 / Options API
|
||||||
|
- JavaScript(必须 TS)
|
||||||
|
- CSS 文件(使用 UnoCSS 原子类)
|
||||||
|
- npm/yarn(必须 pnpm)
|
||||||
|
- 多行 CSS 样式块(用 UnoCSS 属性化或原子类替代)
|
||||||
|
|
||||||
|
## 项目结构
|
||||||
|
|
||||||
|
```
|
||||||
|
admin-ui/(或 web-ui/)
|
||||||
|
├── package.json
|
||||||
|
├── vite.config.ts
|
||||||
|
├── uno.config.ts
|
||||||
|
├── tsconfig.json
|
||||||
|
├── index.html
|
||||||
|
├── src/
|
||||||
|
│ ├── App.vue
|
||||||
|
│ ├── main.ts
|
||||||
|
│ ├── router/
|
||||||
|
│ ├── stores/ # Pinia
|
||||||
|
│ ├── api/ # Axios 封装 + 接口
|
||||||
|
│ ├── views/ # 页面组件
|
||||||
|
│ ├── components/ # 公共组件
|
||||||
|
│ ├── composables/ # 组合函数
|
||||||
|
│ ├── utils/ # 工具函数
|
||||||
|
│ └── styles/ # 仅放 UnoCSS 快捷方式或极少全局样式
|
||||||
|
└── public/
|
||||||
|
```
|
||||||
|
|
||||||
|
## API 调用规范
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// api/user.ts
|
||||||
|
import { request } from '@/utils/request'
|
||||||
|
|
||||||
|
export interface UserInfo {
|
||||||
|
id: number
|
||||||
|
username: string
|
||||||
|
nickname: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export const userApi = {
|
||||||
|
page: (params: any) => request.get<PageResult<UserInfo>>('/user/info/page', { params }),
|
||||||
|
create: (data: UserInfo) => request.post('/user/info/create', data),
|
||||||
|
update: (data: UserInfo) => request.put('/user/info/update', data),
|
||||||
|
remove: (id: number) => request.delete(`/user/info/${id}`),
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## UnoCSS 使用
|
||||||
|
|
||||||
|
```vue
|
||||||
|
<template>
|
||||||
|
<!-- 原子类 -->
|
||||||
|
<div class="flex items-center gap-4 p-4 bg-white rounded shadow">
|
||||||
|
<span class="text-lg font-bold text-primary">标题</span>
|
||||||
|
<el-button type="primary" class="ml-auto">
|
||||||
|
操作
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
// 仅极少情况下使用,优先用 UnoCSS 原子类或 shortcuts
|
||||||
|
</style>
|
||||||
|
```
|
||||||
|
|
||||||
|
## 命名规范
|
||||||
|
|
||||||
|
| 类型 | 规则 | 示例 |
|
||||||
|
|------|------|------|
|
||||||
|
| 文件名 | PascalCase | `UserList.vue`, `useTable.ts` |
|
||||||
|
| 目录名 | kebab-case | `user-info/`, `order-detail/` |
|
||||||
|
| 变量/函数 | camelCase | `userList`, `fetchData` |
|
||||||
|
| 组件 | PascalCase | `<UserCard />` |
|
||||||
|
| Pinia store | useXxxStore | `useUserStore` |
|
||||||
|
| 路径 | 小写短横线 | `/user/info`, `/order/detail` |
|
||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user