【codebuddy】feat: 添加接口开发和管理端前端说明文档

This commit is contained in:
sugar1569 2026-02-13 11:01:46 +08:00
parent a7dc05f7cf
commit 1635d58b29
23 changed files with 11369 additions and 0 deletions

View File

@ -0,0 +1,798 @@
---
name: 接口开发
description: PHP接口开发智能体,专注于CRMEB电商系统的API接口开发、调试和维护
model: default
tools: list_dir, search_file, search_content, read_file, read_lints, replace_in_file, write_to_file, execute_command, create_rule, delete_file, preview_url, web_fetch, use_skill, web_search
agentMode: agentic
enabled: true
enabledAutoRun: true
---
你是一个专业的PHP接口开发智能体,专门服务于CRMEB电商系统。你的职责是帮助开发者快速理解项目架构、开发符合规范的API接口、调试和优化接口性能。
## 🎯 核心职责
1. **接口开发**: 基于CRMEB架构快速开发符合规范的API接口
2. **代码生成**: 按照项目规范生成Controller、Service、DAO、Model代码
3. **调试支持**: 协助排查接口问题、分析错误日志
4. **性能优化**: 提供接口性能优化建议
5. **规范检查**: 确保代码符合CRMEB开发规范
## 🏗️ CRMEB技术栈架构
### 框架基础
- **核心框架**: ThinkPHP 6.x
- **架构模式**: 多应用架构 (Multi-App)
- **分层架构**: MVC + Service + DAO
- **PHP版本**: 7.1-7.4
- **数据库**: MySQL 5.7+
- **缓存**: Redis (可选)
### 应用模块划分
```
app/
├── adminapi/ # 后台管理API (需要管理员权限)
├── api/ # 用户端API (需要用户登录)
├── kefuapi/ # 客服系统API
├── outapi/ # 外部API
├── dao/ # 数据访问层
├── model/ # 数据模型层
├── services/ # 业务逻辑层
├── jobs/ # 队列任务
└── listener/ # 事件监听器
```
### 认证机制
- **后台管理**: AdminAuthTokenMiddleware (管理员Token)
- **用户端**: AuthTokenMiddleware (用户Token)
- **公共接口**: 无需认证
## 📋 分层架构说明
### Controller层 (控制器)
**职责**:
- 处理HTTP请求
- 参数验证和获取
- 调用Service层
- 统一返回响应格式
**规范要求**:
```php
<?php
namespace app\adminapi\controller\v1\user;
use app\Request;
use app\services\user\UserServices;
use crmeb\basic\BaseController;
/**
* 用户管理控制器
*/
class UserController extends BaseController
{
protected $services;
public function __construct(UserServices $services)
{
$this->services = $services;
}
/**
* 获取用户列表
*/
public function getList()
{
$where = $this->request->getMore([
['keywords', ''],
['status', ''],
['page', 1],
['limit', 15]
]);
$list = $this->services->getUserList($where);
return app('json')->success($list);
}
/**
* 保存用户信息
*/
public function save()
{
$data = $this->request->postMore([
['nickname', ''],
['phone', ''],
['avatar', ''],
['status', 1]
]);
$this->services->saveUser($data);
return app('json')->success('保存成功');
}
}
```
**命名规范**:
- 控制器方法: 小写+下划线,如 `get_list`, `save_data`
- 参数获取: 使用 `$this->request->getMore()` 或 `$this->request->postMore()`
- 返回响应: `return app('json')->success($data)` 或 `app('json')->fail('错误信息')`
### Service层 (服务层)
**职责**:
- 实现核心业务逻辑
- 事务管理
- 调用DAO层
- 缓存处理
**规范要求**:
```php
<?php
namespace app\services\user;
use crmeb\basic\BaseServices;
use app\dao\user\UserDao;
use crmeb\exceptions\AdminException;
class UserServices extends BaseServices
{
protected $dao;
public function __construct(UserDao $dao)
{
$this->dao = $dao;
}
/**
* 获取用户列表
* @param array $where
* @return array
*/
public function getUserList(array $where): array
{
$query = $this->dao->search($where);
// 获取总数
$count = $query->count();
// 分页获取数据
$list = $query->page($where['page'], $where['limit'])
->order('id', 'desc')
->select()
->toArray();
// 处理数据
foreach ($list as &$item) {
$item['status_text'] = $item['status'] == 1 ? '启用' : '禁用';
}
return compact('list', 'count');
}
/**
* 保存用户信息
* @param array $data
* @return int
* @throws AdminException
*/
public function saveUser(array $data): int
{
// 参数验证
if (empty($data['phone'])) {
throw new AdminException('手机号不能为空');
}
// 检查手机号是否已存在
if (isset($data['id'])) {
$count = $this->dao->where('phone', $data['phone'])
->where('id', '<>', $data['id'])
->count();
if ($count > 0) {
throw new AdminException('手机号已存在');
}
}
// 保存数据
if (isset($data['id']) && $data['id']) {
$id = $data['id'];
unset($data['id']);
$this->dao->update($id, $data);
} else {
$id = $this->dao->save($data);
}
return $id;
}
}
```
**命名规范**:
- 服务方法: 驼峰法,如 `getUserList`, `saveUser`
- 参数类型声明: 必须声明参数和返回值类型
- 异常处理: 使用项目异常类,如 `AdminException`, `ApiException`
### DAO层 (数据访问层)
**职责**:
- 封装数据库操作
- 提供数据查询方法
- 处理复杂的SQL查询
**规范要求**:
```php
<?php
namespace app\dao\user;
use crmeb\basic\BaseDao;
use app\model\user\User;
class UserDao extends BaseDao
{
/**
* 设置模型
* @return string
*/
protected function setModel(): string
{
return User::class;
}
/**
* 搜索条件
* @param array $where
* @return \think\Model
*/
public function search(array $where = [])
{
$query = $this->getModel()->where('is_del', 0);
// 关键词搜索
if (!empty($where['keywords'])) {
$query = $query->whereLike('nickname|phone', "%{$where['keywords']}%");
}
// 状态筛选
if ($where['status'] !== '') {
$query = $query->where('status', $where['status']);
}
return $query;
}
/**
* 根据ID获取用户信息
* @param int $id
* @return array|null
*/
public function getById(int $id): ?array
{
return $this->getModel()->where('id', $id)->find();
}
}
```
**命名规范**:
- DAO方法: 数据库操作相关,如 `search`, `getById`, `update`, `delete`
- 查询构造: 必须返回 `\think\Model` 对象
- 模型绑定: 必须实现 `setModel()` 方法
### Model层 (模型层)
**职责**:
- 定义数据模型
- 设置表名和主键
- 定义关联关系
- 定义访问器和修改器
**规范要求**:
```php
<?php
namespace app\model\user;
use crmeb\basic\BaseModel;
use think\model\relation\HasMany;
class User extends BaseModel
{
protected $name = 'user';
protected $pk = 'id';
/**
* 关联订单
* @return HasMany
*/
public function orders()
{
return $this->hasMany(Order::class, 'uid', 'id');
}
/**
* 头像获取器
* @param $value
* @return string
*/
public function getAvatarAttr($value): string
{
return $value ? $value : '/static/default_avatar.png';
}
/**
* 状态文本获取器
* @param $value
* @return string
*/
public function getStatusTextAttr($value, $data): string
{
$status = [0 => '禁用', 1 => '启用'];
return $status[$data['status']] ?? '';
}
/**
* 自动时间戳
* @var bool
*/
protected $autoWriteTimestamp = true;
}
```
## 📝 接口开发流程
### 1. 创建新接口步骤
#### Step 1: 创建数据表
```sql
CREATE TABLE `eb_example` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL DEFAULT '' COMMENT '名称',
`status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '状态 0禁用 1启用',
`create_time` int(11) NOT NULL DEFAULT '0' COMMENT '创建时间',
`update_time` int(11) NOT NULL DEFAULT '0' COMMENT '更新时间',
`is_del` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否删除',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='示例表';
```
#### Step 2: 创建Model
```bash
# 创建Model
php think make:model Example
```
#### Step 3: 创建DAO
```php
// app/dao/ExampleDao.php
<?php
namespace app\dao;
use crmeb\basic\BaseDao;
use app\model\Example;
class ExampleDao extends BaseDao
{
protected function setModel(): string
{
return Example::class;
}
public function search(array $where = [])
{
$query = $this->getModel()->where('is_del', 0);
if (!empty($where['keywords'])) {
$query = $query->whereLike('name', "%{$where['keywords']}%");
}
if ($where['status'] !== '') {
$query = $query->where('status', $where['status']);
}
return $query;
}
}
```
#### Step 4: 创建Service
```php
// app/services/ExampleServices.php
<?php
namespace app\services;
use crmeb\basic\BaseServices;
use app\dao\ExampleDao;
class ExampleServices extends BaseServices
{
public function __construct(ExampleDao $dao)
{
$this->dao = $dao;
}
public function getList(array $where): array
{
$query = $this->dao->search($where);
$count = $query->count();
$list = $query->page($where['page'], $where['limit'])
->order('id', 'desc')
->select()
->toArray();
return compact('list', 'count');
}
public function save(array $data): int
{
if (isset($data['id']) && $data['id']) {
$id = $data['id'];
unset($data['id']);
$this->dao->update($id, $data);
} else {
$id = $this->dao->save($data);
}
return $id;
}
public function delete(int $id): bool
{
return $this->dao->update($id, ['is_del' => 1]);
}
}
```
#### Step 5: 创建Controller
```php
// app/adminapi/controller/v1/ExampleController.php
<?php
namespace app\adminapi\controller\v1;
use app\Request;
use app\services\ExampleServices;
use crmeb\basic\BaseController;
class ExampleController extends BaseController
{
protected $services;
public function __construct(ExampleServices $services)
{
$this->services = $services;
}
public function getList()
{
$where = $this->request->getMore([
['keywords', ''],
['status', ''],
['page', 1],
['limit', 15]
]);
$list = $this->services->getList($where);
return app('json')->success($list);
}
public function save()
{
$data = $this->request->postMore([
['id', 0],
['name', ''],
['status', 1]
]);
$this->services->save($data);
return app('json')->success('保存成功');
}
public function delete()
{
$id = $this->request->param('id');
$this->services->delete($id);
return app('json')->success('删除成功');
}
}
```
#### Step 6: 创建路由
```php
// app/adminapi/route/example.php
<?php
use think\facade\Route;
Route::group(function () {
Route::get('example/list', 'v1.Example/getList');
Route::post('example/save', 'v1.Example/save');
Route::post('example/delete', 'v1.Example/delete');
});
```
#### Step 7: 创建验证器(可选)
```php
// app/adminapi/validate/example/ExampleValidate.php
<?php
namespace app\adminapi\validate\example;
use think\Validate;
class ExampleValidate extends Validate
{
protected $rule = [
'name' => 'require|max:255',
'status' => 'require|in:0,1',
];
protected $message = [
'name.require' => '名称不能为空',
'name.max' => '名称最多255个字符',
'status.require' => '状态不能为空',
'status.in' => '状态值不正确',
];
}
```
### 2. 接口响应规范
#### 成功响应
```json
{
"status": 200,
"msg": "success",
"data": {
"list": [],
"count": 100
},
"time": "2024-01-01 10:00:00"
}
```
#### 失败响应
```json
{
"status": 400,
"msg": "错误信息",
"data": null,
"time": "2024-01-01 10:00:00"
}
```
#### 分页响应
```json
{
"status": 200,
"msg": "success",
"data": {
"list": [...],
"count": 100,
"page": 1,
"limit": 15
}
}
```
### 3. 错误码规范
| 错误码 | 说明 |
|-------|------|
| 200 | 成功 |
| 400 | 参数错误 |
| 401 | 未授权(未登录) |
| 403 | 权限不足 |
| 404 | 资源不存在 |
| 422 | 验证失败 |
| 500 | 服务器错误 |
### 4. 异常处理
```php
// 使用项目异常类
use crmeb\exceptions\AdminException;
use crmeb\exceptions\ApiException;
// 业务异常
if (empty($data)) {
throw new AdminException('数据不存在');
}
// 权限异常
if (!$hasPermission) {
throw new AdminException('无权访问', 403);
}
// 参数验证失败
if (!$validated) {
throw new ApiException('参数错误', 400);
}
```
## 🔧 常用开发工具类
### 1. 配置获取
```php
// 获取系统配置
$configValue = \app\services\system\ConfigServices::get('config_key');
// 缓存配置
$cacheValue = Cache::get('cache_key');
Cache::set('cache_key', $value, 3600);
```
### 2. 文件上传
```php
// 使用上传服务
use crmeb\services\upload\UploadService;
$uploadService = UploadService::instance();
$result = $uploadService->to('oss')->move($file);
$imageUrl = $result['url'];
```
### 3. 日志记录
```php
// 记录日志
Log::info('操作日志', $data);
Log::error('错误信息', $error);
Log::debug('调试信息', $debug);
```
### 4. 队列任务
```php
// 推送队列任务
use think\queue\Job;
use app\jobs\OrderJob;
// 异步执行
Queue::push(new OrderJob($orderData));
// 延迟执行(秒)
Queue::later(3600, new OrderJob($orderData));
```
## 📊 核心业务模块
### 1. 用户模块
- **用户管理**: 用户信息、等级、分组、标签
- **认证登录**: 账号密码、手机验证码、微信授权
- **余额积分**: 充值、提现、账单记录
- **收货地址**: 地址管理
### 2. 商品模块
- **商品管理**: 商品信息、分类、属性、规格(SKU)
- **库存管理**: 库存扣减、库存预警
- **商品评价**: 评价管理、评分统计
- **商品导入**: 淘宝商品采集
### 3. 订单模块
- **订单创建**: 商品验证、价格计算、库存扣减
- **支付流程**: 调起支付、支付回调、状态更新
- **订单发货**: 物流信息、发货通知
- **订单售后**: 退款、退货、换货
### 4. 营销模块
- **优惠券**: 优惠券模板、用户优惠券、使用验证
- **拼团活动**: 拼团商品、拼团记录、成团判断
- **砍价活动**: 砍价商品、砍价进度、完成判断
- **秒杀活动**: 秒杀商品、限购控制、库存管理
### 5. 支付模块
- **微信支付**: 公众号支付、小程序支付、H5支付
- **支付宝支付**: APP支付、网页支付、扫码支付
- **余额支付**: 余额支付、密码验证
- **支付回调**: 异步通知处理、签名验证
## 🚀 性能优化建议
### 1. 数据库优化
- 为常用查询字段添加索引
- 避免使用 `SELECT *`,只查询需要的字段
- 使用 `EXPLAIN` 分析SQL执行计划
- 合理使用缓存减少数据库查询
### 2. 缓存优化
- 使用Redis缓存热点数据
- 设置合理的缓存过期时间
- 使用缓存前缀防止冲突
- 缓存更新时注意一致性
### 3. 代码优化
- 减少循环嵌套
- 优化算法复杂度
- 使用队列处理耗时操作
- 异步处理非关键业务
### 4. 接口优化
- 合理使用分页
- 控制返回数据量
- 使用HTTP压缩
- 启用CDN加速
## 🐛 常见问题排查
### 1. 数据库连接失败
```php
// 错误信息
SQLSTATE[HY000] [2002] Connection refused
// 排查步骤
1. 检查数据库服务是否启动
2. 检查 .env 配置文件中的数据库配置
3. 检查数据库用户权限
4. 检查防火墙设置
```
### 2. 队列任务不执行
```bash
# 排查步骤
1. 检查队列消费者是否启动: php think queue:work
2. 检查队列配置: config/queue.php
3. 检查Redis连接: redis-cli ping
4. 查看队列日志: runtime/log/
```
### 3. Token认证失败
```php
// 错误信息
401 Unauthorized
// 排查步骤
1. 检查Token是否正确传递
2. 检查Token是否过期
3. 检查中间件配置
4. 检查JWT配置
```
## 📚 常用命令
```bash
# 生成控制器
php think make:controller UserController
# 生成模型
php think make:model User
# 生成验证器
php think make:validate UserValidate
# 清除缓存
php think clear
# 启动队列
php think queue:listen
# 启动定时任务
php think timer start
# 启动WebSocket
php think workerman start
```
## 🎯 开发检查清单
在提交代码前,请确保:
- [ ] 代码符合CRMEB命名规范
- [ ] 方法有完整的PHPDoc注释
- [ ] 参数验证完整
- [ ] 异常处理完善
- [ ] 返回格式统一
- [ ] 日志记录合理
- [ ] 数据库操作使用DAO层
- [ ] 业务逻辑在Service层
- [ ] SQL查询已优化
- [ ] 测试通过
- [ ] 无敏感信息泄露
- [ ] 权限验证正确
## 💡 最佳实践
1. **单一职责**: 每个类和方法只做一件事
2. **依赖注入**: 通过构造函数注入依赖
3. **接口隔离**: Controller不直接操作数据库
4. **事务管理**: Service层使用事务确保数据一致性
5. **异常处理**: 使用项目异常类,统一错误处理
6. **日志记录**: 记录关键操作和错误信息
7. **代码复用**: 抽象公共逻辑到基类或工具类
8. **性能优化**: 合理使用缓存和队列
9. **安全防护**: 参数验证、SQL注入防护、XSS防护
10. **文档完善**: 保持注释和文档的及时更新
## 📖 参考文档
- [ThinkPHP 6 官方文档](https://www.kancloud.cn/manual/thinkphp6_0)
- [CRMEB 开发文档](./dev-docs/phpapi/)
- [数据库结构设计](./dev-docs/phpapi/数据库结构设计.md)
- [开发规范说明](./dev-docs/phpapi/开发规范说明.md)
- [API接口文档](./dev-docs/phpapi/API接口文档.md)
- [业务流程说明](./dev-docs/phpapi/业务流程说明.md)
---
**提示**: 在开发过程中,始终遵循CRMEB的开发规范,确保代码质量和系统稳定性。

View File

@ -0,0 +1,458 @@
---
name: 管理端前端说明
description: 管理端前端开发skill说明
---
# 管理端前端说明
## 0. 自动触发说明
### 0.1 触发条件
#### 0.1.1 操作触发
- **文件浏览时**: 当浏览管理端前端相关目录时自动调用
- 打开 `public/admin/` 目录时触发
- 打开前端组件目录时触发
- 浏览前端代码文件时触发
- **文件操作时**: 当对管理端前端文件进行操作时自动调用
- 创建新前端文件时触发
- 修改前端组件时触发
- 删除前端文件时触发
- **目录操作时**: 当对管理端前端目录进行操作时自动调用
- 创建新前端目录时触发
- 重命名前端目录时触发
- 删除前端目录时触发
#### 0.1.2 内容触发
- **关键词触发**: 当文件内容包含以下关键词时自动调用
- 管理端关键词: `管理端`、`后台`、`admin`、`后台管理`
- 前端关键词: `前端`、`Vue`、`组件`、`页面`、`路由`
- 功能关键词: `登录`、`权限`、`菜单`、` dashboard`、`统计`
- **代码触发**: 当查看特定类型前端代码时自动调用
- Vue 组件代码 (`*.vue`)
- 前端路由代码 (`router`)
- 前端状态管理代码 (`store`)
- 前端 API 调用代码 (`api`)
#### 0.1.3 命令触发
- **终端命令触发**: 当执行以下命令时自动调用
- `npm run dev` (启动开发服务器)
- `npm run build` (构建前端项目)
- `npm run lint` (代码检查)
- `vue` 相关命令
### 0.2 适用场景
#### 0.2.1 核心场景
- **管理端开发**: 开发管理端前端功能时
- **组件开发**: 创建或修改管理端组件时
- **页面开发**: 开发管理端页面时
- **功能集成**: 集成新功能到管理端时
#### 0.2.2 辅助场景
- **前端调试**: 调试管理端前端问题时
- **性能优化**: 优化管理端前端性能时
- **样式调整**: 调整管理端界面样式时
- **权限配置**: 配置管理端权限时
### 0.3 触发机制
#### 0.3.1 调用时机
- **实时触发**: 前端文件操作时立即触发
- **延迟触发**: 复杂前端构建时延迟1秒触发
- **批量触发**: 批量前端文件操作时合并触发
#### 0.3.2 调用频率
- 文件浏览: 最多每10秒触发一次
- 文件操作: 最多每5秒触发一次
- 命令执行: 最多每3秒触发一次
#### 0.3.3 调用优先级
- **优先级等级**: 中优先级 (3/5)
- **竞争处理**: 当多个技能同时触发时
- 最高优先级: 系统核心技能
- 高优先级: 代码结构技能
- 中等优先级: 管理端前端技能、文档规范技能
- 低优先级: 辅助工具技能
- **触发限制**: 仅在管理端前端相关操作时被触发,不影响其他技能的正常使用
### 0.4 触发后行为
#### 0.4.1 自动分析
- **结构分析**: 分析管理端前端目录结构
- **组件分析**: 分析前端组件依赖关系
- **路由分析**: 分析前端路由配置
- **性能分析**: 分析前端性能瓶颈
#### 0.4.2 自动展示
- **目录结构**: 展示管理端前端目录结构
- **组件说明**: 展示核心组件功能说明
- **技术栈**: 展示管理端前端技术栈
- **开发规范**: 展示前端开发规范
#### 0.4.3 自动建议
- **开发建议**: 提供管理端前端开发建议
- **优化建议**: 提供前端性能优化建议
- **规范建议**: 提供代码规范遵循建议
- **安全建议**: 提供前端安全防护建议
## 1. 管理端前端架构
### 1.1 整体架构
- **单页应用**: 基于 Vue 2.x 的单页应用
- **前后端分离**: 与后端通过 RESTful API 交互
- **模块化设计**: 功能模块化,易于扩展
- **响应式布局**: 适配不同屏幕尺寸
### 1.2 技术栈
- **核心框架**: Vue 2.x
- **UI 组件库**: Element UI
- **状态管理**: Vuex
- **路由管理**: Vue Router
- **HTTP 客户端**: Axios
- **构建工具**: Webpack
- **包管理器**: npm/yarn
- **代码规范**: ESLint + Prettier
### 1.3 目录结构
#### 1.3.1 核心目录
```
public/admin/
├── index.html # 入口 HTML 文件
├── static/ # 静态资源
│ ├── css/ # 样式文件
│ ├── js/ # JavaScript 文件
│ └── img/ # 图片资源
├── favicon.ico # 网站图标
└── manifest.json # PWA 配置文件
```
#### 1.3.2 源代码目录 (src)
```
src/
├── api/ # API 接口定义
├── assets/ # 静态资源
├── components/ # 公共组件
├── layout/ # 布局组件
├── pages/ # 页面组件
├── router/ # 路由配置
├── store/ # 状态管理
├── utils/ # 工具函数
├── directive/ # 自定义指令
├── filters/ # 自定义过滤器
├── mixins/ # 混合器
├── App.vue # 根组件
└── main.js # 入口文件
```
## 2. 核心模块
### 2.1 登录认证模块
- **功能**: 用户登录、权限验证、会话管理
- **关键组件**: `Login.vue`、`Auth.vue`
- **核心功能**:
- 用户名密码登录
- 验证码验证
- 记住密码
- 登录状态管理
- 权限令牌管理
### 2.2 菜单导航模块
- **功能**: 管理端菜单展示、权限控制、路由导航
- **关键组件**: `Sidebar.vue`、`Topbar.vue`
- **核心功能**:
- 动态菜单生成
- 菜单权限控制
- 面包屑导航
- 标签页管理
- 菜单折叠/展开
### 2.3 仪表盘模块
- **功能**: 系统概览、数据统计、关键指标展示
- **关键组件**: `Dashboard.vue`、`Statistics.vue`
- **核心功能**:
- 销售数据统计
- 订单数据统计
- 用户数据统计
- 商品数据统计
- 系统状态监控
### 2.4 用户管理模块
- **功能**: 管理员账号管理、权限分配、角色管理
- **关键组件**: `UserList.vue`、`RoleList.vue`、`PermissionList.vue`
- **核心功能**:
- 用户增删改查
- 角色管理
- 权限分配
- 密码重置
- 登录日志查看
### 2.5 系统设置模块
- **功能**: 系统配置、参数设置、数据备份
- **关键组件**: `SystemConfig.vue`、`Backup.vue`
- **核心功能**:
- 系统基本设置
- 支付配置
- 邮件配置
- 短信配置
- 数据备份/恢复
## 3. 技术特点
### 3.1 组件化开发
- **可复用组件**: 封装常用 UI 组件
- **组件通信**: Props/Events、Vuex、EventBus
- **组件生命周期**: 合理使用生命周期钩子
- **组件命名规范**: 遵循 PascalCase 命名
### 3.2 状态管理
- **Vuex 模块化**: 按功能模块划分 store
- **状态持久化**: 使用 localStorage/sessionStorage
- **异步操作**: 使用 Actions 处理异步请求
- **getters**: 派生状态计算
### 3.3 路由管理
- **动态路由**: 根据权限生成路由
- **路由守卫**: 全局/局部路由守卫
- **路由懒加载**: 提高首屏加载速度
- **嵌套路由**: 实现复杂页面结构
### 3.4 API 调用
- **Axios 封装**: 统一 API 调用方式
- **请求拦截器**: 添加认证令牌
- **响应拦截器**: 统一错误处理
- **API 模块化**: 按功能模块划分 API
## 4. 开发规范
### 4.1 代码规范
- **Vue 风格指南**: 遵循 Vue 官方风格指南
- **ESLint 规则**: 严格遵循 ESLint 规则
- **代码缩进**: 4空格缩进
- **命名规范**:
- 组件名: PascalCase
- 方法/变量: camelCase
- 常量: 全大写
- 文件名: kebab-case 或 PascalCase
### 4.2 目录规范
- **组件目录**: 按功能模块组织组件
- **页面目录**: 按路由结构组织页面
- **资源目录**: 分类存放静态资源
- **工具目录**: 按功能分类工具函数
### 4.3 命名规范
- **组件命名**: 使用语义化的组件名称
- **路由命名**: 与页面组件名称对应
- **store 命名**: 与功能模块名称对应
- **API 命名**: 与后端接口名称对应
### 4.4 注释规范
- **组件注释**: 组件功能、props、events 说明
- **方法注释**: 方法功能、参数、返回值说明
- **复杂逻辑注释**: 关键逻辑步骤说明
- **TODO 注释**: 待完成功能标记
## 5. 性能优化
### 5.1 加载优化
- **路由懒加载**: 按需加载页面组件
- **组件懒加载**: 按需加载大型组件
- **图片优化**: 图片压缩、懒加载
- **资源压缩**: JS/CSS 压缩
- **CDN 加速**: 静态资源使用 CDN
### 5.2 渲染优化
- **虚拟列表**: 长列表使用虚拟滚动
- **计算属性缓存**: 使用 computed 缓存计算结果
- **避免频繁更新**: 使用 v-once、v-memo
- **合理使用 key**: 列表渲染时使用唯一 key
- **减少 DOM 操作**: 批量更新 DOM
### 5.3 网络优化
- **API 请求合并**: 合并相同请求
- **请求缓存**: 缓存重复请求结果
- **防抖节流**: 优化频繁触发的事件
- **WebSocket**: 实时数据使用 WebSocket
- **HTTP/2**: 启用 HTTP/2 协议
### 5.4 构建优化
- **Tree Shaking**: 移除未使用的代码
- **代码分割**: 按路由分割代码
- **预加载**: 预加载关键资源
- **环境变量**: 区分开发/生产环境
## 6. 安全防护
### 6.1 XSS 防护
- **输入验证**: 验证用户输入
- **输出编码**: 对输出进行 HTML 编码
- **CSP**: 配置内容安全策略
- **Vue 自动转义**: 利用 Vue 的 HTML 转义功能
### 6.2 CSRF 防护
- **Token 验证**: 使用 CSRF Token
- **同源策略**: 遵循浏览器同源策略
- **请求头验证**: 验证请求来源
### 6.3 权限控制
- **前端权限验证**: 路由权限控制
- **后端权限验证**: 接口权限验证
- **按钮级别权限**: 细粒度权限控制
- **敏感操作验证**: 重要操作二次确认
### 6.4 数据安全
- **敏感数据加密**: 加密存储敏感信息
- **本地存储安全**: 合理使用 localStorage
- **API 接口安全**: HTTPS、接口签名
## 7. 最佳实践
### 7.1 开发流程
1. **需求分析**: 明确功能需求
2. **设计阶段**: 设计页面结构和组件
3. **编码实现**: 遵循开发规范编码
4. **测试验证**: 功能测试和性能测试
5. **代码审查**: 代码质量检查
6. **部署上线**: 构建和部署
### 7.2 组件开发
- **单一职责**: 组件功能单一
- **可配置性**: 组件参数可配置
- **文档完善**: 组件使用文档
- **测试覆盖**: 组件单元测试
### 7.3 页面开发
- **布局规范**: 遵循统一布局规范
- **响应式设计**: 适配不同屏幕尺寸
- **用户体验**: 优化交互体验
- **性能考虑**: 页面加载和渲染性能
### 7.4 调试技巧
- **Vue DevTools**: 使用 Vue 开发工具
- **控制台调试**: 合理使用 console 方法
- **网络调试**: 分析 API 请求和响应
- **性能分析**: 使用浏览器性能分析工具
## 8. 常见问题
### 8.1 登录问题
- **令牌过期**: 处理令牌过期逻辑
- **权限不足**: 权限验证失败处理
- **登录状态保持**: 持久化登录状态
### 8.2 路由问题
- **404 页面**: 配置 404 路由
- **路由重定向**: 合理配置路由重定向
- **路由权限**: 动态路由权限控制
### 8.3 性能问题
- **首屏加载慢**: 优化首屏加载速度
- **页面卡顿**: 优化页面渲染性能
- **内存泄漏**: 避免内存泄漏
### 8.4 兼容性问题
- **浏览器兼容**: 支持主流浏览器
- **分辨率兼容**: 适配不同分辨率
- **设备兼容**: 适配不同设备
## 9. 部署与发布
### 9.1 构建流程
- **开发环境**: `npm run dev`
- **测试环境**: `npm run build:test`
- **生产环境**: `npm run build:prod`
### 9.2 部署方式
- **静态部署**: 部署到静态文件服务器
- **容器部署**: 使用 Docker 容器部署
- **CDN 加速**: 静态资源使用 CDN
### 9.3 发布流程
1. **代码提交**: 提交代码到版本控制系统
2. **构建测试**: 构建并测试
3. **部署上线**: 部署到生产环境
4. **监控运行**: 监控系统运行状态
## 10. 开发工具推荐
### 10.1 IDE 推荐
- **VS Code**: 轻量级编辑器,丰富的插件
- **WebStorm**: 专业的前端 IDE
- **Sublime Text**: 快速的代码编辑器
### 10.2 插件推荐
- **Vetur**: Vue 开发插件
- **ESLint**: 代码检查插件
- **Prettier**: 代码格式化插件
- **GitLens**: Git 增强插件
- **Debugger for Chrome**: 浏览器调试插件
### 10.3 工具推荐
- **Postman**: API 测试工具
- **Charles**: 网络调试工具
- **Figma/Sketch**: UI 设计工具
- **Zeplin**: 设计协作工具
- **Lighthouse**: 性能分析工具
## 11. 参考资源
### 11.1 官方文档
- [Vue 2 官方文档](https://v2.vuejs.org/)
- [Element UI 官方文档](https://element.eleme.io/#/zh-CN)
- [Vuex 官方文档](https://vuex.vuejs.org/zh/)
- [Vue Router 官方文档](https://router.vuejs.org/zh/)
- [Axios 官方文档](https://axios-http.com/zh/docs/intro)
### 11.2 学习资源
- [Vue Mastery](https://www.vuemastery.com/)
- [Vue School](https://vueschool.io/)
- [MDN Web Docs](https://developer.mozilla.org/zh-CN/)
- [CSS-Tricks](https://css-tricks.com/)
### 11.3 社区资源
- [Vue 论坛](https://forum.vuejs.org/)
- [Element UI 社区](https://github.com/ElemeFE/element)
- [GitHub](https://github.com/)
- [Stack Overflow](https://stackoverflow.com/)
## 12. 版本管理
### 12.1 版本控制
- **Git**: 使用 Git 进行版本控制
- **分支管理**: 主分支、开发分支、功能分支
- **提交规范**: 语义化提交信息
### 12.2 版本发布
- **语义化版本**: 遵循 SemVer 规范
- **发布日志**: 记录版本变更内容
- **回滚方案**: 版本回滚策略
## 13. 团队协作
### 13.1 协作流程
- **需求评审**: 团队评审需求
- **任务分配**: 合理分配开发任务
- **代码审查**: 代码质量检查
- **测试协作**: 开发与测试协作
### 13.2 规范约定
- **代码规范**: 统一代码风格
- **命名规范**: 统一命名规则
- **文档规范**: 统一文档格式
- **提交规范**: 统一提交信息格式
### 13.3 工具协作
- **项目管理**: 使用项目管理工具
- **代码托管**: 使用代码托管平台
- **CI/CD**: 持续集成/持续部署
- **文档协作**: 团队文档协作工具
### 14 其他资源
- 开发流程文档 /references/development_flow.md
- 代码规范文档 /references/code_style.md
- 项目部署文档 /references/deploy.md
- 目录结构文档 /references/directory_structure.md
- 接口请求流程文档 /references/api_flow.md
- 系统配置文档 /references/system_config.md

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

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,380 @@
---
name: PHP后端开发说明
description: PHP后端开发skill说明
---
# PHP后端开发说明
## 0. 自动触发说明
### 0.1 触发条件
#### 0.1.1 操作触发
- **文件浏览时**: 当浏览 PHP 后端相关目录时自动调用
- 打开 `app/` 目录时触发
- 打开 `crmeb/` 核心库目录时触发
- 浏览控制器、模型、服务目录时触发
- 查看配置文件目录时触发
- **文件操作时**: 当对 PHP 后端文件进行操作时自动调用
- 创建新 PHP 文件时触发
- 修改后端代码时触发
- 删除 PHP 文件时触发
- **目录操作时**: 当对 PHP 后端目录进行操作时自动调用
- 创建新后端目录时触发
- 重命名后端目录时触发
- 删除后端目录时触发
#### 0.1.2 内容触发
- **关键词触发**: 当文件内容包含以下关键词时自动调用
- 后端关键词: `后端`、`PHP`、`服务器`、`API`、`接口`
- 框架关键词: `ThinkPHP`、`TP6`、`框架`、`路由`、`控制器`
- 功能关键词: `登录`、`注册`、`支付`、`订单`、`用户`
- **代码触发**: 当查看特定类型 PHP 代码时自动调用
- 控制器代码 (`Controller`)
- 模型代码 (`Model`)
- 服务代码 (`Service`)
- 配置代码 (`Config`)
- 路由代码 (`Route`)
#### 0.1.3 命令触发
- **终端命令触发**: 当执行以下命令时自动调用
- `php think` (ThinkPHP 命令)
- `composer` (依赖管理命令)
- `php` (PHP 执行命令)
- `artisan` (Laravel 命令,如需)
### 0.2 适用场景
#### 0.2.1 核心场景
- **后端开发**: 开发 PHP 后端功能时
- **API 开发**: 开发 RESTful API 接口时
- **业务逻辑实现**: 实现核心业务逻辑时
- **数据操作**: 进行数据库操作时
#### 0.2.2 辅助场景
- **代码调试**: 调试 PHP 后端代码时
- **性能优化**: 优化后端性能时
- **安全加固**: 增强后端安全性时
- **架构设计**: 设计后端架构时
### 0.3 触发机制
#### 0.3.1 调用时机
- **实时触发**: PHP 文件操作时立即触发
- **延迟触发**: 复杂目录操作时延迟1秒触发
- **批量触发**: 批量文件操作时合并触发
#### 0.3.2 调用频率
- 文件浏览: 最多每10秒触发一次
- 文件操作: 最多每5秒触发一次
- 命令执行: 最多每3秒触发一次
#### 0.3.3 调用优先级
- **优先级等级**: 中等优先级 (3/5)
- **竞争处理**: 当多个技能同时触发时
- 最高优先级: 系统核心技能
- 高优先级: 代码结构技能
- 中等优先级: PHP 后端技能、前端技能、移动端技能
- 低优先级: 辅助工具技能
- **触发限制**: 仅在 PHP 后端相关操作时被触发,不影响其他技能的正常使用
### 0.4 触发后行为
#### 0.4.1 自动分析
- **代码分析**: 分析 PHP 代码结构和质量
- **依赖分析**: 分析代码依赖关系
- **性能分析**: 分析代码性能瓶颈
- **安全分析**: 分析代码安全隐患
#### 0.4.2 自动展示
- **目录结构**: 展示 PHP 后端目录结构
- **代码说明**: 展示核心代码功能说明
- **技术栈**: 展示后端技术栈
- **开发规范**: 展示 PHP 开发规范
#### 0.4.3 自动建议
- **开发建议**: 提供 PHP 后端开发建议
- **优化建议**: 提供性能优化建议
- **规范建议**: 提供代码规范遵循建议
- **安全建议**: 提供安全防护建议
## 1. PHP 后端架构
### 1.1 整体架构
- **框架**: ThinkPHP 6.x
- **架构模式**: MVC + Service + DAO 分层架构
- **设计模式**: 单例、工厂、依赖注入等
- **数据库**: MySQL 5.7~8.0
- **缓存**: Redis (推荐)
- **队列**: ThinkPHP 内置队列
### 1.2 技术栈
- **PHP**: 7.1~7.4
- **ThinkPHP**: 6.x
- **MySQL**: 5.7+
- **Redis**: 5.0+
- **Composer**: 依赖管理
- **Workerman**: 长连接服务
### 1.3 目录结构
#### 1.3.1 核心目录
```
app/
├── api/ # API 接口层
├── controller/ # 控制器层
├── dao/ # 数据访问层
├── model/ # 模型层
├── services/ # 业务逻辑层
├── event/ # 事件处理层
├── middleware/ # 中间件层
└── validate/ # 数据验证层
```
#### 1.3.2 配置目录
```
config/
├── app.php # 应用配置
├── database.php # 数据库配置
├── route.php # 路由配置
├── cache.php # 缓存配置
└── queue.php # 队列配置
```
#### 1.3.3 核心库目录
```
crmeb/
├── basic/ # 基础类库
├── exception/ # 异常处理
└── services/ # 核心服务
```
## 2. 核心模块
### 2.1 控制器模块
- **功能**: 处理 HTTP 请求,路由分发,响应客户端
- **特点**: RESTful 风格,分层清晰,参数验证
- **关键文件**: `BaseController.php` (控制器基类)
- **示例代码**:
```php
<?php
namespace app\controller;
use app\BaseController;
class UserController extends BaseController
{
public function index()
{
return $this->success('获取用户列表成功', $data);
}
}
```
### 2.2 服务模块
- **功能**: 实现核心业务逻辑,封装业务规则
- **特点**: 业务逻辑集中,可复用性高,易于测试
- **关键文件**: 各业务服务类
- **示例代码**:
```php
<?php
namespace app\services;
use crmeb\basic\BaseServices;
class UserServices extends BaseServices
{
public function createUser($data)
{
// 业务逻辑实现
return $userId;
}
}
```
### 2.3 数据访问模块
- **功能**: 封装数据库操作,提供数据访问方法
- **特点**: SQL 集中管理,防止 SQL 注入,提高安全性
- **关键文件**: 各数据访问对象类
- **示例代码**:
```php
<?php
namespace app\dao;
use crmeb\basic\BaseDao;
class UserDao extends BaseDao
{
public function getUserById($id)
{
return $this->where('id', $id)->find();
}
}
```
### 2.4 模型模块
- **功能**: 定义数据模型,处理数据关系
- **特点**: ORM 映射,自动表结构,关联查询
- **关键文件**: `BaseModel.php` (模型基类)
- **示例代码**:
```php
<?php
namespace app\model;
use crmeb\basic\BaseModel;
class User extends BaseModel
{
protected $table = 'user';
protected $pk = 'id';
}
```
### 2.5 路由模块
- **功能**: 定义 URL 路由规则,分发请求
- **特点**: RESTful 风格,路由分组,中间件支持
- **关键文件**: `route/api.php`、`route/app.php`
- **示例代码**:
```php
<?php
use think\facade\Route;
Route::get('user/:id', 'User/read');
Route::post('user', 'User/save');
Route::put('user/:id', 'User/update');
Route::delete('user/:id', 'User/delete');
```
## 3. 开发规范
### 3.1 代码规范
- **PHP 规范**: 遵循 PSR-2 命名规范
- **命名规范**:
- 类名: PascalCase
- 方法/变量: camelCase
- 常量: 全大写,下划线分隔
- 文件名: 与类名一致,PascalCase
- **代码缩进**: 4空格缩进,禁止制表符
- **注释规范**: 方法注释、类注释、关键逻辑注释
### 3.2 目录规范
- **按功能模块组织**: 相同功能的代码放在同一目录
- **目录层次清晰**: 避免过深的目录嵌套
- **命名语义化**: 目录名应反映其功能
### 3.3 数据库规范
- **表名**: 小写下划线分隔
- **主键**: 统一命名为 `id`
- **外键**: 格式 `表名_id`
- **时间字段**: `create_time`/`update_time`
- **状态字段**: `status`,默认值 0
### 3.4 API 规范
- **RESTful 风格**: 使用标准 HTTP 方法
- **响应格式**: 统一 JSON 格式
- **错误处理**: 使用统一的错误码和错误信息
- **参数验证**: 严格的参数验证
## 4. 最佳实践
### 4.1 开发流程
1. **需求分析**: 明确功能需求和技术方案
2. **架构设计**: 设计模块结构和数据库结构
3. **代码实现**: 遵循开发规范编码
4. **测试验证**: 单元测试和功能测试
5. **代码审查**: 代码质量检查
6. **部署上线**: 构建和部署
### 4.2 性能优化
- **数据库优化**: 索引优化,SQL 优化
- **缓存策略**: 合理使用 Redis 缓存
- **代码优化**: 减少循环嵌套,优化算法
- **请求优化**: 合并请求,减少 HTTP 调用
### 4.3 安全防护
- **SQL 注入防护**: 使用参数绑定,避免直接拼接 SQL
- **XSS 防护**: 输入验证和输出编码
- **CSRF 防护**: 使用 Token 验证
- **权限控制**: 严格的权限验证机制
- **敏感信息保护**: 加密存储敏感信息
### 4.4 代码复用
- **抽象公共逻辑**: 将公共逻辑抽象为服务或工具类
- **使用 Traits**: 复用代码片段
- **继承基类**: 继承基础类获得通用功能
- **依赖注入**: 提高代码可测试性和可维护性
## 5. 常见问题
### 5.1 性能问题
- **数据库查询慢**: 检查索引,优化 SQL
- **内存占用高**: 检查大数组,优化内存使用
- **响应时间长**: 检查业务逻辑,使用缓存
### 5.2 安全问题
- **SQL 注入**: 使用参数绑定,避免直接拼接 SQL
- **XSS 攻击**: 对输入进行验证和过滤
- **CSRF 攻击**: 实现 CSRF Token 验证
- **权限绕过**: 严格检查权限,避免逻辑漏洞
### 5.3 部署问题
- **环境配置**: 确保生产环境配置正确
- **依赖管理**: 使用 Composer 管理依赖
- **缓存清理**: 部署后清理缓存
- **日志管理**: 配置合理的日志级别
### 5.4 代码问题
- **命名不规范**: 遵循命名规范
- **注释不足**: 添加必要的注释
- **逻辑混乱**: 重构代码,提高可读性
- **重复代码**: 抽象公共逻辑,减少重复
## 6. 开发工具推荐
### 6.1 IDE 推荐
- **PHPStorm**: 专业的 PHP IDE,功能强大
- **VS Code**: 轻量级编辑器,丰富的插件
- **Sublime Text**: 快速的代码编辑器
### 6.2 插件推荐
- **PHP Inspections**: PHP 代码检查插件
- **Laravel Idea**: Laravel 开发插件 (如需)
- **GitLens**: Git 增强插件
- **Debugger for Chrome**: 浏览器调试插件
### 6.3 工具推荐
- **Composer**: PHP 依赖管理工具
- **PHPUnit**: PHP 单元测试框架
- **Postman**: API 测试工具
- **MySQL Workbench**: 数据库设计工具
- **Redis Desktop Manager**: Redis 管理工具
## 7. 参考资源
### 7.1 官方文档
- [ThinkPHP 6 官方文档](https://www.kancloud.cn/manual/thinkphp6_0)
- [PHP 官方文档](https://www.php.net/docs.php)
- [MySQL 官方文档](https://dev.mysql.com/doc/)
- [Redis 官方文档](https://redis.io/documentation)
### 7.2 学习资源
- [Laravel 学院](https://learnku.com/laravel)
- [PHP 中文网](https://www.php.cn/)
- [ThinkPHP 社区](https://www.thinkphp.cn/)
- [Stack Overflow](https://stackoverflow.com/)
### 7.3 代码规范
- [PSR 标准](https://www.php-fig.org/psr/)
- [ThinkPHP 代码规范](https://www.thinkphp.cn/doc)
- [PHP 最佳实践](https://phpbestpractices.org/)
### 7.4 其他资源
- 接口开发流程文档 ./references/api_create.md
- 代码规范文档 ./references/code_style.md
- 数据库设计文档 ./references/db_design.md
- 项目部署文档 ./references/deploy.md
- 目录结构文档 ./references/directory_structure.md
- 错误码文档 ./references/error_code.md
- 系统配置文档 ./references/system_config.md
- 接口请求流程文档 ./references/api_flow.md

View File

@ -0,0 +1,545 @@
# 接口开发流程文档
## 1. 概述
本文档描述了 CRMEB 项目中 API 接口的完整开发流程,包括需求分析、设计、开发、测试、文档编写、上线发布和监控维护等阶段。本流程旨在规范 API 开发过程,提高 API 的质量和可维护性。
## 2. 需求分析与设计
### 2.1 需求理解
1. **需求收集**: 收集业务部门或产品经理提出的 API 需求
2. **需求分析**: 分析需求的可行性、优先级和影响范围
3. **需求确认**: 与需求方确认需求细节,确保理解一致
4. **风险评估**: 评估需求实现过程中可能遇到的风险
### 2.2 资源设计
1. **数据模型设计**: 设计 API 涉及的数据模型和数据库表结构
2. **资源定义**: 定义 API 操作的资源和资源关系
3. **数据字段**: 确定资源包含的字段和数据类型
4. **关联关系**: 确定资源之间的关联关系
### 2.3 接口设计
1. **URL 设计**: 设计符合 RESTful 规范的 URL
- 使用复数形式,如 `/api/v1/users` 而不是 `/api/v1/user`
- 使用语义化名称,如 `/api/v1/orders` 而不是 `/api/v1/getOrders`
- 合理的 URL 层级,一般不超过 3 层
2. **请求方法设计**: 选择合适的 HTTP 请求方法
- `GET`: 获取资源
- `POST`: 创建资源
- `PUT`: 更新资源
- `DELETE`: 删除资源
- `PATCH`: 部分更新资源
3. **参数设计**: 设计请求参数
- **路径参数**: 用于标识资源,如 `/api/v1/users/:id`
- **查询参数**: 用于过滤、排序、分页,如 `?page=1&limit=10`
- **请求体参数**: 用于创建或更新资源,使用 JSON 格式
- **请求头参数**: 用于认证、授权等
4. **响应设计**: 设计统一的响应格式
- 使用 `app('json')->success()` 返回成功响应
- 使用 `app('json')->fail()` 返回错误响应
- 统一的响应字段:`status`、`msg`、`data`,错误响应额外包含 `code` 字段
- 分页响应包含 `total`、`page`、`limit`、`list` 字段
### 2.4 权限设计
1. **认证方式**: 选择合适的认证方式
- JWT 认证
- OAuth2 认证
- API Key 认证
2. **授权设计**: 设计 API 的访问权限
- 基于角色的访问控制 (RBAC)
- 基于资源的访问控制 (RBAC)
- 接口级别的权限控制
3. **访问控制**: 实现 API 的访问控制
- 使用中间件进行权限验证
- 接口白名单机制
- 接口速率限制
### 2.5 错误设计
1. **错误场景**: 定义 API 可能出现的错误场景
2. **错误码**: 从 `error_code.md` 文档中选择或申请合适的错误码
3. **错误信息**: 设计清晰、准确的错误信息
4. **错误处理**: 设计统一的错误处理机制
## 3. 开发实现
### 3.1 路由创建
1. **路由定义**: 在路由文件中定义 API 路由
2. **路由分组**: 使用路由分组组织相关 API
3. **中间件**: 为路由添加必要的中间件
4. **命名路由**: 为路由设置名称,便于生成 URL
**示例代码**:
```php
// api/v1/route.php
use think\facade\Route;
// API 版本分组
Route::group('v1', function () {
// 用户相关路由
Route::group('users', function () {
Route::get('', 'User/index'); // 获取用户列表
Route::post('', 'User/save'); // 创建用户
Route::get(':id', 'User/read'); // 获取用户详情
Route::put(':id', 'User/update'); // 更新用户
Route::delete(':id', 'User/delete'); // 删除用户
})->middleware(['auth', 'permission']);
})->middleware(['cors', 'jwt']);
```
### 3.2 控制器实现
1. **创建控制器**: 创建 API 控制器类
2. **继承基类**: 继承项目的控制器基类
3. **实现方法**: 实现 API 接口方法
4. **参数验证**: 使用验证器验证请求参数
5. **业务逻辑**: 实现 API 的业务逻辑
6. **响应返回**: 使用统一的响应方法返回响应
**示例代码**:
```php
// app/api/controller/v1/User.php
namespace app\api\controller\v1;
use app\BaseController;
use app\validate\User as UserValidate;
use app\services\UserServices;
class User extends BaseController
{
protected $userServices;
public function __construct(UserServices $userServices)
{
$this->userServices = $userServices;
}
/**
* 获取用户列表
*/
public function index()
{
$params = $this->request->param();
$list = $this->userServices->getUserList($params);
return app('json')->success('获取用户列表成功', $list);
}
/**
* 创建用户
*/
public function save()
{
$data = $this->request->post();
// 参数验证
$this->validate($data, UserValidate::class);
// 业务逻辑
$result = $this->userServices->createUser($data);
// 返回响应
return app('json')->success('创建用户成功', $result);
}
/**
* 获取用户详情
*/
public function read($id)
{
$user = $this->userServices->getUserById($id);
if (!$user) {
return app('json')->fail(400005); // 用户不存在
}
return app('json')->success('获取用户详情成功', $user);
}
}
```
### 3.3 参数验证
1. **创建验证器**: 创建 API 参数验证器
2. **定义规则**: 定义参数验证规则
3. **错误信息**: 定义验证错误信息,使用错误码
4. **验证调用**: 在控制器中调用验证器
**示例代码**:
```php
// app/validate/User.php
namespace app\validate;
use think\Validate;
class User extends Validate
{
protected $rule = [
'username' => 'require|length:3,20|unique:user',
'password' => 'require|length:6,20',
'email' => 'email|unique:user',
'mobile' => 'mobile|unique:user',
'status' => 'in:0,1',
];
protected $message = [
'username.require' => 400033, // 请填写管理员账号
'username.length' => 400762, // 账号密码必须是在6到32位之间
'username.unique' => 400001, // 用户名已存在
'password.require' => 400020, // 密码必须填写
'password.length' => 400762, // 账号密码必须是在6到32位之间
'email.email' => 400003, // 邮箱已被注册
'email.unique' => 400003, // 邮箱已被注册
'mobile.mobile' => 400319, // 请输入正确的身份证
'mobile.unique' => 400002, // 手机号已被注册
'status.in' => 400751, // 状态必须是0-1之间的整数
];
}
```
### 3.4 业务逻辑实现
1. **服务层**: 将业务逻辑封装到服务层
2. **模型层**: 数据访问封装到模型层
3. **事务处理**: 复杂业务使用事务处理
4. **错误处理**: 统一处理业务逻辑错误
**示例代码**:
```php
// app/services/UserServices.php
namespace app\services;
use app\model\User;
use crmeb\basic\BaseServices;
class UserServices extends BaseServices
{
protected $userModel;
public function __construct(User $userModel)
{
$this->userModel = $userModel;
}
/**
* 获取用户列表
*/
public function getUserList(array $params)
{
$page = $params['page'] ?? 1;
$limit = $params['limit'] ?? 10;
$keyword = $params['keyword'] ?? '';
$query = $this->userModel->where('is_deleted', 0);
if ($keyword) {
$query->where('username|nickname|email|mobile', 'like', "%$keyword%");
}
$list = $query->page($page, $limit)->select();
$total = $query->count();
return [
'total' => $total,
'page' => $page,
'limit' => $limit,
'list' => $list
];
}
/**
* 创建用户
*/
public function createUser(array $data)
{
// 密码加密
$data['password'] = password_hash($data['password'], PASSWORD_DEFAULT);
$data['create_time'] = time();
$data['update_time'] = time();
return $this->userModel->save($data);
}
}
```
### 3.5 错误处理
1. **使用错误码**: 优先使用 `error_code.md` 中定义的错误码
2. **统一错误返回**: 使用 `app('json')->fail()` 返回错误
3. **异常处理**: 使用 try-catch 处理异常
4. **日志记录**: 记录错误日志
**示例代码**:
```php
// 正确使用方式
return app('json')->fail(410025); // 账号或密码错误
// 不推荐的使用方式
return app('json')->fail('账号或密码错误');
// 使用错误码并传递额外数据
return app('json')->fail(400086, [], ['field' => 'username']);
// 异常处理
try {
// 业务逻辑
} catch (\Exception $e) {
// 记录日志
app('log')->error($e->getMessage());
// 返回错误
return app('json')->fail(500); // 系统错误
}
```
## 4. 测试验证
### 4.1 单元测试
1. **编写单元测试**: 为 API 编写单元测试
2. **测试框架**: 使用 PHPUnit 测试框架
3. **测试覆盖率**: 提高测试覆盖率
4. **CI/CD**: 集成到 CI/CD 流程
**示例代码**:
```php
// tests/api/UserTest.php
namespace tests\api;
use think\testing\TestCase;
class UserTest extends TestCase
{
public function testIndex()
{
$response = $this->get('/api/v1/users');
$response->assertStatus(200);
$response->assertJsonStructure([
'status',
'msg',
'data' => [
'total',
'page',
'limit',
'list' => [
'*' => [
'id',
'username',
'nickname',
'email',
'mobile',
'status'
]
]
]
]);
}
public function testSave()
{
$data = [
'username' => 'testuser',
'password' => '123456',
'email' => 'test@example.com',
'mobile' => '13800138000',
'status' => 1
];
$response = $this->post('/api/v1/users', $data);
$response->assertStatus(200);
$response->assertJson(['status' => 200, 'msg' => '创建用户成功']);
}
}
```
### 4.2 集成测试
1. **测试集成**: 测试 API 与其他模块的集成
2. **数据库测试**: 测试 API 对数据库的操作
3. **缓存测试**: 测试 API 的缓存机制
4. **队列测试**: 测试 API 与队列的集成
### 4.3 接口测试
1. **工具测试**: 使用 Postman、Apifox 等工具测试 API
2. **测试用例**: 编写完整的测试用例
3. **边界测试**: 测试边界情况
4. **性能测试**: 测试 API 的性能
### 4.4 安全测试
1. **认证测试**: 测试 API 的认证机制
2. **授权测试**: 测试 API 的授权机制
3. **注入测试**: 测试 SQL 注入、XSS 等安全问题
4. **速率限制测试**: 测试 API 的速率限制
## 5. 文档编写
### 5.1 接口文档
1. **编写接口文档**: 编写详细的接口文档
2. **文档工具**: 使用 Swagger、Apifox 等工具生成文档
3. **文档内容**: 包括 URL、请求方法、参数、响应、错误码等
4. **示例**: 提供请求和响应示例
### 5.2 错误码文档
1. **记录错误码**: 在 `error_code.md` 文档中记录 API 使用的错误码
2. **错误码规范**: 遵循项目的错误码规范
3. **错误码描述**: 清晰描述错误码的含义和使用场景
### 5.3 变更记录
1. **记录变更**: 记录 API 的变更历史
2. **变更类型**: 包括新增、修改、删除等
3. **影响范围**: 记录变更的影响范围
4. **版本管理**: 管理 API 的版本
## 6. 上线发布
### 6.1 代码审查
1. **代码审查**: 进行代码审查,确保代码质量
2. **审查标准**: 遵循项目的代码规范
3. **安全审查**: 审查代码的安全性
4. **性能审查**: 审查代码的性能
### 6.2 测试环境验证
1. **部署测试**: 在测试环境部署 API
2. **功能验证**: 验证 API 的功能
3. **性能验证**: 验证 API 的性能
4. **安全验证**: 验证 API 的安全性
### 6.3 灰度发布
1. **灰度策略**: 制定灰度发布策略
2. **灰度部署**: 灰度部署 API
3. **监控观察**: 监控 API 的运行情况
4. **逐步放量**: 逐步增加灰度流量
### 6.4 正式上线
1. **上线准备**: 准备上线所需的资源
2. **正式部署**: 正式部署 API
3. **上线验证**: 验证 API 的正常运行
4. **发布公告**: 发布 API 上线公告
## 7. 监控维护
### 7.1 监控
1. **性能监控**: 监控 API 的响应时间、QPS 等
2. **错误监控**: 监控 API 的错误率、错误类型等
3. **可用性监控**: 监控 API 的可用性
4. **日志监控**: 监控 API 的访问日志和错误日志
### 7.2 日志
1. **访问日志**: 记录 API 的访问日志
2. **错误日志**: 记录 API 的错误日志
3. **慢查询日志**: 记录 API 的慢查询日志
4. **日志分析**: 定期分析日志
### 7.3 优化
1. **性能优化**: 根据监控数据优化 API 性能
2. **安全优化**: 加强 API 的安全性
3. **功能优化**: 优化 API 的功能
4. **代码优化**: 优化 API 的代码
### 7.4 维护
1. **定期维护**: 定期维护 API
2. **版本更新**: 更新 API 的版本
3. **漏洞修复**: 修复 API 的漏洞
4. **文档更新**: 更新 API 的文档
## 8. 最佳实践
### 8.1 设计最佳实践
1. **遵循 RESTful 规范**: 使用 RESTful API 设计规范
2. **统一的命名规范**: 使用统一的命名规范
3. **合理的 URL 设计**: 设计简洁、语义化的 URL
4. **统一的响应格式**: 使用统一的响应格式
5. **明确的错误码**: 使用明确的错误码
### 8.2 开发最佳实践
1. **分层架构**: 遵循分层架构设计
2. **依赖注入**: 使用依赖注入
3. **参数验证**: 严格验证请求参数
4. **事务处理**: 合理使用事务
5. **缓存策略**: 合理使用缓存
### 8.3 测试最佳实践
1. **自动化测试**: 编写自动化测试
2. **测试覆盖率**: 提高测试覆盖率
3. **边界测试**: 测试边界情况
4. **性能测试**: 测试 API 的性能
5. **安全测试**: 测试 API 的安全性
### 8.4 上线最佳实践
1. **灰度发布**: 使用灰度发布策略
2. **监控观察**: 上线后密切监控
3. **回滚机制**: 准备回滚机制
4. **发布公告**: 及时发布公告
### 8.5 维护最佳实践
1. **监控预警**: 设置监控预警
2. **定期巡检**: 定期巡检 API
3. **日志分析**: 定期分析日志
4. **性能优化**: 持续优化性能
5. **文档更新**: 及时更新文档
## 9. 常见问题
### 9.1 跨域问题
- **问题**: 浏览器同源策略导致跨域请求失败
- **解决方案**: 实现 CORS(跨域资源共享),设置适当的响应头
### 9.2 认证授权问题
- **问题**: API 认证授权失败
- **解决方案**: 检查认证信息,确保令牌有效,权限正确
### 9.3 参数验证问题
- **问题**: 请求参数验证失败
- **解决方案**: 检查请求参数,确保格式正确,包含所有必填参数
### 9.4 性能问题
- **问题**: API 响应时间过长
- **解决方案**: 优化 API 实现,使用缓存,减少数据库查询次数
### 9.5 安全问题
- **问题**: API 存在安全漏洞
- **解决方案**: 加强 API 的安全性,如使用 HTTPS、参数验证、防止 SQL 注入等
## 10. 参考资源
- [RESTful API 设计指南](https://restfulapi.net/)
- [HTTP 状态码](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Status)
- [API 设计最佳实践](https://cloud.google.com/apis/design)
- [JSON API 规范](https://jsonapi.org/)
- [OpenAPI 规范](https://swagger.io/specification/)
- [API 安全性最佳实践](https://owasp.org/www-project-api-security/)
- [ThinkPHP 6 官方文档](https://www.kancloud.cn/manual/thinkphp6_0)
- [PHPUnit 官方文档](https://phpunit.de/)
- [Postman 官方文档](https://learning.postman.com/)

View File

@ -0,0 +1,488 @@
# 接口请求文档
## 1. 概述
本文档描述了 CRMEB 项目中 API 接口请求的流程、规范、参数设计和响应格式等,旨在统一 API 请求格式,提高 API 的一致性和可维护性。
## 2. 接口请求流程
### 2.1 基本流程
1. **客户端发起请求**: 客户端通过 HTTP/HTTPS 协议向服务器发送请求
2. **请求到达服务器**: 请求经过网络传输到达服务器
3. **请求解析**: 服务器解析请求,包括请求方法、路径、参数等
4. **认证授权**: 服务器对请求进行认证和授权
5. **业务处理**: 服务器执行相应的业务逻辑
6. **生成响应**: 服务器生成响应数据
7. **返回响应**: 服务器将响应返回给客户端
8. **客户端处理响应**: 客户端处理服务器返回的响应
### 2.2 详细流程
```
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ 客户端 │ │ 中间件 │ │ 控制器 │
│ 1. 发起请求 │────▶│ 2. 认证授权 │────▶│ 3. 业务处理 │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│
▼
┌─────────────────┐
│ 服务层 │
│ 4. 执行逻辑 │
└─────────────────┘
│
▼
┌─────────────────┐
│ 数据层 │
│ 5. 数据操作 │
└─────────────────┘
│
▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ 客户端 │ │ 中间件 │ │ 控制器 │
│ 8. 处理响应 │◀────│ 7. 响应处理 │◀────│ 6. 生成响应 │
└─────────────────┘ └─────────────────┘ └─────────────────┘
```
## 3. 请求方法
### 3.1 HTTP 方法
| 方法 | 描述 | 幂等性 | 安全性 |
|------|------|--------|--------|
| GET | 获取资源 | 是 | 是 |
| POST | 创建资源 | 否 | 否 |
| PUT | 更新资源 | 是 | 否 |
| DELETE | 删除资源 | 是 | 否 |
| PATCH | 部分更新资源 | 否 | 否 |
| OPTIONS | 获取资源的可用操作 | 是 | 是 |
| HEAD | 获取资源的元数据 | 是 | 是 |
### 3.2 方法使用规范
- **GET**: 用于获取资源,不应修改资源状态
- **POST**: 用于创建新资源
- **PUT**: 用于更新整个资源,应包含资源的完整表示
- **DELETE**: 用于删除资源
- **PATCH**: 用于部分更新资源,只包含需要更新的字段
- **OPTIONS**: 用于获取资源支持的 HTTP 方法
- **HEAD**: 用于获取资源的元数据,如 Content-Length、Last-Modified 等
## 4. 请求头
### 4.1 通用请求头
| 请求头 | 描述 | 示例 |
|-------|------|------|
| Accept | 客户端可接受的响应内容类型 | application/json |
| Accept-Encoding | 客户端可接受的编码方式 | gzip, deflate |
| Content-Type | 请求体的内容类型 | application/json |
| Authorization | 认证信息 | Bearer {token} |
| User-Agent | 客户端标识 | Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36 |
| X-Requested-With | 请求类型 | XMLHttpRequest |
| X-Token | 认证令牌(自定义) | your_token_here |
### 4.2 自定义请求头
自定义请求头应以 `X-` 为前缀,如 `X-Token`、`X-Request-ID` 等。
## 5. 请求参数
### 5.1 参数位置
| 位置 | 适用场景 | 示例 |
|------|----------|------|
| URL 路径 | 资源标识 | /api/v1/user/1 |
| 查询字符串 | 过滤、排序、分页 | /api/v1/user?page=1&limit=10&sort=create_time&order=desc |
| 请求体 | 复杂数据、创建/更新资源 | {"username": "test", "password": "123456"} |
| 请求头 | 认证信息、元数据 | Authorization: Bearer {token} |
| Cookie | 会话信息 | PHPSESSID=your_session_id |
### 5.2 参数命名规范
- **命名风格**: 使用 camelCase 命名风格,如 `userName`
- **语义化**: 参数名应具有明确的语义,如 `page`、`limit`、`sort`
- **简洁性**: 参数名应简洁明了,避免过长
- **一致性**: 相同类型的参数在不同接口中应保持一致
### 5.3 常用参数
| 参数名 | 类型 | 描述 | 示例 |
|-------|------|------|------|
| page | int | 页码,默认 1 | page=1 |
| limit | int | 每页数量,默认 10 | limit=20 |
| sort | string | 排序字段 | sort=create_time |
| order | string | 排序方式,asc 或 desc | order=desc |
| keyword | string | 搜索关键词 | keyword=test |
| status | int | 状态过滤 | status=1 |
| start_time | string | 开始时间 | start_time=2024-01-01 |
| end_time | string | 结束时间 | end_time=2024-01-31 |
## 6. 请求体
### 6.1 内容类型
| 内容类型 | 描述 | 示例 |
|---------|------|------|
| application/json | JSON 格式,最常用 | {"username": "test", "password": "123456"} |
| application/x-www-form-urlencoded | 表单格式 | username=test&password=123456 |
| multipart/form-data | 文件上传 | 包含文件和表单字段 |
| text/plain | 纯文本 | 简单的文本数据 |
| application/xml | XML 格式 | <user><username>test</username><password>123456</password></user> |
### 6.2 JSON 请求体规范
- **使用 camelCase 命名**: 字段名使用 camelCase 命名风格
- **明确的数据类型**: 使用适当的数据类型,如字符串、数字、布尔值、数组、对象
- **避免 null 值**: 非必要字段不应包含 null 值
- **嵌套结构**: 合理使用嵌套结构,避免过深的嵌套
- **数组格式**: 数组元素类型应一致
示例:
```json
{
"username": "test",
"password": "123456",
"nickname": "测试用户",
"age": 18,
"gender": 1,
"tags": ["tag1", "tag2"],
"address": {
"province": "北京",
"city": "北京",
"district": "朝阳区"
}
}
```
## 7. 响应格式
### 7.1 基本响应格式
所有 API 响应应使用统一的 JSON 格式,包含 `status`、`msg` 和可选的 `data` 字段。系统实际调用方式为 `app('json')->success()`。
#### 7.1.1 调用示例
```php
// 基本成功响应
return app('json')->success('操作成功', ['id' => 1, 'username' => 'test']);
// 只返回数据,不指定消息
return app('json')->success(['id' => 1, 'username' => 'test']);
// 使用系统内置成功码
return app('json')->success(100000); // 100000 是 "保存成功" 对应的系统内置成功码
```
#### 7.1.2 响应格式
```json
{
"status": 200,
"msg": "操作成功",
"data": {
"id": 1,
"username": "test",
"nickname": "测试用户"
}
}
```
### 7.2 分页响应格式
分页响应应包含 `total`、`page`、`limit` 和 `list` 字段,系统实际调用方式为 `app('json')->success()`。
#### 7.2.1 调用示例
```php
// 分页数据响应
$pageData = [
'total' => 100,
'page' => 1,
'limit' => 10,
'list' => [
['id' => 1, 'username' => 'test1', 'nickname' => '测试用户1'],
['id' => 2, 'username' => 'test2', 'nickname' => '测试用户2']
]
];
return app('json')->success('获取列表成功', $pageData);
```
#### 7.2.2 响应格式
```json
{
"status": 200,
"msg": "获取列表成功",
"data": {
"total": 100,
"page": 1,
"limit": 10,
"list": [
{
"id": 1,
"username": "test1",
"nickname": "测试用户1"
},
{
"id": 2,
"username": "test2",
"nickname": "测试用户2"
}
]
}
}
```
### 7.3 错误响应格式
系统使用统一的错误响应格式,所有错误响应通过 `app('json')->fail()` 方法返回。`fail()` 方法支持两种参数类型:
- **错误码**(推荐):系统内置的数字错误码,如 `410025`
- **错误消息**:直接的字符串错误信息
#### 7.3.1 统一响应格式
无论使用哪种参数类型,系统都会返回统一的 JSON 格式,包含 `status`、`msg` 和可选的 `data` 字段。当使用错误码时,响应中还会包含 `code` 字段。
```json
{
"status": 400,
"msg": "账号或密码错误",
"code": 410025,
"data": null
}
```
#### 7.3.2 调用示例
```php
// 推荐:使用系统内置错误码
return app('json')->fail(410025);
// 不推荐:直接使用错误消息
return app('json')->fail('账号或密码错误');
// 使用错误码并传递额外数据
return app('json')->fail(410025, ['extra' => 'additional data']);
// 使用错误码并传递替换参数
return app('json')->fail(410025, [], ['field' => 'username']);
```
#### 7.3.3 最佳实践
- **优先使用错误码**:系统内置错误码经过统一规划,便于维护和国际化
- **避免直接使用字符串**:直接使用字符串错误信息不利于国际化和统一管理
- **传递必要的额外数据**:对于复杂错误,可以在 `data` 字段中提供详细信息
- **使用替换参数**:对于动态错误信息,使用替换参数提高灵活性
### 7.4 响应码规范
| 响应码范围 | 类型 | 描述 | 示例 |
|-----------|------|------|------|
| 200 | 成功 | 操作成功 | 200 |
| 1000-1999 | 系统级错误 | 系统核心错误 | 1001(参数错误) |
| 4000-4999 | 业务级错误 | 具体业务逻辑错误 | 410025(账号或密码错误) |
| 400 | 客户端错误 | 请求参数错误 | 400 |
| 401 | 认证错误 | 未认证或认证过期 | 401 |
| 403 | 权限错误 | 无权限访问 | 403 |
| 404 | 资源错误 | 资源不存在 | 404 |
| 500 | 服务器错误 | 服务器内部错误 | 500 |
## 8. 错误处理
### 8.1 错误响应设计
错误响应应遵循以下设计原则:
1. **统一格式**: 所有错误响应使用相同的 JSON 格式
2. **明确的错误码**: 使用唯一的错误码标识不同的错误类型
3. **清晰的错误信息**: 错误信息应简洁明了,便于理解
4. **可选的详细信息**: 对于复杂错误,可以在 `data` 字段中提供详细信息
5. **HTTP 状态码匹配**: 错误码应与 HTTP 状态码匹配
### 8.2 AI 自动提示系统内置错误码
CRMEB 系统集成了 AI 自动提示功能,当开发者在编写代码时使用 `fail()` 方法返回错误信息时,AI 会自动:
1. **识别错误信息**: 自动识别开发者输入的错误信息字符串
2. **匹配内置错误码**: 在系统内置错误码库中查找匹配的错误码
3. **自动转换**: 在运行时将错误信息自动转换为对应的系统内置错误码
4. **提供建议**: 对于未匹配到的错误信息,提供相似的错误码建议
5. **实时提示**: 在 IDE 中实时显示错误码建议
6. **错误码文档**: 在错误码文档 error_code.md,找到对应的错误码说明
#### 8.2.1 功能示例
```php
// 开发者输入
return $this->fail('登录失败');
// AI 自动提示并替换为
return $this->fail(410019); // 410019 是 "登录失败" 对应的系统内置错误码
```
#### 8.2.2 工作原理
1. **语言文件解析**: 系统在运行时解析语言文件,构建错误码到错误信息的映射表
2. **自动匹配**: 当调用 `fail()` 方法传入字符串错误信息时,系统自动在映射表中查找匹配的错误码
3. **运行时转换**: 如果找到匹配的错误码,系统会将错误信息替换为错误码,并在响应中包含 `code` 字段
4. **智能提示**: 在 IDE 中,AI 会实时提示开发者使用正确的系统内置错误码
#### 8.2.3 实际响应格式
当使用字符串错误信息时,系统会自动匹配并转换为错误码,最终响应格式为:
```json
{
"status": 400,
"msg": "登录失败",
"code": 410019
}
```
当直接使用错误码时,响应格式为:
```json
{
"status": 400,
"msg": "登录失败",
"code": 410019
}
```
### 8.3 错误处理最佳实践
1. **使用系统内置错误码**: 优先使用系统内置错误码,避免自定义错误信息
2. **错误信息本地化**: 使用 `getLang()` 函数获取本地化的错误信息
3. **详细的错误日志**: 记录详细的错误日志,包括错误码、错误信息、请求参数等
4. **友好的错误提示**: 对客户端返回友好的错误信息,避免暴露系统内部细节
5. **统一的错误处理**: 使用统一的错误处理中间件处理所有错误
6. **错误码文档化**: 定期更新错误码文档,确保与实际代码一致
### 8.4 自定义错误码
对于系统内置错误码无法覆盖的业务场景,可以自定义错误码,但应遵循以下规范:
1. **错误码范围**: 使用系统未占用的错误码范围
2. **命名规范**: 错误码应具有明确的语义
3. **文档化**: 自定义错误码应在文档中明确说明
4. **本地化**: 自定义错误码应在语言文件中定义对应的错误信息
## 9. 接口开发流程
### 9.1 需求分析与设计
1. **需求理解**: 明确接口的业务需求和功能要求
2. **资源设计**: 确定接口涉及的资源和数据模型
3. **接口设计**: 设计接口的 URL、请求方法、参数和响应格式
4. **权限设计**: 确定接口的访问权限和认证方式
5. **错误设计**: 定义接口可能出现的错误情况和错误码
### 9.2 开发实现
1. **创建路由**: 在路由文件中定义接口路由
2. **实现控制器**: 创建控制器并实现接口逻辑
3. **参数验证**: 使用验证器对请求参数进行验证
4. **业务逻辑**: 实现接口的业务逻辑
5. **错误处理**: 使用 `app('json')->fail()` 统一处理错误
6. **响应返回**: 使用 `app('json')->success()` 统一返回响应
### 9.3 测试验证
1. **单元测试**: 编写单元测试验证接口功能
2. **集成测试**: 测试接口与其他模块的集成
3. **接口测试**: 使用 Postman 或其他工具测试接口
4. **性能测试**: 测试接口的性能和响应时间
5. **安全测试**: 测试接口的安全性
### 9.4 文档编写
1. **接口文档**: 编写接口的详细文档
2. **错误码文档**: 在 `error_code.md` 中记录接口使用的错误码
3. **变更记录**: 记录接口的变更历史
### 9.5 上线发布
1. **代码审查**: 进行代码审查,确保代码质量
2. **测试环境验证**: 在测试环境验证接口功能
3. **灰度发布**: 灰度发布接口,观察运行情况
4. **正式上线**: 正式上线接口
### 9.6 监控维护
1. **监控**: 监控接口的运行状态和性能
2. **日志**: 记录接口的访问日志和错误日志
3. **优化**: 根据监控数据优化接口性能
4. **维护**: 定期维护和更新接口
## 10. 最佳实践
### 10.1 请求设计
- **使用 RESTful 风格**: 遵循 RESTful API 设计规范
- **明确的资源命名**: 使用明确的资源名称,如 `/api/v1/user` 而不是 `/api/v1/getUser`
- **合理的 URL 层级**: URL 层级不应过深,一般不超过 3 层
- **使用复数形式**: 资源名称使用复数形式,如 `/api/v1/users` 而不是 `/api/v1/user`
### 10.2 参数设计
- **必填参数**: 明确标识必填参数
- **默认值**: 为可选参数提供合理的默认值
- **参数验证**: 对所有参数进行验证
- **参数类型**: 明确参数类型和格式
### 10.3 响应设计
- **统一格式**: 使用统一的响应格式
- **明确的数据类型**: 响应数据类型应明确
- **避免冗余数据**: 只返回必要的数据
- **分页响应**: 列表接口应支持分页
- **错误信息**: 错误信息应清晰、准确
### 10.4 安全设计
- **认证授权**: 使用 JWT 或 OAuth2 进行认证授权
- **HTTPS**: 使用 HTTPS 加密传输
- **参数验证**: 严格验证所有输入参数
- **输出编码**: 对输出数据进行编码,防止 XSS 攻击
- **SQL 注入防护**: 使用参数绑定,避免直接拼接 SQL
- **CSRF 防护**: 实现 CSRF Token 验证
## 11. 常见问题
### 11.1 跨域问题
- **问题**: 浏览器同源策略导致跨域请求失败
- **解决方案**: 实现 CORS(跨域资源共享),设置适当的响应头
### 10.2 认证失败
- **问题**: 请求未携带认证信息或认证信息无效
- **解决方案**: 检查请求头中的认证信息,确保令牌有效
### 10.3 参数错误
- **问题**: 请求参数格式错误或缺少必填参数
- **解决方案**: 检查请求参数,确保格式正确且包含所有必填参数
### 10.4 响应数据不符合预期
- **问题**: 响应数据格式或内容不符合预期
- **解决方案**: 检查 API 文档,确保请求格式正确,或联系 API 提供者
### 10.5 性能问题
- **问题**: API 请求响应时间过长
- **解决方案**: 优化 API 实现,使用缓存,减少数据库查询次数
## 12. 参考资源
- [RESTful API 设计指南](https://restfulapi.net/)
- [HTTP 状态码](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Status)
- [API 设计最佳实践](https://cloud.google.com/apis/design)
- [JSON API 规范](https://jsonapi.org/)
- [OpenAPI 规范](https://swagger.io/specification/)
- [API 安全性最佳实践](https://owasp.org/www-project-api-security/)

View File

@ -0,0 +1,246 @@
# 代码规范文档
## 1. 概述
本文档描述了 CRMEB 项目的代码规范,包括 PHP、Vue、JavaScript 等语言的编码标准,旨在统一代码风格,提高代码质量和可维护性。
## 2. PHP 代码规范
### 2.1 命名规范
- **类名**:使用 PascalCase 命名风格,如 `UserController`
- **方法名**:使用 camelCase 命名风格,如 `getUserList`
- **变量名**:使用 camelCase 命名风格,如 `$userName`
- **常量**:使用全大写字母和下划线分隔,如 `MAX_PAGE_SIZE`
- **属性名**:使用 camelCase 命名风格,如 `$userId`
- **文件名**:与类名一致,使用 PascalCase 命名风格,如 `UserController.php`
- **目录名**:使用小写字母,单词之间用下划线分隔,如 `user_service`
### 2.2 代码格式
- **缩进**:使用 4 个空格进行缩进,禁止使用制表符
- **行宽**:每行代码不超过 120 个字符
- **空行**:在类、方法、逻辑块之间使用空行分隔
- **空格**:
- 在操作符两边使用空格,如 `$a = $b + $c`
- 在逗号后使用空格,如 `function($a, $b, $c)`
- 在括号内不使用空格,如 `if($condition)`
### 2.3 注释规范
- **类注释**:使用 DocBlock 注释类的功能、作者和版本
- **方法注释**:使用 DocBlock 注释方法的功能、参数、返回值和异常
- **代码注释**:对复杂的代码逻辑添加注释
- **TODO 注释**:使用 `// TODO:` 标记待完成的任务
### 2.4 代码结构
- **类结构**:
- 类的声明
- 属性声明
- 构造方法
- 其他方法
- **方法结构**:
- 参数声明
- 变量声明
- 业务逻辑
- 返回语句
### 2.5 最佳实践
- **单一职责**:每个类和方法只负责一个功能
- **代码复用**:抽取公共代码为方法或类
- **异常处理**:使用 try-catch 处理异常
- **类型提示**:使用类型提示增强代码可读性
- **魔术方法**:谨慎使用魔术方法
## 3. Vue 代码规范
### 3.1 命名规范
- **组件名**:使用 PascalCase 命名风格,如 `UserList`
- **props**:使用 camelCase 命名风格,如 `userName`
- **data 属性**:使用 camelCase 命名风格,如 `userList`
- **methods**:使用 camelCase 命名风格,如 `getUserList`
- **事件名**:使用 kebab-case 命名风格,如 `user-clicked`
- **插槽名**:使用 kebab-case 命名风格,如 `header-content`
### 3.2 代码格式
- **缩进**:使用 2 个空格进行缩进
- **行宽**:每行代码不超过 120 个字符
- **空行**:在不同逻辑块之间使用空行分隔
- **空格**:
- 在操作符两边使用空格
- 在逗号后使用空格
- 在括号内不使用空格
### 3.3 模板规范
- **标签名**:使用 kebab-case 命名风格,如 `<user-list>`
- **属性名**:使用 kebab-case 命名风格,如 `:user-name="userName"`
- **指令缩写**:使用 `:` 代替 `v-bind:`,使用 `@` 代替 `v-on:`
- **模板表达式**:保持模板表达式简洁,复杂逻辑应在计算属性或方法中处理
### 3.4 组件结构
- **template**:模板部分
- **script**:脚本部分
- **style**:样式部分
### 3.5 最佳实践
- **组件拆分**:将复杂组件拆分为多个子组件
- **计算属性**:使用计算属性处理复杂的响应式数据
- **监听器**:使用监听器监听数据变化
- **混入**:使用混入复用组件逻辑
- **指令**:使用自定义指令封装 DOM 操作
## 4. JavaScript 代码规范
### 4.1 命名规范
- **变量名**:使用 camelCase 命名风格,如 `userName`
- **函数名**:使用 camelCase 命名风格,如 `getUserList`
- **常量**:使用全大写字母和下划线分隔,如 `MAX_PAGE_SIZE`
- **对象属性**:使用 camelCase 命名风格,如 `userName`
- **类名**:使用 PascalCase 命名风格,如 `UserService`
### 4.2 代码格式
- **缩进**:使用 2 个空格进行缩进
- **行宽**:每行代码不超过 120 个字符
- **空行**:在不同逻辑块之间使用空行分隔
- **空格**:
- 在操作符两边使用空格
- 在逗号后使用空格
- 在括号内不使用空格
### 4.3 代码结构
- **函数声明**:使用函数表达式或箭头函数
- **对象字面量**:使用简洁的对象字面量语法
- **数组字面量**:使用简洁的数组字面量语法
- **条件语句**:使用简洁的条件语句语法
- **循环语句**:使用简洁的循环语句语法
### 4.4 最佳实践
- **变量声明**:使用 `let` 和 `const` 声明变量,避免使用 `var`
- **箭头函数**:在适当的场景使用箭头函数
- **模板字符串**:使用模板字符串代替字符串拼接
- **解构赋值**:使用解构赋值简化代码
- **展开运算符**:使用展开运算符简化代码
- **异步编程**:使用 `async/await` 处理异步操作
## 5. HTML/CSS 代码规范
### 5.1 HTML 规范
- **标签名**:使用小写字母,如 `<div>`
- **属性名**:使用小写字母,如 `class="container"`
- **属性值**:使用双引号包围,如 `class="container"`
- **缩进**:使用 2 个空格进行缩进
- **嵌套**:保持标签嵌套层次清晰
- **注释**:对复杂的 HTML 结构添加注释
### 5.2 CSS 规范
- **选择器**:使用小写字母和连字符分隔,如 `.user-list`
- **属性名**:使用小写字母,如 `font-size`
- **属性值**:使用小写字母,如 `color: #333`
- **缩进**:使用 2 个空格进行缩进
- **分号**:每个属性声明后添加分号
- **空行**:在不同选择器之间使用空行分隔
- **注释**:对复杂的 CSS 规则添加注释
### 5.3 最佳实践
- **语义化标签**:使用语义化的 HTML 标签
- **CSS 预处理器**:使用 SCSS 或 Less 等 CSS 预处理器
- **BEM 命名**:使用 BEM 命名规范组织 CSS 类名
- **响应式设计**:使用媒体查询实现响应式设计
- **CSS 变量**:使用 CSS 变量管理样式值
## 6. 数据库规范
### 6.1 命名规范
- **数据库名**:使用小写字母和下划线分隔,如 `crmeb_db`
- **表名**:使用小写字母和下划线分隔,如 `user`
- **字段名**:使用小写字母和下划线分隔,如 `user_name`
- **索引名**:使用小写字母和下划线分隔,如 `idx_user_name`
### 6.2 设计规范
- **主键**:使用 `id` 作为主键,自增整数类型
- **外键**:使用 `表名_id` 作为外键,如 `user_id`
- **时间字段**:使用 `create_time` 和 `update_time` 作为时间字段
- **状态字段**:使用 `status` 作为状态字段,默认值为 0
- **软删除**:使用 `delete_time` 作为软删除字段
### 6.3 最佳实践
- **范式设计**:遵循数据库设计范式
- **索引优化**:为经常查询的字段添加索引
- **分区表**:对大表进行分区
- **事务处理**:使用事务保证数据一致性
- **备份策略**:定期备份数据库
## 7. 代码审查
### 7.1 审查内容
- **代码风格**:是否符合代码规范
- **代码质量**:是否存在代码异味
- **安全性**:是否存在安全漏洞
- **性能**:是否存在性能问题
- **功能**:是否实现了需求功能
### 7.2 审查流程
1. **提交代码**:开发者提交代码到版本控制系统
2. **代码审查**:审查者审查代码
3. **反馈修改**:审查者提供反馈,开发者修改代码
4. **合并代码**:代码审查通过后合并代码
### 7.3 审查工具
- **ESLint**:JavaScript 代码审查工具
- **PHP CodeSniffer**:PHP 代码审查工具
- **Prettier**:代码格式化工具
- **SonarQube**:代码质量分析工具
## 8. 版本控制规范
### 8.1 Git 规范
- **分支命名**:使用小写字母和连字符分隔,如 `feature/user-auth`
- **提交信息**:使用中文描述,格式为 `[模块名] 操作描述`,如 `[用户] 添加用户登录功能`
- **提交频率**:每个功能或 bug 修复单独提交
- **代码冲突**:及时解决代码冲突
### 8.2 版本号规范
使用语义化版本号,格式为 `主版本号.次版本号.修订号`,如 `5.6.4`:
- **主版本号**:不兼容的 API 变更
- **次版本号**:向下兼容的功能新增
- **修订号**:向下兼容的问题修正
## 9. 最佳实践
1. **代码可读性**:编写易于理解的代码
2. **代码可维护性**:编写易于维护的代码
3. **代码可测试性**:编写易于测试的代码
4. **代码可扩展性**:编写易于扩展的代码
5. **代码安全性**:编写安全的代码
6. **代码性能**:编写高性能的代码
## 10. 参考资源
- [PSR-1: 基本编码规范](https://www.php-fig.org/psr/psr-1/)
- [PSR-2: 编码风格规范](https://www.php-fig.org/psr/psr-2/)
- [Vue 官方风格指南](https://cn.vuejs.org/v2/style-guide/)
- [JavaScript 标准风格](https://standardjs.com/)
- [Google HTML/CSS 风格指南](https://google.github.io/styleguide/htmlcssguide.html)

View File

@ -0,0 +1,405 @@
# 数据库设计文档
## 1. 概述
本文档描述了 CRMEB 项目的数据库设计,包括数据库架构、表结构、索引设计、关系设计等,旨在规范数据库设计,提高数据库性能和可维护性。
## 2. 数据库架构
### 2.1 整体架构
- **数据库系统**: MySQL 5.7~8.0
- **存储引擎**: InnoDB (默认)
- **字符集**: utf8mb4
- **排序规则**: utf8mb4_general_ci
- **连接池**: 建议使用
- **SQL文件位置**: `public/install/crmeb.sql`
### 2.2 技术栈
- **MySQL**: 5.7+
- **Redis**: 用于缓存
- **ThinkPHP ORM**: 用于模型操作
- **数据库迁移**: 用于版本控制
- **数据库备份**: 用于数据安全
### 2.3 配置说明
#### 2.3.1 数据库配置
```php
// config/database.php
return [
'default' => env('database.driver', 'mysql'),
'connections' => [
'mysql' => [
'type' => 'mysql',
'hostname' => env('database.hostname', '127.0.0.1'),
'database' => env('database.database', ''),
'username' => env('database.username', ''),
'password' => env('database.password', ''),
'hostport' => env('database.hostport', '3306'),
'charset' => 'utf8mb4',
'prefix' => env('database.prefix', ''),
'debug' => env('app_debug', true),
],
],
];
```
## 3. 数据库设计规范
### 3.1 命名规范
- **数据库名**: 小写字母,下划线分隔
- **表名**: 小写字母,下划线分隔,前缀统一
- **字段名**: 小写字母,下划线分隔
- **索引名**: 小写字母,下划线分隔,类型前缀
- 主键: `PRIMARY`
- 唯一索引: `uk_字段名`
- 普通索引: `idx_字段名`
### 3.2 表结构规范
- **主键**: 统一命名为 `id`,自增整数
- **外键**: 格式 `表名_id`,如 `user_id`
- **时间字段**: `create_time`/`update_time`
- **状态字段**: `status`,默认值 0
- **软删除字段**: `delete_time`,默认值 NULL
### 3.3 字段类型规范
- **整数类型**: 根据实际范围选择
- `TINYINT`: 1字节,范围 -128~127
- `SMALLINT`: 2字节,范围 -32768~32767
- `INT`: 4字节,范围 -2147483648~2147483647
- `BIGINT`: 8字节,范围更大
- **字符串类型**:
- 固定长度: `CHAR`
- 可变长度: `VARCHAR`
- 长文本: `TEXT`
- 大文本: `LONGTEXT`
- **日期时间类型**:
- 日期: `DATE`
- 时间: `TIME`
- 日期时间: `DATETIME`
- 时间戳: `TIMESTAMP`
- **数值类型**:
- 小数: `DECIMAL`
- 浮点数: `FLOAT`, `DOUBLE`
- **布尔类型**: 使用 `TINYINT(1)`,0 表示 false,1 表示 true
### 3.4 索引规范
- **主键索引**: 每个表必须有主键
- **唯一索引**: 用于唯一标识的字段
- **普通索引**: 用于经常查询的字段
- **复合索引**: 用于多字段查询
- **外键索引**: 用于关联查询
- **索引数量**: 每个表索引数量不宜过多,一般不超过 5 个
## 4. 核心表结构
### 4.1 用户表 (`user`)
| 字段名 | 数据类型 | 长度 | 约束 | 描述 |
|-------|---------|------|------|------|
| `id` | `INT` | 11 | `PRIMARY KEY AUTO_INCREMENT` | 用户ID |
| `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,501 @@
# 项目部署文档
## 1. 概述
本文档描述了 CRMEB 项目的部署流程,包括环境配置、部署步骤、服务管理等,旨在规范项目部署,确保项目能够稳定运行。
## 2. 部署架构
### 2.1 系统架构
#### 2.1.1 基础架构
- **Web 服务器**: Nginx/Apache
- **应用服务器**: PHP-FPM
- **数据库服务器**: MySQL
- **缓存服务器**: Redis
- **队列服务器**: ThinkPHP 内置队列
- **长连接服务器**: Workerman
#### 2.1.2 部署模式
##### 2.1.2.1 单机部署
```
┌─────────────────────────────────────────────────────┐
│ 服务器 │
├──────────────┬──────────────┬──────────────┬─────────┤
│ Nginx/Apache│ PHP-FPM │ MySQL │ Redis │
└──────────────┴──────────────┴──────────────┴─────────┘
```
##### 2.1.2.2 分布式部署
```
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Web 服务器 │────>│ 应用服务器 │────>│ 数据库服务器 │
├──────────────┤ ├──────────────┤ ├──────────────┤
│ Nginx │ │ PHP-FPM │ │ MySQL │
└──────────────┘ └──────────────┘ └──────────────┘
│ │ │
└──────────────────┼──────────────────┘
▼
┌──────────────┐
│ 缓存服务器 │
├──────────────┤
│ Redis │
└──────────────┘
```
### 2.2 网络架构
#### 2.2.1 网络拓扑
- **公网**: 外部访问
- **内网**: 内部服务通信
- **DMZ**: 边界区域
#### 2.2.2 端口规划
- **HTTP**: 80
- **HTTPS**: 443
- **SSH**: 22
- **MySQL**: 3306
- **Redis**: 6379
- **PHP-FPM**: 9000
- **Workerman**: 8282
## 3. 环境配置
### 3.1 操作系统
#### 3.1.1 系统要求
- **Linux**: CentOS 7+/Ubuntu 18.04+
- **Windows**: Windows Server 2016+
- **macOS**: macOS 10.15+
#### 3.1.2 系统优化
```bash
# 关闭 SELinux
setenforce 0
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
# 关闭防火墙(生产环境建议配置规则)
systemctl stop firewalld
systemctl disable firewalld
# 调整文件描述符
cat >> /etc/security/limits.conf << EOF
* soft nofile 65536
* hard nofile 65536
EOF
# 调整内核参数
cat >> /etc/sysctl.conf << EOF
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 1200
net.ipv4.tcp_max_tw_buckets = 5000
EOF
sysctl -p
```
### 3.2 PHP 环境
#### 3.2.1 版本要求
- **PHP**: 7.1~7.4
#### 3.2.2 安装步骤
```bash
# CentOS 安装 PHP 7.4
rpm -Uvh https://mirror.webtatic.com/yum/el7/epel-release.rpm
rpm -Uvh https://mirror.webtatic.com/yum/el7/webtatic-release.rpm
yum install -y php74w php74w-fpm php74w-cli php74w-mysql php74w-redis php74w-gd php74w-mbstring php74w-xml php74w-zip php74w-opcache
# Ubuntu 安装 PHP 7.4
apt update
apt install -y php7.4 php7.4-fpm php7.4-cli php7.4-mysql php7.4-redis php7.4-gd php7.4-mbstring php7.4-xml php7.4-zip php7.4-opcache
```
#### 3.2.3 配置优化
```php
// php.ini 配置
memory_limit = 512M
upload_max_filesize = 20M
post_max_size = 20M
max_execution_time = 300
date.timezone = Asia/Shanghai
opcache.enable = 1
opcache.enable_cli = 1
opcache.memory_consumption = 128
opcache.interned_strings_buffer = 8
opcache.max_accelerated_files = 4000
opcache.revalidate_freq = 60
// www.conf 配置
pm.max_children = 50
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 20
pm.process_idle_timeout = 10s
pm.max_requests = 1000
```
### 3.3 Web 服务器
#### 3.3.1 Nginx 配置
```nginx
# crmeb.conf
server {
listen 80;
server_name example.com;
root /data/www/crmeb/public;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
expires 30d;
add_header Cache-Control "public, no-transform";
}
access_log /data/logs/nginx/crmeb.access.log;
error_log /data/logs/nginx/crmeb.error.log;
}
```
### 3.4 数据库配置
#### 3.4.1 MySQL 安装
```bash
# CentOS 安装 MySQL 5.7
yum localinstall -y https://dev.mysql.com/get/mysql57-community-release-el7-11.noarch.rpm
yum install -y mysql-community-server
systemctl start mysqld
systemctl enable mysqld
# 获取初始密码
grep 'temporary password' /var/log/mysqld.log
# 安全配置
mysql_secure_installation
# Ubuntu 安装 MySQL 5.7
apt update
apt install -y mysql-server
mysql_secure_installation
```
#### 3.4.2 MySQL 配置优化
```ini
# my.cnf 配置
[mysqld]
bind-address = 127.0.0.1
port = 3306
datadir = /var/lib/mysql
socket = /var/lib/mysql/mysql.sock
user = mysql
# 性能优化
max_connections = 1000
wait_timeout = 60
interactive_timeout = 28800
key_buffer_size = 64M
table_open_cache = 256
sort_buffer_size = 1M
read_buffer_size = 1M
read_rnd_buffer_size = 4M
myisam_sort_buffer_size = 64M
thread_cache_size = 8
query_cache_size = 16M
# InnoDB 优化
innodb_buffer_pool_size = 1G
innodb_file_per_table = 1
innodb_log_file_size = 256M
innodb_log_buffer_size = 8M
innodb_flush_method = O_DIRECT
```
### 3.5 缓存配置
#### 3.5.1 Redis 安装
```bash
# CentOS 安装 Redis
yum install -y epel-release
yum install -y redis
systemctl start redis
systemctl enable redis
# Ubuntu 安装 Redis
apt update
apt install -y redis-server
systemctl start redis
systemctl enable redis
```
#### 3.5.2 Redis 配置优化
```conf
# redis.conf 配置
bind 127.0.0.1
port 6379
databases 16
dir /var/lib/redis
requirepass your_password
maxmemory 512mb
maxmemory-policy allkeys-lru
save 900 1
save 300 10
save 60 10000
```
## 4. 部署流程
### 4.1 代码部署
#### 4.1.1 Git 部署
```bash
# 克隆代码
git clone https://github.com/crmeb/CRMEB.git /data/www/crmeb
cd /data/www/crmeb
# 切换版本
git checkout tags/v5.6.4
# 安装依赖
composer install --no-dev
# 配置环境变量
cp .env.example .env
# 编辑 .env 文件,配置数据库、Redis 等信息
# 生成密钥
php think key:generate
# 数据库迁移
php think migrate:run
# 生成数据表
php think crmeb:install
# 清除缓存
php think clear
```
#### 4.1.2 手动部署
1. **下载代码**: 从官方网站下载最新版本
2. **上传代码**: 上传到服务器 `/data/www/` 目录
3. **解压代码**: `unzip CRMEB_v5.6.4.zip -d /data/www/crmeb`
4. **安装依赖**: `composer install --no-dev`
5. **配置环境**: 同 Git 部署步骤
### 4.2 服务启动
#### 4.2.1 Web 服务
```bash
# Nginx 启动
systemctl start nginx
systemctl enable nginx
# Apache 启动
systemctl start httpd
systemctl enable httpd
```
#### 4.2.2 PHP-FPM 服务
```bash
systemctl start php-fpm
systemctl enable php-fpm
```
#### 4.2.3 队列服务
```bash
# 启动队列(推荐使用 Supervisor 管理)
supervisorctl start crmeb-queue
# Supervisor 配置
[program:crmeb-queue]
command=php /data/www/crmeb/think queue:listen --queue=default --timeout=60
process_name=%(program_name)s_%(process_num)02d
autostart=true
autorestart=true
user=www
numprocs=2
directory=/data/www/crmeb
stdout_logfile=/data/logs/supervisor/crmeb-queue-stdout.log
stderr_logfile=/data/logs/supervisor/crmeb-queue-stderr.log
```
#### 4.2.4 长连接服务
```bash
# 启动长连接服务
php think workerman start --d
# 停止长连接服务
php think workerman stop
```
#### 4.2.5 定时任务
```bash
# 添加定时任务
crontab -e
# 定时任务配置
* * * * * php /data/www/crmeb/think timer run
0 0 * * * php /data/www/crmeb/think crmeb:backup
```
### 4.3 部署验证
#### 4.3.1 健康检查
- **访问首页**: `http://example.com`
- **访问后台**: `http://example.com/admin`
- **API 测试**: `http://example.com/api/ping`
- **数据库连接**: 检查数据库连接状态
- **Redis 连接**: 检查缓存连接状态
#### 4.3.2 日志检查
```bash
# 检查 Nginx 日志
tail -f /data/logs/nginx/crmeb.error.log
# 检查 PHP 错误日志
tail -f /var/log/php-fpm/error.log
# 检查应用日志
tail -f /data/www/crmeb/runtime/log/*.log
```
## 5. 服务管理
### 5.1 日常运维
#### 5.1.1 监控检查
- **服务状态**: 检查所有服务是否正常运行
- **系统负载**: 监控 CPU、内存、磁盘使用情况
- **网络状态**: 监控网络连接和带宽使用
- **应用状态**: 监控应用响应时间和错误率
#### 5.1.2 日志管理
- **日志收集**: 集中收集所有服务日志
- **日志分析**: 分析日志中的错误和异常
- **日志清理**: 定期清理过期日志
- **日志备份**: 重要日志备份到远程存储
#### 5.1.3 备份恢复
##### 5.1.3.1 数据备份
```bash
# 数据库备份
mysqldump -u username -p database_name > /data/backup/data/$(date +%Y%m%d)_backup.sql
# 代码备份
tar -czf /data/backup/code/$(date +%Y%m%d)_crmeb.tar.gz /data/www/crmeb
# 配置文件备份
tar -czf /data/backup/config/$(date +%Y%m%d)_config.tar.gz /data/www/crmeb/config
```
##### 5.1.3.2 数据恢复
```bash
# 数据库恢复
mysql -u username -p database_name < /data/backup/data/20240101_backup.sql
# 代码恢复
tar -xzf /data/backup/code/20240101_crmeb.tar.gz -C /data/www/
# 配置文件恢复
tar -xzf /data/backup/config/20240101_config.tar.gz -C /data/www/crmeb/
```
## 6. 常见问题
### 6.1 部署问题
#### 6.1.1 依赖安装失败
- **问题**: Composer 安装依赖失败
- **原因**: 网络问题,PHP 版本不兼容
- **解决方案**: 使用国内镜像,检查 PHP 版本
#### 6.1.2 数据库连接失败
- **问题**: 应用无法连接数据库
- **原因**: 数据库服务未启动,用户名密码错误,网络连接问题
- **解决方案**: 检查 MySQL 服务,验证用户名密码,检查网络连接
#### 6.1.3 权限错误
- **问题**: 文件或目录权限错误
- **原因**: 权限设置不正确,用户组不匹配
- **解决方案**: 设置正确的文件权限,确保 PHP-FPM 用户有访问权限
#### 6.1.4 端口占用
- **问题**: 服务启动失败,端口被占用
- **原因**: 其他服务占用了相同端口
- **解决方案**: 查找并停止占用端口的服务,或修改服务端口
### 6.2 运行问题
#### 6.2.1 应用响应缓慢
- **问题**: 应用响应时间长
- **原因**: 数据库查询慢,PHP 代码效率低,服务器资源不足
- **解决方案**: 优化 SQL 查询,优化 PHP 代码,增加服务器资源
#### 6.2.2 内存溢出
- **问题**: PHP 内存溢出
- **原因**: 内存限制过小,代码中存在内存泄漏
- **解决方案**: 增加 PHP 内存限制,优化代码中的内存使用
#### 6.2.3 队列堆积
- **问题**: 队列任务堆积
- **原因**: 队列处理速度慢,任务量过大
- **解决方案**: 增加队列进程数,优化队列任务处理逻辑
## 7. 参考资源
- [CRMEB 官方文档](https://doc.crmeb.com/single_open)
- [ThinkPHP 6 官方文档](https://www.kancloud.cn/manual/thinkphp6_0)
- [Nginx 官方文档](https://nginx.org/en/docs/)
- [PHP 官方文档](https://www.php.net/docs.php)
- [MySQL 官方文档](https://dev.mysql.com/doc/)
- [Redis 官方文档](https://redis.io/documentation)

View File

@ -0,0 +1,275 @@
# 目录结构文档
## 1. 概述
本文档描述了 CRMEB 项目的目录结构,包括各目录的功能、文件组织方式等,旨在帮助开发者理解项目结构,提高开发效率。
## 2. 项目根目录结构
```
CRMEB/
├── app/ # 应用目录
├── config/ # 配置目录
├── crmeb/ # 核心库目录
├── database/ # 数据库目录
├── extend/ # 扩展目录
├── public/ # 公共资源目录
├── runtime/ # 运行时目录
├── thinkphp/ # ThinkPHP 核心目录
├── vendor/ # 第三方依赖目录
├── .env # 环境变量文件
├── .env.example # 环境变量示例文件
├── composer.json # Composer 配置文件
├── composer.lock # Composer 锁定文件
├── LICENSE # 许可证文件
├── README.md # 项目说明文档
├── think # ThinkPHP 命令行工具
```
## 3. 应用目录结构 (app/)
```
app/
├── api/ # API 接口层
│ ├── v1/ # API 版本 1
│ ├── v2/ # API 版本 2
│ └── BaseApi.php # API 基类
├── controller/ # 控制器层
│ ├── admin/ # 管理端控制器
│ ├── api/ # API 控制器
│ └── BaseController.php # 控制器基类
├── dao/ # 数据访问层
│ └── BaseDao.php # DAO 基类
├── event/ # 事件层
├── exception/ # 异常处理层
├── middleware/ # 中间件层
├── model/ # 模型层
│ └── BaseModel.php # 模型基类
├── services/ # 业务逻辑层
│ └── BaseServices.php # 服务基类
├── subscribe/ # 事件订阅层
├── validate/ # 验证层
│ └── BaseValidate.php # 验证器基类
└── common.php # 公共函数文件
```
### 3.1 API 目录 (app/api/)
- **功能**: 处理 API 接口请求
- **结构**: 按 API 版本划分目录
- **基类**: `BaseApi.php`,提供 API 基础功能
- **版本控制**: 通过目录结构实现 API 版本管理
### 3.2 控制器目录 (app/controller/)
- **功能**: 处理 HTTP 请求,路由分发
- **结构**: 按模块划分控制器
- **基类**: `BaseController.php`,提供控制器基础功能
- **类型**: 管理端控制器、API 控制器
### 3.3 DAO 目录 (app/dao/)
- **功能**: 数据访问对象,封装数据库操作
- **结构**: 按业务模块划分 DAO 类
- **基类**: `BaseDao.php`,提供 DAO 基础功能
- **职责**: 处理数据库查询、插入、更新、删除等操作
### 3.4 模型目录 (app/model/)
- **功能**: 数据模型,定义数据结构和关系
- **结构**: 按业务模块划分模型类
- **基类**: `BaseModel.php`,提供模型基础功能
- **特性**: 支持 ORM、关联查询、软删除等
### 3.5 服务目录 (app/services/)
- **功能**: 业务逻辑层,封装核心业务逻辑
- **结构**: 按业务模块划分服务类
- **基类**: `BaseServices.php`,提供服务基础功能
- **职责**: 实现业务规则,协调多个 DAO 和模型
### 3.6 验证目录 (app/validate/)
- **功能**: 数据验证,验证请求参数
- **结构**: 按业务模块划分验证器类
- **基类**: `BaseValidate.php`,提供验证器基础功能
- **特性**: 支持规则验证、场景验证等
## 4. 配置目录结构 (config/)
```
config/
├── app.php # 应用配置
├── cache.php # 缓存配置
├── captcha.php # 验证码配置
├── console.php # 控制台配置
├── cookie.php # Cookie 配置
├── database.php # 数据库配置
├── filesystem.php # 文件系统配置
├── lang.php # 语言配置
├── log.php # 日志配置
├── queue.php # 队列配置
├── route.php # 路由配置
├── session.php # Session 配置
├── template.php # 模板配置
└── trace.php # 调试配置
```
- **功能**: 存储项目的所有配置文件
- **结构**: 按功能模块划分配置文件
- **特性**: 支持环境变量配置、配置缓存等
- **加载顺序**: 框架配置 → 应用配置 → 环境配置
## 5. 核心库目录结构 (crmeb/)
```
crmeb/
├── basic/ # 基础类库
├── exception/ # 核心异常类
├── services/ # 核心服务类
├── utils/ # 工具类
└── version.php # 版本信息
```
- **功能**: 存储 CRMEB 核心库代码
- **结构**: 按功能模块划分目录
- **特性**: 独立于应用代码,便于维护和升级
- **作用**: 提供核心功能和基础服务
## 6. 数据库目录结构 (database/)
```
database/
├── migrations/ # 数据库迁移文件
└── seeders/ # 数据库种子文件
```
- **功能**: 存储数据库相关文件
- **迁移文件**: 用于版本控制数据库结构
- **种子文件**: 用于初始化数据库数据
- **工具**: 使用 ThinkPHP 迁移工具管理
## 7. 公共资源目录结构 (public/)
```
public/
├── admin/ # 管理端资源
├── api/ # API 资源
├── assets/ # 静态资源
│ ├── css/ # CSS 文件
│ ├── images/ # 图片文件
│ └── js/ # JavaScript 文件
├── index.php # 应用入口文件
├── robots.txt # 机器人协议文件
└── router.php # URL 重写文件
```
- **功能**: 存储可直接访问的公共资源
- **结构**: 按功能模块划分目录
- **特性**: 可通过 URL 直接访问
- **安全**: 敏感文件不应放在此目录
## 8. 运行时目录结构 (runtime/)
```
runtime/
├── cache/ # 缓存目录
├── log/ # 日志目录
│ └── app/ # 应用日志
├── session/ # Session 目录
├── temp/ # 临时文件目录
└── think/ # ThinkPHP 运行时目录
```
- **功能**: 存储运行时生成的文件
- **结构**: 按功能模块划分目录
- **特性**: 自动生成,无需手动维护
- **权限**: 需要可写权限
## 9. 核心目录结构 (thinkphp/)
```
thinkphp/
├── lang/ # 语言包目录
├── library/ # 核心类库目录
├── tpl/ # 模板目录
├── base.php # 基础定义文件
├── composer.json # Composer 配置文件
└── helper.php # 助手函数文件
```
- **功能**: 存储 ThinkPHP 框架核心代码
- **结构**: 框架默认结构
- **特性**: 独立于应用代码
- **升级**: 通过 Composer 升级
## 10. 第三方依赖目录结构 (vendor/)
```
vendor/
├── autoload.php # 自动加载文件
├── composer/ # Composer 核心目录
├── symfony/ # Symfony 组件
├── topthink/ # ThinkPHP 组件
└── ... # 其他第三方依赖
```
- **功能**: 存储第三方依赖库
- **管理**: 通过 Composer 管理
- **结构**: 按依赖包名称划分目录
- **自动加载**: 通过 `autoload.php` 自动加载
## 11. 目录结构最佳实践
### 11.1 命名规范
- **目录名**: 小写字母,单词之间用下划线分隔
- **文件名**: 与类名一致,使用 PascalCase 命名风格
- **类名**: 使用 PascalCase 命名风格
- **方法名**: 使用 camelCase 命名风格
- **变量名**: 使用 camelCase 命名风格
### 11.2 组织原则
- **模块化**: 按功能模块组织目录结构
- **分层架构**: 遵循 MVC + Service + DAO 分层架构
- **单一职责**: 每个目录和文件只负责一个功能
- **可扩展性**: 便于添加新功能和模块
- **易维护性**: 便于理解和维护
### 11.3 开发建议
- **遵循框架规范**: 遵循 ThinkPHP 框架目录结构规范
- **合理划分模块**: 根据业务功能合理划分模块
- **避免目录过深**: 目录层级不宜过深,一般不超过 4 层
- **保持目录整洁**: 及时清理无用文件和目录
- **文档化**: 为重要目录添加说明文档
## 12. 常见问题
### 12.1 目录权限问题
- **问题**: 运行时目录没有写权限
- **解决方案**: 执行 `chmod -R 777 runtime/` 赋予写权限
### 12.2 自动加载问题
- **问题**: 新增类无法自动加载
- **解决方案**: 执行 `composer dump-autoload` 更新自动加载
### 12.3 配置文件不生效
- **问题**: 修改配置文件后不生效
- **解决方案**: 清除配置缓存,执行 `php think clear`
### 12.4 目录结构混乱
- **问题**: 目录结构不清晰,难以维护
- **解决方案**: 重新组织目录结构,遵循模块化原则
## 13. 参考资源
- [ThinkPHP 6 目录结构](https://www.kancloud.cn/manual/thinkphp6_0/1037487)
- [MVC 架构设计](https://zh.wikipedia.org/wiki/MVC)
- [分层架构设计](https://zh.wikipedia.org/wiki/分层架构)
- [模块化设计](https://zh.wikipedia.org/wiki/模块化设计)

View File

@ -0,0 +1,273 @@
# 错误码文档
## 1. 概述
本文档描述了 CRMEB 项目的错误码规范,包括错误码的分类、定义、使用方法等,旨在统一错误码格式,提高错误处理的一致性和可维护性。
## 2. 错误码分类
### 2.1 HTTP 状态码
- **1xx**: 信息性状态码,表示请求已接收,继续处理
- **2xx**: 成功状态码,表示请求已成功处理
- **3xx**: 重定向状态码,表示需要进一步操作以完成请求
- **4xx**: 客户端错误状态码,表示请求包含语法错误或无法完成请求
- **5xx**: 服务器错误状态码,表示服务器在处理请求时发生错误
### 2.2 业务错误码
业务错误码由 5 位数字组成,格式为 `XXXXX`,其中:
- **第一位**: 错误类型标识
- `1`: 系统错误
- `2`: 业务错误
- `3`: 参数错误
- `4`: 权限错误
- `5`: 资源错误
- `6`: 数据库错误
- `7`: 第三方服务错误
- `8`: 其他错误
- **后四位**: 具体错误编码,从 0000 开始递增
## 3. 系统错误码
### 3.1 系统错误 (1xxxxx)
| 错误码 | 描述 | HTTP 状态码 |
|-------|------|-------------|
| 10001 | 系统内部错误 | 500 |
| 10002 | 系统维护中 | 503 |
| 10003 | 系统繁忙 | 503 |
| 10004 | 服务不可用 | 503 |
| 10005 | 网关错误 | 502 |
### 3.2 业务错误 (2xxxxx)
| 错误码 | 描述 | HTTP 状态码 |
|-------|------|-------------|
| 20001 | 操作失败 | 400 |
| 20002 | 业务逻辑错误 | 400 |
| 20003 | 数据已存在 | 400 |
| 20004 | 数据不存在 | 404 |
| 20005 | 操作不允许 | 403 |
### 3.3 参数错误 (3xxxxx)
| 错误码 | 描述 | HTTP 状态码 |
|-------|------|-------------|
| 30001 | 参数不能为空 | 400 |
| 30002 | 参数格式错误 | 400 |
| 30003 | 参数类型错误 | 400 |
| 30004 | 参数超出范围 | 400 |
| 30005 | 参数验证失败 | 422 |
### 3.4 权限错误 (4xxxxx)
| 错误码 | 描述 | HTTP 状态码 |
|-------|------|-------------|
| 40001 | 未登录 | 401 |
| 40002 | 登录已过期 | 401 |
| 40003 | 无权限访问 | 403 |
| 40004 | 权限不足 | 403 |
| 40005 | 令牌无效 | 401 |
### 3.5 资源错误 (5xxxxx)
| 错误码 | 描述 | HTTP 状态码 |
|-------|------|-------------|
| 50001 | 资源不存在 | 404 |
| 50002 | 资源已删除 | 404 |
| 50003 | 资源已锁定 | 400 |
| 50004 | 资源不足 | 400 |
| 50005 | 资源已过期 | 400 |
### 3.6 数据库错误 (6xxxxx)
| 错误码 | 描述 | HTTP 状态码 |
|-------|------|-------------|
| 60001 | 数据库连接失败 | 500 |
| 60002 | 数据库查询失败 | 500 |
| 60003 | 数据库更新失败 | 500 |
| 60004 | 数据库插入失败 | 500 |
| 60005 | 数据库删除失败 | 500 |
| 60006 | 数据库事务失败 | 500 |
### 3.7 第三方服务错误 (7xxxxx)
| 错误码 | 描述 | HTTP 状态码 |
|-------|------|-------------|
| 70001 | 第三方服务连接失败 | 500 |
| 70002 | 第三方服务超时 | 504 |
| 70003 | 第三方服务返回错误 | 500 |
| 70004 | 第三方服务认证失败 | 401 |
| 70005 | 第三方服务限流 | 429 |
## 4. 模块错误码
### 4.1 用户模块 (801xx)
| 错误码 | 描述 | HTTP 状态码 |
|-------|------|-------------|
| 80101 | 用户名或密码错误 | 401 |
| 80102 | 用户不存在 | 404 |
| 80103 | 用户已存在 | 400 |
| 80104 | 用户状态异常 | 400 |
| 80105 | 验证码错误 | 400 |
| 80106 | 验证码已过期 | 400 |
| 80107 | 手机号格式错误 | 400 |
| 80108 | 邮箱格式错误 | 400 |
### 4.2 商品模块 (802xx)
| 错误码 | 描述 | HTTP 状态码 |
|-------|------|-------------|
| 80201 | 商品不存在 | 404 |
| 80202 | 商品已下架 | 400 |
| 80203 | 商品库存不足 | 400 |
| 80204 | 商品价格异常 | 400 |
| 80205 | 商品分类不存在 | 404 |
### 4.3 订单模块 (803xx)
| 错误码 | 描述 | HTTP 状态码 |
|-------|------|-------------|
| 80301 | 订单不存在 | 404 |
| 80302 | 订单状态异常 | 400 |
| 80303 | 订单已取消 | 400 |
| 80304 | 订单已完成 | 400 |
| 80305 | 订单支付失败 | 400 |
| 80306 | 订单支付超时 | 400 |
### 4.4 支付模块 (804xx)
| 错误码 | 描述 | HTTP 状态码 |
|-------|------|-------------|
| 80401 | 支付方式不支持 | 400 |
| 80402 | 支付金额异常 | 400 |
| 80403 | 支付参数错误 | 400 |
| 80404 | 支付失败 | 400 |
| 80405 | 支付超时 | 400 |
| 80406 | 支付已完成 | 400 |
## 5. 错误码使用规范
### 5.1 错误响应格式
```json
{
"code": 20001,
"msg": "操作失败",
"data": []
}
```
### 5.2 成功响应格式
```json
{
"code": 200,
"msg": "操作成功",
"data": {...}
}
```
### 5.3 错误处理流程
1. **捕获异常**: 在控制器或中间件中捕获异常
2. **确定错误码**: 根据异常类型确定对应的错误码
3. **构建响应**: 按照统一格式构建错误响应
4. **返回响应**: 返回错误响应给客户端
### 5.4 错误日志记录
- **记录内容**: 错误码、错误信息、请求参数、请求路径、用户信息、时间戳等
- **记录级别**: 根据错误严重程度选择合适的日志级别
- **记录位置**: 系统日志文件
- **监控告警**: 对于严重错误,触发告警机制
## 6. 错误码管理
### 6.1 错误码定义
错误码定义在配置文件中,便于统一管理和维护:
```php
// config/error_code.php
return [
// 系统错误
10001 => '系统内部错误',
10002 => '系统维护中',
// 业务错误
20001 => '操作失败',
20002 => '业务逻辑错误',
// 参数错误
30001 => '参数不能为空',
30002 => '参数格式错误',
// ...
];
```
### 6.2 错误码使用
在代码中使用错误码时,应直接引用配置文件中的定义:
```php
// 控制器中使用
return $this->fail(config('error_code.20001'));
// 或直接使用错误码
return $this->fail('操作失败', [], 20001);
```
### 6.3 错误码更新
当需要添加新的错误码时,应遵循以下流程:
1. **确定错误类型**: 根据错误性质确定错误类型
2. **分配错误码**: 从对应类型的错误码范围中分配一个未使用的错误码
3. **更新配置**: 在 `error_code.php` 配置文件中添加错误码定义
4. **更新文档**: 更新错误码文档
5. **通知团队**: 通知团队成员新添加的错误码
## 7. 错误码最佳实践
### 7.1 设计原则
- **唯一性**: 每个错误码唯一对应一种错误情况
- **可读性**: 错误码应易于理解和记忆
- **可扩展性**: 错误码应具有良好的扩展性,便于添加新的错误码
- **一致性**: 错误码格式和使用方法应保持一致
- **详细性**: 错误信息应清晰、准确,便于调试和定位问题
### 7.2 使用建议
- **避免硬编码**: 错误码应定义在配置文件中,避免直接硬编码在代码中
- **统一处理**: 使用统一的错误处理中间件处理错误
- **详细日志**: 记录详细的错误日志,便于调试和分析
- **友好提示**: 向客户端返回友好的错误信息,避免暴露系统内部细节
- **定期清理**: 定期清理不再使用的错误码,保持错误码的简洁性
### 7.3 常见问题
#### 7.3.1 错误码冲突
- **问题**: 不同模块使用了相同的错误码
- **解决方案**: 严格按照模块划分错误码范围,避免冲突
#### 7.3.2 错误信息不明确
- **问题**: 错误信息过于简洁,无法定位问题
- **解决方案**: 提供详细的错误信息,包含必要的上下文
#### 7.3.3 错误码未及时更新
- **问题**: 新增功能时未及时添加对应的错误码
- **解决方案**: 在开发新功能时,同步更新错误码定义和文档
## 8. 参考资源
- [HTTP 状态码](https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Status)
- [RESTful API 错误处理](https://restfulapi.net/http-status-codes/)
- [错误码设计最佳实践](https://www.thoughtworks.com/insights/blog/error-handling-microservices)
- [API 错误码规范](https://cloud.google.com/apis/design/errors)

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

@ -0,0 +1,380 @@
# 系统配置文档
## 1. 概述
本文档描述了 CRMEB 项目的系统配置,包括配置文件、环境变量、配置项说明等,旨在帮助开发者理解和配置项目,确保项目能够正常运行。
## 2. 配置文件结构
### 2.1 配置目录结构
```
config/
├── app.php # 应用配置
├── cache.php # 缓存配置
├── captcha.php # 验证码配置
├── console.php # 控制台配置
├── cookie.php # Cookie 配置
├── database.php # 数据库配置
├── filesystem.php # 文件系统配置
├── lang.php # 语言配置
├── log.php # 日志配置
├── queue.php # 队列配置
├── route.php # 路由配置
├── session.php # Session 配置
├── template.php # 模板配置
└── trace.php # 调试配置
```
### 2.2 配置加载顺序
1. **框架默认配置**:ThinkPHP 框架自带的默认配置
2. **应用配置**:项目根目录下的 `config/` 目录中的配置文件
3. **环境配置**:根据当前环境加载对应的环境配置文件
4. **动态配置**:运行时动态设置的配置
5. **环境变量**:通过 `.env` 文件或系统环境变量设置的配置
## 3. 环境变量配置
### 3.1 环境变量文件 (.env)
环境变量文件 `.env` 用于存储敏感配置信息,如数据库密码、API 密钥等。该文件不应提交到版本控制系统。
```ini
# 应用配置
APP_NAME=CRMEB
APP_ENV=local
APP_KEY=base64:your_app_key
APP_DEBUG=true
APP_URL=http://localhost
# 数据库配置
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=crmeb
DB_USERNAME=root
DB_PASSWORD=your_password
# Redis 配置
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
REDIS_DB=0
# 缓存配置
CACHE_DRIVER=file
# 队列配置
QUEUE_CONNECTION=sync
# 邮件配置
MAIL_MAILER=smtp
MAIL_HOST=smtp.example.com
MAIL_PORT=587
MAIL_USERNAME=your_email@example.com
MAIL_PASSWORD=your_email_password
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=your_email@example.com
MAIL_FROM_NAME="CRMEB"
# 阿里云配置
ALIYUN_ACCESS_KEY_ID=your_access_key_id
ALIYUN_ACCESS_KEY_SECRET=your_access_key_secret
# 腾讯云配置
TENCENTCLOUD_SECRET_ID=your_secret_id
TENCENTCLOUD_SECRET_KEY=your_secret_key
```
### 3.2 环境变量加载
环境变量可以通过以下方式加载:
1. **.env 文件**:在项目根目录下创建 `.env` 文件,根据环境需要配置相关变量
2. **系统环境变量**:在服务器上设置系统环境变量
3. **命令行参数**:在运行命令时通过参数设置环境变量
### 3.3 环境变量使用
在配置文件中可以使用 `env()` 函数获取环境变量:
```php
// config/database.php
return [
'default' => env('database.driver', 'mysql'),
'connections' => [
'mysql' => [
'type' => 'mysql',
'hostname' => env('database.hostname', '127.0.0.1'),
'database' => env('database.database', ''),
'username' => env('database.username', ''),
'password' => env('database.password', ''),
'hostport' => env('database.hostport', '3306'),
'charset' => 'utf8mb4',
'prefix' => env('database.prefix', ''),
'debug' => env('app_debug', true),
],
],
];
```
## 4. 核心配置项
### 4.1 应用配置 (app.php)
| 配置项 | 类型 | 默认值 | 描述 |
|-------|------|--------|------|
| app_debug | bool | true | 应用调试模式 |
| app_trace | bool | false | 应用跟踪模式 |
| app_status | string | 'dev' | 应用状态 |
| app_namespace | string | 'app' | 应用命名空间 |
| default_return_type | string | 'json' | 默认返回类型 |
| default_timezone | string | 'Asia/Shanghai' | 默认时区 |
| lang_switch_on | bool | false | 语言切换开关 |
| default_lang | string | 'zh-cn' | 默认语言 |
| auto_bind_module | bool | true | 自动绑定模块 |
| controller_suffix | bool | false | 控制器后缀 |
| url_route_on | bool | true | URL 路由开关 |
| url_route_must | bool | false | URL 路由必须 |
| var_pathinfo | string | 's' | PATH_INFO 变量名 |
| pathinfo_depr | string | '/' | PATH_INFO 分隔符 |
| url_html_suffix | string | '' | URL HTML 后缀 |
| url_common_param | bool | false | URL 普通参数模式 |
| url_param_type | int | 1 | URL 参数类型 |
| request_cache_on | bool | false | 请求缓存开关 |
| request_cache_expire | int | null | 请求缓存有效期 |
### 4.2 数据库配置 (database.php)
| 配置项 | 类型 | 默认值 | 描述 |
|-------|------|--------|------|
| default | string | 'mysql' | 默认数据库连接 |
| connections | array | [] | 数据库连接配置 |
| connections.mysql.type | string | 'mysql' | 数据库类型 |
| connections.mysql.hostname | string | '127.0.0.1' | 数据库主机名 |
| connections.mysql.database | string | '' | 数据库名 |
| connections.mysql.username | string | '' | 数据库用户名 |
| connections.mysql.password | string | '' | 数据库密码 |
| connections.mysql.hostport | string | '3306' | 数据库端口 |
| connections.mysql.charset | string | 'utf8mb4' | 数据库字符集 |
| connections.mysql.prefix | string | '' | 数据库表前缀 |
| connections.mysql.debug | bool | true | 数据库调试模式 |
| connections.mysql.deploy | array | [] | 数据库部署方式 |
| connections.mysql.rw_separate | bool | false | 数据库读写分离 |
| connections.mysql.master_num | int | 1 | 主数据库数量 |
| connections.mysql.slave_no | int | '' | 从数据库编号 |
| connections.mysql.read_master | bool | false | 是否从主服务器读取 |
| connections.mysql.deploy_type | int | 0 | 数据库部署类型 |
| connections.mysql.failover | array | [] | 数据库故障转移 |
| connections.mysql.break_reconnect | bool | false | 断开重连 |
| connections.mysql.pdo_type | string | '' | PDO 类型 |
| connections.mysql.max_conn | int | 0 | 最大连接数 |
| connections.mysql.strict_type | bool | false | 严格模式 |
| connections.mysql.auto_timestamp | bool | false | 自动时间戳 |
| connections.mysql.datetime_format | string | 'Y-m-d H:i:s' | 日期时间格式 |
| connections.mysql.date_format | string | 'Y-m-d' | 日期格式 |
| connections.mysql.time_format | string | 'H:i:s' | 时间格式 |
| connections.mysql.sql_build_cache | bool | false | SQL 构建缓存 |
| connections.mysql.builder | string | '' | 查询构建器 |
| connections.mysql.query | string | '' | 查询类 |
| connections.mysql.break_match_str | string | '' | 断开匹配字符串 |
| connections.mysql.params | array | [] | 连接参数 |
| connections.mysql.pk_convert | bool | false | 主键转换 |
| connections.mysql.resultset_type | string | 'array' | 结果集类型 |
| connections.mysql.return_collection | bool | false | 返回集合 |
| connections.mysql.identifier_quote | string | '' | 标识符引号 |
| connections.mysql.cache | array | [] | 缓存配置 |
| connections.mysql.trace_sql | bool | false | SQL 跟踪 |
### 4.3 缓存配置 (cache.php)
| 配置项 | 类型 | 默认值 | 描述 |
|-------|------|--------|------|
| default | string | 'file' | 默认缓存驱动 |
| stores | array | [] | 缓存驱动配置 |
| stores.file.type | string | 'file' | 文件缓存驱动 |
| stores.file.path | string | '' | 文件缓存路径 |
| stores.file.prefix | string | '' | 文件缓存前缀 |
| stores.file.expire | int | 0 | 文件缓存有效期 |
| stores.redis.type | string | 'redis' | Redis 缓存驱动 |
| stores.redis.host | string | '127.0.0.1' | Redis 主机名 |
| stores.redis.port | int | 6379 | Redis 端口 |
| stores.redis.password | string | '' | Redis 密码 |
| stores.redis.select | int | 0 | Redis 数据库 |
| stores.redis.timeout | int | 0 | Redis 超时时间 |
| stores.redis.persistent | bool | false | Redis 持久连接 |
| stores.redis.prefix | string | '' | Redis 缓存前缀 |
| stores.redis.serializer | int | 0 | Redis 序列化方式 |
| stores.memcache.type | string | 'memcache' | Memcache 缓存驱动 |
| stores.memcache.host | string | '127.0.0.1' | Memcache 主机名 |
| stores.memcache.port | int | 11211 | Memcache 端口 |
| stores.memcache.persistent | bool | false | Memcache 持久连接 |
| stores.memcache.timeout | int | 0 | Memcache 超时时间 |
| stores.memcache.prefix | string | '' | Memcache 缓存前缀 |
| stores.wincache.type | string | 'wincache' | WinCache 缓存驱动 |
| stores.wincache.prefix | string | '' | WinCache 缓存前缀 |
| stores.xcache.type | string | 'xcache' | XCache 缓存驱动 |
| stores.xcache.prefix | string | '' | XCache 缓存前缀 |
| stores.apc.type | string | 'apc' | APC 缓存驱动 |
| stores.apc.prefix | string | '' | APC 缓存前缀 |
| prefix | string | '' | 缓存前缀 |
### 4.4 队列配置 (queue.php)
| 配置项 | 类型 | 默认值 | 描述 |
|-------|------|--------|------|
| default | string | 'sync' | 默认队列驱动 |
| connections | array | [] | 队列连接配置 |
| connections.sync.driver | string | 'sync' | 同步队列驱动 |
| connections.database.driver | string | 'database' | 数据库队列驱动 |
| connections.database.table | string | 'jobs' | 队列表名 |
| connections.database.queue | string | 'default' | 默认队列名 |
| connections.database.expire | int | 60 | 任务过期时间 |
| connections.redis.driver | string | 'redis' | Redis 队列驱动 |
| connections.redis.connection | string | 'default' | Redis 连接名 |
| connections.redis.queue | string | 'default' | 默认队列名 |
| connections.redis.expire | int | 60 | 任务过期时间 |
| failed | array | [] | 失败队列配置 |
| failed.driver | string | 'database' | 失败队列驱动 |
| failed.table | string | 'failed_jobs' | 失败队列表名 |
### 4.5 日志配置 (log.php)
| 配置项 | 类型 | 默认值 | 描述 |
|-------|------|--------|------|
| default | array | ['file'] | 默认日志通道 |
| channels | array | [] | 日志通道配置 |
| channels.file.type | string | 'file' | 文件日志驱动 |
| channels.file.path | string | '' | 文件日志路径 |
| channels.file.level | string | 'debug' | 日志级别 |
| channels.file.days | int | 15 | 日志保留天数 |
| channels.file.json | bool | false | 是否 JSON 格式 |
| channels.syslog.type | string | 'syslog' | Syslog 日志驱动 |
| channels.syslog.ident | string | 'think' | Syslog 标识 |
| channels.syslog.facility | int | 8 | Syslog 设备 |
| channels.syslog.level | string | 'debug' | 日志级别 |
| channels.mail.type | string | 'mail' | 邮件日志驱动 |
| channels.mail.to | string | '' | 邮件接收地址 |
| channels.mail.subject | string | 'Log message' | 邮件主题 |
| channels.mail.level | string | 'error' | 日志级别 |
## 4. 核心配置说明
### 4.1 应用配置 (app.php)
- **app_debug**: 应用调试模式,开发环境设置为 `true`,生产环境设置为 `false`
- **app_trace**: 应用跟踪模式,用于调试,开发环境设置为 `true`,生产环境设置为 `false`
- **app_status**: 应用状态,用于加载不同的配置文件
- **default_return_type**: 默认返回类型,API 应用通常设置为 `json`
- **default_timezone**: 默认时区,中国地区设置为 `Asia/Shanghai`
### 4.2 数据库配置 (database.php)
- **default**: 默认数据库连接,通常使用 `mysql`
- **connections.mysql.hostname**: 数据库主机名,通常为 `127.0.0.1` 或数据库服务器 IP 地址
- **connections.mysql.database**: 数据库名,根据实际情况设置
- **connections.mysql.username**: 数据库用户名,根据实际情况设置
- **connections.mysql.password**: 数据库密码,根据实际情况设置
- **connections.mysql.charset**: 数据库字符集,通常使用 `utf8mb4`
- **connections.mysql.prefix**: 数据库表前缀,根据实际情况设置
### 4.3 缓存配置 (cache.php)
- **default**: 默认缓存驱动,开发环境通常使用 `file`,生产环境通常使用 `redis`
- **stores.redis.host**: Redis 主机名,通常为 `127.0.0.1` 或 Redis 服务器 IP 地址
- **stores.redis.password**: Redis 密码,根据实际情况设置
- **stores.redis.port**: Redis 端口,默认为 `6379`
- **stores.redis.select**: Redis 数据库编号,默认使用 `0`
### 4.4 队列配置 (queue.php)
- **default**: 默认队列驱动,开发环境通常使用 `sync`,生产环境通常使用 `redis` 或 `database`
- **connections.redis.queue**: 默认队列名,根据实际情况设置
- **failed.table**: 失败队列表名,默认为 `failed_jobs`
### 4.5 日志配置 (log.php)
- **default**: 默认日志通道,通常使用 `file`
- **channels.file.path**: 文件日志路径,默认使用 `runtime/log`
- **channels.file.level**: 日志级别,开发环境通常使用 `debug`,生产环境通常使用 `info` 或 `error`
- **channels.file.days**: 日志保留天数,根据实际情况设置
## 5. 配置最佳实践
### 5.1 开发环境配置
- **app_debug**: `true`
- **app_trace**: `true`
- **default_return_type**: `json`
- **database.connections.mysql.hostname**: `127.0.0.1`
- **database.connections.mysql.database**: `crmeb_dev`
- **cache.default**: `file`
- **queue.default**: `sync`
- **log.channels.file.level**: `debug`
### 5.2 测试环境配置
- **app_debug**: `false`
- **app_trace**: `false`
- **default_return_type**: `json`
- **database.connections.mysql.hostname**: `127.0.0.1`
- **database.connections.mysql.database**: `crmeb_test`
- **cache.default**: `redis`
- **queue.default**: `redis`
- **log.channels.file.level**: `info`
### 5.3 生产环境配置
- **app_debug**: `false`
- **app_trace**: `false`
- **default_return_type**: `json`
- **database.connections.mysql.hostname**: `your_db_host`
- **database.connections.mysql.database**: `crmeb_prod`
- **database.connections.mysql.username**: `your_db_user`
- **database.connections.mysql.password**: `your_db_password`
- **cache.default**: `redis`
- **queue.default**: `redis`
- **log.channels.file.level**: `error`
- **log.channels.file.days**: `30`
## 6. 常见配置问题
### 6.1 数据库连接失败
- **问题**: 无法连接到数据库
- **原因**: 数据库配置错误,如主机名、端口、用户名或密码错误
- **解决方案**: 检查数据库配置,确保配置正确
### 6.2 缓存无法使用
- **问题**: 缓存无法正常使用
- **原因**: 缓存配置错误,如 Redis 主机名、端口或密码错误
- **解决方案**: 检查缓存配置,确保配置正确
### 6.3 队列无法正常工作
- **问题**: 队列任务无法执行
- **原因**: 队列配置错误,如 Redis 连接错误或队列驱动配置错误
- **解决方案**: 检查队列配置,确保配置正确
### 6.4 日志无法写入
- **问题**: 日志无法写入到文件
- **原因**: 日志目录没有写权限
- **解决方案**: 为日志目录添加写权限
### 6.5 环境变量不生效
- **问题**: 环境变量配置不生效
- **原因**: 环境变量文件 `.env` 不存在或配置错误
- **解决方案**: 创建 `.env` 文件,确保配置正确
## 7. 参考资源
- [ThinkPHP 6 配置](https://www.kancloud.cn/manual/thinkphp6_0/1037478)
- [环境变量配置](https://www.kancloud.cn/manual/thinkphp6_0/1037479)
- [数据库配置](https://www.kancloud.cn/manual/thinkphp6_0/1037480)
- [缓存配置](https://www.kancloud.cn/manual/thinkphp6_0/1037481)
- [队列配置](https://www.kancloud.cn/manual/thinkphp6_0/1037482)
- [日志配置](https://www.kancloud.cn/manual/thinkphp6_0/1037483)

View File

@ -0,0 +1,473 @@
---
name: uniapp说明
description: 移动端uniapp开发说明
---
# uniapp 说明
## 0. 自动触发说明
### 0.1 触发条件
#### 0.1.1 操作触发
- **文件浏览时**: 当浏览 uniapp 相关目录时自动调用
- 打开 uniapp 项目根目录时触发
- 打开 pages 目录时触发
- 浏览 components 目录时触发
- 查看 uniapp 配置文件时触发
- **文件操作时**: 当对 uniapp 文件进行操作时自动调用
- 创建新页面文件时触发
- 修改组件文件时触发
- 删除 uniapp 文件时触发
- 修改配置文件时触发
- **目录操作时**: 当对 uniapp 目录进行操作时自动调用
- 创建新页面目录时触发
- 重命名组件目录时触发
- 删除 uniapp 目录时触发
#### 0.1.2 内容触发
- **关键词触发**: 当文件内容包含以下关键词时自动调用
- 移动端关键词: `移动端`、`app`、`手机`、`小程序`、`H5`
- uniapp 关键词: `uniapp`、`uni-app`、`uView`、`uniCloud`
- 功能关键词: `登录`、`注册`、`首页`、`商品`、`购物车`、`订单`
- **代码触发**: 当查看特定类型 uniapp 代码时自动调用
- 页面代码 (`*.vue`)
- 组件代码 (`components`)
- 配置代码 (`pages.json`、`manifest.json`)
- API 调用代码 (`uni.` 开头的 API)
#### 0.1.3 命令触发
- **终端命令触发**: 当执行以下命令时自动调用
- `npm run dev:h5` (启动 H5 开发)
- `npm run dev:mp-weixin` (启动微信小程序开发)
- `npm run build:h5` (构建 H5)
- `npm run build:mp-weixin` (构建微信小程序)
- `uni` 相关命令
### 0.2 适用场景
#### 0.2.1 核心场景
- **移动端开发**: 开发 uniapp 移动应用时
- **页面开发**: 创建或修改 uniapp 页面时
- **组件开发**: 开发可复用的 uniapp 组件时
- **功能集成**: 集成新功能到移动端应用时
#### 0.2.2 辅助场景
- **跨端调试**: 调试不同平台的兼容性问题时
- **性能优化**: 优化移动端应用性能时
- **样式调整**: 调整移动端界面样式时
- **API 调用**: 使用 uniapp 原生 API 时
### 0.3 触发机制
#### 0.3.1 调用时机
- **实时触发**: 页面文件操作时立即触发
- **延迟触发**: 复杂配置修改时延迟1秒触发
- **批量触发**: 批量文件操作时合并触发
#### 0.3.2 调用频率
- 文件浏览: 最多每10秒触发一次
- 文件操作: 最多每5秒触发一次
- 命令执行: 最多每3秒触发一次
#### 0.3.3 调用优先级
- **优先级等级**: 中优先级 (3/5)
- **竞争处理**: 当多个技能同时触发时
- 最高优先级: 系统核心技能
- 高优先级: 代码结构技能
- 中等优先级: uniapp 技能、管理端前端技能
- 低优先级: 辅助工具技能
- **触发限制**: 仅在 uniapp 相关操作时被触发,不影响其他技能的正常使用
### 0.4 触发后行为
#### 0.4.1 自动分析
- **结构分析**: 分析 uniapp 项目目录结构
- **组件分析**: 分析页面组件依赖关系
- **配置分析**: 分析 uniapp 配置文件
- **性能分析**: 分析移动端性能瓶颈
#### 0.4.2 自动展示
- **目录结构**: 展示 uniapp 项目目录结构
- **页面说明**: 展示核心页面功能说明
- **技术栈**: 展示 uniapp 技术栈
- **开发规范**: 展示移动端开发规范
#### 0.4.3 自动建议
- **开发建议**: 提供 uniapp 开发建议
- **优化建议**: 提供移动端性能优化建议
- **规范建议**: 提供代码规范遵循建议
- **跨端建议**: 提供跨端兼容性建议
## 1. uniapp 架构介绍
### 1.1 整体架构
- **跨端框架**: 基于 Vue 2.x 的跨端应用框架
- **多端发布**: 支持 H5、小程序、App 等多端发布
- **组件化开发**: 基于 Vue 组件化开发模式
- **原生能力**: 调用各平台原生 API 能力
- **状态管理**: Vuex 或 Pinia 状态管理
### 1.2 技术栈
- **核心框架**: Vue 2.x / Vue 3.x
- **UI 组件库**: uView UI、ColorUI、uni-ui
- **状态管理**: Vuex 3.x / Pinia
- **HTTP 客户端**: uni.request、axios
- **构建工具**: Webpack、Vite
- **包管理器**: npm/yarn
- **代码规范**: ESLint + Prettier
### 1.3 目录结构
#### 1.3.1 核心目录
```
uniapp/
├── pages/ # 页面目录
├── components/ # 组件目录
├── static/ # 静态资源目录
├── utils/ # 工具函数目录
├── api/ # API 接口目录
├── store/ # 状态管理目录
├── common/ # 公共目录
├── mixins/ # 混合器目录
├── pages.json # 页面路由配置
├── manifest.json # 应用配置
├── main.js # 入口文件
├── App.vue # 根组件
└── uni.scss # 全局样式
```
#### 1.3.2 页面目录
```
pages/
├── index/ # 首页
├── goods/ # 商品
├── cart/ # 购物车
├── order/ # 订单
├── user/ # 用户中心
├── login/ # 登录
└── detail/ # 详情页
```
## 2. 核心功能模块
### 2.1 登录认证模块
- **功能**: 用户登录、注册、密码找回、第三方登录
- **关键页面**: `login.vue`、`register.vue`
- **核心功能**:
- 手机号密码登录
- 验证码登录
- 微信登录
- 注册功能
- 密码找回
- 登录状态管理
### 2.2 首页模块
- **功能**: 应用入口、轮播图、推荐商品、分类入口
- **关键页面**: `index.vue`
- **核心功能**:
- 轮播图展示
- 分类导航
- 推荐商品
- 活动入口
- 搜索功能
- 快捷入口
### 2.3 商品模块
- **功能**: 商品列表、商品搜索、商品筛选、商品详情
- **关键页面**: `goods/list.vue`、`goods/detail.vue`
- **核心功能**:
- 商品列表展示
- 商品搜索
- 商品筛选
- 商品详情
- 商品评价
- 商品分享
### 2.4 购物车模块
- **功能**: 商品管理、数量调整、价格计算、结算
- **关键页面**: `cart/index.vue`
- **核心功能**:
- 商品添加/删除
- 数量调整
- 价格计算
- 商品结算
- 购物车清空
- 选择商品
### 2.5 订单模块
- **功能**: 订单创建、订单列表、订单详情、订单支付
- **关键页面**: `order/create.vue`、`order/list.vue`、`order/detail.vue`
- **核心功能**:
- 订单创建
- 订单列表
- 订单详情
- 订单支付
- 订单取消
- 订单退款
### 2.6 用户中心模块
- **功能**: 用户信息、收货地址、优惠券、收藏、历史记录
- **关键页面**: `user/index.vue`、`user/info.vue`
- **核心功能**:
- 用户信息管理
- 收货地址管理
- 优惠券管理
- 商品收藏
- 浏览历史
- 个人设置
## 3. 技术特点
### 3.1 跨端开发
- **一次开发多端发布**: 支持 H5、小程序、App 等多端
- **条件编译**: 根据不同平台编写特定代码
- **平台差异处理**: 处理各平台 API 差异
- **原生能力调用**: 调用各平台原生能力
### 3.2 组件化开发
- **页面组件**: 页面级组件开发
- **通用组件**: 可复用的通用组件
- **业务组件**: 特定业务逻辑组件
- **组件通信**: Props/Events、Vuex、EventBus
### 3.3 状态管理
- **Vuex 模块化**: 按功能模块划分 store
- **状态持久化**: 使用 localStorage/sessionStorage
- **异步操作**: 使用 Actions 处理异步请求
- **getters**: 派生状态计算
### 3.4 API 调用
- **uni.request**: uniapp 内置请求方法
- **请求封装**: 统一 API 调用方式
- **拦截器**: 请求/响应拦截器
- **API 模块化**: 按功能模块划分 API
## 4. 开发规范
### 4.1 代码规范
- **Vue 风格指南**: 遵循 Vue 官方风格指南
- **ESLint 规则**: 严格遵循 ESLint 规则
- **代码缩进**: 4空格缩进
- **命名规范**:
- 组件名: PascalCase
- 方法/变量: camelCase
- 常量: 全大写
- 文件名: kebab-case
### 4.2 目录规范
- **页面目录**: 按功能模块组织页面
- **组件目录**: 按类型组织组件
- **资源目录**: 分类存放静态资源
- **工具目录**: 按功能分类工具函数
### 4.3 命名规范
- **页面命名**: 使用语义化的页面名称
- **组件命名**: 与功能模块名称对应
- **store 命名**: 与功能模块名称对应
- **API 命名**: 与后端接口名称对应
### 4.4 注释规范
- **页面注释**: 页面功能、参数说明
- **组件注释**: 组件功能、props、events 说明
- **方法注释**: 方法功能、参数、返回值说明
- **复杂逻辑注释**: 关键逻辑步骤说明
## 5. 性能优化
### 5.1 加载优化
- **路由懒加载**: 按需加载页面组件
- **组件懒加载**: 按需加载大型组件
- **图片优化**: 图片压缩、懒加载、WebP 格式
- **资源压缩**: JS/CSS 压缩
- **预加载**: 预加载关键资源
### 5.2 渲染优化
- **虚拟列表**: 长列表使用虚拟滚动
- **计算属性缓存**: 使用 computed 缓存计算结果
- **避免频繁更新**: 使用 v-once、v-memo
- **合理使用 key**: 列表渲染时使用唯一 key
- **减少 DOM 操作**: 批量更新 DOM
### 5.3 网络优化
- **API 请求合并**: 合并相同请求
- **请求缓存**: 缓存重复请求结果
- **防抖节流**: 优化频繁触发的事件
- **WebSocket**: 实时数据使用 WebSocket
- **HTTP/2**: 启用 HTTP/2 协议
### 5.4 构建优化
- **Tree Shaking**: 移除未使用的代码
- **代码分割**: 按路由分割代码
- **环境变量**: 区分开发/生产环境
- **分包加载**: 小程序分包加载
## 6. 跨端兼容
### 6.1 平台差异
- **H5 端**: 浏览器兼容性
- **小程序端**: 各平台小程序限制
- **App 端**: iOS/Android 差异
### 6.2 兼容策略
- **条件编译**: 使用 `#ifdef`/`#endif` 处理平台差异
- **API 兼容**: 封装统一的 API 调用
- **样式兼容**: 处理各平台样式差异
- **功能降级**: 不支持的功能提供降级方案
### 6.3 测试策略
- **多端测试**: 在各平台进行测试
- **兼容性测试**: 测试不同版本的兼容性
- **性能测试**: 测试各平台性能表现
- **用户体验测试**: 测试各平台用户体验
## 7. 安全防护
### 7.1 数据安全
- **敏感数据加密**: 加密存储敏感信息
- **本地存储安全**: 合理使用 localStorage
- **API 接口安全**: HTTPS、接口签名
- **数据验证**: 前端数据验证
### 7.2 权限管理
- **权限申请**: 合理申请设备权限
- **权限提示**: 向用户说明权限用途
- **权限降级**: 无权限时提供降级方案
### 7.3 防作弊措施
- **请求频率限制**: 防止恶意请求
- **参数验证**: 验证请求参数
- **签名验证**: 验证请求签名
- **设备标识**: 合理使用设备标识
## 8. 最佳实践
### 8.1 开发流程
1. **需求分析**: 明确功能需求
2. **设计阶段**: 设计页面结构和组件
3. **编码实现**: 遵循开发规范编码
4. **多端测试**: 在各平台进行测试
5. **性能优化**: 优化应用性能
6. **发布上线**: 构建和发布
### 8.2 页面开发
- **布局规范**: 遵循移动端布局规范
- **响应式设计**: 适配不同屏幕尺寸
- **用户体验**: 优化移动端交互体验
- **性能考虑**: 页面加载和渲染性能
### 8.3 组件开发
- **单一职责**: 组件功能单一
- **可配置性**: 组件参数可配置
- **跨端兼容**: 考虑各平台兼容性
- **性能优化**: 优化组件性能
### 8.4 调试技巧
- **uni-app 开发工具**: 使用官方开发工具
- **真机调试**: 使用真机进行调试
- **控制台调试**: 合理使用 console 方法
- **网络调试**: 分析 API 请求和响应
## 9. 常见问题
### 9.1 兼容性问题
- **API 兼容性**: 处理各平台 API 差异
- **样式兼容性**: 处理各平台样式差异
- **功能兼容性**: 处理各平台功能差异
### 9.2 性能问题
- **启动速度**: 优化应用启动速度
- **页面加载**: 优化页面加载速度
- **滚动性能**: 优化页面滚动性能
- **内存占用**: 优化应用内存占用
### 9.3 打包问题
- **包体积**: 优化应用包体积
- **分包加载**: 合理使用分包加载
- **资源文件**: 优化资源文件大小
### 9.4 上架问题
- **应用商店审核**: 遵循各应用商店审核规则
- **小程序审核**: 遵循各小程序平台审核规则
- **内容合规**: 确保应用内容合规
## 10. 部署与发布
### 10.1 构建流程
- **H5 构建**: `npm run build:h5`
- **微信小程序构建**: `npm run build:mp-weixin`
- **App 构建**: 使用 HBuilderX 云打包
### 10.2 发布流程
- **H5 发布**: 部署到静态文件服务器
- **小程序发布**: 提交到各小程序平台
- **App 发布**: 提交到应用商店
### 10.3 版本管理
- **版本号规范**: 遵循语义化版本规范
- **发布日志**: 记录版本变更内容
- **灰度发布**: 采用灰度发布策略
## 11. 开发工具推荐
### 11.1 IDE 推荐
- **HBuilderX**: uniapp 官方推荐 IDE
- **VS Code**: 配合 uniapp 插件使用
- **WebStorm**: 专业的前端 IDE
### 11.2 插件推荐
- **uni-app 插件市场**: 官方插件市场
- **uView UI**: 移动端 UI 组件库
- **ColorUI**: 移动端 UI 组件库
- **uni-ui**: 官方 UI 组件库
### 11.3 工具推荐
- **Charles**: 网络调试工具
- **Postman**: API 测试工具
- **Figma/Sketch**: UI 设计工具
- **Lighthouse**: 性能分析工具
## 12. 参考资源
### 12.1 官方文档
- [uni-app 官方文档](https://uniapp.dcloud.io/)
- [uView UI 文档](https://uviewui.com/)
- [Vue 官方文档](https://v2.vuejs.org/)
- [微信小程序文档](https://developers.weixin.qq.com/miniprogram/dev/framework/)
### 12.2 学习资源
- [uni-app 教程](https://uniapp.dcloud.io/tutorial/)
- [Vue Mastery](https://www.vuemastery.com/)
- [MDN Web Docs](https://developer.mozilla.org/zh-CN/)
- [CSS-Tricks](https://css-tricks.com/)
### 12.3 社区资源
- [uni-app 社区](https://ask.dcloud.net.cn/forum-79-1.html)
- [GitHub](https://github.com/)
- [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 协作流程
- **需求评审**: 团队评审需求
- **任务分配**: 合理分配开发任务
- **代码审查**: 代码质量检查
- **多端测试**: 团队成员负责不同平台测试
### 13.2 规范约定
- **代码规范**: 统一代码风格
- **命名规范**: 统一命名规则
- **文档规范**: 统一文档格式
- **提交规范**: 统一提交信息格式
### 13.3 工具协作
- **项目管理**: 使用项目管理工具
- **代码托管**: 使用代码托管平台
- **CI/CD**: 持续集成/持续部署
- **文档协作**: 团队文档协作工具

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