Files
mp-10550/docs/QR_LOGIN_USAGE.md
赵忠林 e47e34825a ```
feat(passport): 实现统一扫码功能并迁移二维码登录页面

将原有的扫码登录和扫码核销功能合并为统一扫码功能,支持智能识别二维码类型,
自动执行相应操作。同时将二维码登录相关页面迁移到 /passport 路径下,优化用户体验与代码结构。

主要变更:
- 新增统一扫码 Hook (useUnifiedQRScan) 和按钮组件 (UnifiedQRButton)- 新增统一扫码页面 /passport/unified-qr/index
- 迁移二维码登录页面路径:/pages/qr-login → /passport/qr-login
- 更新管理员面板及用户卡片中的扫码入口为统一扫码- 移除旧的 QRLoginDemo 和 qr-test 测试页面- 补充统一扫码使用指南文档```
2025-09-22 15:44:44 +08:00

285 lines
6.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 微信小程序扫码登录使用指南
## 概述
本项目已完整实现微信小程序扫码登录功能,支持用户通过小程序扫描网页端二维码快速登录。
## 功能特性
-**多种集成方式** - 按钮组件、弹窗组件、专门页面
-**自动解析二维码** - 支持多种二维码格式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: '/passport/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: [
// ... 其他页面
'passport/qr-login/index', // 扫码登录页面
'passport/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 | - | 失败回调 |