# 微信小程序最终登录方案 ## 方案说明 采用**自动静默登录**方案,用户打开小程序即自动完成登录,无需任何授权操作。 ## 实现方式 ### 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. 发布 - 审核通过后,点击"发布" - 用户即可使用 ## 总结 当前方案是最简洁、最友好的登录方案: - ✅ 无需任何用户操作 - ✅ 无需小程序认证 - ✅ 代码简洁易维护 - ✅ 用户体验极佳 - ✅ 适用于所有场景 可以直接部署使用!