diff --git a/.env.development b/.env.development index fbcc74b..b8ccd8b 100644 --- a/.env.development +++ b/.env.development @@ -1,5 +1,5 @@ VITE_APP_NAME=后台管理(开发环境) -VITE_API_URL=http://127.0.0.1:9200/api +#VITE_API_URL=http://127.0.0.1:9200/api #VITE_SERVER_API_URL=http://127.0.0.1:8000/api diff --git a/README-QR-LOGIN.md b/README-QR-LOGIN.md new file mode 100644 index 0000000..a599587 --- /dev/null +++ b/README-QR-LOGIN.md @@ -0,0 +1,236 @@ +# 二维码登录功能 + +## 概述 + +基于Vue 3 + TypeScript开发的二维码登录功能,支持APP端和小程序端扫码登录到Web管理后台。 + +## 功能特点 + +- ✅ **便捷登录**:扫码即可登录,无需输入账号密码 +- ✅ **实时状态**:支持实时状态更新和用户反馈 +- ✅ **安全可靠**:二维码具有时效性,支持一次性使用 +- ✅ **跨平台支持**:兼容APP和小程序扫码 +- ✅ **响应式设计**:适配各种屏幕尺寸 +- ✅ **TypeScript支持**:完整的类型定义 + +## 文件结构 + +``` +src/ +├── components/QrLogin/ +│ ├── index.vue # 二维码登录主组件 +│ └── demo.vue # 演示组件 +├── views/passport/ +│ ├── login/index.vue # 登录页面(已集成二维码登录) +│ └── qrConfirm/index.vue # 移动端确认页面 +├── api/passport/ +│ └── qrLogin/index.ts # 二维码登录API +└── router/routes.ts # 路由配置 + +docs/ +├── qr-login-api.md # API接口文档 +└── qr-login-usage.md # 使用说明文档 +``` + +## 快速开始 + +### 1. 查看演示 + +访问演示页面查看功能效果: +``` +http://localhost:3000/qr-demo +``` + +### 2. 在登录页面使用 + +登录页面已经集成了二维码登录功能: +``` +http://localhost:3000/login +``` +点击右上角的二维码图标即可切换到扫码登录模式。 + +### 3. 移动端确认页面 + +扫码后会跳转到确认页面: +``` +http://localhost:3000/qr-confirm?qrCodeKey=xxx +``` + +## 组件使用 + +### 基本用法 + +```vue + + + +``` + +### 事件说明 + +| 事件名 | 参数 | 说明 | +|--------|------|------| +| loginSuccess | token: string | 登录成功时触发,返回登录token | +| loginError | error: string | 登录失败时触发,返回错误信息 | + +## API接口 + +### 需要实现的后端接口 + +1. **生成二维码**: `POST /api/qr-login/generate` +2. **检查状态**: `GET /api/qr-login/status` +3. **扫码标记**: `POST /api/qr-login/scan` +4. **确认登录**: `POST /api/qr-login/confirm` +5. **取消登录**: `POST /api/qr-login/cancel` + +详细的API文档请查看:[docs/qr-login-api.md](docs/qr-login-api.md) + +## 状态流转 + +``` +loading → active → scanned → confirmed ✅ + ↓ ↓ ↓ + error expired cancelled +``` + +- **loading**: 正在生成二维码 +- **active**: 二维码有效,等待扫码 +- **scanned**: 已扫码,等待用户确认 +- **confirmed**: 用户确认,登录成功 +- **expired**: 二维码过期 +- **error**: 生成失败 +- **cancelled**: 用户取消登录 + +## 安全机制 + +1. **时效控制**:二维码默认5分钟过期 +2. **一次性使用**:每个二维码只能使用一次 +3. **状态验证**:严格的状态流转控制 +4. **用户验证**:移动端需要用户登录状态 +5. **HTTPS传输**:敏感数据加密传输 + +## 自定义配置 + +### 样式自定义 + +```less +.qr-login-container { + // 自定义容器样式 + padding: 20px; + + .qr-code-wrapper { + // 自定义二维码区域样式 + min-height: 250px; + } +} +``` + +### 参数配置 + +```typescript +// 二维码大小 +const QR_CODE_SIZE = 200; + +// 过期时间(秒) +const EXPIRE_TIME = 300; + +// 状态检查间隔(毫秒) +const CHECK_INTERVAL = 2000; +``` + +## 开发调试 + +### 启用调试模式 + +```javascript +// 在浏览器控制台执行 +localStorage.setItem('debug', 'qr-login'); +``` + +### 查看网络请求 + +使用浏览器开发者工具的Network面板监控API请求。 + +### 模拟测试 + +访问演示页面 `/qr-demo` 可以模拟各种状态和场景。 + +## 部署注意事项 + +1. **HTTPS要求**:生产环境必须使用HTTPS +2. **跨域配置**:确保API接口支持跨域请求 +3. **移动端适配**:确保移动端页面正常显示 +4. **性能优化**:合理设置轮询间隔和缓存策略 + +## 故障排除 + +### 常见问题 + +1. **二维码不显示** + - 检查网络连接 + - 确认API接口正常 + - 查看控制台错误信息 + +2. **扫码无响应** + - 检查二维码是否过期 + - 确认移动端网络正常 + - 验证用户登录状态 + +3. **登录失败** + - 检查token有效性 + - 确认用户权限 + - 查看后端日志 + +### 调试步骤 + +1. 打开浏览器开发者工具 +2. 查看Console面板的错误信息 +3. 监控Network面板的API请求 +4. 检查Application面板的本地存储 + +## 更新日志 + +### v1.0.0 (2024-01-XX) +- ✅ 完成基础二维码登录功能 +- ✅ 支持实时状态更新 +- ✅ 集成到登录页面 +- ✅ 创建移动端确认页面 +- ✅ 完善文档和演示 + +## 技术栈 + +- **前端框架**: Vue 3 + TypeScript +- **UI组件库**: Ant Design Vue +- **二维码生成**: qrcode + ele-admin-pro +- **状态管理**: Pinia +- **路由管理**: Vue Router +- **HTTP客户端**: Axios + +## 贡献指南 + +1. Fork 项目 +2. 创建功能分支 +3. 提交代码变更 +4. 推送到分支 +5. 创建 Pull Request + +## 许可证 + +MIT License diff --git a/docs/qr-login-api.md b/docs/qr-login-api.md new file mode 100644 index 0000000..21ee6f1 --- /dev/null +++ b/docs/qr-login-api.md @@ -0,0 +1,212 @@ +# 二维码登录API接口文档(已适配后端) + +## 概述 + +二维码登录功能允许用户通过手机APP或小程序扫描Web端生成的二维码来完成登录,提供更便捷和安全的登录体验。 + +**后端实现状态:** ✅ 已完成 +**前端适配状态:** ✅ 已完成 + +## 接口列表 + +### 1. 生成登录二维码 + +**接口地址:** `POST /api/qr-login/generate` + +**请求参数:** 无 + +**响应数据:** +```json +{ + "code": 0, + "message": "生成成功", + "data": { + "token": "abc123def456", + "qrCode": "qr-login:abc123def456", + "expiresIn": 300 + } +} +``` + +**字段说明:** +- `token`: 二维码唯一标识token,用于后续状态查询 +- `qrCode`: 二维码内容(后端生成的原始内容) +- `expiresIn`: 过期时间(秒),默认300秒(5分钟) + +### 2. 检查二维码状态 + +**接口地址:** `GET /api/qr-login/status/{token}` + +**请求参数:** +- `token`: 二维码token(路径参数) + +**响应数据:** +```json +{ + "code": 0, + "message": "查询成功", + "data": { + "status": "pending", + "expiresIn": 280 + } +} +``` + +**状态说明:** +- `pending`: 等待扫码 +- `scanned`: 已扫码,等待确认 +- `confirmed`: 已确认登录 +- `expired`: 已过期 + +**登录成功时的响应:** +```json +{ + "code": 0, + "message": "登录成功", + "data": { + "status": "confirmed", + "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", + "userInfo": { + "userId": 1, + "username": "admin", + "nickname": "管理员", + "avatar": "https://example.com/avatar.jpg" + }, + "expiresIn": 60 + } +} +``` + +### 3. 扫码标记 + +**接口地址:** `POST /api/qr-login/scan/{token}` + +**请求参数:** +- `token`: 二维码token(路径参数) + +**响应数据:** +```json +{ + "code": 0, + "message": "操作成功", + "data": true +} +``` + +### 4. 确认登录 + +**接口地址:** `POST /api/qr-login/confirm` + +**请求参数:** +```json +{ + "token": "abc123def456", + "userId": 1, + "platform": "web" +} +``` + +**响应数据:** +```json +{ + "code": 0, + "message": "确认成功", + "data": { + "status": "confirmed", + "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", + "userInfo": { + "userId": 1, + "username": "admin", + "nickname": "管理员" + }, + "expiresIn": 60 + } +} +``` + +### 5. 微信小程序确认登录 + +**接口地址:** `POST /api/qr-login/wechat-confirm` + +**请求参数:** +```json +{ + "token": "abc123def456", + "userId": 1, + "platform": "miniprogram", + "wechatInfo": { + "openid": "wx_openid_123", + "unionid": "wx_unionid_456", + "nickname": "微信用户", + "avatar": "https://wx.qlogo.cn/..." + } +} +``` + +**响应数据:** +```json +{ + "code": 0, + "message": "微信小程序登录确认成功", + "data": { + "status": "confirmed", + "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", + "userInfo": {...}, + "expiresIn": 60 + } +} +``` + +## 实现流程 + +### Web端流程: +1. 用户点击扫码登录 +2. 前端调用 `/qr-login/generate` 生成二维码 +3. 显示二维码给用户 +4. 前端轮询调用 `/qr-login/status` 检查状态 +5. 当状态为 `confirmed` 时,获取token完成登录 + +### 移动端流程: +1. 用户扫描二维码,跳转到确认页面 +2. 页面加载时调用 `/qr-login/scan` 标记已扫码 +3. 用户点击确认后调用 `/qr-login/confirm` 确认登录 +4. 或用户点击取消后调用 `/qr-login/cancel` 取消登录 + +## 安全考虑 + +1. **二维码有效期**:建议设置5分钟有效期,过期后需要重新生成 +2. **一次性使用**:每个二维码只能使用一次,确认或取消后立即失效 +3. **用户验证**:移动端需要验证用户的登录状态 +4. **IP限制**:可以记录生成二维码的IP,限制异地登录 +5. **频率限制**:限制同一IP生成二维码的频率 + +## 数据库设计建议 + +```sql +CREATE TABLE qr_login_records ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + qr_code_key VARCHAR(64) UNIQUE NOT NULL COMMENT '二维码唯一标识', + status ENUM('waiting', 'scanned', 'confirmed', 'expired', 'cancelled') DEFAULT 'waiting' COMMENT '状态', + user_id BIGINT NULL COMMENT '扫码用户ID', + client_ip VARCHAR(45) COMMENT '客户端IP', + user_agent TEXT COMMENT '用户代理', + expire_time DATETIME NOT NULL COMMENT '过期时间', + scan_time DATETIME NULL COMMENT '扫码时间', + confirm_time DATETIME NULL COMMENT '确认时间', + created_at DATETIME DEFAULT CURRENT_TIMESTAMP, + updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + INDEX idx_qr_code_key (qr_code_key), + INDEX idx_status (status), + INDEX idx_expire_time (expire_time) +); +``` + +## 错误码说明 + +- `0`: 成功 +- `400`: 参数错误 +- `401`: 未授权 +- `404`: 二维码不存在 +- `410`: 二维码已过期 +- `429`: 请求过于频繁 +- `500`: 服务器内部错误 diff --git a/docs/qr-login-setup-guide.md b/docs/qr-login-setup-guide.md new file mode 100644 index 0000000..0204ba9 --- /dev/null +++ b/docs/qr-login-setup-guide.md @@ -0,0 +1,262 @@ +# 二维码登录功能设置指南 + +## 概述 + +本指南将帮助您设置和测试二维码登录功能。后端Java代码已经完成,前端Vue代码已经适配完成。 + +## 🎯 功能状态 + +- ✅ **后端实现**: Java Spring Boot (已完成) +- ✅ **前端适配**: Vue 3 + TypeScript (已完成) +- ✅ **接口对接**: API接口已适配 +- ✅ **测试页面**: 提供完整的测试工具 + +## 🚀 快速开始 + +### 1. 启动后端服务 + +确保您的Java后端服务正在运行,并且包含以下文件: + +``` +java/auto/ +├── controller/QrLoginController.java +├── service/QrLoginService.java +├── service/impl/QrLoginServiceImpl.java +└── dto/ + ├── QrLoginGenerateResponse.java + ├── QrLoginStatusResponse.java + ├── QrLoginConfirmRequest.java + └── QrLoginData.java +``` + +### 2. 启动前端服务 + +```bash +npm run dev +# 或 +yarn dev +``` + +### 3. 测试接口连通性 + +访问接口测试页面: +``` +http://localhost:3000/qr-test +``` + +按照以下步骤测试: + +1. **生成二维码** - 点击"生成二维码"按钮 +2. **检查状态** - 开启"自动检查"开关 +3. **模拟扫码** - 点击"模拟扫码"按钮 +4. **确认登录** - 输入用户ID,点击"确认登录" + +## 📱 使用流程 + +### Web端操作 + +1. **进入登录页面** + ``` + http://localhost:3000/login + ``` + +2. **切换到扫码登录** + - 点击右上角的二维码图标 + - 系统自动生成二维码 + +3. **等待扫码** + - 二维码有效期5分钟 + - 系统每2秒检查一次状态 + +### 移动端操作 + +1. **扫描二维码** + - 使用手机扫描Web端的二维码 + - 或直接访问二维码中的URL + +2. **确认登录** + ``` + http://localhost:3000/qr-confirm?qrCodeKey=abc123def456 + ``` + - 显示用户信息和设备信息 + - 点击"确认登录"完成登录 + +## 🔧 配置说明 + +### 后端配置 + +在 `application.yml` 中配置JWT相关参数: + +```yaml +config: + jwt: + secret: websoft-jwt-secret-key-2025 + expire: 86400 # 24小时 +``` + +### 前端配置 + +在 `src/config/setting.ts` 中确认API地址: + +```typescript +export const SERVER_API_URL = 'http://localhost:8080'; +``` + +## 🧪 测试场景 + +### 1. 正常登录流程 + +1. Web端生成二维码 +2. 移动端扫码 +3. 移动端确认登录 +4. Web端自动登录成功 + +### 2. 过期场景 + +1. 生成二维码后等待5分钟 +2. 二维码自动过期 +3. 点击刷新重新生成 + +### 3. 取消场景 + +1. 移动端扫码后点击取消 +2. Web端继续等待新的扫码 + +## 🔍 调试方法 + +### 1. 查看网络请求 + +打开浏览器开发者工具 → Network面板: + +- `POST /api/qr-login/generate` - 生成二维码 +- `GET /api/qr-login/status/{token}` - 检查状态 +- `POST /api/qr-login/scan/{token}` - 扫码标记 +- `POST /api/qr-login/confirm` - 确认登录 + +### 2. 查看控制台日志 + +前端会输出详细的调试信息: + +```javascript +// 开启调试模式 +localStorage.setItem('debug', 'qr-login'); +``` + +### 3. 后端日志 + +查看后端控制台输出: + +``` +生成扫码登录token: abc123def456 +用户 admin 确认扫码登录,token: abc123def456 +扫码登录token abc123def456 状态更新为已扫码 +``` + +## 🛠️ 常见问题 + +### 1. 二维码生成失败 + +**可能原因:** +- 后端服务未启动 +- Redis服务未启动 +- 网络连接问题 + +**解决方法:** +- 检查后端服务状态 +- 确认Redis连接正常 +- 查看控制台错误信息 + +### 2. 扫码后无响应 + +**可能原因:** +- 二维码已过期 +- 用户未登录 +- 网络请求失败 + +**解决方法:** +- 刷新二维码 +- 确认用户登录状态 +- 检查网络连接 + +### 3. 确认登录失败 + +**可能原因:** +- 用户ID不存在 +- 用户状态异常 +- JWT配置错误 + +**解决方法:** +- 检查用户数据 +- 确认用户状态正常 +- 验证JWT配置 + +## 📋 API接口清单 + +| 接口 | 方法 | 路径 | 说明 | +|------|------|------|------| +| 生成二维码 | POST | `/api/qr-login/generate` | 生成登录二维码 | +| 检查状态 | GET | `/api/qr-login/status/{token}` | 检查二维码状态 | +| 扫码标记 | POST | `/api/qr-login/scan/{token}` | 标记已扫码 | +| 确认登录 | POST | `/api/qr-login/confirm` | 确认登录 | +| 微信确认 | POST | `/api/qr-login/wechat-confirm` | 微信小程序确认 | + +## 🔐 安全特性 + +1. **时效控制**: 二维码5分钟自动过期 +2. **一次性使用**: 每个二维码只能使用一次 +3. **状态验证**: 严格的状态流转控制 +4. **JWT安全**: 使用JWT进行身份验证 +5. **Redis存储**: 使用Redis存储临时数据 + +## 📈 性能优化 + +1. **轮询间隔**: 前端每2秒检查一次状态 +2. **缓存策略**: Redis自动过期清理 +3. **并发控制**: 支持多用户同时使用 +4. **资源清理**: 及时清理过期数据 + +## 🎨 自定义配置 + +### 修改过期时间 + +在后端常量中修改: + +```java +// 默认5分钟 = 300秒 +private static final Long QR_LOGIN_TOKEN_TTL = 300L; +``` + +### 修改检查间隔 + +在前端组件中修改: + +```typescript +// 默认2秒检查一次 +}, 2000); +``` + +### 修改二维码样式 + +在前端组件中修改: + +```vue + +``` + +## 📞 技术支持 + +如果遇到问题,请: + +1. 查看控制台错误信息 +2. 检查网络请求状态 +3. 确认后端服务正常 +4. 查看本文档的常见问题部分 + +## 🔄 更新日志 + +### v1.0.0 (当前版本) +- ✅ 完成后端Java实现 +- ✅ 完成前端Vue适配 +- ✅ 提供完整测试工具 +- ✅ 支持Web端和移动端 +- ✅ 支持微信小程序登录 diff --git a/docs/qr-login-usage.md b/docs/qr-login-usage.md new file mode 100644 index 0000000..77b2dd7 --- /dev/null +++ b/docs/qr-login-usage.md @@ -0,0 +1,234 @@ +# 二维码登录功能使用说明 + +## 功能概述 + +二维码登录功能为用户提供了一种便捷的登录方式,用户可以通过手机APP或小程序扫描Web端生成的二维码来快速登录管理后台,无需输入用户名和密码。 + +## 功能特点 + +1. **便捷性**:无需输入账号密码,扫码即可登录 +2. **安全性**:二维码具有时效性,过期自动失效 +3. **实时性**:支持实时状态更新,用户体验流畅 +4. **跨平台**:支持APP和小程序扫码登录 + +## 使用流程 + +### Web端操作流程 + +1. **进入登录页面** + - 访问系统登录页面 + - 点击右上角的二维码图标切换到扫码登录模式 + +2. **生成二维码** + - 系统自动生成登录二维码 + - 二维码有效期为5分钟 + +3. **等待扫码** + - 使用手机APP或小程序扫描二维码 + - 系统实时检测扫码状态 + +4. **完成登录** + - 用户在手机端确认登录后,Web端自动完成登录 + - 跳转到系统首页 + +### 移动端操作流程 + +1. **扫描二维码** + - 打开手机APP或小程序 + - 使用扫码功能扫描Web端的二维码 + +2. **确认登录** + - 跳转到登录确认页面 + - 显示用户信息和设备信息 + - 点击"确认登录"按钮 + +3. **完成登录** + - 系统完成登录验证 + - Web端自动登录成功 + +## 组件使用 + +### 在登录页面中集成 + +```vue + + + +``` + +### 独立使用二维码组件 + +```vue + + + +``` + +## API接口 + +### 前端API调用 + +```typescript +import { + generateQrCode, + checkQrCodeStatus, + confirmQrLogin, + cancelQrLogin +} from '@/api/passport/qrLogin'; + +// 生成二维码 +const qrData = await generateQrCode(); + +// 检查状态 +const status = await checkQrCodeStatus(qrCodeKey); + +// 确认登录(移动端) +await confirmQrLogin(qrCodeKey, userToken); + +// 取消登录(移动端) +await cancelQrLogin(qrCodeKey); +``` + +## 状态说明 + +| 状态 | 说明 | 显示内容 | +|------|------|----------| +| loading | 正在生成二维码 | 加载动画 + "正在生成二维码..." | +| active | 二维码有效,等待扫码 | 二维码 + "请使用手机APP或小程序扫码登录" | +| scanned | 已扫码,等待确认 | 成功图标 + "扫码成功,请在手机上确认登录" | +| expired | 二维码已过期 | 过期图标 + "二维码已过期" + 刷新按钮 | +| error | 生成失败 | 错误图标 + 错误信息 + 重新生成按钮 | + +## 配置说明 + +### 二维码配置 + +```typescript +// 二维码大小 +const qrCodeSize = 200; // 像素 + +// 过期时间 +const expireTime = 300; // 5分钟 + +// 检查间隔 +const checkInterval = 2000; // 2秒 +``` + +### 样式自定义 + +```less +// 自定义二维码容器样式 +.qr-login-container { + padding: 20px; + text-align: center; + + .qr-code-wrapper { + min-height: 250px; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + } +} +``` + +## 安全注意事项 + +1. **二维码时效性** + - 二维码默认5分钟过期 + - 过期后需要重新生成 + +2. **一次性使用** + - 每个二维码只能使用一次 + - 登录成功或取消后立即失效 + +3. **用户验证** + - 移动端需要用户已登录状态 + - 验证用户身份后才能确认登录 + +4. **网络安全** + - 使用HTTPS协议传输 + - 敏感信息加密处理 + +## 故障排除 + +### 常见问题 + +1. **二维码生成失败** + - 检查网络连接 + - 确认后端API接口正常 + - 查看浏览器控制台错误信息 + +2. **扫码后无响应** + - 检查移动端网络连接 + - 确认二维码未过期 + - 检查用户登录状态 + +3. **登录确认失败** + - 检查用户权限 + - 确认token有效性 + - 查看后端日志 + +### 调试方法 + +1. **开启控制台调试** + ```javascript + // 在浏览器控制台查看详细日志 + localStorage.setItem('debug', 'qr-login'); + ``` + +2. **网络请求监控** + - 使用浏览器开发者工具监控网络请求 + - 检查API响应状态和数据 + +3. **状态跟踪** + - 观察二维码状态变化 + - 记录状态转换时间点 + +## 更新日志 + +### v1.0.0 +- 初始版本发布 +- 支持基本的二维码登录功能 +- 包含Web端和移动端完整流程 + +### 后续计划 +- 支持多设备同时登录 +- 添加登录设备管理 +- 优化用户体验和界面设计 diff --git a/src/api/passport/qrLogin/index.ts b/src/api/passport/qrLogin/index.ts new file mode 100644 index 0000000..8e307e5 --- /dev/null +++ b/src/api/passport/qrLogin/index.ts @@ -0,0 +1,109 @@ +import request from '@/utils/request'; +import type { ApiResult } from '@/api'; +import { SERVER_API_URL } from '@/config/setting'; + +/** + * 二维码生成响应数据 + */ +export interface QrCodeResponse { + token: string; // 二维码唯一标识token + qrCode: string; // 二维码内容 + expiresIn: number; // 过期时间(秒) +} + +/** + * 二维码状态响应 + */ +export interface QrCodeStatusResponse { + status: 'pending' | 'scanned' | 'confirmed' | 'expired'; + accessToken?: string; // 登录成功时返回的JWT token + userInfo?: any; // 用户信息 + expiresIn?: number; // 剩余过期时间(秒) +} + +/** + * 确认登录请求参数 + */ +export interface QrLoginConfirmRequest { + token: string; // 二维码token + userId?: number; // 用户ID + platform?: string; // 登录平台 +} + +/** + * 生成登录二维码 + */ +export async function generateQrCode(): Promise { + const res = await request.post>( + SERVER_API_URL + '/qr-login/generate', + {} + ); + + if (res.data.code === 0 && res.data.data) { + return res.data.data; + } + + return Promise.reject(new Error(res.data.message || '生成二维码失败')); +} + +/** + * 检查二维码状态 + */ +export async function checkQrCodeStatus(token: string): Promise { + const res = await request.get>( + SERVER_API_URL + `/qr-login/status/${token}` + ); + + if (res.data.code === 0 && res.data.data) { + return res.data.data; + } + + return Promise.reject(new Error(res.data.message || '检查二维码状态失败')); +} + +/** + * 扫码确认登录(移动端调用) + */ +export async function confirmQrLogin(requestData: QrLoginConfirmRequest): Promise { + const res = await request.post>( + SERVER_API_URL + '/qr-login/confirm', + requestData + ); + + if (res.data.code === 0 && res.data.data) { + return res.data.data; + } + + return Promise.reject(new Error(res.data.message || '确认登录失败')); +} + +/** + * 扫码标记(移动端扫码时调用) + */ +export async function scanQrCode(token: string): Promise { + const res = await request.post>( + SERVER_API_URL + `/qr-login/scan/${token}` + ); + + if (res.data.code === 0) { + return res.data.data || true; + } + + return Promise.reject(new Error(res.data.message || '扫码失败')); +} + +/** + * 微信小程序扫码登录确认 + */ +export async function wechatMiniProgramConfirm(requestData: QrLoginConfirmRequest): Promise { + const res = await request.post>( + SERVER_API_URL + '/qr-login/wechat-confirm', + requestData + ); + + if (res.data.code === 0 && res.data.data) { + return res.data.data; + } + + return Promise.reject(new Error(res.data.message || '微信小程序登录确认失败')); +} diff --git a/src/components/QrLogin/demo.vue b/src/components/QrLogin/demo.vue new file mode 100644 index 0000000..4127c52 --- /dev/null +++ b/src/components/QrLogin/demo.vue @@ -0,0 +1,258 @@ + + + + + diff --git a/src/components/QrLogin/index.vue b/src/components/QrLogin/index.vue new file mode 100644 index 0000000..e815414 --- /dev/null +++ b/src/components/QrLogin/index.vue @@ -0,0 +1,310 @@ + + + + + diff --git a/src/router/routes.ts b/src/router/routes.ts index 1b85804..c75678b 100644 --- a/src/router/routes.ts +++ b/src/router/routes.ts @@ -35,6 +35,21 @@ export const routes = [ component: () => import('@/views/passport/dealer/register.vue'), meta: { title: '邀请注册' } }, + { + path: '/qr-confirm', + component: () => import('@/views/passport/qrConfirm/index.vue'), + meta: { title: '扫码登录确认' } + }, + { + path: '/qr-demo', + component: () => import('@/components/QrLogin/demo.vue'), + meta: { title: '二维码登录演示' } + }, + { + path: '/qr-test', + component: () => import('@/views/test/qrLoginTest.vue'), + meta: { title: '二维码登录接口测试' } + }, // { // path: '/forget', // component: () => import('@/views/passport/forget/index.vue'), diff --git a/src/views/passport/login/index.vue b/src/views/passport/login/index.vue index a3e3916..1e14a05 100644 --- a/src/views/passport/login/index.vue +++ b/src/views/passport/login/index.vue @@ -182,7 +182,10 @@