如何在Laravel Inertia中监听Baileys API扫码登录状态并切换图片
问题:集成Baileys Rest API到Laravel Inertia后,如何监听会话状态并切换二维码为勾选图标
我正在把Baileys Rest API集成到Laravel Inertia项目中,功能基本正常,但遇到一个问题:用户扫码成功登录后,如何自动监听会话状态,把显示的二维码图片切换成勾选图标?
我尝试用watch监听状态但没效果,就算去掉布尔值检查,在二维码可扫描时也无法触发状态检查。
Device.vue
<template> <AuthenticatedLayout> <div class="m-5 p-5"> <div class="m-5"> <img v-if="qrCode" :src="qrCode" alt="QR Code" /> </div> <button class="btn btn-success" @click="scan(id)">Button</button> <button class="btn btn-error" @click="logout()">logout</button> </div> </AuthenticatedLayout> </template> <script> import AuthenticatedLayout from "@/Layouts/AuthenticatedLayout.vue"; import { ref, onMounted, onUpdated } from "vue"; import QRCode from "qrcode"; import axios from "axios"; export default { components: { AuthenticatedLayout, }, setup() { const qrCode = ref(null); let statusResponse = ref(""); const id = "TheId"; const deviceName = "TheId"; const status = ref(""); const reloadPage = ref(""); let intervalId = null; return { qrCode, statusResponse, id, deviceName, status, reloadPage, intervalId, }; }, watch: { id: { immediate: true, handler(newId) { const scan = this.scan(newId); if (scan) { this.check(newId); } }, }, }, beforeUnmount() { if (this.intervalId) { clearInterval(this.intervalId); } }, methods: { async check(id) { setInterval(async () => { await axios.get( `http://localhost:3000/sessions/${this.deviceName}` ); }, 2000); }, async scan(id) { // console.log("here"); try { //check if session is exists const statusResponse = await axios.get( `http://localhost:3000/sessions/${this.deviceName}/status` ); console.log(statusResponse.data.status); } catch (error) { // this.intervalId = true; console.log(error.response.data.error == "Session not found"); if (error.response.data.error == "Session not found") { // console.log("here"); try { try { const res = await axios.post( `http://localhost:3000/sessions/add`, { sessionId: this.deviceName } ); this.qrCode = res.data.qr; //If QR code Valid or scanned and login return true; } catch (error) { console.error("Error:", error); } } catch (error) { console.log("Error : ", error); } } } }, async logout() { const response = await fetch( `http://localhost:3000/sessions/${this.deviceName}`, { method: "DELETE", headers: { "Content-Type": "application/json", }, } ); location.reload(); }, }, }; </script> <style lang="scss" scoped></style>
解决方案
1. 修复状态检查逻辑,更新本地状态
你的check方法没有处理接口返回值,也没更新本地状态变量,导致视图无法感知会话变化。修改check方法:
async check(id) { // 清除旧定时器,避免重复执行 if (this.intervalId) clearInterval(this.intervalId); this.intervalId = setInterval(async () => { try { const response = await axios.get(`http://localhost:3000/sessions/${this.deviceName}/status`); this.status = response.data.status; // 会话连接成功时,清除定时器并隐藏二维码 if (this.status === 'connected') { clearInterval(this.intervalId); this.qrCode = null; } } catch (error) { console.error('检查会话状态失败:', error); } }, 2000); }
2. 调整视图,根据状态切换显示
修改模板,新增勾选图标,根据会话状态切换显示内容:
<template> <AuthenticatedLayout> <div class="m-5 p-5"> <div class="m-5"> <!-- 未连接时显示二维码 --> <img v-if="qrCode && status !== 'connected'" :src="qrCode" alt="QR Code" /> <!-- 连接成功时显示勾选图标 --> <div v-else-if="status === 'connected'" class="text-green-500 text-4xl"> ✅ </div> </div> <button class="btn btn-success" @click="scan(id)">获取二维码</button> <button class="btn btn-error" @click="logout()">退出登录</button> </div> </AuthenticatedLayout> </template>
3. 修复scan方法的异步逻辑问题
scan是异步函数,不能直接用if(scan)判断返回值,调整后在创建会话后直接启动状态检查:
async scan(id) { try { const statusResponse = await axios.get(`http://localhost:3000/sessions/${this.deviceName}/status`); this.status = statusResponse.data.status; // 已经连接则直接隐藏二维码 if (this.status === 'connected') { this.qrCode = null; return; } } catch (error) { if (error.response?.data?.error === "Session not found") { try { const res = await axios.post(`http://localhost:3000/sessions/add`, { sessionId: this.deviceName }); this.qrCode = res.data.qr; // 创建会话后立即启动状态监听 this.check(id); } catch (err) { console.error('创建会话失败:', err); } } } }
4. 保留定时器清理逻辑
保持beforeUnmount中的代码,确保组件销毁时停止状态检查,避免内存泄漏:
beforeUnmount() { if (this.intervalId) { clearInterval(this.intervalId); } }
关键注意点
- 确认Baileys API的
/sessions/{sessionId}/status接口返回的登录成功状态值为connected,如果接口返回的状态字段或值不同,需要对应调整判断条件。 - 勾选图标可以替换为项目UI规范中的图标组件,不一定用emoji。
内容的提问来源于stack exchange,提问作者Rafly Andrian
相关产品推荐
相关产品推荐

