forked from gxwebsoft/mp-10550
feat(qr-login): 实现扫码登录功能模块
This commit is contained in:
284
docs/QR_LOGIN_USAGE.md
Normal file
284
docs/QR_LOGIN_USAGE.md
Normal file
@@ -0,0 +1,284 @@
|
||||
# 微信小程序扫码登录使用指南
|
||||
|
||||
## 概述
|
||||
|
||||
本项目已完整实现微信小程序扫码登录功能,支持用户通过小程序扫描网页端二维码快速登录。
|
||||
|
||||
## 功能特性
|
||||
|
||||
- ✅ **多种集成方式** - 按钮组件、弹窗组件、专门页面
|
||||
- ✅ **自动解析二维码** - 支持多种二维码格式(URL、JSON、纯token)
|
||||
- ✅ **安全可靠** - Token有效期控制,防重复使用
|
||||
- ✅ **用户体验好** - 实时状态反馈,错误处理完善
|
||||
- ✅ **微信集成** - 自动获取微信用户信息
|
||||
|
||||
## 后端接口
|
||||
|
||||
### 1. 生成扫码token
|
||||
```http
|
||||
POST /api/qr-login/generate
|
||||
```
|
||||
|
||||
### 2. 检查登录状态
|
||||
```http
|
||||
GET /api/qr-login/status/{token}
|
||||
```
|
||||
|
||||
### 3. 确认登录
|
||||
```http
|
||||
POST /api/qr-login/confirm
|
||||
```
|
||||
|
||||
### 4. 扫码操作(可选)
|
||||
```http
|
||||
POST /api/qr-login/scan/{token}
|
||||
```
|
||||
|
||||
## 前端使用方式
|
||||
|
||||
### 方式1: 直接扫码按钮
|
||||
|
||||
最简单的使用方式,点击按钮直接调用扫码API:
|
||||
|
||||
```tsx
|
||||
import QRLoginButton from '@/components/QRLoginButton';
|
||||
|
||||
// 基础使用
|
||||
<QRLoginButton />
|
||||
|
||||
// 自定义配置
|
||||
<QRLoginButton
|
||||
text="扫码登录"
|
||||
type="primary"
|
||||
size="large"
|
||||
onSuccess={(result) => console.log('登录成功', result)}
|
||||
onError={(error) => console.log('登录失败', error)}
|
||||
/>
|
||||
```
|
||||
|
||||
### 方式2: 弹窗扫码
|
||||
|
||||
在当前页面弹出扫码弹窗:
|
||||
|
||||
```tsx
|
||||
import { useState } from 'react';
|
||||
import QRScanModal from '@/components/QRScanModal';
|
||||
|
||||
const MyComponent = () => {
|
||||
const [showScan, setShowScan] = useState(false);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Button onClick={() => setShowScan(true)}>
|
||||
扫码登录
|
||||
</Button>
|
||||
|
||||
<QRScanModal
|
||||
visible={showScan}
|
||||
onClose={() => setShowScan(false)}
|
||||
onSuccess={(result) => {
|
||||
console.log('登录成功', result);
|
||||
setShowScan(false);
|
||||
}}
|
||||
onError={(error) => {
|
||||
console.log('登录失败', error);
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
### 方式3: 跳转到专门页面
|
||||
|
||||
跳转到专门的扫码登录页面:
|
||||
|
||||
```tsx
|
||||
import QRLoginButton from '@/components/QRLoginButton';
|
||||
|
||||
// 使用页面模式
|
||||
<QRLoginButton
|
||||
text="进入扫码页面"
|
||||
usePageMode={true}
|
||||
/>
|
||||
|
||||
// 或者自定义跳转
|
||||
<Button onClick={() => {
|
||||
Taro.navigateTo({
|
||||
url: '/pages/qr-login/index'
|
||||
});
|
||||
}}>
|
||||
扫码登录
|
||||
</Button>
|
||||
```
|
||||
|
||||
### 方式4: 使用Hook
|
||||
|
||||
直接使用Hook进行更灵活的控制:
|
||||
|
||||
```tsx
|
||||
import { useQRLogin } from '@/hooks/useQRLogin';
|
||||
|
||||
const MyComponent = () => {
|
||||
const {
|
||||
startScan,
|
||||
isLoading,
|
||||
isSuccess,
|
||||
isError,
|
||||
error,
|
||||
result,
|
||||
canScan
|
||||
} = useQRLogin();
|
||||
|
||||
return (
|
||||
<Button
|
||||
loading={isLoading}
|
||||
disabled={!canScan()}
|
||||
onClick={startScan}
|
||||
>
|
||||
{isLoading ? '扫码中...' : '扫码登录'}
|
||||
</Button>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
## 二维码格式支持
|
||||
|
||||
系统支持多种二维码格式:
|
||||
|
||||
### 1. URL格式
|
||||
```
|
||||
https://mp.websoft.top/qr-confirm?qrCodeKey=02278c578d3e4aad87dece6aab2f0296
|
||||
https://example.com/login?token=abc123
|
||||
```
|
||||
|
||||
### 2. JSON格式
|
||||
```json
|
||||
{
|
||||
"token": "02278c578d3e4aad87dece6aab2f0296",
|
||||
"type": "qr-login"
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 简单格式
|
||||
```
|
||||
qr-login:02278c578d3e4aad87dece6aab2f0296
|
||||
02278c578d3e4aad87dece6aab2f0296
|
||||
```
|
||||
|
||||
## 页面配置
|
||||
|
||||
确保在 `app.config.ts` 中添加了相关页面:
|
||||
|
||||
```typescript
|
||||
export default {
|
||||
pages: [
|
||||
// ... 其他页面
|
||||
'pages/qr-login/index', // 扫码登录页面
|
||||
'pages/qr-confirm/index', // 登录确认页面
|
||||
],
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
## 使用示例
|
||||
|
||||
### 完整示例组件
|
||||
|
||||
```tsx
|
||||
import React, { useState } from 'react';
|
||||
import { View } from '@tarojs/components';
|
||||
import { Button } from '@nutui/nutui-react-taro';
|
||||
import QRLoginButton from '@/components/QRLoginButton';
|
||||
import QRScanModal from '@/components/QRScanModal';
|
||||
|
||||
const LoginPage = () => {
|
||||
const [showModal, setShowModal] = useState(false);
|
||||
|
||||
const handleSuccess = (result) => {
|
||||
console.log('登录成功:', result);
|
||||
// 处理登录成功逻辑
|
||||
};
|
||||
|
||||
const handleError = (error) => {
|
||||
console.error('登录失败:', error);
|
||||
// 处理登录失败逻辑
|
||||
};
|
||||
|
||||
return (
|
||||
<View className="p-4">
|
||||
{/* 方式1: 直接扫码 */}
|
||||
<QRLoginButton
|
||||
text="扫码登录"
|
||||
onSuccess={handleSuccess}
|
||||
onError={handleError}
|
||||
/>
|
||||
|
||||
{/* 方式2: 弹窗扫码 */}
|
||||
<Button onClick={() => setShowModal(true)}>
|
||||
弹窗扫码
|
||||
</Button>
|
||||
|
||||
{/* 方式3: 跳转页面 */}
|
||||
<QRLoginButton
|
||||
text="进入扫码页面"
|
||||
usePageMode={true}
|
||||
/>
|
||||
|
||||
<QRScanModal
|
||||
visible={showModal}
|
||||
onClose={() => setShowModal(false)}
|
||||
onSuccess={handleSuccess}
|
||||
onError={handleError}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **用户登录状态**: 使用扫码登录功能前,用户必须已在小程序中登录
|
||||
2. **权限申请**: 确保小程序已申请摄像头权限
|
||||
3. **网络环境**: 确保网络连接正常,API接口可访问
|
||||
4. **二维码有效期**: 二维码有5分钟有效期,过期需重新生成
|
||||
5. **安全性**: 只扫描来自官方网站的登录二维码
|
||||
|
||||
## 错误处理
|
||||
|
||||
常见错误及解决方案:
|
||||
|
||||
- `请先登录小程序`: 用户未登录,需要先完成小程序登录
|
||||
- `无效的登录二维码`: 二维码格式不正确或已过期
|
||||
- `登录确认失败`: 网络问题或服务器错误,可重试
|
||||
- `扫码失败`: 摄像头权限问题或二维码不清晰
|
||||
|
||||
## API接口详情
|
||||
|
||||
详细的API接口文档请参考:`src/api/qr-login/index.ts`
|
||||
|
||||
## 组件API
|
||||
|
||||
### QRLoginButton Props
|
||||
|
||||
| 属性 | 类型 | 默认值 | 说明 |
|
||||
|------|------|--------|------|
|
||||
| type | string | 'primary' | 按钮类型 |
|
||||
| size | string | 'normal' | 按钮大小 |
|
||||
| text | string | '扫码登录' | 按钮文本 |
|
||||
| showIcon | boolean | true | 是否显示图标 |
|
||||
| usePageMode | boolean | false | 是否使用页面模式 |
|
||||
| onSuccess | function | - | 成功回调 |
|
||||
| onError | function | - | 失败回调 |
|
||||
|
||||
### QRScanModal Props
|
||||
|
||||
| 属性 | 类型 | 默认值 | 说明 |
|
||||
|------|------|--------|------|
|
||||
| visible | boolean | false | 是否显示弹窗 |
|
||||
| title | string | '扫描登录二维码' | 弹窗标题 |
|
||||
| description | string | '扫描网页端显示的登录二维码' | 描述文本 |
|
||||
| autoConfirm | boolean | true | 是否自动确认登录 |
|
||||
| onClose | function | - | 关闭回调 |
|
||||
| onSuccess | function | - | 成功回调 |
|
||||
| onError | function | - | 失败回调 |
|
||||
Reference in New Issue
Block a user