【SKILL】AI SKILL技能完善docs(uniapp): 添加本地参考文档链接

feat(php-api): 更新数据库设计文档内容

feat(admin-element): 添加部署文档和API流程文档

feat(uniapp): 添加代码规范和API流程文档

refactor(skills): 重构技能列表文档结构

docs: 统一添加各模块参考文档
This commit is contained in:
sugar1569 2026-01-27 09:43:19 +08:00
parent 58655a6fbb
commit fb32d31fc1
13 changed files with 5205 additions and 25 deletions

View File

@ -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项目开发的重要辅助工具,通过规范的技能文档和触发机制,可以帮助开发人员更快地了解项目结构、开发规范和最佳实践,提高开发效率和代码质量。

View 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 调用的安全性、可靠性和性能。

View 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 项目中管理端前端的代码规范,包括命名规范、代码风格、文件结构、组件开发等方面的规范。遵循本文档的规范,可以提高代码的可读性、可维护性和可扩展性,确保项目的质量和稳定性。
代码规范是团队协作的基础,建议开发团队成员严格遵循本文档的规范,共同维护一个高质量的代码库。

View 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 项目中管理端前端的部署流程,包括构建、部署、配置等环节,以及相关的最佳实践和常见问题解决方案。
遵循本文档的部署流程和规范,可以确保前端部署的顺利进行和系统的稳定运行,同时提高部署效率和系统安全性。
随着项目的发展和技术的演进,部署流程也需要不断优化和调整,以适应新的业务需求和技术挑战。

View 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 项目中管理端前端的开发流程,包括需求分析、设计、编码、测试、部署等环节,以及相关的开发规范和最佳实践。
遵循本文档的开发流程和规范,可以提高前端开发效率和代码质量,减少开发过程中的问题和风险,确保项目的顺利进行。
同时,开发流程也需要根据项目的实际情况进行调整和优化,以适应不同项目的需求和特点。

View 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 项目结构,通过清晰的目录组织和命名规范,提高了代码的可维护性和可扩展性。开发者应遵循目录结构规范,合理组织代码,确保项目的长期可维护性。

View 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、权限、国际化、构建、开发、部署、性能和安全等多个方面。合理的配置管理可以提高项目的可维护性、可扩展性和安全性,同时提升开发效率和用户体验。
开发者应遵循配置管理的最佳实践,根据项目需求和环境特点,合理配置各项参数,确保项目的稳定运行和持续演进。

View File

@ -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 项目的数据库设计规范和最佳实践,包括数据库架构、表结构、索引设计、关系设计、性能优化、安全设计、备份与恢复、版本控制、维护与监控等方面。
遵循本文档的设计规范,可以提高数据库性能和可维护性,确保系统的稳定运行。同时,定期对数据库进行维护和监控,可以及时发现和解决潜在问题,保障系统的安全性和可靠性。
随着业务的发展和系统的演进,数据库设计也需要不断优化和调整,以适应新的业务需求和技术挑战。

View 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 特定命令、数据库命令、性能优化命令、故障排查命令等。
通过掌握这些命令,开发者可以更加高效地进行项目开发、部署和维护。同时,本文档也提供了一些最佳实践和常见问题的解决方案,希望能够帮助开发者避免一些常见的问题。
随着项目的发展和技术的演进,这些命令也可能会有所变化,建议开发者定期查阅相关文档,了解最新的命令和用法。

View File

@ -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 协作流程

View 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 开发流程也需要不断优化和调整,以适应新的业务需求和技术挑战。

View 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 移动端的代码规范,包括命名规范、代码风格、文件结构、组件开发等。遵循本文档的规范,可以提高代码的可读性、可维护性和可扩展性,确保项目的质量和稳定性。
代码规范是团队协作的基础,建议开发团队成员严格遵循本文档的规范,共同维护一个高质量的代码库。

View 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 移动端的目录结构,包括各目录的功能、文件组织方式等。遵循本文档的目录结构规范,可以提高项目的可维护性和可扩展性,便于团队协作开发。
随着业务的发展和技术的演进,目录结构也可能需要不断优化和调整,以适应新的业务需求和技术挑战。