# 微信小程序扫码登录使用指南

## 概述

本项目已完整实现微信小程序扫码登录功能，支持用户通过小程序扫描网页端二维码快速登录。

## 功能特性

- ✅ **多种集成方式** - 按钮组件、弹窗组件、专门页面
- ✅ **自动解析二维码** - 支持多种二维码格式（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 | - | 失败回调 |
