mirror of
https://github.com/crmeb/CRMEB.git
synced 2026-10-28 21:40:50 +00:00
【SKILL】AI SKILL技能完善docs(uniapp): 添加本地参考文档链接
feat(php-api): 更新数据库设计文档内容 feat(admin-element): 添加部署文档和API流程文档 feat(uniapp): 添加代码规范和API流程文档 refactor(skills): 重构技能列表文档结构 docs: 统一添加各模块参考文档
This commit is contained in:
parent
58655a6fbb
commit
fb32d31fc1
@ -6,19 +6,11 @@
|
||||
|
||||
| 技能名称 | 目录 | 描述 |
|
||||
|---------|------|------|
|
||||
| 管理端前端说明 | 管理端文档说明/ | 管理端前端开发skill说明 |
|
||||
| docs规范 | docs规范/ | 文档写作规范 |
|
||||
| uniapp说明 | uniapp说明/ | 移动端uniapp开发说明 |
|
||||
| 目录结构 | 目录结构/ | 代码结构说明 |
|
||||
| PHP后端说明 | php后端说明/ | PHP后端开发skill说明 |
|
||||
| 数据库设计说明 | 数据库设计说明/ | 数据库设计skill说明 |
|
||||
| API接口开发说明 | api接口开发说明/ | API接口开发skill说明 |
|
||||
| 系统配置说明 | 系统配置说明/ | 系统配置skill说明 |
|
||||
| 安全开发说明 | 安全开发说明/ | 安全开发skill说明 |
|
||||
| 性能优化说明 | 性能优化说明/ | 性能优化skill说明 |
|
||||
| 测试开发说明 | 测试开发说明/ | 测试开发skill说明 |
|
||||
| 部署运维说明 | 部署运维说明/ | 部署运维skill说明 |
|
||||
| 开发文档AI生成说明 | 开发文档AI生成说明/ | 开发文档AI生成skill说明 |
|
||||
| 管理端前端说明 | admin-element/ | 管理端前端开发skill说明 |
|
||||
| 开发文档AI生成说明 | dev-docs-generate/ | 开发文档AI生成skill说明 |
|
||||
| Git提交规范 | git-commit/ | 规范git提交信息格式,确保不同目录下的文件提交时添加正确的前缀 |
|
||||
| PHP后端开发说明 | php-api/ | PHP后端开发skill说明,包含API接口开发、数据库设计等 |
|
||||
| 移动端开发说明 | uniapp/ | 移动端uniapp开发说明 |
|
||||
|
||||
## 技能文档规范
|
||||
|
||||
@ -26,9 +18,11 @@
|
||||
|
||||
```
|
||||
.trae/skills/
|
||||
├── 技能名称/
|
||||
│ └── SKILL.md # 技能说明文档
|
||||
└── SKLLmd # 技能列表文档
|
||||
├── 技能目录/
|
||||
│ ├── SKILL.md # 技能说明文档
|
||||
│ └── references/ # 参考文档目录(可选)
|
||||
│ └── *.md # 相关参考文档
|
||||
└── SKLL.md # 技能列表文档
|
||||
```
|
||||
|
||||
### 2. SKILL.md 格式规范
|
||||
@ -70,14 +64,6 @@ description: 技能描述
|
||||
- **中等优先级**:开发技能(前端、后端、移动端)
|
||||
- **低优先级**:辅助工具技能
|
||||
|
||||
### 4. 技能开发流程
|
||||
|
||||
1. **需求分析**:确定技能的功能和范围
|
||||
2. **文档编写**:按照规范编写SKILL.md文档
|
||||
3. **目录创建**:创建技能目录结构
|
||||
4. **测试验证**:测试技能触发和功能
|
||||
5. **发布使用**:部署技能供开发人员使用
|
||||
|
||||
## 技能使用指南
|
||||
|
||||
### 1. 开发人员使用
|
||||
@ -93,6 +79,34 @@ description: 技能描述
|
||||
2. **技能扩展**:根据新功能添加新技能
|
||||
3. **技能优化**:优化技能触发机制和内容
|
||||
|
||||
## 技能目录说明
|
||||
|
||||
### 1. admin-element/
|
||||
- **功能**:管理端前端开发相关技能
|
||||
- **触发场景**:浏览或编辑管理端前端文件时触发
|
||||
- **核心内容**:前端组件开发、页面布局、交互逻辑等
|
||||
|
||||
### 2. dev-docs-generate/
|
||||
- **功能**:开发文档AI生成相关技能
|
||||
- **触发场景**:需要生成开发文档时触发
|
||||
- **核心内容**:文档结构设计、内容生成、格式规范等
|
||||
|
||||
### 3. git-commit/
|
||||
- **功能**:Git提交规范相关技能
|
||||
- **触发场景**:执行Git提交操作时触发
|
||||
- **核心内容**:提交信息格式、目录前缀规范、最佳实践等
|
||||
|
||||
### 4. php-api/
|
||||
- **功能**:PHP后端开发相关技能
|
||||
- **触发场景**:浏览或编辑后端代码时触发
|
||||
- **核心内容**:API接口开发、数据库设计、业务逻辑实现等
|
||||
- **参考文档**:包含API开发流程、数据库设计、代码规范等详细文档
|
||||
|
||||
### 5. uniapp/
|
||||
- **功能**:移动端开发相关技能
|
||||
- **触发场景**:浏览或编辑移动端代码时触发
|
||||
- **核心内容**:UniApp组件开发、页面路由、数据交互等
|
||||
|
||||
## 总结
|
||||
|
||||
技能系统是CRMEB项目开发的重要辅助工具,通过规范的技能文档和触发机制,可以帮助开发人员更快地了解项目结构、开发规范和最佳实践,提高开发效率和代码质量。
|
||||
|
||||
514
.trae/skills/admin-element/references/api_flow.md
Normal file
514
.trae/skills/admin-element/references/api_flow.md
Normal file
@ -0,0 +1,514 @@
|
||||
# Admin-Element 接口请求流程文档
|
||||
|
||||
## 1 API 请求流程概述
|
||||
|
||||
Admin-Element 项目的 API 请求流程遵循以下步骤:
|
||||
|
||||
1. **接口定义**: 在 `src/api/` 目录下按模块定义 API 接口
|
||||
2. **请求封装**: 使用 `axios` 封装网络请求,添加拦截器
|
||||
3. **接口调用**: 在组件或业务逻辑中调用 API 接口
|
||||
4. **响应处理**: 统一处理 API 响应,包括成功和失败情况
|
||||
5. **错误处理**: 统一处理网络错误、业务错误等异常情况
|
||||
6. **数据管理**: 将获取的数据存储到状态管理或组件中
|
||||
|
||||
## 2 网络请求封装
|
||||
|
||||
### 2.1 axios 实例创建
|
||||
|
||||
在 `src/utils/request.js` 中创建 axios 实例并配置:
|
||||
|
||||
```javascript
|
||||
import axios from 'axios'
|
||||
import { Message, Loading } from 'element-ui'
|
||||
import store from '@/store'
|
||||
import { getToken } from '@/utils/auth'
|
||||
|
||||
// 创建 axios 实例
|
||||
const service = axios.create({
|
||||
baseURL: process.env.VUE_APP_BASE_API, // API 基础路径
|
||||
timeout: 10000, // 请求超时时间
|
||||
headers: {
|
||||
'Content-Type': 'application/json;charset=utf-8'
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
### 2.2 请求拦截器
|
||||
|
||||
```javascript
|
||||
// 请求拦截器
|
||||
service.interceptors.request.use(
|
||||
config => {
|
||||
// 显示加载动画
|
||||
if (config.loading !== false) {
|
||||
store.dispatch('app/showLoading')
|
||||
}
|
||||
|
||||
// 自动添加 token
|
||||
if (store.getters.token) {
|
||||
config.headers['Authorization'] = `Bearer ${getToken()}`
|
||||
}
|
||||
|
||||
return config
|
||||
},
|
||||
error => {
|
||||
// 隐藏加载动画
|
||||
store.dispatch('app/hideLoading')
|
||||
console.error('请求错误:', error)
|
||||
return Promise.reject(error)
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
### 2.3 响应拦截器
|
||||
|
||||
```javascript
|
||||
// 响应拦截器
|
||||
service.interceptors.response.use(
|
||||
response => {
|
||||
// 隐藏加载动画
|
||||
store.dispatch('app/hideLoading')
|
||||
|
||||
const res = response.data
|
||||
|
||||
// 检查响应状态
|
||||
if (res.code !== 200) {
|
||||
// 显示错误消息
|
||||
Message.error({
|
||||
message: res.message || '操作失败',
|
||||
duration: 3000
|
||||
})
|
||||
|
||||
// 处理 token 过期等特殊情况
|
||||
if (res.code === 401) {
|
||||
// 跳转到登录页面
|
||||
store.dispatch('user/logout').then(() => {
|
||||
location.reload()
|
||||
})
|
||||
}
|
||||
|
||||
return Promise.reject(new Error(res.message || '操作失败'))
|
||||
} else {
|
||||
return res
|
||||
}
|
||||
},
|
||||
error => {
|
||||
// 隐藏加载动画
|
||||
store.dispatch('app/hideLoading')
|
||||
|
||||
// 处理网络错误
|
||||
let message = '网络请求失败'
|
||||
if (error.response) {
|
||||
const status = error.response.status
|
||||
switch (status) {
|
||||
case 400:
|
||||
message = '请求参数错误'
|
||||
break
|
||||
case 401:
|
||||
message = '未授权,请重新登录'
|
||||
// 跳转到登录页面
|
||||
store.dispatch('user/logout').then(() => {
|
||||
location.reload()
|
||||
})
|
||||
break
|
||||
case 403:
|
||||
message = '拒绝访问'
|
||||
break
|
||||
case 404:
|
||||
message = '请求地址不存在'
|
||||
break
|
||||
case 500:
|
||||
message = '服务器内部错误'
|
||||
break
|
||||
default:
|
||||
message = `请求失败 (${status})`
|
||||
}
|
||||
} else if (error.message.includes('timeout')) {
|
||||
message = '请求超时'
|
||||
}
|
||||
|
||||
// 显示错误消息
|
||||
Message.error({
|
||||
message: message,
|
||||
duration: 3000
|
||||
})
|
||||
|
||||
return Promise.reject(error)
|
||||
}
|
||||
)
|
||||
|
||||
export default service
|
||||
```
|
||||
|
||||
## 3 API 接口定义
|
||||
|
||||
### 3.1 接口文件组织
|
||||
|
||||
API 接口按模块组织,存放在 `src/api/` 目录下:
|
||||
|
||||
```
|
||||
src/api/
|
||||
├── index.js # API 入口文件
|
||||
├── user.js # 用户相关接口
|
||||
├── goods.js # 商品相关接口
|
||||
├── order.js # 订单相关接口
|
||||
└── ... # 其他模块接口
|
||||
```
|
||||
|
||||
### 3.2 接口定义示例
|
||||
|
||||
在 `src/api/user.js` 中定义用户相关接口:
|
||||
|
||||
```javascript
|
||||
import request from '@/utils/request'
|
||||
|
||||
export default {
|
||||
// 登录
|
||||
login(data) {
|
||||
return request({
|
||||
url: '/admin/login',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
},
|
||||
|
||||
// 获取用户信息
|
||||
getUserInfo() {
|
||||
return request({
|
||||
url: '/admin/user/info',
|
||||
method: 'get'
|
||||
})
|
||||
},
|
||||
|
||||
// 获取用户列表
|
||||
getUserList(params) {
|
||||
return request({
|
||||
url: '/admin/user/list',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
},
|
||||
|
||||
// 修改用户信息
|
||||
updateUser(data) {
|
||||
return request({
|
||||
url: '/admin/user/update',
|
||||
method: 'put',
|
||||
data
|
||||
})
|
||||
},
|
||||
|
||||
// 删除用户
|
||||
deleteUser(id) {
|
||||
return request({
|
||||
url: `/admin/user/delete/${id}`,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3.3 API 入口文件
|
||||
|
||||
在 `src/api/index.js` 中导出所有 API 模块:
|
||||
|
||||
```javascript
|
||||
import user from './user'
|
||||
import goods from './goods'
|
||||
import order from './order'
|
||||
|
||||
// 导出 API 模块
|
||||
export default {
|
||||
user,
|
||||
goods,
|
||||
order
|
||||
}
|
||||
```
|
||||
|
||||
## 4 请求和响应处理
|
||||
|
||||
### 4.1 请求参数处理
|
||||
|
||||
#### 4.1.1 GET 请求
|
||||
|
||||
```javascript
|
||||
// 带查询参数的 GET 请求
|
||||
api.user.getUserList({
|
||||
page: 1,
|
||||
limit: 10,
|
||||
keyword: 'test'
|
||||
})
|
||||
```
|
||||
|
||||
#### 4.1.2 POST 请求
|
||||
|
||||
```javascript
|
||||
// 带请求体的 POST 请求
|
||||
api.user.login({
|
||||
username: 'admin',
|
||||
password: '123456'
|
||||
})
|
||||
```
|
||||
|
||||
#### 4.1.3 PUT 请求
|
||||
|
||||
```javascript
|
||||
// 带请求体的 PUT 请求
|
||||
api.user.updateUser({
|
||||
id: 1,
|
||||
username: 'newadmin',
|
||||
nickname: '新管理员'
|
||||
})
|
||||
```
|
||||
|
||||
#### 4.1.4 DELETE 请求
|
||||
|
||||
```javascript
|
||||
// 路径参数的 DELETE 请求
|
||||
api.user.deleteUser(1)
|
||||
```
|
||||
|
||||
### 4.2 响应数据结构
|
||||
|
||||
后端 API 响应数据结构应遵循以下规范:
|
||||
|
||||
```javascript
|
||||
{
|
||||
"code": 200, // 状态码,200 表示成功
|
||||
"message": "操作成功", // 响应消息
|
||||
"data": { ... } // 响应数据
|
||||
}
|
||||
```
|
||||
|
||||
### 4.3 响应处理示例
|
||||
|
||||
```javascript
|
||||
// 在组件中调用 API
|
||||
import api from '@/api'
|
||||
|
||||
export default {
|
||||
methods: {
|
||||
async fetchUserList() {
|
||||
try {
|
||||
const res = await api.user.getUserList({
|
||||
page: this.page,
|
||||
limit: this.limit
|
||||
})
|
||||
|
||||
// 处理成功响应
|
||||
this.userList = res.data.list
|
||||
this.total = res.data.total
|
||||
} catch (error) {
|
||||
// 错误已在拦截器中处理,这里可以做额外处理
|
||||
console.error('获取用户列表失败:', error)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 5 错误处理机制
|
||||
|
||||
### 5.1 网络错误
|
||||
|
||||
- 网络连接失败
|
||||
- 请求超时
|
||||
- 服务器无响应
|
||||
|
||||
### 5.2 业务错误
|
||||
|
||||
- 参数错误 (400)
|
||||
- 未授权 (401)
|
||||
- 拒绝访问 (403)
|
||||
- 请求地址不存在 (404)
|
||||
- 服务器内部错误 (500)
|
||||
|
||||
### 5.3 业务逻辑错误
|
||||
|
||||
- 状态码非 200 的响应
|
||||
- 业务规则验证失败
|
||||
|
||||
### 5.4 错误处理最佳实践
|
||||
|
||||
1. **统一错误处理**: 在响应拦截器中统一处理错误
|
||||
2. **友好的错误提示**: 向用户显示清晰的错误消息
|
||||
3. **错误日志记录**: 记录错误信息,便于排查问题
|
||||
4. **特殊错误处理**: 对 token 过期等特殊情况进行处理
|
||||
5. **降级处理**: 网络错误时提供合理的降级方案
|
||||
|
||||
## 6 接口调用最佳实践
|
||||
|
||||
### 6.1 使用 async/await
|
||||
|
||||
```javascript
|
||||
async fetchData() {
|
||||
try {
|
||||
const res = await api.goods.getGoodsList(this.queryParams)
|
||||
this.goodsList = res.data.list
|
||||
this.total = res.data.total
|
||||
} catch (error) {
|
||||
// 错误处理
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 6.2 加载状态管理
|
||||
|
||||
```javascript
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
goodsList: []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async fetchData() {
|
||||
this.loading = true
|
||||
try {
|
||||
const res = await api.goods.getGoodsList(this.queryParams)
|
||||
this.goodsList = res.data.list
|
||||
} catch (error) {
|
||||
// 错误处理
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 6.3 防抖和节流
|
||||
|
||||
对于频繁触发的请求,使用防抖或节流优化:
|
||||
|
||||
```javascript
|
||||
import { debounce } from 'lodash'
|
||||
|
||||
export default {
|
||||
methods: {
|
||||
// 使用防抖优化搜索请求
|
||||
search: debounce(async function(query) {
|
||||
try {
|
||||
const res = await api.goods.searchGoods({ keyword: query })
|
||||
this.searchResults = res.data
|
||||
} catch (error) {
|
||||
// 错误处理
|
||||
}
|
||||
}, 300)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 6.4 请求取消
|
||||
|
||||
对于可能重复触发的请求,使用取消令牌避免重复请求:
|
||||
|
||||
```javascript
|
||||
import axios from 'axios'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
cancelToken: null
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async fetchData() {
|
||||
// 取消之前的请求
|
||||
if (this.cancelToken) {
|
||||
this.cancelToken.cancel('取消重复请求')
|
||||
}
|
||||
|
||||
// 创建新的取消令牌
|
||||
this.cancelToken = axios.CancelToken.source()
|
||||
|
||||
try {
|
||||
const res = await api.goods.getGoodsList({
|
||||
page: this.page,
|
||||
limit: this.limit
|
||||
}, {
|
||||
cancelToken: this.cancelToken.token
|
||||
})
|
||||
this.goodsList = res.data.list
|
||||
} catch (error) {
|
||||
if (axios.isCancel(error)) {
|
||||
console.log('请求已取消:', error.message)
|
||||
} else {
|
||||
// 错误处理
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 7 接口安全
|
||||
|
||||
### 7.1 认证与授权
|
||||
|
||||
- 使用 JWT 令牌进行身份认证
|
||||
- 请求头中携带 Authorization 字段
|
||||
- 定期刷新令牌,避免过期
|
||||
|
||||
### 7.2 数据加密
|
||||
|
||||
- 敏感数据传输加密
|
||||
- 密码等敏感信息使用 HTTPS 传输
|
||||
|
||||
### 7.3 防止 CSRF 攻击
|
||||
|
||||
- 使用 CSRF Token
|
||||
- 验证请求来源
|
||||
|
||||
### 7.4 接口速率限制
|
||||
|
||||
- 后端实现接口速率限制
|
||||
- 前端避免频繁请求
|
||||
|
||||
## 8 性能优化
|
||||
|
||||
### 8.1 请求合并
|
||||
|
||||
对于多个相同类型的请求,合并为一个请求:
|
||||
|
||||
```javascript
|
||||
// 批量获取数据
|
||||
api.goods.batchGetGoodsInfo(ids)
|
||||
```
|
||||
|
||||
### 8.2 缓存策略
|
||||
|
||||
- 对不常变化的数据进行缓存
|
||||
- 使用 localStorage 或 sessionStorage 缓存数据
|
||||
|
||||
### 8.3 懒加载
|
||||
|
||||
- 按需加载数据
|
||||
- 滚动到底部加载更多数据
|
||||
|
||||
### 8.4 预加载
|
||||
|
||||
- 预加载可能需要的数据
|
||||
- 提升用户体验
|
||||
|
||||
## 9 调试技巧
|
||||
|
||||
### 9.1 接口调试工具
|
||||
|
||||
- 使用 Chrome DevTools 的 Network 面板
|
||||
- 使用 Postman 等 API 调试工具
|
||||
|
||||
### 9.2 日志记录
|
||||
|
||||
- 在开发环境下打印详细的请求和响应信息
|
||||
- 在生产环境下只记录错误信息
|
||||
|
||||
### 9.3 模拟数据
|
||||
|
||||
- 使用 Mock 数据进行前端开发
|
||||
- 减少对后端接口的依赖
|
||||
|
||||
## 10 总结
|
||||
|
||||
Admin-Element 项目的 API 请求流程采用了统一的封装和处理机制,通过 axios 拦截器实现了请求和响应的统一处理,提高了代码的可维护性和可扩展性。开发者应遵循接口定义规范和最佳实践,确保 API 调用的安全性、可靠性和性能。
|
||||
747
.trae/skills/admin-element/references/code_style.md
Normal file
747
.trae/skills/admin-element/references/code_style.md
Normal file
@ -0,0 +1,747 @@
|
||||
# 管理端前端代码规范文档
|
||||
|
||||
## 1. 概述
|
||||
|
||||
本文档描述了 CRMEB 项目中管理端前端的代码规范,包括命名规范、代码风格、文件结构、组件开发等方面的规范,旨在统一代码风格,提高代码质量和可维护性。
|
||||
|
||||
## 2. 命名规范
|
||||
|
||||
### 2.1 目录命名
|
||||
- **目录名**: 小写字母,单词之间用连字符分隔
|
||||
- **示例**: `components/common/`、`pages/user-management/`、`utils/`
|
||||
- **规范**: 简洁明了,反映目录的功能
|
||||
|
||||
### 2.2 文件命名
|
||||
- **组件文件**: 大写字母开头的 PascalCase 命名风格
|
||||
- **示例**: `Button.vue`、`UserList.vue`、`Navbar.vue`
|
||||
- **页面文件**: 小写字母,单词之间用连字符分隔
|
||||
- **示例**: `login.vue`、`user-list.vue`、`dashboard.vue`
|
||||
- **JS 文件**: 小写字母,单词之间用连字符分隔
|
||||
- **示例**: `api.js`、`request.js`、`util.js`
|
||||
- **CSS/SCSS 文件**: 小写字母,单词之间用连字符分隔
|
||||
- **示例**: `common.scss`、`theme.scss`、`variables.scss`
|
||||
|
||||
### 2.3 变量命名
|
||||
- **普通变量**: 驼峰命名法
|
||||
- **示例**: `userInfo`、`goodsList`、`isLoading`
|
||||
- **常量**: 全大写,单词之间用下划线分隔
|
||||
- **示例**: `BASE_URL`、`MAX_COUNT`、`DEFAULT_PAGE_SIZE`
|
||||
- **布尔变量**: 以 `is` 开头的驼峰命名法
|
||||
- **示例**: `isShow`、`isLoading`、`isLogin`
|
||||
- **数组变量**: 以复数形式命名
|
||||
- **示例**: `users`、`goods`、`orders`
|
||||
- **对象变量**: 以单数形式命名
|
||||
- **示例**: `user`、`good`、`order`
|
||||
|
||||
### 2.4 函数命名
|
||||
- **函数名**: 驼峰命名法,动词开头
|
||||
- **示例**: `getUserInfo`、`submitForm`、`handleClick`
|
||||
- **方法名**: 驼峰命名法
|
||||
- **示例**: `data`、`methods`、`computed`、`watch`
|
||||
- **生命周期函数**: 按照 Vue 规范命名
|
||||
- **示例**: `created`、`mounted`、`beforeDestroy`
|
||||
- **事件处理函数**: 以 `handle` 开头
|
||||
- **示例**: `handleSubmit`、`handleClick`、`handleChange`
|
||||
|
||||
### 2.5 组件命名
|
||||
- **组件名**: PascalCase 命名风格
|
||||
- **示例**: `Button`、`UserList`、`Navbar`
|
||||
- **组件标签**: 小写字母,单词之间用连字符分隔
|
||||
- **示例**: `<el-button>`、`<user-list>`、`<nav-bar>`
|
||||
- **组件文件名**: 与组件名一致,PascalCase 命名
|
||||
- **示例**: `Button.vue`、`UserList.vue`、`Navbar.vue`
|
||||
|
||||
### 2.6 其他命名
|
||||
- **路由命名**: 小写字母,单词之间用连字符分隔
|
||||
- **示例**: `/login`、`/user/list`、`/dashboard`
|
||||
- **CSS 类名**: 小写字母,单词之间用连字符分隔
|
||||
- **示例**: `.user-info`、`.goods-list`、`.btn-primary`
|
||||
- **ID 命名**: 小写字母,单词之间用连字符分隔
|
||||
- **示例**: `#app`、`#header`、`#footer`
|
||||
- **Vuex 模块命名**: 小写字母,单词之间用连字符分隔
|
||||
- **示例**: `user`、`goods`、`orders`
|
||||
|
||||
## 3. 代码风格
|
||||
|
||||
### 3.1 缩进
|
||||
- **缩进方式**: 4 个空格
|
||||
- **示例**:
|
||||
```vue
|
||||
<template>
|
||||
<div class="container">
|
||||
<h1>{{ title }}</h1>
|
||||
</div>
|
||||
</template>
|
||||
```
|
||||
|
||||
### 3.2 换行
|
||||
- **标签换行**: 多个属性的标签应该换行
|
||||
- **示例**:
|
||||
```vue
|
||||
<el-button
|
||||
type="primary"
|
||||
size="medium"
|
||||
@click="handleSubmit"
|
||||
>
|
||||
提交
|
||||
</el-button>
|
||||
```
|
||||
- **代码块换行**: 逻辑代码块应该换行
|
||||
- **示例**:
|
||||
```javascript
|
||||
if (condition) {
|
||||
// 代码块
|
||||
} else {
|
||||
// 代码块
|
||||
}
|
||||
```
|
||||
|
||||
### 3.3 空格
|
||||
- **运算符空格**: 运算符两侧应该有空格
|
||||
- **示例**: `a + b`、`x = y`、`i < 10`
|
||||
- **逗号空格**: 逗号后面应该有空格
|
||||
- **示例**: `[1, 2, 3]`、`{ name: '张三', age: 18 }`
|
||||
- **括号空格**: 括号内侧不应该有空格
|
||||
- **示例**: `if (condition)`、`function (param)`
|
||||
- **冒号空格**: 对象字面量中冒号后面应该有空格
|
||||
- **示例**: `{ name: '张三', age: 18 }`
|
||||
|
||||
### 3.4 注释
|
||||
- **单行注释**: 使用 `//` 注释
|
||||
- **示例**: `// 这是单行注释`
|
||||
- **多行注释**: 使用 `/* */` 注释
|
||||
- **示例**:
|
||||
```javascript
|
||||
/*
|
||||
* 这是多行注释
|
||||
* 第二行
|
||||
*/
|
||||
```
|
||||
- **文档注释**: 使用 JSDoc 风格的注释
|
||||
- **示例**:
|
||||
```javascript
|
||||
/**
|
||||
* 获取用户信息
|
||||
* @param {number} id - 用户ID
|
||||
* @returns {Promise} 用户信息
|
||||
*/
|
||||
async function getUserInfo(id) {
|
||||
// 代码
|
||||
}
|
||||
```
|
||||
- **组件注释**: 组件使用文档注释
|
||||
- **示例**:
|
||||
```vue
|
||||
/**
|
||||
* 用户列表组件
|
||||
* @props {Array} users - 用户列表数据
|
||||
* @props {Boolean} loading - 是否加载中
|
||||
* @events {Function} select - 选择用户时触发
|
||||
*/
|
||||
```
|
||||
|
||||
### 3.5 引号
|
||||
- **字符串**: 使用单引号 `''`
|
||||
- **示例**: `const name = '张三'`、`<span>Hello</span>`
|
||||
- **模板字符串**: 使用反引号 `` ` ``
|
||||
- **示例**: `` const url = `${baseUrl}/api/user` ``
|
||||
- **HTML 属性**: 使用双引号 `""`
|
||||
- **示例**: `<div class="container">`、`<img src="https://example.com/img.jpg">`
|
||||
|
||||
### 3.6 分号
|
||||
- **语句结束**: 每个语句结束都应该加分号
|
||||
- **示例**: `const name = '张三';`、`function() {};`
|
||||
|
||||
### 3.7 空行
|
||||
- **代码块之间**: 代码块之间应该有空行
|
||||
- **示例**:
|
||||
```javascript
|
||||
function first() {
|
||||
// 代码
|
||||
}
|
||||
|
||||
function second() {
|
||||
// 代码
|
||||
}
|
||||
```
|
||||
- **逻辑块之间**: 逻辑块之间应该有空行
|
||||
- **示例**:
|
||||
```javascript
|
||||
if (condition) {
|
||||
// 代码
|
||||
}
|
||||
|
||||
while (loop) {
|
||||
// 代码
|
||||
}
|
||||
```
|
||||
|
||||
## 4. 文件结构
|
||||
|
||||
### 4.1 组件文件结构
|
||||
```vue
|
||||
<template>
|
||||
<!-- 模板内容 -->
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// 导入依赖
|
||||
import { mapState, mapActions } from 'vuex';
|
||||
import UserApi from '@/api/user';
|
||||
|
||||
// 导出组件
|
||||
export default {
|
||||
// 组件名称
|
||||
name: 'UserList',
|
||||
|
||||
// 组件属性
|
||||
props: {
|
||||
pageSize: {
|
||||
type: Number,
|
||||
default: 10
|
||||
}
|
||||
},
|
||||
|
||||
// 数据
|
||||
data() {
|
||||
return {
|
||||
users: [],
|
||||
loading: false,
|
||||
currentPage: 1,
|
||||
total: 0
|
||||
};
|
||||
},
|
||||
|
||||
// 计算属性
|
||||
computed: {
|
||||
...mapState('user', ['userInfo']),
|
||||
|
||||
// 计算总页数
|
||||
totalPages() {
|
||||
return Math.ceil(this.total / this.pageSize);
|
||||
}
|
||||
},
|
||||
|
||||
// 监听
|
||||
watch: {
|
||||
currentPage: {
|
||||
handler(newPage) {
|
||||
this.getUserList(newPage);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// 生命周期函数
|
||||
created() {
|
||||
this.getUserList();
|
||||
},
|
||||
|
||||
// 方法
|
||||
methods: {
|
||||
// 从 Vuex 映射的方法
|
||||
...mapActions('user', ['setUserInfo']),
|
||||
|
||||
// 获取用户列表
|
||||
async getUserList(page = 1) {
|
||||
try {
|
||||
this.loading = true;
|
||||
const res = await UserApi.getList({
|
||||
page,
|
||||
pageSize: this.pageSize
|
||||
});
|
||||
this.users = res.data;
|
||||
this.total = res.total;
|
||||
} catch (error) {
|
||||
console.error('获取用户列表失败:', error);
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
|
||||
// 选择用户
|
||||
handleSelect(user) {
|
||||
this.$emit('select', user);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.user-list {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.user-item {
|
||||
margin-bottom: 10px;
|
||||
padding: 15px;
|
||||
border: 1px solid #eaeaea;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.user-name {
|
||||
font-weight: bold;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.user-email {
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
### 4.2 页面文件结构
|
||||
```vue
|
||||
<template>
|
||||
<div class="user-management">
|
||||
<el-card>
|
||||
<template slot="header">
|
||||
<div class="card-header">
|
||||
<span>用户管理</span>
|
||||
<el-button type="primary" @click="handleAdd">添加用户</el-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<el-form :inline="true" :model="searchForm" class="search-form">
|
||||
<el-form-item label="用户名">
|
||||
<el-input v-model="searchForm.username" placeholder="请输入用户名"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleSearch">搜索</el-button>
|
||||
<el-button @click="resetForm">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-table :data="users" style="width: 100%">
|
||||
<el-table-column prop="id" label="ID" width="80"></el-table-column>
|
||||
<el-table-column prop="username" label="用户名"></el-table-column>
|
||||
<el-table-column prop="email" label="邮箱"></el-table-column>
|
||||
<el-table-column prop="created_at" label="创建时间"></el-table-column>
|
||||
<el-table-column label="操作" width="150">
|
||||
<template slot-scope="scope">
|
||||
<el-button size="small" @click="handleEdit(scope.row)">编辑</el-button>
|
||||
<el-button size="small" type="danger" @click="handleDelete(scope.row.id)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div class="pagination">
|
||||
<el-pagination
|
||||
v-model="currentPage"
|
||||
:page-size="pageSize"
|
||||
:total="total"
|
||||
layout="total, prev, pager, next, jumper"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
></el-pagination>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<!-- 添加/编辑对话框 -->
|
||||
<el-dialog
|
||||
:title="dialogTitle"
|
||||
:visible.sync="dialogVisible"
|
||||
width="500px"
|
||||
>
|
||||
<el-form :model="form" :rules="rules" ref="form">
|
||||
<el-form-item label="用户名" prop="username">
|
||||
<el-input v-model="form.username"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="邮箱" prop="email">
|
||||
<el-input v-model="form.email"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="密码" v-if="!form.id">
|
||||
<el-input v-model="form.password" type="password"></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit">确定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import UserApi from '@/api/user';
|
||||
|
||||
export default {
|
||||
name: 'UserManagement',
|
||||
|
||||
data() {
|
||||
return {
|
||||
// 搜索表单
|
||||
searchForm: {
|
||||
username: ''
|
||||
},
|
||||
// 用户列表
|
||||
users: [],
|
||||
// 分页信息
|
||||
currentPage: 1,
|
||||
pageSize: 10,
|
||||
total: 0,
|
||||
// 对话框
|
||||
dialogVisible: false,
|
||||
dialogTitle: '',
|
||||
form: {},
|
||||
// 表单验证规则
|
||||
rules: {
|
||||
username: [
|
||||
{ required: true, message: '请输入用户名', trigger: 'blur' }
|
||||
],
|
||||
email: [
|
||||
{ required: true, message: '请输入邮箱', trigger: 'blur' },
|
||||
{ type: 'email', message: '请输入正确的邮箱格式', trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
created() {
|
||||
this.getUserList();
|
||||
},
|
||||
|
||||
methods: {
|
||||
// 获取用户列表
|
||||
async getUserList() {
|
||||
try {
|
||||
const res = await UserApi.getList({
|
||||
page: this.currentPage,
|
||||
pageSize: this.pageSize,
|
||||
username: this.searchForm.username
|
||||
});
|
||||
this.users = res.data;
|
||||
this.total = res.total;
|
||||
} catch (error) {
|
||||
console.error('获取用户列表失败:', error);
|
||||
}
|
||||
},
|
||||
|
||||
// 搜索
|
||||
handleSearch() {
|
||||
this.currentPage = 1;
|
||||
this.getUserList();
|
||||
},
|
||||
|
||||
// 重置表单
|
||||
resetForm() {
|
||||
this.searchForm = {
|
||||
username: ''
|
||||
};
|
||||
this.currentPage = 1;
|
||||
this.getUserList();
|
||||
},
|
||||
|
||||
// 分页大小变化
|
||||
handleSizeChange(size) {
|
||||
this.pageSize = size;
|
||||
this.getUserList();
|
||||
},
|
||||
|
||||
// 当前页变化
|
||||
handleCurrentChange(current) {
|
||||
this.currentPage = current;
|
||||
this.getUserList();
|
||||
},
|
||||
|
||||
// 添加用户
|
||||
handleAdd() {
|
||||
this.dialogTitle = '添加用户';
|
||||
this.form = {};
|
||||
this.dialogVisible = true;
|
||||
},
|
||||
|
||||
// 编辑用户
|
||||
handleEdit(user) {
|
||||
this.dialogTitle = '编辑用户';
|
||||
this.form = { ...user };
|
||||
this.dialogVisible = true;
|
||||
},
|
||||
|
||||
// 删除用户
|
||||
handleDelete(id) {
|
||||
this.$confirm('确定要删除这个用户吗?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(async () => {
|
||||
try {
|
||||
await UserApi.delete(id);
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: '删除成功'
|
||||
});
|
||||
this.getUserList();
|
||||
} catch (error) {
|
||||
console.error('删除用户失败:', error);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// 提交表单
|
||||
async handleSubmit() {
|
||||
try {
|
||||
await this.$refs.form.validate();
|
||||
if (this.form.id) {
|
||||
// 编辑
|
||||
await UserApi.update(this.form.id, this.form);
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: '更新成功'
|
||||
});
|
||||
} else {
|
||||
// 添加
|
||||
await UserApi.create(this.form);
|
||||
this.$message({
|
||||
type: 'success',
|
||||
message: '添加成功'
|
||||
});
|
||||
}
|
||||
this.dialogVisible = false;
|
||||
this.getUserList();
|
||||
} catch (error) {
|
||||
console.error('提交失败:', error);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.user-management {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.search-form {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.pagination {
|
||||
margin-top: 20px;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
### 4.3 JS 文件结构
|
||||
```javascript
|
||||
// 导入依赖
|
||||
import axios from 'axios';
|
||||
import { Message } from 'element-ui';
|
||||
|
||||
// 常量定义
|
||||
const BASE_URL = process.env.VUE_APP_API_BASE_URL;
|
||||
const TIMEOUT = 10000;
|
||||
|
||||
// 创建 axios 实例
|
||||
const service = axios.create({
|
||||
baseURL: BASE_URL,
|
||||
timeout: TIMEOUT
|
||||
});
|
||||
|
||||
// 请求拦截器
|
||||
service.interceptors.request.use(
|
||||
config => {
|
||||
// 添加 token
|
||||
const token = localStorage.getItem('token');
|
||||
if (token) {
|
||||
config.headers['Authorization'] = `Bearer ${token}`;
|
||||
}
|
||||
return config;
|
||||
},
|
||||
error => {
|
||||
console.error('请求错误:', error);
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
// 响应拦截器
|
||||
service.interceptors.response.use(
|
||||
response => {
|
||||
const { data } = response;
|
||||
if (data.code !== 200) {
|
||||
Message.error(data.message || '请求失败');
|
||||
return Promise.reject(data);
|
||||
}
|
||||
return data;
|
||||
},
|
||||
error => {
|
||||
console.error('响应错误:', error);
|
||||
Message.error('网络错误,请稍后重试');
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
// 工具函数
|
||||
function formatDate(date) {
|
||||
const d = new Date(date);
|
||||
return d.toLocaleString();
|
||||
}
|
||||
|
||||
function deepClone(obj) {
|
||||
return JSON.parse(JSON.stringify(obj));
|
||||
}
|
||||
|
||||
// 导出
|
||||
export {
|
||||
service,
|
||||
formatDate,
|
||||
deepClone
|
||||
};
|
||||
|
||||
// 默认导出
|
||||
export default service;
|
||||
```
|
||||
|
||||
## 5. 组件开发规范
|
||||
|
||||
### 5.1 组件设计
|
||||
- **单一职责**: 每个组件只负责一个功能
|
||||
- **可复用性**: 设计通用的、可复用的组件
|
||||
- **可配置性**: 通过 props 提供配置选项
|
||||
- **事件通信**: 通过事件与父组件通信
|
||||
- **插槽支持**: 提供插槽,增强组件灵活性
|
||||
|
||||
### 5.2 组件使用
|
||||
- **组件导入**: 使用 import 导入组件
|
||||
- **示例**: `import Button from '@/components/Button.vue'`
|
||||
- **组件注册**: 在 components 中注册组件
|
||||
- **示例**:
|
||||
```javascript
|
||||
components: {
|
||||
Button
|
||||
}
|
||||
```
|
||||
- **组件使用**: 使用组件标签
|
||||
- **示例**: `<Button type="primary">点击</Button>`
|
||||
- **组件传值**: 通过 props 传递数据
|
||||
- **示例**: `<UserList :users="userList" :loading="loading" />`
|
||||
- **事件监听**: 监听组件事件
|
||||
- **示例**: `<UserList @select="handleSelect" />`
|
||||
|
||||
### 5.3 组件通信
|
||||
- **props 向下传递**: 父组件通过 props 向子组件传递数据
|
||||
- **events 向上传递**: 子组件通过 events 向父组件传递事件
|
||||
- **refs 引用**: 通过 refs 引用子组件实例
|
||||
- **provide/inject**: 祖先组件向后代组件传递数据
|
||||
- **Vuex 全局状态**: 使用 Vuex 管理全局状态
|
||||
- **EventBus**: 组件间事件总线
|
||||
|
||||
### 5.4 组件生命周期
|
||||
- **created**: 初始化数据,发送请求
|
||||
- **mounted**: 操作 DOM,初始化第三方库
|
||||
- **beforeUpdate**: 更新前的准备工作
|
||||
- **updated**: 数据更新后的操作
|
||||
- **beforeDestroy**: 清理定时器,取消订阅
|
||||
- **destroyed**: 组件销毁后的清理工作
|
||||
|
||||
### 5.5 组件命名规范
|
||||
- **组件名**: PascalCase 命名风格
|
||||
- **组件文件名**: 与组件名一致
|
||||
- **组件目录**: 按功能分类存放
|
||||
- **组件前缀**: 通用组件使用统一前缀
|
||||
|
||||
## 6. 页面开发规范
|
||||
|
||||
### 6.1 页面结构
|
||||
- **模板结构**: 清晰明了,层次分明
|
||||
- **脚本结构**: 按照 Vue 规范组织代码
|
||||
- **样式结构**: 模块化,可维护
|
||||
- **布局规范**: 遵循统一的布局规范
|
||||
|
||||
### 6.2 数据管理
|
||||
- **本地数据**: 使用 data 管理组件内部数据
|
||||
- **计算数据**: 使用 computed 计算衍生数据
|
||||
- **监听数据**: 使用 watch 监听数据变化
|
||||
- **全局数据**: 使用 Vuex 管理全局数据
|
||||
|
||||
### 6.3 路由管理
|
||||
- **路由配置**: 在 router 目录中配置路由
|
||||
- **路由跳转**: 使用 router.push、router.replace 等方法
|
||||
- **路由参数**: 通过 $route.params 获取路由参数
|
||||
- **路由守卫**: 使用全局/局部路由守卫
|
||||
|
||||
### 6.4 API 调用
|
||||
- **API 封装**: 统一封装 API 调用
|
||||
- **异步处理**: 使用 async/await 处理异步请求
|
||||
- **错误处理**: 使用 try/catch 捕获错误
|
||||
- **加载状态**: 显示加载状态,提升用户体验
|
||||
|
||||
### 6.5 用户体验
|
||||
- **响应式设计**: 适配不同屏幕尺寸
|
||||
- **加载状态**: 显示加载中提示
|
||||
- **错误提示**: 显示错误信息
|
||||
- **成功提示**: 显示操作成功提示
|
||||
- **表单验证**: 实时表单验证
|
||||
- **防抖节流**: 优化频繁触发的事件
|
||||
|
||||
## 7. 性能优化
|
||||
|
||||
### 7.1 代码优化
|
||||
- **减少冗余代码**: 避免重复的代码
|
||||
- **使用计算属性**: 对于复杂的计算,使用 computed
|
||||
- **使用 v-if 和 v-show 合理**: 根据场景选择合适的指令
|
||||
- **使用 key**: 在 v-for 中使用 key,提高渲染性能
|
||||
- **避免频繁更新**: 使用防抖和节流
|
||||
|
||||
### 7.2 网络优化
|
||||
- **合理使用缓存**: 缓存不经常变化的数据
|
||||
- **减少请求次数**: 合并请求,批量操作
|
||||
- **使用 CDN**: 静态资源使用 CDN
|
||||
- **压缩传输**: 使用 gzip 压缩传输数据
|
||||
|
||||
### 7.3 构建优化
|
||||
- **Tree Shaking**: 移除未使用的代码
|
||||
- **代码分割**: 按路由分割代码
|
||||
- **懒加载**: 路由懒加载,组件懒加载
|
||||
- **预加载**: 预加载关键资源
|
||||
|
||||
### 7.4 其他优化
|
||||
- **减少 DOM 节点**: 简化 DOM 结构
|
||||
- **优化图片**: 使用合适的图片格式和大小
|
||||
- **使用虚拟列表**: 对于长列表,使用虚拟列表
|
||||
- **避免内存泄漏**: 及时清理定时器、事件监听器等
|
||||
|
||||
## 8. 常见问题
|
||||
|
||||
### 8.1 代码风格问题
|
||||
- **问题**: 代码风格不一致
|
||||
- **解决方案**: 使用 ESLint 和 Prettier 统一代码风格
|
||||
|
||||
### 8.2 性能问题
|
||||
- **问题**: 页面加载慢,卡顿
|
||||
- **解决方案**: 优化代码,减少 DOM 操作,使用虚拟列表等
|
||||
|
||||
### 8.3 兼容性问题
|
||||
- **问题**: 在不同浏览器上表现不一致
|
||||
- **解决方案**: 遵循 Web 标准,使用 polyfill
|
||||
|
||||
### 8.4 维护性问题
|
||||
- **问题**: 代码难以维护
|
||||
- **解决方案**: 模块化开发,添加注释,遵循代码规范
|
||||
|
||||
### 8.5 命名冲突问题
|
||||
- **问题**: 命名冲突
|
||||
- **解决方案**: 使用命名空间,避免全局变量
|
||||
|
||||
## 9. 参考资源
|
||||
|
||||
- [Vue 官方风格指南](https://v2.vuejs.org/v2/style-guide/)
|
||||
- [Element UI 官方文档](https://element.eleme.io/#/zh-CN)
|
||||
- [ESLint 官方文档](https://eslint.org/docs/user-guide/)
|
||||
- [Prettier 官方文档](https://prettier.io/docs/en/)
|
||||
- [JavaScript 代码规范](https://github.com/airbnb/javascript)
|
||||
- [CSS 代码规范](https://github.com/airbnb/css)
|
||||
|
||||
## 10. 总结
|
||||
|
||||
本文档描述了 CRMEB 项目中管理端前端的代码规范,包括命名规范、代码风格、文件结构、组件开发等方面的规范。遵循本文档的规范,可以提高代码的可读性、可维护性和可扩展性,确保项目的质量和稳定性。
|
||||
|
||||
代码规范是团队协作的基础,建议开发团队成员严格遵循本文档的规范,共同维护一个高质量的代码库。
|
||||
411
.trae/skills/admin-element/references/deploy.md
Normal file
411
.trae/skills/admin-element/references/deploy.md
Normal file
@ -0,0 +1,411 @@
|
||||
# 管理端前端部署文档
|
||||
|
||||
## 1. 概述
|
||||
|
||||
本文档描述了 CRMEB 项目中管理端前端的部署流程,包括构建、部署、配置等环节,旨在规范前端部署流程,确保部署过程的顺利进行和系统的稳定运行。
|
||||
|
||||
## 2. 部署环境
|
||||
|
||||
### 2.1 服务器要求
|
||||
- **操作系统**: Linux (Ubuntu 18.04+、CentOS 7+)
|
||||
- **Web 服务器**: Nginx 1.14+ 或 Apache 2.4+
|
||||
- **Node.js**: v12.0.0+ (仅构建时需要)
|
||||
- **npm/yarn**: v6.0.0+ (仅构建时需要)
|
||||
- **内存**: 至少 2GB RAM
|
||||
- **CPU**: 至少 2 核 CPU
|
||||
- **磁盘空间**: 至少 20GB 可用空间
|
||||
|
||||
### 2.2 环境准备
|
||||
- **Web 服务器配置**: 配置虚拟主机,指向前端构建产物目录
|
||||
- **SSL 证书**: 配置 HTTPS,使用 SSL 证书
|
||||
- **防火墙**: 开放 80/443 端口
|
||||
- **域名**: 配置域名解析,指向服务器 IP
|
||||
|
||||
## 3. 构建流程
|
||||
|
||||
### 3.1 开发环境构建
|
||||
- **命令**: `npm run dev`
|
||||
- **用途**: 本地开发,启动开发服务器
|
||||
- **访问地址**: `http://localhost:8080`
|
||||
|
||||
### 3.2 测试环境构建
|
||||
- **命令**: `npm run build:test`
|
||||
- **用途**: 测试环境部署
|
||||
- **构建产物**: `dist/` 目录
|
||||
|
||||
### 3.3 生产环境构建
|
||||
- **命令**: `npm run build:prod`
|
||||
- **用途**: 生产环境部署
|
||||
- **构建产物**: `dist/` 目录
|
||||
|
||||
### 3.4 构建优化
|
||||
- **代码压缩**: 压缩 JS/CSS/HTML 文件
|
||||
- **资源压缩**: 压缩图片等静态资源
|
||||
- **Tree Shaking**: 移除未使用的代码
|
||||
- **代码分割**: 按路由分割代码
|
||||
- **预加载**: 预加载关键资源
|
||||
|
||||
## 4. 部署方式
|
||||
|
||||
### 4.1 静态部署
|
||||
|
||||
#### 4.1.1 Nginx 配置
|
||||
```nginx
|
||||
server {
|
||||
listen 80;
|
||||
server_name admin.example.com;
|
||||
return 301 https://$server_name$request_uri;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl http2;
|
||||
server_name admin.example.com;
|
||||
|
||||
# SSL 配置
|
||||
ssl_certificate /path/to/ssl/cert.pem;
|
||||
ssl_certificate_key /path/to/ssl/key.pem;
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384;
|
||||
ssl_prefer_server_ciphers on;
|
||||
|
||||
# 静态文件配置
|
||||
root /path/to/admin/dist;
|
||||
index index.html;
|
||||
|
||||
# 路由重写,解决单页应用刷新 404 问题
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
|
||||
# 静态资源缓存
|
||||
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
|
||||
expires 30d;
|
||||
add_header Cache-Control "public, max-age=2592000";
|
||||
}
|
||||
|
||||
# 日志配置
|
||||
access_log /var/log/nginx/admin_access.log;
|
||||
error_log /var/log/nginx/admin_error.log;
|
||||
}
|
||||
```
|
||||
|
||||
#### 4.1.2 Apache 配置
|
||||
```apache
|
||||
<VirtualHost *:80>
|
||||
ServerName admin.example.com
|
||||
Redirect permanent / https://admin.example.com/
|
||||
</VirtualHost>
|
||||
|
||||
<VirtualHost *:443>
|
||||
ServerName admin.example.com
|
||||
|
||||
# SSL 配置
|
||||
SSLEngine on
|
||||
SSLCertificateFile /path/to/ssl/cert.pem
|
||||
SSLCertificateKeyFile /path/to/ssl/key.pem
|
||||
|
||||
# 静态文件配置
|
||||
DocumentRoot /path/to/admin/dist
|
||||
<Directory /path/to/admin/dist>
|
||||
AllowOverride All
|
||||
Require all granted
|
||||
</Directory>
|
||||
|
||||
# 路由重写,解决单页应用刷新 404 问题
|
||||
<IfModule mod_rewrite.c>
|
||||
RewriteEngine On
|
||||
RewriteBase /
|
||||
RewriteRule ^index\.html$ - [L]
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteCond %{REQUEST_FILENAME} !-d
|
||||
RewriteRule . /index.html [L]
|
||||
</IfModule>
|
||||
|
||||
# 日志配置
|
||||
ErrorLog ${APACHE_LOG_DIR}/admin_error.log
|
||||
CustomLog ${APACHE_LOG_DIR}/admin_access.log combined
|
||||
</VirtualHost>
|
||||
```
|
||||
|
||||
### 4.2 容器部署
|
||||
|
||||
#### 4.2.1 Dockerfile
|
||||
```dockerfile
|
||||
# 基础镜像
|
||||
FROM node:12-alpine as build
|
||||
|
||||
# 设置工作目录
|
||||
WORKDIR /app
|
||||
|
||||
# 复制依赖文件
|
||||
COPY package*.json ./
|
||||
|
||||
# 安装依赖
|
||||
RUN npm install
|
||||
|
||||
# 复制源代码
|
||||
COPY . .
|
||||
|
||||
# 构建生产版本
|
||||
RUN npm run build:prod
|
||||
|
||||
# 生产镜像
|
||||
FROM nginx:1.19-alpine
|
||||
|
||||
# 复制构建产物
|
||||
COPY --from=build /app/dist /usr/share/nginx/html
|
||||
|
||||
# 复制 Nginx 配置
|
||||
COPY nginx.conf /etc/nginx/conf.d/default.conf
|
||||
|
||||
# 暴露端口
|
||||
EXPOSE 80
|
||||
|
||||
# 启动 Nginx
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
||||
```
|
||||
|
||||
#### 4.2.2 Docker Compose
|
||||
```yaml
|
||||
version: '3'
|
||||
services:
|
||||
admin:
|
||||
build: .
|
||||
ports:
|
||||
- "80:80"
|
||||
restart: always
|
||||
volumes:
|
||||
- ./ssl:/etc/nginx/ssl
|
||||
environment:
|
||||
- TZ=Asia/Shanghai
|
||||
```
|
||||
|
||||
#### 4.2.3 部署命令
|
||||
```bash
|
||||
# 构建镜像
|
||||
docker build -t crmeb-admin .
|
||||
|
||||
# 运行容器
|
||||
docker run -d --name crmeb-admin -p 80:80 crmeb-admin
|
||||
|
||||
# 使用 Docker Compose
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
### 4.3 CDN 部署
|
||||
|
||||
#### 4.3.1 配置 CDN
|
||||
- **源站设置**: 指向静态文件服务器
|
||||
- **缓存策略**: 配置静态资源缓存时间
|
||||
- **HTTPS**: 开启 HTTPS
|
||||
- **HTTP/2**: 开启 HTTP/2
|
||||
|
||||
#### 4.3.2 部署流程
|
||||
1. 构建前端项目
|
||||
2. 上传构建产物到 CDN
|
||||
3. 配置 CDN 缓存策略
|
||||
4. 验证部署结果
|
||||
|
||||
## 5. 配置管理
|
||||
|
||||
### 5.1 环境变量配置
|
||||
- **开发环境**: `.env.development`
|
||||
- **测试环境**: `.env.test`
|
||||
- **生产环境**: `.env.production`
|
||||
|
||||
### 5.2 配置示例
|
||||
```env
|
||||
# API 基础地址
|
||||
VUE_APP_API_BASE_URL=https://api.example.com
|
||||
|
||||
# 静态资源 CDN 地址
|
||||
VUE_APP_CDN_BASE_URL=https://cdn.example.com
|
||||
|
||||
# 应用名称
|
||||
VUE_APP_TITLE=CRMEB 管理后台
|
||||
|
||||
# 构建环境
|
||||
NODE_ENV=production
|
||||
|
||||
# 构建版本
|
||||
VUE_APP_VERSION=1.0.0
|
||||
```
|
||||
|
||||
### 5.3 运行时配置
|
||||
- **API 地址**: 可通过环境变量或配置文件修改
|
||||
- **主题配置**: 可通过配置文件修改
|
||||
- **权限配置**: 可通过后端 API 动态获取
|
||||
|
||||
## 6. 部署流程
|
||||
|
||||
### 6.1 手动部署
|
||||
1. **拉取代码**: `git pull origin master`
|
||||
2. **安装依赖**: `npm install`
|
||||
3. **构建项目**: `npm run build:prod`
|
||||
4. **部署文件**: 将 `dist/` 目录复制到服务器
|
||||
5. **配置 Web 服务器**: 配置虚拟主机
|
||||
6. **重启服务**: 重启 Web 服务器
|
||||
7. **验证部署**: 访问管理端地址
|
||||
|
||||
### 6.2 自动化部署
|
||||
|
||||
#### 6.2.1 CI/CD 配置
|
||||
- **Jenkins**: 配置 Jenkins 任务,实现自动构建和部署
|
||||
- **GitLab CI**: 配置 `.gitlab-ci.yml`,实现自动构建和部署
|
||||
- **GitHub Actions**: 配置 `.github/workflows/deploy.yml`,实现自动构建和部署
|
||||
|
||||
#### 6.2.2 GitHub Actions 示例
|
||||
```yaml
|
||||
name: Deploy Admin Frontend
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: '12'
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm install
|
||||
|
||||
- name: Build project
|
||||
run: npm run build:prod
|
||||
|
||||
- name: Deploy to server
|
||||
uses: easingthemes/ssh-deploy@v2.1.5
|
||||
env:
|
||||
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
|
||||
ARGS: '-rltgoDzvO --delete'
|
||||
SOURCE: 'dist/'
|
||||
REMOTE_HOST: ${{ secrets.REMOTE_HOST }}
|
||||
REMOTE_USER: ${{ secrets.REMOTE_USER }}
|
||||
REMOTE_PORT: ${{ secrets.REMOTE_PORT }}
|
||||
TARGET: ${{ secrets.REMOTE_TARGET }}
|
||||
|
||||
- name: Restart Nginx
|
||||
uses: appleboy/ssh-action@master
|
||||
with:
|
||||
host: ${{ secrets.REMOTE_HOST }}
|
||||
username: ${{ secrets.REMOTE_USER }}
|
||||
key: ${{ secrets.SSH_PRIVATE_KEY }}
|
||||
port: ${{ secrets.REMOTE_PORT }}
|
||||
script: sudo systemctl restart nginx
|
||||
```
|
||||
|
||||
## 7. 监控与维护
|
||||
|
||||
### 7.1 监控
|
||||
- **访问日志**: 分析 Web 服务器访问日志
|
||||
- **错误日志**: 监控 Web 服务器错误日志
|
||||
- **性能监控**: 监控页面加载速度、响应时间
|
||||
- **可用性监控**: 监控服务可用性,设置告警
|
||||
|
||||
### 7.2 维护
|
||||
- **定期更新**: 定期更新前端代码,修复漏洞
|
||||
- **缓存清理**: 定期清理 CDN 缓存
|
||||
- **日志清理**: 定期清理日志文件
|
||||
- **备份**: 定期备份构建产物和配置文件
|
||||
|
||||
### 7.3 常见问题
|
||||
|
||||
#### 7.3.1 404 问题
|
||||
- **问题**: 刷新页面出现 404 错误
|
||||
- **解决方案**: 配置 Web 服务器,将所有请求重定向到 index.html
|
||||
|
||||
#### 7.3.2 静态资源加载失败
|
||||
- **问题**: 静态资源(JS/CSS/图片)加载失败
|
||||
- **解决方案**: 检查静态资源路径,确保 CDN 配置正确
|
||||
|
||||
#### 7.3.3 API 调用失败
|
||||
- **问题**: 前端无法调用后端 API
|
||||
- **解决方案**: 检查 API 地址配置,确保后端服务正常运行
|
||||
|
||||
#### 7.3.4 性能问题
|
||||
- **问题**: 页面加载慢,卡顿
|
||||
- **解决方案**: 优化前端代码,使用 CDN,启用 HTTP/2
|
||||
|
||||
## 8. 回滚策略
|
||||
|
||||
### 8.1 版本管理
|
||||
- **版本号**: 遵循语义化版本规范
|
||||
- **发布记录**: 记录每次发布的版本和变更内容
|
||||
- **备份**: 备份每次发布的构建产物
|
||||
|
||||
### 8.2 回滚流程
|
||||
1. **停止服务**: 停止当前版本的服务
|
||||
2. **恢复备份**: 恢复到上一个稳定版本
|
||||
3. **重启服务**: 启动恢复后的服务
|
||||
4. **验证回滚**: 验证服务是否正常运行
|
||||
|
||||
### 8.3 回滚方案
|
||||
- **手动回滚**: 手动复制备份文件到部署目录
|
||||
- **自动化回滚**: 通过 CI/CD 工具实现自动回滚
|
||||
- **容器回滚**: 通过 Docker 镜像版本回滚
|
||||
|
||||
## 9. 安全部署
|
||||
|
||||
### 9.1 HTTPS 配置
|
||||
- **SSL 证书**: 使用正规 CA 签发的 SSL 证书
|
||||
- **证书续期**: 定期续期 SSL 证书
|
||||
- **HTTP 重定向**: 将 HTTP 请求重定向到 HTTPS
|
||||
|
||||
### 9.2 安全头部
|
||||
- **Content-Security-Policy**: 配置内容安全策略
|
||||
- **X-Content-Type-Options**: 防止 MIME 类型嗅探
|
||||
- **X-Frame-Options**: 防止点击劫持
|
||||
- **X-XSS-Protection**: 启用 XSS 过滤
|
||||
|
||||
### 9.3 访问控制
|
||||
- **IP 白名单**: 限制管理端访问 IP
|
||||
- **登录验证**: 强制登录验证
|
||||
- **权限控制**: 基于角色的权限控制
|
||||
- **会话管理**: 安全的会话管理
|
||||
|
||||
### 9.4 漏洞防护
|
||||
- **依赖扫描**: 定期扫描依赖包漏洞
|
||||
- **代码审计**: 定期进行代码安全审计
|
||||
- **渗透测试**: 定期进行渗透测试
|
||||
|
||||
## 10. 最佳实践
|
||||
|
||||
### 10.1 构建优化
|
||||
- **使用缓存**: 缓存依赖包和构建产物
|
||||
- **并行构建**: 使用多线程并行构建
|
||||
- **增量构建**: 只构建变更的文件
|
||||
- **构建日志**: 保存构建日志,便于排查问题
|
||||
|
||||
### 10.2 部署优化
|
||||
- **灰度发布**: 采用灰度发布策略
|
||||
- **蓝绿部署**: 采用蓝绿部署策略
|
||||
- **滚动部署**: 采用滚动部署策略
|
||||
- **金丝雀发布**: 采用金丝雀发布策略
|
||||
|
||||
### 10.3 监控优化
|
||||
- **实时监控**: 实时监控系统运行状态
|
||||
- **告警机制**: 设置合理的告警阈值
|
||||
- **日志聚合**: 聚合多服务器日志
|
||||
- **性能分析**: 定期分析系统性能
|
||||
|
||||
### 10.4 安全优化
|
||||
- **最小权限**: 遵循最小权限原则
|
||||
- **定期更新**: 定期更新依赖和系统
|
||||
- **安全扫描**: 定期进行安全扫描
|
||||
- **应急响应**: 建立安全应急响应机制
|
||||
|
||||
## 11. 总结
|
||||
|
||||
本文档描述了 CRMEB 项目中管理端前端的部署流程,包括构建、部署、配置等环节,以及相关的最佳实践和常见问题解决方案。
|
||||
|
||||
遵循本文档的部署流程和规范,可以确保前端部署的顺利进行和系统的稳定运行,同时提高部署效率和系统安全性。
|
||||
|
||||
随着项目的发展和技术的演进,部署流程也需要不断优化和调整,以适应新的业务需求和技术挑战。
|
||||
276
.trae/skills/admin-element/references/development_flow.md
Normal file
276
.trae/skills/admin-element/references/development_flow.md
Normal file
@ -0,0 +1,276 @@
|
||||
# 管理端前端开发流程文档
|
||||
|
||||
## 1. 概述
|
||||
|
||||
本文档描述了 CRMEB 项目中管理端前端的开发流程,包括需求分析、设计、编码、测试、部署等环节,旨在规范前端开发流程,提高开发效率和代码质量。
|
||||
|
||||
## 2. 开发流程
|
||||
|
||||
### 2.1 需求分析
|
||||
|
||||
#### 2.1.1 需求获取
|
||||
- **需求来源**: 产品经理、业务方、后端开发、测试人员
|
||||
- **需求形式**: PRD 文档、需求评审会议、邮件、即时通讯工具
|
||||
- **需求内容**: 功能需求、非功能需求、UI/UX 需求
|
||||
|
||||
#### 2.1.2 需求评审
|
||||
- **评审人员**: 前端开发、后端开发、产品经理、测试人员
|
||||
- **评审内容**: 需求可行性、技术实现方案、时间评估、风险评估
|
||||
- **评审输出**: 评审纪要、任务分解、时间计划
|
||||
|
||||
#### 2.1.3 需求确认
|
||||
- **确认内容**: 需求细节、技术方案、交付标准
|
||||
- **确认形式**: 需求确认邮件、需求确认会议
|
||||
- **确认输出**: 需求确认文档
|
||||
|
||||
### 2.2 设计阶段
|
||||
|
||||
#### 2.2.1 UI 设计
|
||||
- **设计工具**: Figma、Sketch、Adobe XD
|
||||
- **设计内容**: 页面布局、组件样式、交互设计、色彩方案
|
||||
- **设计输出**: UI 设计稿、设计规范文档
|
||||
|
||||
#### 2.2.2 技术设计
|
||||
- **设计内容**: 技术选型、架构设计、目录结构、组件设计、API 设计
|
||||
- **设计输出**: 技术设计文档、架构图、组件设计图
|
||||
|
||||
#### 2.2.3 原型设计
|
||||
- **原型工具**: Axure、Figma、Sketch
|
||||
- **原型内容**: 页面原型、交互原型、流程原型
|
||||
- **原型输出**: 交互式原型、流程图
|
||||
|
||||
### 2.3 编码实现
|
||||
|
||||
#### 2.3.1 环境搭建
|
||||
- **开发环境**: Node.js、npm/yarn、VS Code、Git
|
||||
- **依赖安装**: `npm install` 或 `yarn install`
|
||||
- **开发工具**: Vue DevTools、Chrome DevTools
|
||||
|
||||
#### 2.3.2 代码开发
|
||||
- **开发顺序**: 基础组件 → 页面组件 → 业务逻辑 → 测试
|
||||
- **开发规范**: 遵循代码规范、命名规范、文档规范
|
||||
- **代码质量**: 代码可读性、可维护性、可扩展性
|
||||
|
||||
#### 2.3.3 代码审查
|
||||
- **审查人员**: 前端团队成员
|
||||
- **审查内容**: 代码质量、功能实现、性能优化、安全防护
|
||||
- **审查工具**: GitLab/GitHub Code Review、ESLint、Prettier
|
||||
|
||||
### 2.4 测试验证
|
||||
|
||||
#### 2.4.1 单元测试
|
||||
- **测试工具**: Jest、Vue Test Utils
|
||||
- **测试内容**: 组件测试、工具函数测试、状态管理测试
|
||||
- **测试覆盖率**: 关键功能测试覆盖率 ≥ 80%
|
||||
|
||||
#### 2.4.2 功能测试
|
||||
- **测试人员**: 前端开发、测试人员
|
||||
- **测试内容**: 功能实现、交互体验、页面布局、响应式设计
|
||||
- **测试工具**: 浏览器、测试管理工具
|
||||
|
||||
#### 2.4.3 性能测试
|
||||
- **测试工具**: Chrome DevTools、Lighthouse、WebPageTest
|
||||
- **测试内容**: 首屏加载速度、页面渲染性能、内存使用、网络请求
|
||||
- **测试指标**: FCP、LCP、TTI、CLS、FID
|
||||
|
||||
#### 2.4.4 兼容性测试
|
||||
- **测试浏览器**: Chrome、Firefox、Safari、Edge
|
||||
- **测试分辨率**: 1024x768、1366x768、1920x1080
|
||||
- **测试内容**: 页面显示、功能实现、交互体验
|
||||
|
||||
### 2.5 部署上线
|
||||
|
||||
#### 2.5.1 构建打包
|
||||
- **构建命令**: `npm run build:prod`
|
||||
- **构建产物**: 静态资源文件
|
||||
- **构建优化**: 代码压缩、资源压缩、Tree Shaking
|
||||
|
||||
#### 2.5.2 部署配置
|
||||
- **部署环境**: 测试环境、预发布环境、生产环境
|
||||
- **部署工具**: Nginx、Apache、CDN
|
||||
- **配置内容**: 服务器配置、域名配置、HTTPS 配置
|
||||
|
||||
#### 2.5.3 上线发布
|
||||
- **发布流程**: 测试环境 → 预发布环境 → 生产环境
|
||||
- **发布时间**: 非业务高峰期
|
||||
- **发布监控**: 实时监控系统运行状态
|
||||
|
||||
#### 2.5.4 上线后验证
|
||||
- **验证内容**: 功能验证、性能验证、兼容性验证
|
||||
- **验证人员**: 前端开发、测试人员、产品经理
|
||||
- **验证输出**: 上线验证报告
|
||||
|
||||
## 3. 开发规范
|
||||
|
||||
### 3.1 代码规范
|
||||
- **ESLint 规则**: 遵循 Vue 官方推荐的 ESLint 规则
|
||||
- **Prettier 配置**: 统一代码格式化规则
|
||||
- **代码缩进**: 4 空格缩进
|
||||
- **命名规范**: 组件名 PascalCase,变量/方法名 camelCase,常量全大写
|
||||
|
||||
### 3.2 提交规范
|
||||
- **提交信息格式**: `[类型] 描述`
|
||||
- **类型**: feat(新功能)、fix(修复)、docs(文档)、style(样式)、refactor(重构)、test(测试)、chore(构建/依赖)
|
||||
- **提交频率**: 小步提交,每个功能或修复一个提交
|
||||
- **提交内容**: 只提交相关代码,不提交无关文件
|
||||
|
||||
### 3.3 分支规范
|
||||
- **主分支**: master(生产环境)、develop(开发环境)
|
||||
- **功能分支**: feature/功能名称
|
||||
- **修复分支**: fix/修复内容
|
||||
- **发布分支**: release/版本号
|
||||
- **分支管理**: 定期清理无用分支
|
||||
|
||||
### 3.4 文档规范
|
||||
- **README.md**: 项目说明、安装说明、开发说明
|
||||
- **组件文档**: 组件使用说明、Props、Events、Slots
|
||||
- **API 文档**: API 接口说明、请求参数、响应格式
|
||||
- **开发文档**: 开发流程、编码规范、部署流程
|
||||
|
||||
## 4. 开发工具
|
||||
|
||||
### 4.1 开发环境
|
||||
- **Node.js**: v12.0.0+
|
||||
- **npm**: v6.0.0+ 或 **yarn**: v1.22.0+
|
||||
- **VS Code**: 最新版本
|
||||
- **Git**: 最新版本
|
||||
|
||||
### 4.2 编辑器插件
|
||||
- **Vetur**: Vue 开发插件
|
||||
- **ESLint**: 代码检查插件
|
||||
- **Prettier**: 代码格式化插件
|
||||
- **GitLens**: Git 增强插件
|
||||
- **Debugger for Chrome**: 浏览器调试插件
|
||||
- **Auto Close Tag**: 自动闭合标签
|
||||
- **Auto Rename Tag**: 自动重命名标签
|
||||
|
||||
### 4.3 开发工具
|
||||
- **Vue DevTools**: Vue 开发调试工具
|
||||
- **Chrome DevTools**: 浏览器调试工具
|
||||
- **Postman**: API 测试工具
|
||||
- **Charles**: 网络调试工具
|
||||
- **Figma/Sketch**: UI 设计工具
|
||||
- **Zeplin**: 设计协作工具
|
||||
|
||||
### 4.4 构建工具
|
||||
- **Webpack**: 模块打包工具
|
||||
- **Babel**: JavaScript 编译器
|
||||
- **Sass/Less**: CSS 预处理器
|
||||
- **ESLint**: 代码检查工具
|
||||
- **Prettier**: 代码格式化工具
|
||||
|
||||
## 5. 常见问题及解决方案
|
||||
|
||||
### 5.1 需求变更
|
||||
|
||||
- **问题**: 开发过程中需求发生变更
|
||||
- **解决方案**:
|
||||
1. 记录需求变更内容
|
||||
2. 评估变更影响范围
|
||||
3. 与产品经理确认变更可行性
|
||||
4. 调整开发计划和时间评估
|
||||
5. 通知相关团队成员
|
||||
|
||||
### 5.2 技术难题
|
||||
|
||||
- **问题**: 遇到技术难题无法解决
|
||||
- **解决方案**:
|
||||
1. 查阅相关文档和资料
|
||||
2. 寻求团队成员帮助
|
||||
3. 咨询外部专家
|
||||
4. 尝试替代方案
|
||||
5. 记录解决方案,形成知识库
|
||||
|
||||
### 5.3 时间紧张
|
||||
|
||||
- **问题**: 开发时间紧张,任务无法按时完成
|
||||
- **解决方案**:
|
||||
1. 评估任务优先级
|
||||
2. 与产品经理沟通,调整需求优先级
|
||||
3. 寻求团队成员协助
|
||||
4. 优化开发流程,提高开发效率
|
||||
5. 加班完成(作为最后手段)
|
||||
|
||||
### 5.4 代码冲突
|
||||
|
||||
- **问题**: Git 代码冲突
|
||||
- **解决方案**:
|
||||
1. 拉取最新代码
|
||||
2. 手动解决冲突
|
||||
3. 测试冲突解决后的代码
|
||||
4. 提交解决冲突后的代码
|
||||
5. 通知相关团队成员
|
||||
|
||||
### 5.5 线上问题
|
||||
|
||||
- **问题**: 线上出现问题
|
||||
- **解决方案**:
|
||||
1. 快速定位问题原因
|
||||
2. 制定解决方案
|
||||
3. 紧急修复并部署
|
||||
4. 验证修复效果
|
||||
5. 分析问题原因,避免类似问题再次发生
|
||||
|
||||
## 6. 最佳实践
|
||||
|
||||
### 6.1 开发前准备
|
||||
- **需求确认**: 确保需求理解正确
|
||||
- **技术方案**: 制定详细的技术实现方案
|
||||
- **环境搭建**: 确保开发环境配置正确
|
||||
- **依赖安装**: 安装必要的依赖包
|
||||
|
||||
### 6.2 编码实现
|
||||
- **组件化开发**: 封装可复用组件
|
||||
- **模块化开发**: 按功能模块组织代码
|
||||
- **代码复用**: 提取公共逻辑,避免重复代码
|
||||
- **性能优化**: 考虑代码性能,避免性能瓶颈
|
||||
- **安全性**: 考虑代码安全性,避免安全漏洞
|
||||
|
||||
### 6.3 测试验证
|
||||
- **单元测试**: 编写关键功能的单元测试
|
||||
- **功能测试**: 全面测试功能实现
|
||||
- **性能测试**: 测试页面性能
|
||||
- **兼容性测试**: 测试不同浏览器兼容性
|
||||
- **用户体验测试**: 测试页面交互体验
|
||||
|
||||
### 6.4 部署上线
|
||||
- **构建优化**: 优化构建产物
|
||||
- **部署策略**: 采用灰度发布策略
|
||||
- **监控告警**: 配置系统监控和告警
|
||||
- **回滚方案**: 准备系统回滚方案
|
||||
- **上线验证**: 上线后及时验证系统状态
|
||||
|
||||
### 6.5 维护迭代
|
||||
- **问题跟踪**: 及时跟踪和解决线上问题
|
||||
- **代码维护**: 定期维护和优化代码
|
||||
- **文档更新**: 及时更新相关文档
|
||||
- **技术债务**: 定期清理技术债务
|
||||
- **知识共享**: 分享开发经验和解决方案
|
||||
|
||||
## 7. 团队协作
|
||||
|
||||
### 7.1 协作模式
|
||||
- **敏捷开发**: 采用 Scrum 或 Kanban 敏捷开发模式
|
||||
- **每日站会**: 每日 15 分钟站会,同步开发进度
|
||||
- **迭代周期**: 2-4 周一个迭代周期
|
||||
- **迭代回顾**: 迭代结束后进行回顾,总结经验教训
|
||||
|
||||
### 7.2 沟通工具
|
||||
- **即时通讯**: 企业微信、钉钉、Slack
|
||||
- **项目管理**: Jira、Trello、GitHub Issues
|
||||
- **代码托管**: GitLab、GitHub、Gitee
|
||||
- **文档协作**: 语雀、Confluence、Google Docs
|
||||
|
||||
### 7.3 知识共享
|
||||
- **技术分享**: 定期组织技术分享会议
|
||||
- **代码审查**: 相互代码审查,分享编码经验
|
||||
- **问题讨论**: 定期组织问题讨论会议
|
||||
- **知识库**: 建立团队知识库,积累技术经验
|
||||
|
||||
## 8. 总结
|
||||
|
||||
本文档描述了 CRMEB 项目中管理端前端的开发流程,包括需求分析、设计、编码、测试、部署等环节,以及相关的开发规范和最佳实践。
|
||||
|
||||
遵循本文档的开发流程和规范,可以提高前端开发效率和代码质量,减少开发过程中的问题和风险,确保项目的顺利进行。
|
||||
|
||||
同时,开发流程也需要根据项目的实际情况进行调整和优化,以适应不同项目的需求和特点。
|
||||
188
.trae/skills/admin-element/references/directory_structure.md
Normal file
188
.trae/skills/admin-element/references/directory_structure.md
Normal file
@ -0,0 +1,188 @@
|
||||
# Admin-Element 目录结构文档
|
||||
|
||||
## 1 项目根目录结构
|
||||
|
||||
```
|
||||
template/ # 前端项目目录
|
||||
├── admin-element/ # 管理端前端项目
|
||||
│ ├── public/ # 静态资源目录
|
||||
│ │ ├── favicon.ico # 网站图标
|
||||
│ │ ├── index.html # 入口HTML文件
|
||||
│ │ └── static/ # 静态资源文件
|
||||
│ ├── src/ # 源代码目录
|
||||
│ │ ├── api/ # API接口定义
|
||||
│ │ ├── assets/ # 静态资源
|
||||
│ │ ├── components/ # 通用组件
|
||||
│ │ ├── config/ # 配置文件
|
||||
│ │ ├── directive/ # 自定义指令
|
||||
│ │ ├── filters/ # 过滤器
|
||||
│ │ ├── layout/ # 布局组件
|
||||
│ │ ├── router/ # 路由配置
|
||||
│ │ ├── store/ # 状态管理
|
||||
│ │ ├── styles/ # 样式文件
|
||||
│ │ ├── utils/ # 工具函数
|
||||
│ │ ├── views/ # 页面组件
|
||||
│ │ ├── App.vue # 根组件
|
||||
│ │ └── main.js # 入口文件
|
||||
│ ├── tests/ # 测试文件
|
||||
│ ├── .env.* # 环境变量配置
|
||||
│ ├── babel.config.js # Babel配置
|
||||
│ ├── package.json # 项目依赖
|
||||
│ ├── vue.config.js # Vue配置
|
||||
│ └── README.md # 项目说明
|
||||
```
|
||||
|
||||
## 2 主要目录说明
|
||||
|
||||
### 2.1 public/ 目录
|
||||
- **favicon.ico**: 网站图标文件
|
||||
- **index.html**: 应用入口HTML文件,Vue应用将挂载到这个文件中
|
||||
- **static/**: 静态资源目录,存放不需要经过webpack处理的静态文件
|
||||
|
||||
### 2.2 src/ 目录
|
||||
|
||||
#### 2.2.1 api/ 目录
|
||||
- 定义所有API接口请求
|
||||
- 按模块组织API文件
|
||||
- 包含接口调用方法和参数配置
|
||||
|
||||
#### 2.2.2 assets/ 目录
|
||||
- **images/**: 图片资源
|
||||
- **icons/**: 图标资源
|
||||
- **styles/**: 全局样式文件
|
||||
- 其他静态资源文件
|
||||
|
||||
#### 2.2.3 components/ 目录
|
||||
- **base/**: 基础组件
|
||||
- **business/**: 业务组件
|
||||
- **common/**: 通用组件
|
||||
- 可复用的Vue组件
|
||||
|
||||
#### 2.2.4 config/ 目录
|
||||
- **index.js**: 主配置文件
|
||||
- **router.config.js**: 路由配置
|
||||
- **menu.config.js**: 菜单配置
|
||||
- **theme.config.js**: 主题配置
|
||||
- 其他系统配置文件
|
||||
|
||||
#### 2.2.5 directive/ 目录
|
||||
- 自定义Vue指令
|
||||
- 如权限控制、表单验证等指令
|
||||
|
||||
#### 2.2.6 filters/ 目录
|
||||
- 自定义Vue过滤器
|
||||
- 如日期格式化、数字格式化等
|
||||
|
||||
#### 2.2.7 layout/ 目录
|
||||
- **components/**: 布局组件
|
||||
- **index.vue**: 主布局文件
|
||||
- **AppMain.vue**: 内容区域组件
|
||||
- **Navbar.vue**: 导航栏组件
|
||||
- **Sidebar.vue**: 侧边栏组件
|
||||
|
||||
#### 2.2.8 router/ 目录
|
||||
- **index.js**: 路由配置主文件
|
||||
- **modules/**: 按模块组织的路由配置
|
||||
- 路由守卫配置
|
||||
|
||||
#### 2.2.9 store/ 目录
|
||||
- **index.js**: 状态管理主文件
|
||||
- **modules/**: 按模块组织的状态管理
|
||||
- **getters.js**: 全局计算属性
|
||||
|
||||
#### 2.2.10 styles/ 目录
|
||||
- **index.scss**: 全局样式入口
|
||||
- **variables.scss**: 全局变量
|
||||
- **mixins.scss**: 混合器
|
||||
- **reset.scss**: 重置样式
|
||||
|
||||
#### 2.2.11 utils/ 目录
|
||||
- **request.js**: 网络请求封装
|
||||
- **auth.js**: 认证相关工具
|
||||
- **tools.js**: 通用工具函数
|
||||
- **storage.js**: 存储工具
|
||||
|
||||
#### 2.2.12 views/ 目录
|
||||
- 按业务模块组织页面组件
|
||||
- 每个模块一个目录
|
||||
- 包含页面组件和相关子组件
|
||||
|
||||
#### 2.2.13 App.vue
|
||||
- 应用根组件
|
||||
- 包含全局布局结构
|
||||
|
||||
#### 2.2.14 main.js
|
||||
- 应用入口文件
|
||||
- 初始化Vue实例
|
||||
- 加载插件和全局配置
|
||||
|
||||
### 2.3 配置文件
|
||||
|
||||
#### 2.3.1 package.json
|
||||
- 项目依赖配置
|
||||
- 脚本命令配置
|
||||
- 项目信息配置
|
||||
|
||||
#### 2.3.2 vue.config.js
|
||||
- Vue CLI配置
|
||||
- 构建配置
|
||||
- 代理配置
|
||||
|
||||
#### 2.3.3 babel.config.js
|
||||
- Babel转译配置
|
||||
|
||||
#### 2.3.4 .env.*
|
||||
- 环境变量配置文件
|
||||
- **.env.development**: 开发环境
|
||||
- **.env.production**: 生产环境
|
||||
- **.env.staging**: 测试环境
|
||||
|
||||
## 3 目录规范
|
||||
|
||||
### 3.1 命名规范
|
||||
- 目录名使用小写字母,多单词用连字符(-)分隔
|
||||
- 文件名使用小写字母,多单词用连字符(-)分隔
|
||||
- 组件名使用 PascalCase 命名法
|
||||
|
||||
### 3.2 目录组织原则
|
||||
1. **按功能模块组织**: 相关功能的文件放在同一目录
|
||||
2. **模块化**: 每个模块保持相对独立
|
||||
3. **可扩展性**: 目录结构应易于扩展和维护
|
||||
4. **一致性**: 保持目录结构的一致性
|
||||
|
||||
### 3.3 特殊目录处理
|
||||
- **components/**: 只存放可复用组件
|
||||
- **views/**: 存放页面级组件
|
||||
- **api/**: 按模块组织API接口
|
||||
- **store/modules/**: 按模块组织状态管理
|
||||
|
||||
## 4 最佳实践
|
||||
|
||||
### 4.1 目录使用建议
|
||||
- 新增业务模块时,在 views/ 下创建对应的目录
|
||||
- 新增可复用组件时,放在 components/ 下的对应子目录
|
||||
- 新增API接口时,在 api/ 下按模块组织
|
||||
- 新增状态管理时,在 store/modules/ 下创建对应模块
|
||||
|
||||
### 4.2 目录结构维护
|
||||
- 定期清理无用文件和目录
|
||||
- 保持目录结构的清晰和整洁
|
||||
- 遵循统一的命名规范
|
||||
- 文档及时更新,反映目录结构的变化
|
||||
|
||||
## 5 常见问题
|
||||
|
||||
### 5.1 目录权限问题
|
||||
- 确保目录权限正确,避免构建时出现权限错误
|
||||
|
||||
### 5.2 路径引用问题
|
||||
- 使用相对路径或别名路径引用文件
|
||||
- 避免使用绝对路径
|
||||
|
||||
### 5.3 目录结构优化
|
||||
- 随着项目规模增大,适时调整目录结构
|
||||
- 保持目录层级合理,避免过深的嵌套
|
||||
|
||||
## 6 总结
|
||||
|
||||
Admin-Element 项目采用标准的 Vue + ElementUI 项目结构,通过清晰的目录组织和命名规范,提高了代码的可维护性和可扩展性。开发者应遵循目录结构规范,合理组织代码,确保项目的长期可维护性。
|
||||
950
.trae/skills/admin-element/references/system_config.md
Normal file
950
.trae/skills/admin-element/references/system_config.md
Normal file
@ -0,0 +1,950 @@
|
||||
# Admin-Element 系统配置文档
|
||||
|
||||
## 1 环境变量配置
|
||||
|
||||
### 1.1 环境变量文件
|
||||
|
||||
Admin-Element 项目使用 `.env` 文件管理环境变量:
|
||||
|
||||
```
|
||||
template/admin-element/
|
||||
├── .env # 基础环境变量文件
|
||||
├── .env.development # 开发环境变量
|
||||
├── .env.production # 生产环境变量
|
||||
└── .env.staging # 测试环境变量
|
||||
```
|
||||
|
||||
### 1.2 环境变量配置示例
|
||||
|
||||
在 `.env.development` 中配置开发环境变量:
|
||||
|
||||
```dotenv
|
||||
# 基础 API 路径
|
||||
VUE_APP_BASE_API = 'http://localhost:8080/api'
|
||||
|
||||
# 项目标题
|
||||
VUE_APP_TITLE = 'CRMEB 管理端'
|
||||
|
||||
# 开发环境
|
||||
NODE_ENV = 'development'
|
||||
|
||||
# 端口
|
||||
VUE_APP_PORT = '9527'
|
||||
|
||||
# 构建输出目录
|
||||
VUE_APP_OUTPUT_DIR = 'dist'
|
||||
|
||||
# 是否启用代码压缩
|
||||
VUE_APP_COMPRESS = 'false'
|
||||
|
||||
# 是否启用 source map
|
||||
VUE_APP_SOURCE_MAP = 'true'
|
||||
```
|
||||
|
||||
在 `.env.production` 中配置生产环境变量:
|
||||
|
||||
```dotenv
|
||||
# 基础 API 路径
|
||||
VUE_APP_BASE_API = 'https://api.example.com'
|
||||
|
||||
# 项目标题
|
||||
VUE_APP_TITLE = 'CRMEB 管理端'
|
||||
|
||||
# 生产环境
|
||||
NODE_ENV = 'production'
|
||||
|
||||
# 端口
|
||||
VUE_APP_PORT = '80'
|
||||
|
||||
# 构建输出目录
|
||||
VUE_APP_OUTPUT_DIR = 'dist'
|
||||
|
||||
# 是否启用代码压缩
|
||||
VUE_APP_COMPRESS = 'true'
|
||||
|
||||
# 是否启用 source map
|
||||
VUE_APP_SOURCE_MAP = 'false'
|
||||
```
|
||||
|
||||
## 2 项目基本配置
|
||||
|
||||
### 2.1 package.json 配置
|
||||
|
||||
在 `package.json` 文件中配置项目基本信息和依赖:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "admin-element",
|
||||
"version": "1.0.0",
|
||||
"description": "CRMEB 管理端前端项目",
|
||||
"author": "CRMEB Team",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "vue-cli-service serve",
|
||||
"build": "vue-cli-service build",
|
||||
"lint": "vue-cli-service lint",
|
||||
"preview": "serve dist",
|
||||
"test": "vue-cli-service test:unit"
|
||||
},
|
||||
"dependencies": {
|
||||
"vue": "^2.6.11",
|
||||
"vue-router": "^3.2.0",
|
||||
"vuex": "^3.4.0",
|
||||
"axios": "^0.21.1",
|
||||
"element-ui": "^2.14.1",
|
||||
"lodash": "^4.17.21"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vue/cli-service": "^4.5.13",
|
||||
"@vue/cli-plugin-babel": "^4.5.13",
|
||||
"@vue/cli-plugin-eslint": "^4.5.13",
|
||||
"@vue/cli-plugin-unit-jest": "^4.5.13",
|
||||
"babel-eslint": "^10.1.0",
|
||||
"eslint": "^6.7.2",
|
||||
"eslint-plugin-vue": "^6.2.2"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2.2 vue.config.js 配置
|
||||
|
||||
在 `vue.config.js` 文件中配置 Vue CLI 相关选项:
|
||||
|
||||
```javascript
|
||||
const { defineConfig } = require('@vue/cli-service')
|
||||
const path = require('path')
|
||||
|
||||
module.exports = defineConfig({
|
||||
// 部署应用包的基本 URL
|
||||
publicPath: process.env.NODE_ENV === 'production' ? '/' : '/',
|
||||
|
||||
// 构建输出目录
|
||||
outputDir: process.env.VUE_APP_OUTPUT_DIR || 'dist',
|
||||
|
||||
// 静态资源目录
|
||||
assetsDir: 'static',
|
||||
|
||||
// 生产环境是否生成 source map
|
||||
productionSourceMap: process.env.VUE_APP_SOURCE_MAP === 'true',
|
||||
|
||||
// 开发服务器配置
|
||||
devServer: {
|
||||
port: process.env.VUE_APP_PORT || 9527,
|
||||
open: true,
|
||||
overlay: {
|
||||
warnings: false,
|
||||
errors: true
|
||||
},
|
||||
proxy: {
|
||||
// API 代理配置
|
||||
'/api': {
|
||||
target: 'http://localhost:8080',
|
||||
changeOrigin: true,
|
||||
pathRewrite: {
|
||||
'^/api': '/api'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// 构建配置
|
||||
configureWebpack: {
|
||||
// 提供 webpack 全局变量
|
||||
plugins: [
|
||||
// 其他插件配置
|
||||
],
|
||||
// 解析配置
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': path.resolve(__dirname, 'src'),
|
||||
'@components': path.resolve(__dirname, 'src/components'),
|
||||
'@views': path.resolve(__dirname, 'src/views'),
|
||||
'@api': path.resolve(__dirname, 'src/api'),
|
||||
'@utils': path.resolve(__dirname, 'src/utils')
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// 链式配置
|
||||
chainWebpack: config => {
|
||||
// 配置别名
|
||||
config.resolve.alias
|
||||
.set('@', path.resolve(__dirname, 'src'))
|
||||
|
||||
// 配置构建优化
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
// 生产环境配置
|
||||
config.optimization.minimizer('terser').tap(args => {
|
||||
// 配置 terser 选项
|
||||
return args
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
## 3 路由配置
|
||||
|
||||
### 3.1 路由配置文件
|
||||
|
||||
路由配置文件位于 `src/router/` 目录:
|
||||
|
||||
```
|
||||
src/router/
|
||||
├── index.js # 路由配置主文件
|
||||
└── modules/ # 按模块组织的路由配置
|
||||
├── user.js # 用户模块路由
|
||||
├── goods.js # 商品模块路由
|
||||
└── order.js # 订单模块路由
|
||||
```
|
||||
|
||||
### 3.2 路由配置示例
|
||||
|
||||
在 `src/router/index.js` 中配置主路由:
|
||||
|
||||
```javascript
|
||||
import Vue from 'vue'
|
||||
import Router from 'vue-router'
|
||||
import Layout from '@/layout'
|
||||
|
||||
Vue.use(Router)
|
||||
|
||||
// 静态路由
|
||||
export const constantRoutes = [
|
||||
{
|
||||
path: '/login',
|
||||
component: () => import('@/views/login/index'),
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: '/404',
|
||||
component: () => import('@/views/404'),
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: '/',
|
||||
component: Layout,
|
||||
redirect: '/dashboard',
|
||||
children: [{
|
||||
path: 'dashboard',
|
||||
name: 'Dashboard',
|
||||
component: () => import('@/views/dashboard/index'),
|
||||
meta: { title: '控制台', icon: 'dashboard', affix: true }
|
||||
}]
|
||||
}
|
||||
]
|
||||
|
||||
// 动态路由
|
||||
export const asyncRoutes = [
|
||||
// 用户管理
|
||||
{
|
||||
path: '/user',
|
||||
component: Layout,
|
||||
redirect: '/user/list',
|
||||
name: 'User',
|
||||
meta: { title: '用户管理', icon: 'user', roles: ['admin'] },
|
||||
children: [
|
||||
{
|
||||
path: 'list',
|
||||
name: 'UserList',
|
||||
component: () => import('@/views/user/list'),
|
||||
meta: { title: '用户列表', roles: ['admin'] }
|
||||
},
|
||||
{
|
||||
path: 'add',
|
||||
name: 'UserAdd',
|
||||
component: () => import('@/views/user/add'),
|
||||
meta: { title: '添加用户', roles: ['admin'] }
|
||||
},
|
||||
{
|
||||
path: 'edit/:id',
|
||||
name: 'UserEdit',
|
||||
component: () => import('@/views/user/edit'),
|
||||
meta: { title: '编辑用户', roles: ['admin'] },
|
||||
hidden: true
|
||||
}
|
||||
]
|
||||
},
|
||||
// 404 页面必须放在最后
|
||||
{ path: '*', redirect: '/404', hidden: true }
|
||||
]
|
||||
|
||||
const createRouter = () => new Router({
|
||||
mode: 'history',
|
||||
scrollBehavior: () => ({ y: 0 }),
|
||||
routes: constantRoutes
|
||||
})
|
||||
|
||||
const router = createRouter()
|
||||
|
||||
export function resetRouter() {
|
||||
const newRouter = createRouter()
|
||||
router.matcher = newRouter.matcher
|
||||
}
|
||||
|
||||
export default router
|
||||
```
|
||||
|
||||
## 4 菜单配置
|
||||
|
||||
### 4.1 菜单配置文件
|
||||
|
||||
菜单配置文件位于 `src/config/menu.config.js`:
|
||||
|
||||
```javascript
|
||||
export default [
|
||||
{
|
||||
path: '/dashboard',
|
||||
title: '控制台',
|
||||
icon: 'dashboard',
|
||||
component: 'dashboard/index',
|
||||
meta: {
|
||||
roles: ['admin', 'editor']
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/user',
|
||||
title: '用户管理',
|
||||
icon: 'user',
|
||||
component: 'layout',
|
||||
redirect: '/user/list',
|
||||
meta: {
|
||||
roles: ['admin']
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: 'list',
|
||||
title: '用户列表',
|
||||
component: 'user/list',
|
||||
meta: {
|
||||
roles: ['admin']
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'add',
|
||||
title: '添加用户',
|
||||
component: 'user/add',
|
||||
meta: {
|
||||
roles: ['admin']
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
path: '/goods',
|
||||
title: '商品管理',
|
||||
icon: 'shopping',
|
||||
component: 'layout',
|
||||
redirect: '/goods/list',
|
||||
meta: {
|
||||
roles: ['admin', 'editor']
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: 'list',
|
||||
title: '商品列表',
|
||||
component: 'goods/list',
|
||||
meta: {
|
||||
roles: ['admin', 'editor']
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'category',
|
||||
title: '商品分类',
|
||||
component: 'goods/category',
|
||||
meta: {
|
||||
roles: ['admin']
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
## 5 主题配置
|
||||
|
||||
### 5.1 主题配置文件
|
||||
|
||||
主题配置文件位于 `src/config/theme.config.js`:
|
||||
|
||||
```javascript
|
||||
export default {
|
||||
// 主题颜色
|
||||
primaryColor: '#409EFF',
|
||||
|
||||
// 成功颜色
|
||||
successColor: '#67C23A',
|
||||
|
||||
// 警告颜色
|
||||
warningColor: '#E6A23C',
|
||||
|
||||
// 错误颜色
|
||||
errorColor: '#F56C6C',
|
||||
|
||||
// 信息颜色
|
||||
infoColor: '#909399',
|
||||
|
||||
// 菜单主题
|
||||
menuTheme: 'dark', // dark, light
|
||||
|
||||
// 顶部导航栏主题
|
||||
navbarTheme: 'light', // dark, light
|
||||
|
||||
// 布局模式
|
||||
layoutMode: 'side', // side, top
|
||||
|
||||
// 是否固定顶部导航栏
|
||||
fixedNavbar: true,
|
||||
|
||||
// 是否固定侧边栏
|
||||
fixedSidebar: true,
|
||||
|
||||
// 是否显示标签栏
|
||||
showTagsView: true,
|
||||
|
||||
// 是否显示logo
|
||||
showLogo: true,
|
||||
|
||||
// 是否显示面包屑
|
||||
showBreadcrumb: true,
|
||||
|
||||
// 是否启用响应式布局
|
||||
responsiveLayout: true
|
||||
}
|
||||
```
|
||||
|
||||
## 6 API 配置
|
||||
|
||||
### 6.1 API 基础配置
|
||||
|
||||
在 `src/utils/request.js` 中配置 API 请求基础设置:
|
||||
|
||||
```javascript
|
||||
import axios from 'axios'
|
||||
|
||||
const service = axios.create({
|
||||
baseURL: process.env.VUE_APP_BASE_API,
|
||||
timeout: 10000,
|
||||
headers: {
|
||||
'Content-Type': 'application/json;charset=utf-8'
|
||||
}
|
||||
})
|
||||
|
||||
// 其他配置...
|
||||
|
||||
export default service
|
||||
```
|
||||
|
||||
### 6.2 API 模块配置
|
||||
|
||||
在 `src/api/` 目录下按模块配置 API 接口:
|
||||
|
||||
```javascript
|
||||
// src/api/user.js
|
||||
import request from '@/utils/request'
|
||||
|
||||
export default {
|
||||
// 登录
|
||||
login(data) {
|
||||
return request({
|
||||
url: '/admin/login',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
},
|
||||
|
||||
// 获取用户信息
|
||||
getUserInfo() {
|
||||
return request({
|
||||
url: '/admin/user/info',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 7 权限配置
|
||||
|
||||
### 7.1 权限配置文件
|
||||
|
||||
权限配置文件位于 `src/config/permission.config.js`:
|
||||
|
||||
```javascript
|
||||
export default {
|
||||
// 路由权限配置
|
||||
routePermissions: {
|
||||
'/user': ['admin'],
|
||||
'/goods': ['admin', 'editor'],
|
||||
'/order': ['admin', 'editor'],
|
||||
'/finance': ['admin'],
|
||||
'/system': ['admin']
|
||||
},
|
||||
|
||||
// 按钮权限配置
|
||||
buttonPermissions: {
|
||||
'user:add': ['admin'],
|
||||
'user:edit': ['admin'],
|
||||
'user:delete': ['admin'],
|
||||
'goods:add': ['admin', 'editor'],
|
||||
'goods:edit': ['admin', 'editor'],
|
||||
'goods:delete': ['admin'],
|
||||
'order:edit': ['admin', 'editor'],
|
||||
'order:delete': ['admin']
|
||||
},
|
||||
|
||||
// 角色配置
|
||||
roles: {
|
||||
admin: {
|
||||
name: '管理员',
|
||||
permissions: ['user:add', 'user:edit', 'user:delete', 'goods:add', 'goods:edit', 'goods:delete', 'order:edit', 'order:delete']
|
||||
},
|
||||
editor: {
|
||||
name: '编辑',
|
||||
permissions: ['goods:add', 'goods:edit', 'order:edit']
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 7.2 权限指令
|
||||
|
||||
在 `src/directive/permission.js` 中配置权限指令:
|
||||
|
||||
```javascript
|
||||
import permission from '@/config/permission.config'
|
||||
|
||||
export default {
|
||||
inserted(el, binding) {
|
||||
const { value } = binding
|
||||
const userRoles = JSON.parse(localStorage.getItem('userRoles') || '[]')
|
||||
|
||||
if (value && value instanceof Array && value.length > 0) {
|
||||
const hasPermission = value.some(permission => {
|
||||
return userRoles.includes(permission)
|
||||
})
|
||||
|
||||
if (!hasPermission) {
|
||||
el.parentNode && el.parentNode.removeChild(el)
|
||||
}
|
||||
} else {
|
||||
throw new Error('权限指令必须指定权限值')
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 8 国际化配置
|
||||
|
||||
### 8.1 国际化配置文件
|
||||
|
||||
国际化配置文件位于 `src/lang/` 目录:
|
||||
|
||||
```
|
||||
src/lang/
|
||||
├── index.js # 国际化入口文件
|
||||
├── zh-CN.js # 中文语言包
|
||||
└── en-US.js # 英文语言包
|
||||
```
|
||||
|
||||
在 `src/lang/zh-CN.js` 中配置中文语言包:
|
||||
|
||||
```javascript
|
||||
export default {
|
||||
login: {
|
||||
title: '登录',
|
||||
username: '用户名',
|
||||
password: '密码',
|
||||
loginBtn: '登录',
|
||||
forgetPassword: '忘记密码',
|
||||
register: '注册'
|
||||
},
|
||||
dashboard: {
|
||||
title: '控制台',
|
||||
welcome: '欢迎回来',
|
||||
todayStats: '今日统计',
|
||||
totalStats: '总统计'
|
||||
},
|
||||
user: {
|
||||
title: '用户管理',
|
||||
list: '用户列表',
|
||||
add: '添加用户',
|
||||
edit: '编辑用户',
|
||||
delete: '删除用户',
|
||||
username: '用户名',
|
||||
nickname: '昵称',
|
||||
email: '邮箱',
|
||||
phone: '手机号',
|
||||
status: '状态'
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 9 构建配置
|
||||
|
||||
### 9.1 构建脚本配置
|
||||
|
||||
在 `package.json` 中配置构建脚本:
|
||||
|
||||
```json
|
||||
{
|
||||
"scripts": {
|
||||
"build": "vue-cli-service build",
|
||||
"build:dev": "vue-cli-service build --mode development",
|
||||
"build:prod": "vue-cli-service build --mode production",
|
||||
"build:staging": "vue-cli-service build --mode staging",
|
||||
"build:analyze": "vue-cli-service build --report"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 9.2 构建优化配置
|
||||
|
||||
在 `vue.config.js` 中配置构建优化:
|
||||
|
||||
```javascript
|
||||
module.exports = {
|
||||
configureWebpack: {
|
||||
optimization: {
|
||||
// 分割代码块
|
||||
splitChunks: {
|
||||
chunks: 'all',
|
||||
cacheGroups: {
|
||||
// 第三方库
|
||||
vendor: {
|
||||
name: 'chunk-vendors',
|
||||
test: /[\\/]node_modules[\\/]/,
|
||||
priority: 10,
|
||||
chunks: 'initial'
|
||||
},
|
||||
// 公共组件
|
||||
common: {
|
||||
name: 'chunk-common',
|
||||
minChunks: 2,
|
||||
priority: 5,
|
||||
chunks: 'initial',
|
||||
reuseExistingChunk: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 10 开发配置
|
||||
|
||||
### 10.1 开发服务器配置
|
||||
|
||||
在 `vue.config.js` 中配置开发服务器:
|
||||
|
||||
```javascript
|
||||
module.exports = {
|
||||
devServer: {
|
||||
// 端口
|
||||
port: 9527,
|
||||
|
||||
// 自动打开浏览器
|
||||
open: true,
|
||||
|
||||
// 错误和警告显示
|
||||
overlay: {
|
||||
warnings: false,
|
||||
errors: true
|
||||
},
|
||||
|
||||
// 代理配置
|
||||
proxy: {
|
||||
'/api': {
|
||||
target: 'http://localhost:8080',
|
||||
changeOrigin: true,
|
||||
pathRewrite: {
|
||||
'^/api': '/api'
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// 热更新
|
||||
hot: true,
|
||||
|
||||
// 静态资源目录
|
||||
static: {
|
||||
directory: path.join(__dirname, 'public')
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 10.2 ESLint 配置
|
||||
|
||||
ESLint 配置文件位于 `template/admin-element/.eslintrc.js`:
|
||||
|
||||
```javascript
|
||||
module.exports = {
|
||||
root: true,
|
||||
env: {
|
||||
node: true
|
||||
},
|
||||
extends: [
|
||||
'plugin:vue/essential',
|
||||
'@vue/standard'
|
||||
],
|
||||
parserOptions: {
|
||||
parser: 'babel-eslint'
|
||||
},
|
||||
rules: {
|
||||
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
|
||||
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
|
||||
'indent': ['error', 2],
|
||||
'linebreak-style': ['error', 'unix'],
|
||||
'quotes': ['error', 'single'],
|
||||
'semi': ['error', 'never']
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 11 部署配置
|
||||
|
||||
### 11.1 部署配置文件
|
||||
|
||||
部署配置文件位于 `src/config/deploy.config.js`:
|
||||
|
||||
```javascript
|
||||
export default {
|
||||
// 部署环境
|
||||
environments: {
|
||||
// 测试环境
|
||||
staging: {
|
||||
host: 'staging.example.com',
|
||||
port: 22,
|
||||
username: 'deploy',
|
||||
password: '',
|
||||
privateKey: '/path/to/privateKey',
|
||||
passphrase: '',
|
||||
from: 'dist/',
|
||||
to: '/var/www/html/admin-staging',
|
||||
timeout: 60000
|
||||
},
|
||||
// 生产环境
|
||||
production: {
|
||||
host: 'production.example.com',
|
||||
port: 22,
|
||||
username: 'deploy',
|
||||
password: '',
|
||||
privateKey: '/path/to/privateKey',
|
||||
passphrase: '',
|
||||
from: 'dist/',
|
||||
to: '/var/www/html/admin',
|
||||
timeout: 60000
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 11.2 Nginx 配置
|
||||
|
||||
在服务器上配置 Nginx:
|
||||
|
||||
```nginx
|
||||
server {
|
||||
listen 80;
|
||||
server_name admin.example.com;
|
||||
|
||||
root /var/www/html/admin;
|
||||
index index.html;
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
|
||||
location /api {
|
||||
proxy_pass http://localhost:8080;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
|
||||
# 静态资源缓存
|
||||
location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg)$ {
|
||||
expires 7d;
|
||||
add_header Cache-Control "public, max-age=604800";
|
||||
}
|
||||
|
||||
# 错误页面
|
||||
error_page 404 /index.html;
|
||||
error_page 500 502 503 504 /50x.html;
|
||||
location = /50x.html {
|
||||
root /usr/share/nginx/html;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 12 性能配置
|
||||
|
||||
### 12.1 性能优化配置
|
||||
|
||||
在 `vue.config.js` 中配置性能优化:
|
||||
|
||||
```javascript
|
||||
module.exports = {
|
||||
configureWebpack: {
|
||||
// 性能配置
|
||||
performance: {
|
||||
maxAssetSize: 300000, // 300kb
|
||||
maxEntrypointSize: 300000, // 300kb
|
||||
hints: 'warning'
|
||||
}
|
||||
},
|
||||
|
||||
// 构建优化
|
||||
chainWebpack: config => {
|
||||
// 配置图片压缩
|
||||
config.module
|
||||
.rule('images')
|
||||
.use('image-webpack-loader')
|
||||
.loader('image-webpack-loader')
|
||||
.options({
|
||||
mozjpeg: {
|
||||
progressive: true,
|
||||
quality: 65
|
||||
},
|
||||
optipng: {
|
||||
enabled: false
|
||||
},
|
||||
pngquant: {
|
||||
quality: [0.65, 0.90],
|
||||
speed: 4
|
||||
},
|
||||
gifsicle: {
|
||||
interlaced: false
|
||||
}
|
||||
})
|
||||
|
||||
// 配置代码分割
|
||||
config.optimization
|
||||
.splitChunks({
|
||||
chunks: 'all',
|
||||
cacheGroups: {
|
||||
vendor: {
|
||||
name: 'vendor',
|
||||
test: /[\\/]node_modules[\\/]/,
|
||||
priority: 10,
|
||||
chunks: 'initial'
|
||||
},
|
||||
common: {
|
||||
name: 'common',
|
||||
minChunks: 2,
|
||||
priority: 5,
|
||||
chunks: 'all',
|
||||
reuseExistingChunk: true
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 13 安全配置
|
||||
|
||||
### 13.1 安全配置文件
|
||||
|
||||
安全配置文件位于 `src/config/security.config.js`:
|
||||
|
||||
```javascript
|
||||
export default {
|
||||
// 是否启用 CSRF 保护
|
||||
enableCsrf: true,
|
||||
|
||||
// CSRF Token 名称
|
||||
csrfTokenName: 'X-CSRF-Token',
|
||||
|
||||
// 是否启用 XSS 防护
|
||||
enableXss: true,
|
||||
|
||||
// 是否启用 CSP (Content Security Policy)
|
||||
enableCsp: true,
|
||||
|
||||
// CSP 配置
|
||||
csp: {
|
||||
defaultSrc: "'self'",
|
||||
scriptSrc: "'self' 'unsafe-inline' 'unsafe-eval'",
|
||||
styleSrc: "'self' 'unsafe-inline'",
|
||||
imgSrc: "'self' data: https:",
|
||||
connectSrc: "'self'",
|
||||
fontSrc: "'self'",
|
||||
objectSrc: "'none'",
|
||||
frameSrc: "'none'",
|
||||
baseSrc: "'self'",
|
||||
formAction: "'self'"
|
||||
},
|
||||
|
||||
// 是否启用 HTTP Strict Transport Security
|
||||
enableHsts: true,
|
||||
|
||||
// HSTS 配置
|
||||
hsts: {
|
||||
maxAge: 31536000,
|
||||
includeSubDomains: true,
|
||||
preload: true
|
||||
},
|
||||
|
||||
// 是否启用 X-Content-Type-Options
|
||||
enableXContentTypeOptions: true,
|
||||
|
||||
// 是否启用 X-Frame-Options
|
||||
enableXFrameOptions: true,
|
||||
|
||||
// X-Frame-Options 配置
|
||||
xFrameOptions: 'DENY', // DENY, SAMEORIGIN, ALLOW-FROM
|
||||
|
||||
// 是否启用 X-XSS-Protection
|
||||
enableXXssProtection: true
|
||||
}
|
||||
```
|
||||
|
||||
## 14 最佳实践
|
||||
|
||||
### 14.1 配置管理最佳实践
|
||||
|
||||
1. **环境变量管理**
|
||||
- 使用 `.env` 文件管理不同环境的配置
|
||||
- 敏感信息不要硬编码在代码中
|
||||
- 不同环境使用不同的配置文件
|
||||
|
||||
2. **配置文件组织**
|
||||
- 按功能模块组织配置文件
|
||||
- 使用统一的配置管理方式
|
||||
- 配置文件应该有清晰的注释
|
||||
|
||||
3. **配置加载顺序**
|
||||
- 环境变量 > 配置文件 > 默认配置
|
||||
- 确保配置加载的一致性
|
||||
|
||||
4. **配置验证**
|
||||
- 对配置项进行验证
|
||||
- 提供默认值和错误处理
|
||||
|
||||
5. **配置监控**
|
||||
- 监控配置的变化
|
||||
- 记录配置变更日志
|
||||
|
||||
6. **配置安全性**
|
||||
- 敏感配置加密存储
|
||||
- 配置文件权限控制
|
||||
- 避免在日志中输出敏感配置
|
||||
|
||||
7. **配置可维护性**
|
||||
- 使用结构化的配置格式
|
||||
- 配置项命名规范
|
||||
- 定期清理无用的配置
|
||||
|
||||
8. **配置扩展性**
|
||||
- 设计可扩展的配置结构
|
||||
- 支持动态配置更新
|
||||
- 配置项应该有合理的默认值
|
||||
|
||||
## 15 总结
|
||||
|
||||
Admin-Element 项目的系统配置涵盖了环境变量、路由、菜单、主题、API、权限、国际化、构建、开发、部署、性能和安全等多个方面。合理的配置管理可以提高项目的可维护性、可扩展性和安全性,同时提升开发效率和用户体验。
|
||||
|
||||
开发者应遵循配置管理的最佳实践,根据项目需求和环境特点,合理配置各项参数,确保项目的稳定运行和持续演进。
|
||||
@ -13,6 +13,7 @@
|
||||
- **字符集**: utf8mb4
|
||||
- **排序规则**: utf8mb4_general_ci
|
||||
- **连接池**: 建议使用
|
||||
- **SQL文件位置**: `public/install/crmeb.sql`
|
||||
|
||||
### 2.2 技术栈
|
||||
|
||||
@ -108,4 +109,297 @@ return [
|
||||
| 字段名 | 数据类型 | 长度 | 约束 | 描述 |
|
||||
|-------|---------|------|------|------|
|
||||
| `id` | `INT` | 11 | `PRIMARY KEY AUTO_INCREMENT` | 用户ID |
|
||||
| `username
|
||||
| `username` | `VARCHAR` | 50 | `NOT NULL` | 用户名 |
|
||||
| `password` | `VARCHAR` | 255 | `NOT NULL` | 密码 |
|
||||
| `nickname` | `VARCHAR` | 50 | `NOT NULL` | 昵称 |
|
||||
| `avatar` | `VARCHAR` | 255 | | 头像 |
|
||||
| `mobile` | `VARCHAR` | 20 | | 手机号 |
|
||||
| `email` | `VARCHAR` | 100 | | 邮箱 |
|
||||
| `status` | `TINYINT` | 1 | `DEFAULT 1` | 状态 |
|
||||
| `create_time` | `DATETIME` | | `DEFAULT CURRENT_TIMESTAMP` | 创建时间 |
|
||||
| `update_time` | `DATETIME` | | `DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP` | 更新时间 |
|
||||
| `delete_time` | `DATETIME` | | | 删除时间 |
|
||||
|
||||
### 4.2 商品表 (`product`)
|
||||
|
||||
| 字段名 | 数据类型 | 长度 | 约束 | 描述 |
|
||||
|-------|---------|------|------|------|
|
||||
| `id` | `INT` | 11 | `PRIMARY KEY AUTO_INCREMENT` | 商品ID |
|
||||
| `name` | `VARCHAR` | 255 | `NOT NULL` | 商品名称 |
|
||||
| `category_id` | `INT` | 11 | `NOT NULL` | 分类ID |
|
||||
| `price` | `DECIMAL` | 10,2 | `NOT NULL` | 价格 |
|
||||
| `stock` | `INT` | 11 | `NOT NULL` | 库存 |
|
||||
| `status` | `TINYINT` | 1 | `DEFAULT 1` | 状态 |
|
||||
| `create_time` | `DATETIME` | | `DEFAULT CURRENT_TIMESTAMP` | 创建时间 |
|
||||
| `update_time` | `DATETIME` | | `DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP` | 更新时间 |
|
||||
| `delete_time` | `DATETIME` | | | 删除时间 |
|
||||
|
||||
### 4.3 订单表 (`order`)
|
||||
|
||||
| 字段名 | 数据类型 | 长度 | 约束 | 描述 |
|
||||
|-------|---------|------|------|------|
|
||||
| `id` | `INT` | 11 | `PRIMARY KEY AUTO_INCREMENT` | 订单ID |
|
||||
| `order_sn` | `VARCHAR` | 32 | `NOT NULL UNIQUE` | 订单号 |
|
||||
| `user_id` | `INT` | 11 | `NOT NULL` | 用户ID |
|
||||
| `total_price` | `DECIMAL` | 10,2 | `NOT NULL` | 总价 |
|
||||
| `status` | `TINYINT` | 1 | `DEFAULT 0` | 状态 |
|
||||
| `create_time` | `DATETIME` | | `DEFAULT CURRENT_TIMESTAMP` | 创建时间 |
|
||||
| `update_time` | `DATETIME` | | `DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP` | 更新时间 |
|
||||
| `delete_time` | `DATETIME` | | | 删除时间 |
|
||||
|
||||
### 4.4 分类表 (`category`)
|
||||
|
||||
| 字段名 | 数据类型 | 长度 | 约束 | 描述 |
|
||||
|-------|---------|------|------|------|
|
||||
| `id` | `INT` | 11 | `PRIMARY KEY AUTO_INCREMENT` | 分类ID |
|
||||
| `name` | `VARCHAR` | 50 | `NOT NULL` | 分类名称 |
|
||||
| `parent_id` | `INT` | 11 | `DEFAULT 0` | 父分类ID |
|
||||
| `sort` | `INT` | 11 | `DEFAULT 0` | 排序 |
|
||||
| `status` | `TINYINT` | 1 | `DEFAULT 1` | 状态 |
|
||||
| `create_time` | `DATETIME` | | `DEFAULT CURRENT_TIMESTAMP` | 创建时间 |
|
||||
| `update_time` | `DATETIME` | | `DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP` | 更新时间 |
|
||||
| `delete_time` | `DATETIME` | | | 删除时间 |
|
||||
|
||||
### 4.5 地址表 (`address`)
|
||||
|
||||
| 字段名 | 数据类型 | 长度 | 约束 | 描述 |
|
||||
|-------|---------|------|------|------|
|
||||
| `id` | `INT` | 11 | `PRIMARY KEY AUTO_INCREMENT` | 地址ID |
|
||||
| `user_id` | `INT` | 11 | `NOT NULL` | 用户ID |
|
||||
| `name` | `VARCHAR` | 50 | `NOT NULL` | 收货人姓名 |
|
||||
| `mobile` | `VARCHAR` | 20 | `NOT NULL` | 手机号 |
|
||||
| `province` | `VARCHAR` | 50 | `NOT NULL` | 省份 |
|
||||
| `city` | `VARCHAR` | 50 | `NOT NULL` | 城市 |
|
||||
| `district` | `VARCHAR` | 50 | `NOT NULL` | 区县 |
|
||||
| `detail` | `VARCHAR` | 255 | `NOT NULL` | 详细地址 |
|
||||
| `is_default` | `TINYINT` | 1 | `DEFAULT 0` | 是否默认 |
|
||||
| `create_time` | `DATETIME` | | `DEFAULT CURRENT_TIMESTAMP` | 创建时间 |
|
||||
| `update_time` | `DATETIME` | | `DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP` | 更新时间 |
|
||||
| `delete_time` | `DATETIME` | | | 删除时间 |
|
||||
|
||||
## 5. 索引设计
|
||||
|
||||
### 5.1 用户表索引
|
||||
|
||||
| 索引名 | 类型 | 字段 | 描述 |
|
||||
|-------|------|------|------|
|
||||
| `PRIMARY` | 主键 | `id` | 主键索引 |
|
||||
| `uk_username` | 唯一 | `username` | 用户名唯一索引 |
|
||||
| `idx_mobile` | 普通 | `mobile` | 手机号索引 |
|
||||
| `idx_email` | 普通 | `email` | 邮箱索引 |
|
||||
| `idx_status` | 普通 | `status` | 状态索引 |
|
||||
|
||||
### 5.2 商品表索引
|
||||
|
||||
| 索引名 | 类型 | 字段 | 描述 |
|
||||
|-------|------|------|------|
|
||||
| `PRIMARY` | 主键 | `id` | 主键索引 |
|
||||
| `idx_category_id` | 普通 | `category_id` | 分类ID索引 |
|
||||
| `idx_price` | 普通 | `price` | 价格索引 |
|
||||
| `idx_status` | 普通 | `status` | 状态索引 |
|
||||
|
||||
### 5.3 订单表索引
|
||||
|
||||
| 索引名 | 类型 | 字段 | 描述 |
|
||||
|-------|------|------|------|
|
||||
| `PRIMARY` | 主键 | `id` | 主键索引 |
|
||||
| `uk_order_sn` | 唯一 | `order_sn` | 订单号唯一索引 |
|
||||
| `idx_user_id` | 普通 | `user_id` | 用户ID索引 |
|
||||
| `idx_status` | 普通 | `status` | 状态索引 |
|
||||
| `idx_create_time` | 普通 | `create_time` | 创建时间索引 |
|
||||
|
||||
### 5.4 分类表索引
|
||||
|
||||
| 索引名 | 类型 | 字段 | 描述 |
|
||||
|-------|------|------|------|
|
||||
| `PRIMARY` | 主键 | `id` | 主键索引 |
|
||||
| `idx_parent_id` | 普通 | `parent_id` | 父分类ID索引 |
|
||||
| `idx_sort` | 普通 | `sort` | 排序索引 |
|
||||
| `idx_status` | 普通 | `status` | 状态索引 |
|
||||
|
||||
### 5.5 地址表索引
|
||||
|
||||
| 索引名 | 类型 | 字段 | 描述 |
|
||||
|-------|------|------|------|
|
||||
| `PRIMARY` | 主键 | `id` | 主键索引 |
|
||||
| `idx_user_id` | 普通 | `user_id` | 用户ID索引 |
|
||||
| `idx_is_default` | 普通 | `is_default` | 是否默认索引 |
|
||||
|
||||
## 6. 关系设计
|
||||
|
||||
### 6.1 表关系图
|
||||
|
||||
```
|
||||
user ----------------- order
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
address product
|
||||
|
|
||||
|
|
||||
|
|
||||
category
|
||||
```
|
||||
|
||||
### 6.2 关系说明
|
||||
|
||||
- **用户与订单**: 一对多关系,一个用户可以有多个订单
|
||||
- **用户与地址**: 一对多关系,一个用户可以有多个地址
|
||||
- **商品与分类**: 多对一关系,多个商品属于一个分类
|
||||
- **订单与商品**: 多对多关系,一个订单可以包含多个商品,一个商品可以出现在多个订单中
|
||||
|
||||
### 6.3 外键关系
|
||||
|
||||
| 主表 | 主键 | 从表 | 外键 | 描述 |
|
||||
|------|------|------|------|------|
|
||||
| `user` | `id` | `order` | `user_id` | 订单所属用户 |
|
||||
| `user` | `id` | `address` | `user_id` | 地址所属用户 |
|
||||
| `category` | `id` | `product` | `category_id` | 商品所属分类 |
|
||||
|
||||
## 7. 性能优化
|
||||
|
||||
### 7.1 索引优化
|
||||
|
||||
- **选择合适的索引类型**: 根据查询场景选择合适的索引类型
|
||||
- **避免过度索引**: 只在需要的字段上创建索引
|
||||
- **使用复合索引**: 对于多字段查询,使用复合索引
|
||||
- **定期维护索引**: 定期重建碎片化的索引
|
||||
|
||||
### 7.2 查询优化
|
||||
|
||||
- **避免全表扫描**: 使用索引覆盖查询
|
||||
- **减少查询字段**: 只查询需要的字段
|
||||
- **使用连接查询**: 合理使用连接查询,避免子查询
|
||||
- **限制查询结果**: 使用 LIMIT 限制查询结果数量
|
||||
|
||||
### 7.3 存储优化
|
||||
|
||||
- **选择合适的字段类型**: 根据实际需求选择合适的字段类型
|
||||
- **使用分区表**: 对于大表,使用分区表提高查询性能
|
||||
- **定期清理数据**: 定期清理无用数据,减少表大小
|
||||
- **使用缓存**: 对于频繁查询的数据,使用 Redis 缓存
|
||||
|
||||
### 7.4 配置优化
|
||||
|
||||
- **调整 innodb_buffer_pool_size**: 根据服务器内存大小调整
|
||||
- **调整 max_connections**: 根据并发量调整
|
||||
- **启用查询缓存**: 对于读多写少的场景
|
||||
- **优化日志配置**: 合理配置二进制日志和慢查询日志
|
||||
|
||||
## 8. 安全设计
|
||||
|
||||
### 8.1 数据安全
|
||||
|
||||
- **加密存储**: 敏感数据(如密码)加密存储
|
||||
- **数据备份**: 定期备份数据库
|
||||
- **数据恢复**: 建立数据恢复机制
|
||||
- **访问控制**: 严格控制数据库访问权限
|
||||
|
||||
### 8.2 SQL 注入防护
|
||||
|
||||
- **使用参数化查询**: 避免直接拼接 SQL
|
||||
- **使用 ORM**: 使用 ThinkPHP ORM 框架
|
||||
- **输入验证**: 对用户输入进行验证
|
||||
- **转义特殊字符**: 对特殊字符进行转义
|
||||
|
||||
### 8.3 权限管理
|
||||
|
||||
- **最小权限原则**: 只授予必要的权限
|
||||
- **角色分离**: 不同角色拥有不同权限
|
||||
- **定期审计**: 定期审计数据库访问日志
|
||||
|
||||
## 9. 备份与恢复
|
||||
|
||||
### 9.1 备份策略
|
||||
|
||||
- **全量备份**: 定期进行全量备份
|
||||
- **增量备份**: 每天进行增量备份
|
||||
- **日志备份**: 备份二进制日志
|
||||
|
||||
### 9.2 恢复策略
|
||||
|
||||
- **全量恢复**: 使用全量备份恢复
|
||||
- **增量恢复**: 使用增量备份恢复
|
||||
- **点恢复**: 使用二进制日志进行点恢复
|
||||
|
||||
### 9.3 备份工具
|
||||
|
||||
- **mysqldump**: MySQL 自带备份工具
|
||||
- **xtrabackup**: Percona 提供的备份工具
|
||||
- **第三方工具**: 如 Navicat 等
|
||||
|
||||
## 10. 版本控制
|
||||
|
||||
### 10.1 数据库迁移
|
||||
|
||||
- **使用迁移工具**: 使用 ThinkPHP 数据库迁移工具
|
||||
- **版本管理**: 对数据库结构变更进行版本管理
|
||||
- **回滚机制**: 支持数据库结构回滚
|
||||
|
||||
### 10.2 迁移文件命名规范
|
||||
|
||||
- **格式**: `YYYYMMDDHHMMSS_描述.php`
|
||||
- **示例**: `20230101000000_create_user_table.php`
|
||||
|
||||
### 10.3 迁移文件结构
|
||||
|
||||
```php
|
||||
<?php
|
||||
use think\migration\Migrator;
|
||||
use think\migration\db\Column;
|
||||
|
||||
class CreateUserTable extends Migrator
|
||||
{
|
||||
public function change()
|
||||
{
|
||||
$table = $this->table('user');
|
||||
$table->addColumn('username', 'string', ['limit' => 50, 'comment' => '用户名'])
|
||||
->addColumn('password', 'string', ['limit' => 255, 'comment' => '密码'])
|
||||
->addColumn('nickname', 'string', ['limit' => 50, 'comment' => '昵称'])
|
||||
->addColumn('avatar', 'string', ['limit' => 255, 'comment' => '头像'])
|
||||
->addColumn('mobile', 'string', ['limit' => 20, 'comment' => '手机号'])
|
||||
->addColumn('email', 'string', ['limit' => 100, 'comment' => '邮箱'])
|
||||
->addColumn('status', 'tinyint', ['default' => 1, 'comment' => '状态'])
|
||||
->addColumn('create_time', 'datetime', ['default' => 'CURRENT_TIMESTAMP', 'comment' => '创建时间'])
|
||||
->addColumn('update_time', 'datetime', ['default' => 'CURRENT_TIMESTAMP', 'update' => 'CURRENT_TIMESTAMP', 'comment' => '更新时间'])
|
||||
->addColumn('delete_time', 'datetime', ['comment' => '删除时间'])
|
||||
->addIndex('username', ['unique' => true])
|
||||
->addIndex('mobile')
|
||||
->addIndex('email')
|
||||
->addIndex('status')
|
||||
->create();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 11. 维护与监控
|
||||
|
||||
### 11.1 日常维护
|
||||
|
||||
- **定期优化表**: 定期执行 OPTIMIZE TABLE 命令
|
||||
- **监控表大小**: 监控表大小变化
|
||||
- **检查慢查询**: 定期分析慢查询日志
|
||||
- **更新统计信息**: 定期更新表统计信息
|
||||
|
||||
### 11.2 监控指标
|
||||
|
||||
- **查询性能**: 监控查询响应时间
|
||||
- **连接数**: 监控数据库连接数
|
||||
- **缓存命中率**: 监控缓存命中率
|
||||
- **磁盘使用率**: 监控磁盘空间使用情况
|
||||
- **CPU 使用率**: 监控数据库服务器 CPU 使用率
|
||||
|
||||
### 11.3 监控工具
|
||||
|
||||
- **MySQL Enterprise Monitor**: MySQL 企业版监控工具
|
||||
- **Percona Monitoring and Management**: 开源监控工具
|
||||
- **Zabbix**: 通用监控工具
|
||||
- **Prometheus + Grafana**: 现代化监控方案
|
||||
|
||||
## 12. 总结
|
||||
|
||||
本文档描述了 CRMEB 项目的数据库设计规范和最佳实践,包括数据库架构、表结构、索引设计、关系设计、性能优化、安全设计、备份与恢复、版本控制、维护与监控等方面。
|
||||
|
||||
遵循本文档的设计规范,可以提高数据库性能和可维护性,确保系统的稳定运行。同时,定期对数据库进行维护和监控,可以及时发现和解决潜在问题,保障系统的安全性和可靠性。
|
||||
|
||||
随着业务的发展和系统的演进,数据库设计也需要不断优化和调整,以适应新的业务需求和技术挑战。
|
||||
525
.trae/skills/php-api/references/php_commands.md
Normal file
525
.trae/skills/php-api/references/php_commands.md
Normal file
@ -0,0 +1,525 @@
|
||||
# PHP常用命令文档
|
||||
|
||||
## 1. 概述
|
||||
|
||||
本文档描述了 CRMEB 项目中常用的 PHP 命令,包括 PHP 基础命令、Composer 命令、ThinkPHP 命令、CRMEB 特定命令等,旨在帮助开发者快速了解和使用这些命令,提高开发效率。
|
||||
|
||||
## 2. PHP 基础命令
|
||||
|
||||
### 2.1 PHP 版本查看
|
||||
|
||||
```bash
|
||||
# 查看 PHP 版本
|
||||
php -v
|
||||
|
||||
# 查看 PHP 详细信息
|
||||
php -i
|
||||
|
||||
# 查看 PHP 配置文件位置
|
||||
php --ini
|
||||
```
|
||||
|
||||
### 2.2 PHP 运行命令
|
||||
|
||||
```bash
|
||||
# 运行 PHP 文件
|
||||
php filename.php
|
||||
|
||||
# 交互式运行 PHP
|
||||
php -a
|
||||
|
||||
# 执行 PHP 代码
|
||||
php -r "echo 'Hello, CRMEB!';"
|
||||
|
||||
# 检查语法错误
|
||||
php -l filename.php
|
||||
```
|
||||
|
||||
### 2.3 PHP 扩展管理
|
||||
|
||||
```bash
|
||||
# 查看已安装的扩展
|
||||
php -m
|
||||
|
||||
# 查看特定扩展的信息
|
||||
php -i | grep extension_name
|
||||
|
||||
# 查看扩展目录
|
||||
php -i | grep extension_dir
|
||||
```
|
||||
|
||||
## 3. Composer 命令
|
||||
|
||||
### 3.1 Composer 基础命令
|
||||
|
||||
```bash
|
||||
# 查看 Composer 版本
|
||||
composer -V
|
||||
|
||||
# 初始化 Composer 项目
|
||||
composer init
|
||||
|
||||
# 安装依赖
|
||||
composer install
|
||||
|
||||
# 更新依赖
|
||||
composer update
|
||||
|
||||
# 添加新依赖
|
||||
composer require package_name
|
||||
|
||||
# 移除依赖
|
||||
composer remove package_name
|
||||
|
||||
# 查看已安装的依赖
|
||||
composer show
|
||||
|
||||
# 优化自动加载
|
||||
composer dump-autoload
|
||||
|
||||
# 优化自动加载(生产环境)
|
||||
composer dump-autoload --optimize
|
||||
```
|
||||
|
||||
### 3.2 Composer 配置命令
|
||||
|
||||
```bash
|
||||
# 查看 Composer 配置
|
||||
composer config --list
|
||||
|
||||
# 设置 Composer 镜像
|
||||
composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/
|
||||
|
||||
# 取消 Composer 镜像设置
|
||||
composer config -g --unset repo.packagist
|
||||
```
|
||||
|
||||
## 4. ThinkPHP 命令
|
||||
|
||||
### 4.1 ThinkPHP 基础命令
|
||||
|
||||
```bash
|
||||
# 查看 ThinkPHP 命令列表
|
||||
php think
|
||||
|
||||
# 查看命令帮助
|
||||
php think help command_name
|
||||
|
||||
# 清除缓存
|
||||
php think clear
|
||||
|
||||
# 查看路由列表
|
||||
php think route:list
|
||||
|
||||
# 生成应用密钥
|
||||
php think generate:key
|
||||
```
|
||||
|
||||
### 4.2 数据库相关命令
|
||||
|
||||
```bash
|
||||
# 运行数据库迁移
|
||||
php think migrate:run
|
||||
|
||||
# 回滚数据库迁移
|
||||
php think migrate:rollback
|
||||
|
||||
# 创建数据库迁移文件
|
||||
php think migrate:create migration_name
|
||||
|
||||
# 运行数据库种子
|
||||
php think seed:run
|
||||
|
||||
# 创建数据库种子文件
|
||||
php think seed:create seed_name
|
||||
```
|
||||
|
||||
### 4.3 代码生成命令
|
||||
|
||||
```bash
|
||||
# 生成模型
|
||||
php think make:model ModelName
|
||||
|
||||
# 生成控制器
|
||||
php think make:controller ControllerName
|
||||
|
||||
# 生成中间件
|
||||
php think make:middleware MiddlewareName
|
||||
|
||||
# 生成验证器
|
||||
php think make:validate ValidateName
|
||||
|
||||
# 生成事件
|
||||
php think make:event EventName
|
||||
|
||||
# 生成监听器
|
||||
php think make:listener ListenerName
|
||||
```
|
||||
|
||||
## 5. CRMEB 特定命令
|
||||
|
||||
### 5.1 CRMEB 代码生成命令
|
||||
|
||||
```bash
|
||||
# 生成 CRUD 代码
|
||||
php think crmeb:build
|
||||
|
||||
# 生成 API 接口
|
||||
php think crmeb:api
|
||||
|
||||
# 生成后台管理
|
||||
php think crmeb:admin
|
||||
```
|
||||
|
||||
### 5.2 CRMEB 系统命令
|
||||
|
||||
```bash
|
||||
# 查看系统版本
|
||||
php think crmeb:version
|
||||
|
||||
# 系统初始化
|
||||
php think crmeb:init
|
||||
|
||||
# 清理系统缓存
|
||||
php think crmeb:clear
|
||||
|
||||
# 生成系统配置
|
||||
php think crmeb:config
|
||||
```
|
||||
|
||||
### 5.3 队列相关命令
|
||||
|
||||
```bash
|
||||
# 启动队列监听器
|
||||
php think queue:listen
|
||||
|
||||
# 启动队列工作进程
|
||||
php think queue:work
|
||||
|
||||
# 查看队列状态
|
||||
php think queue:status
|
||||
|
||||
# 重启队列
|
||||
php think queue:restart
|
||||
```
|
||||
|
||||
### 5.4 定时任务命令
|
||||
|
||||
```bash
|
||||
# 启动定时任务
|
||||
php think timer start --d
|
||||
|
||||
# 停止定时任务
|
||||
php think timer stop
|
||||
|
||||
# 查看定时任务状态
|
||||
php think timer status
|
||||
```
|
||||
|
||||
### 5.5 长连接命令
|
||||
|
||||
```bash
|
||||
# 启动长连接服务
|
||||
php think workerman start --d
|
||||
|
||||
# 停止长连接服务
|
||||
php think workerman stop
|
||||
|
||||
# 重启长连接服务
|
||||
php think workerman restart
|
||||
|
||||
# 查看长连接服务状态
|
||||
php think workerman status
|
||||
```
|
||||
|
||||
## 6. 开发工具命令
|
||||
|
||||
### 6.1 代码检查命令
|
||||
|
||||
```bash
|
||||
# 使用 PHP_CodeSniffer 检查代码规范
|
||||
./vendor/bin/phpcs
|
||||
|
||||
# 使用 PHPStan 进行静态分析
|
||||
./vendor/bin/phpstan analyze
|
||||
|
||||
# 使用 Psalm 进行静态分析
|
||||
./vendor/bin/psalm
|
||||
```
|
||||
|
||||
### 6.2 测试命令
|
||||
|
||||
```bash
|
||||
# 运行 PHPUnit 测试
|
||||
./vendor/bin/phpunit
|
||||
|
||||
# 运行特定测试
|
||||
./vendor/bin/phpunit tests/TestCase.php
|
||||
|
||||
# 生成测试覆盖率报告
|
||||
./vendor/bin/phpunit --coverage-html coverage
|
||||
```
|
||||
|
||||
### 6.3 代码格式化命令
|
||||
|
||||
```bash
|
||||
# 使用 PHP-CS-Fixer 格式化代码
|
||||
./vendor/bin/php-cs-fixer fix
|
||||
|
||||
# 使用 Pretty PHP 格式化代码
|
||||
./vendor/bin/pretty-php
|
||||
```
|
||||
|
||||
## 7. 部署命令
|
||||
|
||||
### 7.1 项目构建命令
|
||||
|
||||
```bash
|
||||
# 安装依赖(生产环境)
|
||||
composer install --no-dev --optimize-autoloader
|
||||
|
||||
# 编译前端资源
|
||||
npm install
|
||||
npm run build
|
||||
|
||||
# 清理缓存
|
||||
php think clear
|
||||
```
|
||||
|
||||
### 7.2 服务器部署命令
|
||||
|
||||
```bash
|
||||
# 上传代码到服务器
|
||||
scp -r local_directory user@server:/remote_directory
|
||||
|
||||
# 远程执行命令
|
||||
ssh user@server "cd /project/directory && php think clear"
|
||||
|
||||
# 使用 rsync 同步代码
|
||||
rsync -avz --exclude='.git' --exclude='vendor' local_directory/ user@server:/remote_directory/
|
||||
```
|
||||
|
||||
### 7.3 Docker 部署命令
|
||||
|
||||
```bash
|
||||
# 构建 Docker 镜像
|
||||
docker build -t crmeb .
|
||||
|
||||
# 运行 Docker 容器
|
||||
docker run -d --name crmeb -p 80:80 crmeb
|
||||
|
||||
# 查看 Docker 容器状态
|
||||
docker ps
|
||||
|
||||
# 进入 Docker 容器
|
||||
docker exec -it crmeb bash
|
||||
```
|
||||
|
||||
## 8. 数据库命令
|
||||
|
||||
### 8.1 MySQL 命令
|
||||
|
||||
```bash
|
||||
# 连接 MySQL 数据库
|
||||
mysql -u username -p database_name
|
||||
|
||||
# 导入 SQL 文件
|
||||
mysql -u username -p database_name < crmeb.sql
|
||||
|
||||
# 导出 SQL 文件
|
||||
mysqldump -u username -p database_name > backup.sql
|
||||
|
||||
# 导出特定表
|
||||
mysqldump -u username -p database_name table1 table2 > backup.sql
|
||||
```
|
||||
|
||||
### 8.2 数据库迁移命令
|
||||
|
||||
```bash
|
||||
# 创建迁移文件
|
||||
php think migrate:create CreateUsersTable
|
||||
|
||||
# 运行迁移
|
||||
php think migrate:run
|
||||
|
||||
# 回滚迁移
|
||||
php think migrate:rollback
|
||||
|
||||
# 查看迁移状态
|
||||
php think migrate:status
|
||||
```
|
||||
|
||||
### 8.3 数据库种子命令
|
||||
|
||||
```bash
|
||||
# 创建种子文件
|
||||
php think seed:create UserSeeder
|
||||
|
||||
# 运行种子
|
||||
php think seed:run
|
||||
|
||||
# 运行特定种子
|
||||
php think seed:run --seed=UserSeeder
|
||||
```
|
||||
|
||||
## 9. 性能优化命令
|
||||
|
||||
### 9.1 代码优化命令
|
||||
|
||||
```bash
|
||||
# 优化 Composer 自动加载
|
||||
composer dump-autoload --optimize --classmap-authoritative
|
||||
|
||||
# 生成 OPcache 预热脚本
|
||||
php -r '$files = glob(__DIR__ . "/vendor/**/*.php", GLOB_BRACE); foreach ($files as $file) { require_once $file; }'
|
||||
```
|
||||
|
||||
### 9.2 缓存优化命令
|
||||
|
||||
```bash
|
||||
# 清除所有缓存
|
||||
php think clear
|
||||
|
||||
# 清除模板缓存
|
||||
php think clear --template
|
||||
|
||||
# 清除配置缓存
|
||||
php think clear --config
|
||||
|
||||
# 清除路由缓存
|
||||
php think clear --route
|
||||
```
|
||||
|
||||
### 9.3 数据库优化命令
|
||||
|
||||
```bash
|
||||
# 优化 MySQL 表
|
||||
mysql -u username -p -e "OPTIMIZE TABLE table1, table2;" database_name
|
||||
|
||||
# 修复 MySQL 表
|
||||
mysql -u username -p -e "REPAIR TABLE table1, table2;" database_name
|
||||
|
||||
# 分析 MySQL 表
|
||||
mysql -u username -p -e "ANALYZE TABLE table1, table2;" database_name
|
||||
```
|
||||
|
||||
## 10. 故障排查命令
|
||||
|
||||
### 10.1 日志查看命令
|
||||
|
||||
```bash
|
||||
# 查看 Nginx 错误日志
|
||||
tail -f /var/log/nginx/error.log
|
||||
|
||||
# 查看 PHP-FPM 错误日志
|
||||
tail -f /var/log/php-fpm/error.log
|
||||
|
||||
# 查看 CRMEB 应用日志
|
||||
tail -f runtime/log/$(date +%Y%m%d).log
|
||||
|
||||
# 查看慢查询日志
|
||||
tail -f /var/log/mysql/mysql-slow.log
|
||||
```
|
||||
|
||||
### 10.2 进程查看命令
|
||||
|
||||
```bash
|
||||
# 查看 PHP-FPM 进程
|
||||
ps aux | grep php-fpm
|
||||
|
||||
# 查看 Nginx 进程
|
||||
ps aux | grep nginx
|
||||
|
||||
# 查看 MySQL 进程
|
||||
ps aux | grep mysql
|
||||
|
||||
# 查看 CRMEB 队列进程
|
||||
ps aux | grep queue:work
|
||||
```
|
||||
|
||||
### 10.3 网络查看命令
|
||||
|
||||
```bash
|
||||
# 查看端口占用
|
||||
netstat -tuln
|
||||
|
||||
# 查看特定端口占用
|
||||
lsof -i :80
|
||||
|
||||
# 查看网络连接
|
||||
netstat -an | grep ESTABLISHED
|
||||
|
||||
# 测试网络连接
|
||||
ping example.com
|
||||
|
||||
# 测试端口连接
|
||||
telnet example.com 80
|
||||
```
|
||||
|
||||
## 11. 最佳实践
|
||||
|
||||
### 11.1 命令使用建议
|
||||
|
||||
- **使用绝对路径**: 执行命令时尽量使用绝对路径,避免路径问题
|
||||
- **添加执行权限**: 对于脚本文件,记得添加执行权限
|
||||
- **使用别名**: 对于常用命令,可以在 `.bashrc` 或 `.zshrc` 中添加别名
|
||||
- **查看帮助**: 遇到不熟悉的命令,使用 `--help` 查看帮助信息
|
||||
- **记录常用命令**: 将常用命令记录在文档中,方便查阅
|
||||
|
||||
### 11.2 安全建议
|
||||
|
||||
- **避免使用 root 用户**: 执行 PHP 命令时,避免使用 root 用户
|
||||
- **保护敏感信息**: 避免在命令行中直接输入密码等敏感信息
|
||||
- **限制命令执行权限**: 对于生产环境,限制命令的执行权限
|
||||
- **定期更新依赖**: 定期使用 `composer update` 更新依赖,修复安全漏洞
|
||||
|
||||
### 11.3 性能建议
|
||||
|
||||
- **使用缓存**: 对于频繁执行的命令,考虑使用缓存
|
||||
- **并行执行**: 对于独立的任务,可以考虑并行执行
|
||||
- **限制输出**: 对于产生大量输出的命令,使用管道或重定向限制输出
|
||||
- **使用后台执行**: 对于耗时较长的命令,使用后台执行
|
||||
|
||||
## 12. 常见问题
|
||||
|
||||
### 12.1 PHP 命令执行失败
|
||||
|
||||
- **问题**: 执行 PHP 命令时提示 "Command not found"
|
||||
- **解决方案**: 检查 PHP 是否已安装,以及是否在 PATH 环境变量中
|
||||
|
||||
### 12.2 Composer 命令执行失败
|
||||
|
||||
- **问题**: 执行 Composer 命令时提示 "Composer could not find a composer.json file"
|
||||
- **解决方案**: 确保在项目根目录执行命令,且存在 composer.json 文件
|
||||
|
||||
### 12.3 ThinkPHP 命令执行失败
|
||||
|
||||
- **问题**: 执行 ThinkPHP 命令时提示 "Class not found"
|
||||
- **解决方案**: 执行 `composer dump-autoload` 更新自动加载
|
||||
|
||||
### 12.4 数据库命令执行失败
|
||||
|
||||
- **问题**: 执行数据库命令时提示 "Access denied for user"
|
||||
- **解决方案**: 检查数据库用户名和密码是否正确,以及是否有相应的权限
|
||||
|
||||
### 12.5 队列命令执行失败
|
||||
|
||||
- **问题**: 执行队列命令时提示 "Queue not found"
|
||||
- **解决方案**: 检查队列配置是否正确,以及队列服务是否启动
|
||||
|
||||
## 13. 参考资源
|
||||
|
||||
- [PHP 官方文档](https://www.php.net/docs.php)
|
||||
- [Composer 官方文档](https://getcomposer.org/doc/)
|
||||
- [ThinkPHP 官方文档](https://www.kancloud.cn/manual/thinkphp6_0)
|
||||
- [MySQL 官方文档](https://dev.mysql.com/doc/)
|
||||
- [Docker 官方文档](https://docs.docker.com/)
|
||||
- [Linux 命令大全](https://www.runoob.com/linux/linux-command-manual.html)
|
||||
|
||||
## 14. 总结
|
||||
|
||||
本文档介绍了 CRMEB 项目中常用的 PHP 命令,包括 PHP 基础命令、Composer 命令、ThinkPHP 命令、CRMEB 特定命令、数据库命令、性能优化命令、故障排查命令等。
|
||||
|
||||
通过掌握这些命令,开发者可以更加高效地进行项目开发、部署和维护。同时,本文档也提供了一些最佳实践和常见问题的解决方案,希望能够帮助开发者避免一些常见的问题。
|
||||
|
||||
随着项目的发展和技术的演进,这些命令也可能会有所变化,建议开发者定期查阅相关文档,了解最新的命令和用法。
|
||||
@ -447,6 +447,11 @@ pages/
|
||||
- [Stack Overflow](https://stackoverflow.com/)
|
||||
- [掘金](https://juejin.cn/)
|
||||
|
||||
### 12.4 本地参考文档
|
||||
- [UniApp 目录结构文档](./references/directory_structure.md)
|
||||
- [UniApp API 开发流程文档](./references/api_flow.md)
|
||||
- [UniApp 代码规范文档](./references/code_style.md)
|
||||
|
||||
## 13. 团队协作
|
||||
|
||||
### 13.1 协作流程
|
||||
|
||||
472
.trae/skills/uniapp/references/api_flow.md
Normal file
472
.trae/skills/uniapp/references/api_flow.md
Normal file
@ -0,0 +1,472 @@
|
||||
# UniApp API 开发流程文档
|
||||
|
||||
## 1. 概述
|
||||
|
||||
本文档描述了 CRMEB 项目中 UniApp 移动端的 API 开发流程,包括 API 接口设计、请求流程、响应处理、错误处理等,旨在规范 API 开发,提高开发效率和代码质量。
|
||||
|
||||
## 2. API 目录结构
|
||||
|
||||
```
|
||||
template/uni-app/api/
|
||||
├── activity.js # 活动相关接口
|
||||
├── admin.js # 管理相关接口
|
||||
├── api.js # 基础 API 配置
|
||||
├── kefu.js # 客服相关接口
|
||||
├── lottery.js # 抽奖相关接口
|
||||
├── order.js # 订单相关接口
|
||||
├── public.js # 公共接口
|
||||
├── store.js # 商城相关接口
|
||||
└── user.js # 用户相关接口
|
||||
```
|
||||
|
||||
## 3. 基础 API 配置 (api.js)
|
||||
|
||||
```javascript
|
||||
// 基础 API 配置
|
||||
const baseURL = 'https://api.crmeb.net';
|
||||
|
||||
// 请求超时时间
|
||||
const timeout = 10000;
|
||||
|
||||
// 请求拦截器
|
||||
const requestInterceptor = (config) => {
|
||||
// 添加 token
|
||||
const token = uni.getStorageSync('token');
|
||||
if (token) {
|
||||
config.header['Authorization'] = `Bearer ${token}`;
|
||||
}
|
||||
|
||||
// 添加设备信息
|
||||
config.header['X-Device-Type'] = uni.getSystemInfoSync().platform;
|
||||
|
||||
return config;
|
||||
};
|
||||
|
||||
// 响应拦截器
|
||||
const responseInterceptor = (response) => {
|
||||
const { data } = response;
|
||||
|
||||
// 统一处理错误
|
||||
if (data.code !== 200) {
|
||||
uni.showToast({
|
||||
title: data.message || '请求失败',
|
||||
icon: 'none'
|
||||
});
|
||||
|
||||
// 处理登录过期
|
||||
if (data.code === 401) {
|
||||
uni.redirectTo({
|
||||
url: '/pages/login/index'
|
||||
});
|
||||
}
|
||||
|
||||
return Promise.reject(data);
|
||||
}
|
||||
|
||||
return data;
|
||||
};
|
||||
|
||||
// 错误处理
|
||||
const errorHandler = (error) => {
|
||||
uni.showToast({
|
||||
title: '网络错误,请稍后重试',
|
||||
icon: 'none'
|
||||
});
|
||||
|
||||
return Promise.reject(error);
|
||||
};
|
||||
|
||||
// 导出配置
|
||||
export default {
|
||||
baseURL,
|
||||
timeout,
|
||||
requestInterceptor,
|
||||
responseInterceptor,
|
||||
errorHandler
|
||||
};
|
||||
```
|
||||
|
||||
## 4. API 接口封装
|
||||
|
||||
### 4.1 通用请求方法
|
||||
|
||||
```javascript
|
||||
// utils/request.js
|
||||
import apiConfig from '../api/api';
|
||||
|
||||
class Request {
|
||||
constructor() {
|
||||
this.baseURL = apiConfig.baseURL;
|
||||
this.timeout = apiConfig.timeout;
|
||||
}
|
||||
|
||||
// 通用请求方法
|
||||
request(options) {
|
||||
return new Promise((resolve, reject) => {
|
||||
// 应用请求拦截器
|
||||
if (apiConfig.requestInterceptor) {
|
||||
options = apiConfig.requestInterceptor(options);
|
||||
}
|
||||
|
||||
uni.request({
|
||||
url: this.baseURL + options.url,
|
||||
method: options.method || 'GET',
|
||||
data: options.data || {},
|
||||
header: options.header || {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
timeout: this.timeout,
|
||||
success: (response) => {
|
||||
// 应用响应拦截器
|
||||
if (apiConfig.responseInterceptor) {
|
||||
try {
|
||||
const result = apiConfig.responseInterceptor(response);
|
||||
resolve(result);
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
} else {
|
||||
resolve(response.data);
|
||||
}
|
||||
},
|
||||
fail: (error) => {
|
||||
// 应用错误处理器
|
||||
if (apiConfig.errorHandler) {
|
||||
apiConfig.errorHandler(error);
|
||||
}
|
||||
reject(error);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// GET 请求
|
||||
get(url, params = {}) {
|
||||
return this.request({
|
||||
url,
|
||||
method: 'GET',
|
||||
data: params
|
||||
});
|
||||
}
|
||||
|
||||
// POST 请求
|
||||
post(url, data = {}) {
|
||||
return this.request({
|
||||
url,
|
||||
method: 'POST',
|
||||
data
|
||||
});
|
||||
}
|
||||
|
||||
// PUT 请求
|
||||
put(url, data = {}) {
|
||||
return this.request({
|
||||
url,
|
||||
method: 'PUT',
|
||||
data
|
||||
});
|
||||
}
|
||||
|
||||
// DELETE 请求
|
||||
delete(url, params = {}) {
|
||||
return this.request({
|
||||
url,
|
||||
method: 'DELETE',
|
||||
data: params
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default new Request();
|
||||
```
|
||||
|
||||
### 4.2 业务接口封装
|
||||
|
||||
```javascript
|
||||
// api/user.js
|
||||
import request from '../utils/request';
|
||||
|
||||
// 用户相关接口
|
||||
export default {
|
||||
// 登录
|
||||
login: (data) => request.post('/api/user/login', data),
|
||||
|
||||
// 注册
|
||||
register: (data) => request.post('/api/user/register', data),
|
||||
|
||||
// 获取用户信息
|
||||
getUserInfo: () => request.get('/api/user/info'),
|
||||
|
||||
// 更新用户信息
|
||||
updateUserInfo: (data) => request.put('/api/user/info', data),
|
||||
|
||||
// 修改密码
|
||||
changePassword: (data) => request.post('/api/user/password', data),
|
||||
|
||||
// 获取地址列表
|
||||
getAddressList: () => request.get('/api/user/address'),
|
||||
|
||||
// 添加地址
|
||||
addAddress: (data) => request.post('/api/user/address', data),
|
||||
|
||||
// 更新地址
|
||||
updateAddress: (id, data) => request.put(`/api/user/address/${id}`, data),
|
||||
|
||||
// 删除地址
|
||||
deleteAddress: (id) => request.delete(`/api/user/address/${id}`),
|
||||
|
||||
// 设置默认地址
|
||||
setDefaultAddress: (id) => request.put(`/api/user/address/${id}/default`)
|
||||
};
|
||||
```
|
||||
|
||||
## 5. API 调用示例
|
||||
|
||||
### 5.1 页面中调用 API
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<view class="user-info">
|
||||
<view v-if="loading">加载中...</view>
|
||||
<view v-else>
|
||||
<image :src="userInfo.avatar" class="avatar"></image>
|
||||
<view class="name">{{ userInfo.nickname }}</view>
|
||||
<view class="mobile">{{ userInfo.mobile }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import userApi from '../../api/user';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
loading: false,
|
||||
userInfo: {}
|
||||
};
|
||||
},
|
||||
|
||||
onLoad() {
|
||||
this.getUserInfo();
|
||||
},
|
||||
|
||||
methods: {
|
||||
async getUserInfo() {
|
||||
try {
|
||||
this.loading = true;
|
||||
const res = await userApi.getUserInfo();
|
||||
this.userInfo = res.data;
|
||||
} catch (error) {
|
||||
console.error('获取用户信息失败:', error);
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
```
|
||||
|
||||
### 5.2 组件中调用 API
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<view class="address-item" v-for="item in addressList" :key="item.id">
|
||||
<view class="address-info">
|
||||
<view class="name">{{ item.name }} {{ item.mobile }}</view>
|
||||
<view class="detail">{{ item.province }}{{ item.city }}{{ item.district }}{{ item.detail }}</view>
|
||||
</view>
|
||||
<view class="address-actions">
|
||||
<button @click="editAddress(item)">编辑</button>
|
||||
<button @click="deleteAddress(item.id)">删除</button>
|
||||
<button v-if="!item.is_default" @click="setDefault(item.id)">设为默认</button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import userApi from '../../api/user';
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
addressList: []
|
||||
};
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.getAddressList();
|
||||
},
|
||||
|
||||
methods: {
|
||||
async getAddressList() {
|
||||
try {
|
||||
const res = await userApi.getAddressList();
|
||||
this.addressList = res.data;
|
||||
} catch (error) {
|
||||
console.error('获取地址列表失败:', error);
|
||||
}
|
||||
},
|
||||
|
||||
editAddress(item) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/address/edit?id=${item.id}`
|
||||
});
|
||||
},
|
||||
|
||||
async deleteAddress(id) {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '确定要删除这个地址吗?',
|
||||
success: async (res) => {
|
||||
if (res.confirm) {
|
||||
try {
|
||||
await userApi.deleteAddress(id);
|
||||
uni.showToast({
|
||||
title: '删除成功',
|
||||
icon: 'success'
|
||||
});
|
||||
this.getAddressList();
|
||||
} catch (error) {
|
||||
console.error('删除地址失败:', error);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
async setDefault(id) {
|
||||
try {
|
||||
await userApi.setDefaultAddress(id);
|
||||
uni.showToast({
|
||||
title: '设置成功',
|
||||
icon: 'success'
|
||||
});
|
||||
this.getAddressList();
|
||||
} catch (error) {
|
||||
console.error('设置默认地址失败:', error);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
```
|
||||
|
||||
## 6. API 开发最佳实践
|
||||
|
||||
### 6.1 命名规范
|
||||
|
||||
- **文件命名**: 小写字母,单词之间用下划线分隔,如 `user.js`
|
||||
- **方法命名**: 驼峰命名法,如 `getUserInfo`
|
||||
- **URL 命名**: 小写字母,单词之间用连字符分隔,如 `/api/user/info`
|
||||
- **参数命名**: 驼峰命名法,与后端保持一致
|
||||
|
||||
### 6.2 接口设计规范
|
||||
|
||||
- **RESTful 风格**: 遵循 RESTful API 设计规范
|
||||
- **版本控制**: 在 URL 中包含版本号,如 `/api/v1/user/info`
|
||||
- **统一响应格式**: 所有接口返回统一的响应格式
|
||||
- **错误处理**: 统一的错误码和错误信息
|
||||
|
||||
### 6.3 请求规范
|
||||
|
||||
- **请求方法**: 根据操作类型选择合适的 HTTP 方法
|
||||
- GET: 获取资源
|
||||
- POST: 创建资源
|
||||
- PUT: 更新资源
|
||||
- DELETE: 删除资源
|
||||
- **请求头**: 统一添加必要的请求头,如 Authorization、Content-Type 等
|
||||
- **参数传递**: 根据请求方法选择合适的参数传递方式
|
||||
- GET: 查询参数
|
||||
- POST/PUT: 请求体
|
||||
- DELETE: 查询参数或路径参数
|
||||
|
||||
### 6.4 响应规范
|
||||
|
||||
- **成功响应**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "请求成功",
|
||||
"data": {}
|
||||
}
|
||||
```
|
||||
- **失败响应**:
|
||||
```json
|
||||
{
|
||||
"code": 400,
|
||||
"message": "请求失败",
|
||||
"data": {}
|
||||
}
|
||||
```
|
||||
|
||||
### 6.5 错误处理规范
|
||||
|
||||
- **网络错误**: 统一处理网络错误,如超时、断网等
|
||||
- **业务错误**: 根据错误码处理不同的业务错误
|
||||
- **登录过期**: 统一处理登录过期,跳转到登录页面
|
||||
- **错误提示**: 统一的错误提示方式,使用 uni.showToast
|
||||
|
||||
## 7. API 性能优化
|
||||
|
||||
### 7.1 请求优化
|
||||
|
||||
- **合并请求**: 多个相关请求合并为一个
|
||||
- **缓存策略**: 对不经常变化的数据使用缓存
|
||||
- **请求防抖**: 避免频繁发送相同的请求
|
||||
- **批量操作**: 支持批量操作,减少请求次数
|
||||
|
||||
### 7.2 响应优化
|
||||
|
||||
- **数据结构优化**: 优化响应数据结构,减少数据传输量
|
||||
- **分页处理**: 对列表数据使用分页
|
||||
- **字段筛选**: 支持字段筛选,只返回需要的字段
|
||||
- **压缩传输**: 使用 gzip 压缩传输数据
|
||||
|
||||
### 7.3 代码优化
|
||||
|
||||
- **模块化**: 按业务模块划分 API 文件
|
||||
- **复用代码**: 提取通用的请求逻辑
|
||||
- **减少冗余**: 避免重复的 API 调用
|
||||
- **代码可读性**: 保持代码清晰易读
|
||||
|
||||
## 8. 常见问题
|
||||
|
||||
### 8.1 跨域问题
|
||||
|
||||
- **问题**: 开发环境中遇到跨域问题
|
||||
- **解决方案**: 在本地开发服务器中配置跨域代理
|
||||
|
||||
### 8.2 Token 过期问题
|
||||
|
||||
- **问题**: Token 过期后请求失败
|
||||
- **解决方案**: 在响应拦截器中处理 Token 过期,跳转到登录页面
|
||||
|
||||
### 8.3 请求超时问题
|
||||
|
||||
- **问题**: 网络不稳定时请求超时
|
||||
- **解决方案**: 设置合理的超时时间,添加网络状态检测
|
||||
|
||||
### 8.4 重复请求问题
|
||||
|
||||
- **问题**: 快速点击按钮导致重复请求
|
||||
- **解决方案**: 添加请求防抖或锁机制
|
||||
|
||||
### 8.5 数据缓存问题
|
||||
|
||||
- **问题**: 缓存数据与服务器数据不一致
|
||||
- **解决方案**: 合理设置缓存过期时间,提供手动刷新机制
|
||||
|
||||
## 9. 参考资源
|
||||
|
||||
- [UniApp 网络请求文档](https://uniapp.dcloud.io/api/request/request)
|
||||
- [RESTful API 设计指南](https://restfulapi.cn/)
|
||||
- [Axios 文档](https://axios-http.com/zh/docs/intro)
|
||||
- [HTTP 方法](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Methods)
|
||||
|
||||
## 10. 总结
|
||||
|
||||
本文档描述了 CRMEB 项目中 UniApp 移动端的 API 开发流程,包括 API 接口设计、请求流程、响应处理、错误处理等。遵循本文档的开发规范,可以提高 API 开发的效率和质量,确保应用的稳定性和可靠性。
|
||||
|
||||
随着业务的发展和技术的演进,API 开发流程也需要不断优化和调整,以适应新的业务需求和技术挑战。
|
||||
502
.trae/skills/uniapp/references/code_style.md
Normal file
502
.trae/skills/uniapp/references/code_style.md
Normal file
@ -0,0 +1,502 @@
|
||||
# UniApp 代码规范文档
|
||||
|
||||
## 1. 概述
|
||||
|
||||
本文档描述了 CRMEB 项目中 UniApp 移动端的代码规范,包括命名规范、代码风格、文件结构、组件开发等,旨在统一代码风格,提高代码质量和可维护性。
|
||||
|
||||
## 2. 命名规范
|
||||
|
||||
### 2.1 目录命名
|
||||
|
||||
- **目录名**: 小写字母,单词之间用下划线分隔
|
||||
- **示例**: `pages/index/`、`components/common/`、`utils/`
|
||||
- **规范**: 简洁明了,反映目录的功能
|
||||
|
||||
### 2.2 文件命名
|
||||
|
||||
- **页面文件**: 小写字母,单词之间用下划线分隔
|
||||
- **示例**: `index.vue`、`login.vue`、`user_info.vue`
|
||||
- **组件文件**: 大写字母开头的 PascalCase 命名风格
|
||||
- **示例**: `Button.vue`、`NavBar.vue`、`GoodsList.vue`
|
||||
- **JS 文件**: 小写字母,单词之间用下划线分隔
|
||||
- **示例**: `user.js`、`request.js`、`util.js`
|
||||
- **CSS/SCSS 文件**: 小写字母,单词之间用下划线分隔
|
||||
- **示例**: `common.scss`、`theme.scss`
|
||||
|
||||
### 2.3 变量命名
|
||||
|
||||
- **普通变量**: 驼峰命名法
|
||||
- **示例**: `userInfo`、`goodsList`、`isLoading`
|
||||
- **常量**: 全大写,单词之间用下划线分隔
|
||||
- **示例**: `BASE_URL`、`MAX_COUNT`、`DEFAULT_PAGE_SIZE`
|
||||
- **布尔变量**: 以 `is` 开头的驼峰命名法
|
||||
- **示例**: `isShow`、`isLoading`、`isLogin`
|
||||
|
||||
### 2.4 函数命名
|
||||
|
||||
- **函数名**: 驼峰命名法,动词开头
|
||||
- **示例**: `getUserInfo`、`submitForm`、`handleClick`
|
||||
- **方法名**: 驼峰命名法
|
||||
- **示例**: `data`、`methods`、`computed`、`watch`
|
||||
- **生命周期函数**: 按照 Vue 规范命名
|
||||
- **示例**: `created`、`mounted`、`beforeDestroy`
|
||||
|
||||
### 2.5 组件命名
|
||||
|
||||
- **组件名**: PascalCase 命名风格
|
||||
- **示例**: `Button`、`NavBar`、`GoodsList`
|
||||
- **组件标签**: 小写字母,单词之间用连字符分隔
|
||||
- **示例**: `<my-button>`、`<nav-bar>`、`<goods-list>`
|
||||
|
||||
### 2.6 其他命名
|
||||
|
||||
- **路由命名**: 小写字母,单词之间用连字符分隔
|
||||
- **示例**: `/pages/index/index`、`/pages/user/login`
|
||||
- **CSS 类名**: 小写字母,单词之间用连字符分隔
|
||||
- **示例**: `.user-info`、`.goods-list`、`.btn-primary`
|
||||
- **ID 命名**: 小写字母,单词之间用连字符分隔
|
||||
- **示例**: `#app`、`#header`、`#footer`
|
||||
|
||||
## 3. 代码风格
|
||||
|
||||
### 3.1 缩进
|
||||
|
||||
- **缩进方式**: 4 个空格
|
||||
- **示例**:
|
||||
```vue
|
||||
<template>
|
||||
<view class="container">
|
||||
<text>{{ message }}</text>
|
||||
</view>
|
||||
</template>
|
||||
```
|
||||
|
||||
### 3.2 换行
|
||||
|
||||
- **标签换行**: 多个属性的标签应该换行
|
||||
- **示例**:
|
||||
```vue
|
||||
<view
|
||||
class="container"
|
||||
:class="{ active: isActive }"
|
||||
@click="handleClick"
|
||||
>
|
||||
<text>{{ message }}</text>
|
||||
</view>
|
||||
```
|
||||
- **代码块换行**: 逻辑代码块应该换行
|
||||
- **示例**:
|
||||
```javascript
|
||||
if (condition) {
|
||||
// 代码块
|
||||
} else {
|
||||
// 代码块
|
||||
}
|
||||
```
|
||||
|
||||
### 3.3 空格
|
||||
|
||||
- **运算符空格**: 运算符两侧应该有空格
|
||||
- **示例**: `a + b`、`x = y`、`i < 10`
|
||||
- **逗号空格**: 逗号后面应该有空格
|
||||
- **示例**: `[1, 2, 3]`、`{ name: '张三', age: 18 }`
|
||||
- **括号空格**: 括号内侧不应该有空格
|
||||
- **示例**: `if (condition)`、`function (param)`
|
||||
|
||||
### 3.4 注释
|
||||
|
||||
- **单行注释**: 使用 `//` 注释
|
||||
- **示例**: `// 这是单行注释`
|
||||
- **多行注释**: 使用 `/* */` 注释
|
||||
- **示例**:
|
||||
```javascript
|
||||
/*
|
||||
* 这是多行注释
|
||||
* 第二行
|
||||
*/
|
||||
```
|
||||
- **文档注释**: 使用 JSDoc 风格的注释
|
||||
- **示例**:
|
||||
```javascript
|
||||
/**
|
||||
* 获取用户信息
|
||||
* @param {number} id - 用户ID
|
||||
* @returns {Promise} 用户信息
|
||||
*/
|
||||
async function getUserInfo(id) {
|
||||
// 代码
|
||||
}
|
||||
```
|
||||
|
||||
### 3.5 引号
|
||||
|
||||
- **字符串**: 使用单引号 `''`
|
||||
- **示例**: `const name = '张三'`、`<text>Hello</text>`
|
||||
- **模板字符串**: 使用反引号 `` ` ``
|
||||
- **示例**: `` const url = `${baseUrl}/api/user` ``
|
||||
- **HTML 属性**: 使用双引号 `""`
|
||||
- **示例**: `<view class="container">`、`<image src="https://example.com/img.jpg">`
|
||||
|
||||
## 4. 文件结构
|
||||
|
||||
### 4.1 页面文件结构
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<!-- 模板内容 -->
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// 导入依赖
|
||||
import userApi from '../../api/user';
|
||||
|
||||
// 导出组件
|
||||
export default {
|
||||
// 组件名称
|
||||
name: 'UserInfo',
|
||||
|
||||
// 组件属性
|
||||
props: {
|
||||
userId: {
|
||||
type: Number,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
|
||||
// 数据
|
||||
data() {
|
||||
return {
|
||||
userInfo: {},
|
||||
loading: false
|
||||
};
|
||||
},
|
||||
|
||||
// 计算属性
|
||||
computed: {
|
||||
fullName() {
|
||||
return this.userInfo.firstName + ' ' + this.userInfo.lastName;
|
||||
}
|
||||
},
|
||||
|
||||
// 监听
|
||||
watch: {
|
||||
userId: {
|
||||
handler(newVal) {
|
||||
this.getUserInfo(newVal);
|
||||
},
|
||||
immediate: true
|
||||
}
|
||||
},
|
||||
|
||||
// 生命周期函数
|
||||
created() {
|
||||
// 初始化
|
||||
},
|
||||
|
||||
mounted() {
|
||||
// 挂载后
|
||||
},
|
||||
|
||||
// 方法
|
||||
methods: {
|
||||
async getUserInfo(id) {
|
||||
try {
|
||||
this.loading = true;
|
||||
const res = await userApi.getUserInfo(id);
|
||||
this.userInfo = res.data;
|
||||
} catch (error) {
|
||||
console.error('获取用户信息失败:', error);
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
|
||||
handleEdit() {
|
||||
// 编辑用户信息
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 样式 */
|
||||
.user-info {
|
||||
padding: 20rpx;
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
.name {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
### 4.2 组件文件结构
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<!-- 模板内容 -->
|
||||
<view class="my-button">
|
||||
<button
|
||||
:class="[type, { disabled }]"
|
||||
:disabled="disabled"
|
||||
@click="handleClick"
|
||||
>
|
||||
<slot></slot>
|
||||
</button>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'MyButton',
|
||||
|
||||
props: {
|
||||
type: {
|
||||
type: String,
|
||||
default: 'primary',
|
||||
validator: (value) => {
|
||||
return ['primary', 'success', 'warning', 'danger'].includes(value);
|
||||
}
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
handleClick() {
|
||||
if (!this.disabled) {
|
||||
this.$emit('click');
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.my-button {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
button {
|
||||
padding: 20rpx 40rpx;
|
||||
border-radius: 8rpx;
|
||||
font-size: 28rpx;
|
||||
border: none;
|
||||
outline: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.primary {
|
||||
background-color: #007aff;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.success {
|
||||
background-color: #4cd964;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.warning {
|
||||
background-color: #ff9500;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.danger {
|
||||
background-color: #ff3b30;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.disabled {
|
||||
opacity: 0.6;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
</style>
|
||||
```
|
||||
|
||||
### 4.3 JS 文件结构
|
||||
|
||||
```javascript
|
||||
// 导入依赖
|
||||
import request from './request';
|
||||
|
||||
// 常量定义
|
||||
const BASE_URL = 'https://api.crmeb.net';
|
||||
const TIMEOUT = 10000;
|
||||
|
||||
// 工具函数
|
||||
function formatTime(time) {
|
||||
const date = new Date(time);
|
||||
return date.toLocaleString();
|
||||
}
|
||||
|
||||
function getRandomNum(min, max) {
|
||||
return Math.floor(Math.random() * (max - min + 1)) + min;
|
||||
}
|
||||
|
||||
// 导出
|
||||
export {
|
||||
formatTime,
|
||||
getRandomNum
|
||||
};
|
||||
|
||||
// 默认导出
|
||||
export default {
|
||||
BASE_URL,
|
||||
TIMEOUT
|
||||
};
|
||||
```
|
||||
|
||||
## 5. 组件开发规范
|
||||
|
||||
### 5.1 组件设计
|
||||
|
||||
- **单一职责**: 每个组件只负责一个功能
|
||||
- **可复用性**: 设计通用的、可复用的组件
|
||||
- **可配置性**: 通过 props 提供配置选项
|
||||
- **事件通信**: 通过事件与父组件通信
|
||||
|
||||
### 5.2 组件使用
|
||||
|
||||
- **组件导入**: 使用 import 导入组件
|
||||
- **示例**: `import Button from '../../components/Button.vue'`
|
||||
- **组件注册**: 在 components 中注册组件
|
||||
- **示例**:
|
||||
```javascript
|
||||
components: {
|
||||
Button
|
||||
}
|
||||
```
|
||||
- **组件使用**: 使用组件标签
|
||||
- **示例**: `<Button type="primary">点击</Button>`
|
||||
|
||||
### 5.3 组件通信
|
||||
|
||||
- **props 向下传递**: 父组件通过 props 向子组件传递数据
|
||||
- **events 向上传递**: 子组件通过 events 向父组件传递事件
|
||||
- **refs 引用**: 通过 refs 引用子组件实例
|
||||
- **provide/inject**: 祖先组件向后代组件传递数据
|
||||
|
||||
## 6. 页面开发规范
|
||||
|
||||
### 6.1 页面结构
|
||||
|
||||
- **模板结构**: 清晰明了,层次分明
|
||||
- **脚本结构**: 按照 Vue 规范组织代码
|
||||
- **样式结构**: 模块化,可维护
|
||||
|
||||
### 6.2 数据管理
|
||||
|
||||
- **本地数据**: 使用 data 管理组件内部数据
|
||||
- **计算数据**: 使用 computed 计算衍生数据
|
||||
- **监听数据**: 使用 watch 监听数据变化
|
||||
- **全局数据**: 使用 Vuex 管理全局数据
|
||||
|
||||
### 6.3 生命周期管理
|
||||
|
||||
- **created**: 初始化数据,发送请求
|
||||
- **mounted**: 操作 DOM,初始化第三方库
|
||||
- **beforeDestroy**: 清理定时器,取消订阅
|
||||
|
||||
### 6.4 路由管理
|
||||
|
||||
- **路由配置**: 在 pages.json 中配置路由
|
||||
- **路由跳转**: 使用 uni.navigateTo、uni.redirectTo 等方法
|
||||
- **路由参数**: 通过 options 或 $route.params 获取路由参数
|
||||
|
||||
## 7. API 调用规范
|
||||
|
||||
### 7.1 API 封装
|
||||
|
||||
- **模块化**: 按业务模块封装 API
|
||||
- **统一处理**: 统一处理请求头、响应拦截、错误处理
|
||||
- **Promise 化**: 使用 Promise 处理异步请求
|
||||
|
||||
### 7.2 API 调用
|
||||
|
||||
- **异步处理**: 使用 async/await 处理异步请求
|
||||
- **错误处理**: 使用 try/catch 捕获错误
|
||||
- **加载状态**: 显示加载状态,提升用户体验
|
||||
- **错误提示**: 统一处理错误提示
|
||||
|
||||
### 7.3 示例代码
|
||||
|
||||
```javascript
|
||||
async function getUserInfo() {
|
||||
try {
|
||||
this.loading = true;
|
||||
const res = await userApi.getUserInfo();
|
||||
this.userInfo = res.data;
|
||||
} catch (error) {
|
||||
console.error('获取用户信息失败:', error);
|
||||
uni.showToast({
|
||||
title: '获取用户信息失败',
|
||||
icon: 'none'
|
||||
});
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 8. 性能优化
|
||||
|
||||
### 8.1 代码优化
|
||||
|
||||
- **减少冗余代码**: 避免重复的代码
|
||||
- **使用计算属性**: 对于复杂的计算,使用 computed
|
||||
- **使用 v-if 和 v-show 合理**: 根据场景选择合适的指令
|
||||
- **使用 key**: 在 v-for 中使用 key,提高渲染性能
|
||||
|
||||
### 8.2 网络优化
|
||||
|
||||
- **合理使用缓存**: 缓存不经常变化的数据
|
||||
- **减少请求次数**: 合并请求,批量操作
|
||||
- **使用防抖和节流**: 避免频繁的事件触发
|
||||
- **延迟加载**: 对于非首屏内容,使用延迟加载
|
||||
|
||||
### 8.3 其他优化
|
||||
|
||||
- **减少 DOM 节点**: 简化 DOM 结构
|
||||
- **优化图片**: 使用合适的图片格式和大小
|
||||
- **使用虚拟列表**: 对于长列表,使用虚拟列表
|
||||
- **避免内存泄漏**: 及时清理定时器、事件监听器等
|
||||
|
||||
## 9. 常见问题
|
||||
|
||||
### 9.1 代码风格问题
|
||||
|
||||
- **问题**: 代码风格不一致
|
||||
- **解决方案**: 使用 ESLint 等工具进行代码检查
|
||||
|
||||
### 9.2 性能问题
|
||||
|
||||
- **问题**: 页面加载慢,卡顿
|
||||
- **解决方案**: 优化代码,减少 DOM 操作,使用虚拟列表等
|
||||
|
||||
### 9.3 兼容性问题
|
||||
|
||||
- **问题**: 在不同平台上表现不一致
|
||||
- **解决方案**: 遵循 UniApp 规范,使用条件编译
|
||||
|
||||
### 9.4 维护性问题
|
||||
|
||||
- **问题**: 代码难以维护
|
||||
- **解决方案**: 模块化开发,添加注释,遵循代码规范
|
||||
|
||||
## 10. 参考资源
|
||||
|
||||
- [Vue 官方文档](https://cn.vuejs.org/)
|
||||
- [UniApp 官方文档](https://uniapp.dcloud.io/)
|
||||
- [ESLint 官方文档](https://eslint.org/docs/user-guide/)
|
||||
- [Prettier 官方文档](https://prettier.io/docs/en/)
|
||||
- [前端代码规范指南](https://github.com/ecomfe/spec)
|
||||
|
||||
## 11. 总结
|
||||
|
||||
本文档描述了 CRMEB 项目中 UniApp 移动端的代码规范,包括命名规范、代码风格、文件结构、组件开发等。遵循本文档的规范,可以提高代码的可读性、可维护性和可扩展性,确保项目的质量和稳定性。
|
||||
|
||||
代码规范是团队协作的基础,建议开发团队成员严格遵循本文档的规范,共同维护一个高质量的代码库。
|
||||
282
.trae/skills/uniapp/references/directory_structure.md
Normal file
282
.trae/skills/uniapp/references/directory_structure.md
Normal file
@ -0,0 +1,282 @@
|
||||
# UniApp 目录结构文档
|
||||
|
||||
## 1. 概述
|
||||
|
||||
本文档描述了 CRMEB 项目中 UniApp 移动端的目录结构,包括各目录的功能、文件组织方式等,旨在帮助开发者理解项目结构,提高开发效率。
|
||||
|
||||
## 2. 项目根目录结构
|
||||
|
||||
```
|
||||
template/uni-app/
|
||||
├── api/ # API 接口目录
|
||||
├── config/ # 配置目录
|
||||
├── libs/ # 库文件目录
|
||||
├── mixins/ # 混入目录
|
||||
├── store/ # 状态管理目录
|
||||
├── utils/ # 工具类目录
|
||||
├── App.vue # 应用入口组件
|
||||
├── main.js # 应用入口文件
|
||||
├── manifest.json # 应用配置文件
|
||||
├── package.json # 项目配置文件
|
||||
├── pages.json # 页面路由配置文件
|
||||
├── uni.scss # UniApp 全局样式文件
|
||||
└── vue.config.js # Vue 配置文件
|
||||
```
|
||||
|
||||
## 3. API 目录结构 (api/)
|
||||
|
||||
```
|
||||
api/
|
||||
├── activity.js # 活动相关接口
|
||||
├── admin.js # 管理相关接口
|
||||
├── api.js # 基础 API 配置
|
||||
├── kefu.js # 客服相关接口
|
||||
├── lottery.js # 抽奖相关接口
|
||||
├── order.js # 订单相关接口
|
||||
├── public.js # 公共接口
|
||||
├── store.js # 商城相关接口
|
||||
└── user.js # 用户相关接口
|
||||
```
|
||||
|
||||
- **功能**: 封装与后端交互的 API 接口
|
||||
- **结构**: 按业务模块划分接口文件
|
||||
- **特性**: 统一处理请求头、响应拦截、错误处理等
|
||||
- **调用方式**: 通过 `import` 导入使用
|
||||
|
||||
## 4. 配置目录结构 (config/)
|
||||
|
||||
```
|
||||
config/
|
||||
├── app.js # 应用配置
|
||||
├── cache.js # 缓存配置
|
||||
└── socket.js # WebSocket 配置
|
||||
```
|
||||
|
||||
- **功能**: 存储项目的所有配置文件
|
||||
- **结构**: 按功能模块划分配置文件
|
||||
- **特性**: 集中管理配置,便于维护和修改
|
||||
- **加载顺序**: 应用启动时加载
|
||||
|
||||
## 5. 库文件目录结构 (libs/)
|
||||
|
||||
```
|
||||
libs/
|
||||
├── chat.js # 聊天相关功能
|
||||
├── login.js # 登录相关功能
|
||||
├── new_chat.js # 新聊天功能
|
||||
├── order.js # 订单相关功能
|
||||
├── routine.js # 小程序相关功能
|
||||
├── uniApi.js # UniApp API 封装
|
||||
└── wechat.js # 微信相关功能
|
||||
```
|
||||
|
||||
- **功能**: 存储通用库文件和功能模块
|
||||
- **结构**: 按功能划分库文件
|
||||
- **特性**: 独立于页面代码,便于复用
|
||||
- **作用**: 提供通用功能和服务
|
||||
|
||||
## 6. 混入目录结构 (mixins/)
|
||||
|
||||
```
|
||||
mixins/
|
||||
└── color.js # 颜色相关混入
|
||||
```
|
||||
|
||||
- **功能**: 存储 Vue 混入对象
|
||||
- **结构**: 按功能划分混入文件
|
||||
- **特性**: 实现代码复用,避免重复逻辑
|
||||
- **作用**: 为组件提供共享的方法和数据
|
||||
|
||||
## 7. 状态管理目录结构 (store/)
|
||||
|
||||
```
|
||||
store/
|
||||
├── getters.js # 状态获取器
|
||||
└── index.js # 状态管理入口
|
||||
```
|
||||
|
||||
- **功能**: 存储 Vuex 状态管理相关文件
|
||||
- **结构**: 按 Vuex 规范划分文件
|
||||
- **特性**: 集中管理应用状态,实现组件间通信
|
||||
- **作用**: 管理全局状态,如用户信息、购物车数据等
|
||||
|
||||
## 8. 工具类目录结构 (utils/)
|
||||
|
||||
```
|
||||
utils/
|
||||
├── cache.js # 缓存工具
|
||||
├── emoji.js # 表情工具
|
||||
├── index.js # 工具类入口
|
||||
├── lang.js # 语言工具
|
||||
├── request.js # 网络请求工具
|
||||
├── theme.js # 主题工具
|
||||
├── util.js # 通用工具
|
||||
└── validate.js # 验证工具
|
||||
```
|
||||
|
||||
- **功能**: 存储通用工具类
|
||||
- **结构**: 按功能划分工具文件
|
||||
- **特性**: 提供通用功能,便于复用
|
||||
- **作用**: 处理缓存、网络请求、验证等通用操作
|
||||
|
||||
## 9. 页面目录结构
|
||||
|
||||
### 9.1 页面配置 (pages.json)
|
||||
|
||||
```json
|
||||
{
|
||||
"pages": [
|
||||
{
|
||||
"path": "pages/index/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "首页"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/user/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "个人中心"
|
||||
}
|
||||
}
|
||||
],
|
||||
"subPackages": [
|
||||
{
|
||||
"root": "pages/order",
|
||||
"pages": [
|
||||
{
|
||||
"path": "index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "订单列表"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
- **功能**: 配置页面路由、导航栏样式等
|
||||
- **结构**: 按页面层级配置
|
||||
- **特性**: 支持分包加载,优化应用体积
|
||||
- **作用**: 定义应用的页面结构和导航样式
|
||||
|
||||
## 10. 应用配置文件
|
||||
|
||||
### 10.1 manifest.json
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "CRMEB商城",
|
||||
"appid": "__UNI__APPID__",
|
||||
"description": "CRMEB商城移动端",
|
||||
"versionName": "1.0.0",
|
||||
"versionCode": "100",
|
||||
"transformPx": true,
|
||||
"uniStatistics": {
|
||||
"enable": true
|
||||
},
|
||||
"app-plus": {
|
||||
"usingComponents": true,
|
||||
"nvueStyleCompiler": "uni-app"
|
||||
},
|
||||
"mp-weixin": {
|
||||
"appid": "wx_appid",
|
||||
"setting": {
|
||||
"urlCheck": false
|
||||
},
|
||||
"usingComponents": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- **功能**: 配置应用的基本信息、平台配置等
|
||||
- **结构**: 按平台划分配置
|
||||
- **特性**: 支持多平台配置,如微信小程序、App 等
|
||||
- **作用**: 定义应用的全局配置信息
|
||||
|
||||
### 10.2 package.json
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "crmeb-uni-app",
|
||||
"version": "1.0.0",
|
||||
"description": "CRMEB商城移动端",
|
||||
"main": "main.js",
|
||||
"scripts": {
|
||||
"dev": "npm run dev:mp-weixin",
|
||||
"dev:mp-weixin": "cross-env NODE_ENV=development UNI_PLATFORM=mp-weixin vue-cli-service uni-build --watch",
|
||||
"build": "npm run build:mp-weixin",
|
||||
"build:mp-weixin": "cross-env NODE_ENV=production UNI_PLATFORM=mp-weixin vue-cli-service uni-build"
|
||||
},
|
||||
"dependencies": {
|
||||
"vue": "^2.6.11",
|
||||
"vuex": "^3.4.0"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- **功能**: 配置项目的依赖、脚本等
|
||||
- **结构**: 标准 npm 配置格式
|
||||
- **特性**: 管理项目依赖,定义构建脚本
|
||||
- **作用**: 管理项目的依赖和构建流程
|
||||
|
||||
## 11. 目录结构最佳实践
|
||||
|
||||
### 11.1 命名规范
|
||||
|
||||
- **目录名**: 小写字母,单词之间用下划线分隔
|
||||
- **文件名**: 小写字母,单词之间用下划线分隔
|
||||
- **组件名**: 使用 PascalCase 命名风格
|
||||
- **方法名**: 使用 camelCase 命名风格
|
||||
- **变量名**: 使用 camelCase 命名风格
|
||||
|
||||
### 11.2 组织原则
|
||||
|
||||
- **模块化**: 按功能模块组织目录结构
|
||||
- **分层架构**: 遵循 Vue 组件化开发架构
|
||||
- **单一职责**: 每个目录和文件只负责一个功能
|
||||
- **可扩展性**: 便于添加新功能和模块
|
||||
- **易维护性**: 便于理解和维护
|
||||
|
||||
### 11.3 开发建议
|
||||
|
||||
- **遵循 UniApp 规范**: 遵循 UniApp 官方目录结构规范
|
||||
- **合理划分模块**: 根据业务功能合理划分模块
|
||||
- **避免目录过深**: 目录层级不宜过深,一般不超过 4 层
|
||||
- **保持目录整洁**: 及时清理无用文件和目录
|
||||
- **文档化**: 为重要目录添加说明文档
|
||||
|
||||
## 12. 常见问题
|
||||
|
||||
### 12.1 目录权限问题
|
||||
|
||||
- **问题**: 某些目录没有读写权限
|
||||
- **解决方案**: 确保项目目录有正确的读写权限
|
||||
|
||||
### 12.2 页面路由配置问题
|
||||
|
||||
- **问题**: 新增页面后无法访问
|
||||
- **解决方案**: 在 pages.json 中添加页面路由配置
|
||||
|
||||
### 12.3 分包加载问题
|
||||
|
||||
- **问题**: 应用体积过大,无法上传到小程序平台
|
||||
- **解决方案**: 使用分包加载,将页面划分到不同的分包中
|
||||
|
||||
### 12.4 目录结构混乱
|
||||
|
||||
- **问题**: 目录结构不清晰,难以维护
|
||||
- **解决方案**: 重新组织目录结构,遵循模块化原则
|
||||
|
||||
## 13. 参考资源
|
||||
|
||||
- [UniApp 官方文档](https://uniapp.dcloud.io/)
|
||||
- [Vue 官方文档](https://cn.vuejs.org/)
|
||||
- [Vuex 官方文档](https://vuex.vuejs.org/zh/)
|
||||
- [微信小程序开发文档](https://developers.weixin.qq.com/miniprogram/dev/framework/)
|
||||
|
||||
## 14. 总结
|
||||
|
||||
本文档描述了 CRMEB 项目中 UniApp 移动端的目录结构,包括各目录的功能、文件组织方式等。遵循本文档的目录结构规范,可以提高项目的可维护性和可扩展性,便于团队协作开发。
|
||||
|
||||
随着业务的发展和技术的演进,目录结构也可能需要不断优化和调整,以适应新的业务需求和技术挑战。
|
||||
Loading…
x
Reference in New Issue
Block a user