You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 18:33:13