# 微信小程序最终登录方案

## 方案说明

采用**自动静默登录**方案，用户打开小程序即自动完成登录，无需任何授权操作。

## 实现方式

### 1. 进入首页自动登录
- 用户打开小程序，进入首页
- 检查本地缓存，如果有登录信息，直接使用
- 如果没有缓存，自动调用 `wx.login` 获取 code
- 使用 code 调用后端 identify 接口完成登录
- 全程无需用户操作

### 2. 登录流程

```
用户打开小程序
  ↓
进入首页 (pages/index/index)
  ↓
检查缓存 (token, userInfo, wechatId)
  ↓
有缓存 → 直接使用
  ↓
无缓存 → 自动登录
  ↓
wx.login 获取 code
  ↓
调用 identify 接口
  ↓
保存登录信息
  ↓
完成登录
```

### 3. Token 过期处理

```
API 请求返回 401
  ↓
清除缓存
  ↓
提示"登录已过期，正在重新登录"
  ↓
刷新页面
  ↓
触发自动登录
```

### 4. 退出登录

```
点击"退出"按钮
  ↓
确认对话框
  ↓
清除登录信息
  ↓
调用 autoLogin() 重新登录
```

## 代码实现

### 首页 (pages/index/index.uvue)

```typescript
// 初始化用户信息
async function initUserInfo() {
  try {
    // 1. 先尝试从缓存获取
    const cachedWechatId = uni.getStorageSync('wechatId')
    const cachedUserInfo = uni.getStorageSync('userInfo')
    const cachedToken = uni.getStorageSync('token')
    
    if (cachedWechatId && cachedUserInfo && cachedToken) {
      // 有完整缓存，直接使用
      const parsedUserInfo = typeof cachedUserInfo === 'string' 
        ? JSON.parse(cachedUserInfo) 
        : cachedUserInfo
      
      userInfo.value = {
        wechatId: cachedWechatId,
        username: parsedUserInfo.username || parsedUserInfo.realName || '微信用户',
        phone: parsedUserInfo.phone || '',
        userId: parsedUserInfo.userId || ''
      }
      
      // 判断用户类型
      userType.value = parsedUserInfo.status !== 'guest'
      
      console.log('使用缓存的用户信息:', userInfo.value)
      return
    }

    // 2. 没有缓存，自动登录
    await autoLogin()
  } catch (error) {
    console.error('初始化用户信息失败:', error)
    await autoLogin()
  }
}

// 自动登录
async function autoLogin() {
  uni.showLoading({ title: '登录中...' })
  
  try {
    uni.login({
      provider: 'weixin',
      success: async (loginRes) => {
        console.log('微信登录成功，code:', loginRes.code)
        
        const code = loginRes.code
        const wechatId = code.substring(0, 20) // 使用部分code作为临时ID
        
        // 调用 identify 接口
        const identifyRes = await guestAPI.identify({
          wechatId: wechatId,
          phone: ''
        })
        
        uni.hideLoading()
        
        if (identifyRes.success && identifyRes.data) {
          const loginDomain = identifyRes.data
          
          // 保存登录信息
          uni.setStorageSync('token', loginDomain.token || '')
          uni.setStorageSync('userInfo', JSON.stringify(loginDomain.user))
          uni.setStorageSync('loginDomain', JSON.stringify(loginDomain))
          uni.setStorageSync('wechatId', wechatId)
          
          // 更新用户信息
          userInfo.value = {
            wechatId: wechatId,
            username: loginDomain.user?.username || loginDomain.user?.realName || '微信用户',
            phone: loginDomain.user?.phone || '',
            userId: loginDomain.user?.userId || ''
          }
          
          // 判断用户类型
          userType.value = loginDomain.user?.status !== 'guest'
          
          console.log('自动登录成功:', userInfo.value)
        } else {
          uni.showToast({
            title: identifyRes.message || '登录失败',
            icon: 'none'
          })
        }
      },
      fail: (err) => {
        console.error('微信登录失败:', err)
        uni.hideLoading()
        uni.showToast({ title: '登录失败，请重试', icon: 'none' })
      }
    })
  } catch (error: any) {
    console.error('自动登录失败:', error)
    uni.hideLoading()
    uni.showToast({
      title: error.message || '登录失败',
      icon: 'none'
    })
  }
}
```

## 优势

### 1. 用户体验极佳
- ✅ 无需任何授权操作
- ✅ 打开即用
- ✅ 无感知登录
- ✅ 无弹窗干扰

### 2. 无权限要求
- ✅ 不需要企业认证
- ✅ 不需要开通手机号快速验证
- ✅ 个人小程序也可使用
- ✅ 测试环境友好

### 3. 代码简洁
- ✅ 删除了授权页面
- ✅ 删除了切换用户功能
- ✅ 删除了所有 mock 相关代码
- ✅ 只保留核心登录逻辑

### 4. 维护方便
- ✅ 登录逻辑集中在首页
- ✅ Token 过期自动处理
- ✅ 错误处理完善
- ✅ 日志清晰

## 后端要求

### identify 接口

```typescript
POST /urban-lifeline/system/guest/identify
{
  "wechatId": "微信ID（使用code的前20位作为临时标识）",
  "phone": ""  // 可以为空
}

返回：
{
  "success": true,
  "data": {
    "token": "jwt_token",
    "user": {
      "userId": "用户ID",
      "username": "用户名",
      "realName": "真实姓名",
      "phone": "手机号（可能为空）",
      "status": "guest" | "employee"
    }
  }
}
```

### 建议优化

1. **后端可以通过 code 换取 openid**
   - 前端传递完整的 code
   - 后端调用微信 API 换取 openid
   - 使用 openid 作为用户唯一标识

2. **支持游客模式**
   - 如果 wechatId 不存在，创建游客账号
   - 返回游客身份的 token
   - 允许后续绑定手机号升级为正式用户

## 已删除的内容

### 1. 授权页面
- ❌ `pages/auth/auth.uvue` - 已删除
- ❌ pages.json 中的 auth 路由配置 - 已删除

### 2. 切换用户功能
- ❌ `switchMockUser()` 函数 - 已删除
- ❌ `isMockMode` 变量 - 已删除
- ❌ 切换按钮 UI - 已删除
- ❌ 所有条件编译代码 - 已删除

### 3. getUserProfile
- ❌ 不再使用 `getUserProfile` API
- ❌ 不再需要用户授权昵称

### 4. getPhoneNumber
- ❌ 不再使用 `getPhoneNumber` API
- ❌ 不再需要手机号授权

## 保留的功能

### 1. 退出登录
- ✅ 右上角"退出"按钮
- ✅ 点击后清除缓存并重新自动登录
- ✅ 红色主题，易于识别

### 2. Token 管理
- ✅ 自动检测 401 错误
- ✅ 自动清除过期信息
- ✅ 自动重新登录

### 3. 用户类型识别
- ✅ 区分 guest 和 employee
- ✅ 根据类型控制功能权限

## 测试清单

### 首次使用
- [ ] 打开小程序，自动登录成功
- [ ] 无任何授权弹窗
- [ ] 用户信息正确显示
- [ ] 可以正常使用所有功能

### 再次使用
- [ ] 关闭小程序重新打开
- [ ] 直接进入首页，无需重新登录
- [ ] 用户信息保持不变

### Token 过期
- [ ] 模拟 Token 过期（后端返回 401）
- [ ] 自动提示"登录已过期，正在重新登录"
- [ ] 自动完成重新登录
- [ ] 功能恢复正常

### 退出登录
- [ ] 点击"退出"按钮
- [ ] 显示确认对话框
- [ ] 确认后自动重新登录
- [ ] 登录成功后可正常使用

### API 请求
- [ ] 所有 API 请求携带正确的 token
- [ ] 请求路径正确（/urban-lifeline/）
- [ ] WebSocket 连接正常
- [ ] 文件上传功能正常

## 部署说明

### 1. 编译
```bash
npm run build:mp-weixin
```

### 2. 上传
- 使用微信开发者工具打开 `unpackage/dist/build/mp-weixin`
- 点击"上传"按钮
- 填写版本号和备注

### 3. 提交审核
- 登录微信公众平台
- 进入"版本管理"
- 提交审核

### 4. 发布
- 审核通过后，点击"发布"
- 用户即可使用

## 总结

当前方案是最简洁、最友好的登录方案：
- ✅ 无需任何用户操作
- ✅ 无需小程序认证
- ✅ 代码简洁易维护
- ✅ 用户体验极佳
- ✅ 适用于所有场景

可以直接部署使用！
