# bs-server **Repository Path**: benshou888/bs-server ## Basic Information - **Project Name**: bs-server - **Description**: 管理后台的后端代码 - **Primary Language**: NodeJS - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-11-02 - **Last Updated**: 2025-11-12 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # bs-server #### 介绍 管理后台的 Node.js API 服务系统,基于 Express 和 MySQL。 #### 技术栈 - **Node.js** - 运行环境 - **Express** - Web 框架 - **MySQL2** - MySQL 数据库驱动 - **dotenv** - 环境变量管理 - **CORS** - 跨域支持 - **morgan** - HTTP 请求日志 - **bcryptjs** - 密码加密 - **jsonwebtoken** - JWT 身份验证 #### Docker 部署(推荐) 使用 Docker Compose 可以快速部署应用,无需手动配置环境。 **快速开始:** ```bash # 1. 准备环境变量文件 cp env.prod.example .env.prod # 编辑 .env.prod 文件,修改密码和密钥 # 2. 使用部署脚本一键部署 ./docker/deploy.sh prod # 或手动部署 docker-compose -f docker-compose.prod.yml --env-file .env.prod up -d ``` **详细部署说明请查看 [DEPLOY.md](./DEPLOY.md)** --- #### 安装教程(本地开发) ```bash npm install ``` 2. 配置环境变量 - 复制 `env.example` 为 `.env` - 修改 `.env` 文件中的配置: ``` DB_HOST=localhost DB_PORT=3306 DB_USER=root DB_PASSWORD=your_password DB_NAME=bs_database PORT=3000 JWT_SECRET=your_jwt_secret_key_here ``` 3. 创建数据库并导入表结构 ```bash # 登录 MySQL mysql -u root -p # 创建数据库 CREATE DATABASE bs_database CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; # 退出 MySQL,然后导入表结构 mysql -u root -p bs_database < create_tables.sql ``` 4. 启动服务 ```bash # 开发模式(使用 nodemon 自动重启) npm run dev # 生产模式 npm start ``` #### API 接口说明 服务启动后,访问 `http://localhost:3000` 查看接口列表。 ##### 认证接口 (Auth) - `POST /api/auth/register` - 用户注册 - 请求体: ```json { "username": "用户名", "password": "密码(至少6位)", "role": "超级管理员" 或 "普通老师", "contact_info": "联系方式(可选)" } ``` - 响应: ```json { "success": true, "message": "注册成功", "data": { "user": { "user_id": 1, "username": "用户名", "role": "超级管理员", "contact_info": "联系方式", "created_at": "2024-01-01T00:00:00.000Z" } } } ``` - `POST /api/auth/login` - 用户登录 - 请求体: ```json { "username": "用户名", "password": "密码" } ``` - 响应: ```json { "success": true, "message": "登录成功", "data": { "user": { "user_id": 1, "username": "用户名", "role": "超级管理员", "contact_info": "联系方式" }, "token": "JWT_TOKEN_HERE" } } ``` - `GET /api/auth/me` - 获取当前用户信息(需要 token) - 请求头: `Authorization: Bearer ` - 响应: ```json { "success": true, "data": { "user": { "user_id": 1, "username": "用户名", "role": "超级管理员", "contact_info": "联系方式", "created_at": "2024-01-01T00:00:00.000Z" } } } ``` ##### 用户管理 (Users) - `GET /api/users` - 获取所有用户 - `GET /api/users/:id` - 获取指定用户 - `POST /api/users` - 创建用户(管理员功能) - 请求体支持 `password`(明文)或 `password_hash`(哈希值) - 示例: ```json { "username": "用户名", "password": "密码", "role": "超级管理员", "contact_info": "联系方式" } ``` - `PUT /api/users/:id` - 更新用户 - 支持更新 `password`(明文,会自动加密)或 `password_hash` - `DELETE /api/users/:id` - 删除用户 ##### 客户管理 (Customers) - `GET /api/customers` - 获取客户列表(支持分页和筛选) - 查询参数: `page`, `limit`, `status`(可选值:`active`、`archived`) - 返回数据包含 `diet_plan` 字段(客户当前饮食方案:A、B、AB、C) - `GET /api/customers/:id` - 获取指定客户 - 返回数据包含 `diet_plan` 字段(客户当前饮食方案:A、B、AB、C) - `POST /api/customers` - 创建客户 - 支持 `diet_plan` 字段(可选值:A、B、AB、C) - `PUT /api/customers/:id` - 更新客户 - 支持 `diet_plan` 字段(可选值:A、B、AB、C) - `PUT /api/customers/:id/diet-plan` - 单独更新客户饮食方案 - 请求体: `{ "diet_plan": "A" }`(可选值:A、B、AB、C) - `POST /api/customers/:id/archive` - 归档客户(支持PUT和POST方法) - `POST /api/customers/:id/unarchive` - 取消归档客户(支持PUT和POST方法) - `DELETE /api/customers/:id` - 删除客户 ##### 客户每日登记记录 (Daily Records) - `GET /api/daily-records` - 获取每日登记记录 - 查询参数: `customer_id`, `page`, `limit` - `GET /api/daily-records/latest/:customer_id` - 获取指定客户的最新登记记录 - `GET /api/daily-records/:id` - 获取指定记录 - `POST /api/daily-records` - 创建每日登记记录 - 请求体示例: ```json { "customer_id": 1, "record_date": "2025-01-15", "weight": 75.5, "recorded_by": 1, "recent_status": "状态良好,精神饱满", "hunger_level": "很舒服", "diet_compliance": "非常好", "weight_loss_satisfaction": "非常满意", "other_changes": "睡眠质量有所改善", "notes": "备注信息" } ``` - 字段说明: - `hunger_level`: 当前饥饿感,可选值:`很舒服`、`有点饥饿感`、`经常非常饿` - `diet_compliance`: 饮食执行情况,可选值:`非常好`、`偶尔没按要求`、`几乎没按要求` - `weight_loss_satisfaction`: 掉秤满意度,可选值:`非常满意`、`正常`、`有点着急`、`非常着急` - `PUT /api/daily-records/:id` - 更新记录 - `DELETE /api/daily-records/:id` - 删除记录 ##### 体质评估 (Assessments) - `GET /api/assessments` - 获取评估记录 - `GET /api/assessments/:id` - 获取指定评估 - `POST /api/assessments` - 创建评估记录 - `PUT /api/assessments/:id` - 更新评估 - `DELETE /api/assessments/:id` - 删除评估 - `POST /api/assessments/ai/:customer_id` - AI评估接口 - 路径参数: `customer_id` - 客户ID - 请求体(可选): ```json { "is_first": true } ``` - 响应: ```json { "success": true, "message": "AI评估完成", "data": "评估结果文本内容..." } ``` ##### 减重方案 (Plans) - `GET /api/plans` - 获取方案列表 - 查询参数: `customer_id`, `status`, `page`, `limit` - `GET /api/plans/:id` - 获取指定方案 - `POST /api/plans` - 创建方案 - `PUT /api/plans/:id` - 更新方案 - `DELETE /api/plans/:id` - 删除方案 ##### 健康检查 - `GET /api/health` - 检查服务状态 #### 项目结构 ``` bs-server/ ├── src/ │ ├── config/ │ │ └── database.js # 数据库配置 │ ├── middleware/ │ │ ├── errorHandler.js # 错误处理 │ │ ├── asyncHandler.js # 异步函数包装 │ │ └── auth.js # 认证中间件 │ ├── routes/ │ │ ├── index.js # 路由入口 │ │ ├── auth.js # 认证路由(登录、注册) │ │ ├── users.js # 用户路由 │ │ ├── customers.js # 客户路由 │ │ ├── dailyRecords.js # 每日登记记录路由 │ │ ├── assessments.js # 评估路由 │ │ └── plans.js # 方案路由 │ ├── utils/ │ │ └── jwt.js # JWT 工具函数 │ └── server.js # 服务器入口 ├── create_tables.sql # 数据库表结构 ├── package.json # 项目配置 └── README.md # 项目说明 ``` #### 使用说明 1. 所有接口返回格式统一为: ```json { "success": true/false, "data": {...}, "error": {...} } ``` 2. 分页接口返回格式: ```json { "success": true, "data": [...], "pagination": { "page": 1, "limit": 10, "total": 100, "pages": 10 } } ``` 3. JSON 字段(如 `plan_content`, `assessment_data` 等)会自动序列化和反序列化。 4. **身份验证**: - 登录成功后,客户端需要在请求头中携带 token: `Authorization: Bearer ` - Token 默认有效期为 7 天(可通过 `JWT_EXPIRES_IN` 环境变量配置) - 使用认证中间件可以保护需要登录的接口: ```javascript const { authenticate, authorize } = require('./middleware/auth'); // 需要登录 router.get('/protected', authenticate, handler); // 需要特定角色 router.get('/admin-only', authenticate, authorize('超级管理员'), handler); ``` 5. **密码安全**: - 注册和登录接口使用 bcrypt 加密密码 - 密码长度至少 6 位 - 密码不会在响应中返回 #### 参与贡献 1. Fork 本仓库 2. 新建 Feat_xxx 分支 3. 提交代码 4. 新建 Pull Request