feat: implement QR code generation for WechatClawBot status display

This commit is contained in:
jxxghp
2026-05-10 22:10:30 +08:00
parent 30bf895ae1
commit 310a501380
@@ -4,6 +4,7 @@ import { NotificationConf } from '@/api/types'
import { getLogoUrl } from '@/utils/imageUtils' import { getLogoUrl } from '@/utils/imageUtils'
import { useToast } from 'vue-toastification' import { useToast } from 'vue-toastification'
import { cloneDeep } from 'lodash-es' import { cloneDeep } from 'lodash-es'
import QRCode from 'qrcode'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { useDisplay } from 'vuetify' import { useDisplay } from 'vuetify'
@@ -115,8 +116,57 @@ function ensureWechatClawBotConfigDefaults(notification: NotificationConf) {
const wechatClawBotLoading = ref(false) const wechatClawBotLoading = ref(false)
const wechatClawBotActionLoading = ref(false) const wechatClawBotActionLoading = ref(false)
const wechatClawBotStatus = ref<WechatClawBotStatus | null>(null) const wechatClawBotStatus = ref<WechatClawBotStatus | null>(null)
const wechatClawBotQrImage = ref('')
let wechatClawBotTimer: number | null = null let wechatClawBotTimer: number | null = null
function isImageSource(value?: string | null) {
if (!value) {
return false
}
const raw = value.trim()
if (!raw) {
return false
}
if (raw.toLowerCase().startsWith('data:image/')) {
return true
}
return /\.(png|jpe?g|gif|webp|svg)(\?|$)/i.test(raw)
}
function getWechatClawBotQrText(status?: WechatClawBotStatus | null) {
const directUrl = status?.qrcode_url?.trim()
if (directUrl) {
return directUrl
}
const qrcode = status?.qrcode?.trim()
if (!qrcode) {
return ''
}
return `https://liteapp.weixin.qq.com/q/7GiQu1?qrcode=${encodeURIComponent(qrcode)}&bot_type=3`
}
async function updateWechatClawBotQrImage(status?: WechatClawBotStatus | null) {
const directUrl = status?.qrcode_url?.trim()
if (isImageSource(directUrl)) {
wechatClawBotQrImage.value = directUrl || ''
return
}
const qrText = getWechatClawBotQrText(status)
if (!qrText) {
wechatClawBotQrImage.value = ''
return
}
try {
wechatClawBotQrImage.value = await QRCode.toDataURL(qrText, {
width: 220,
margin: 1,
})
} catch (error) {
console.error(error)
wechatClawBotQrImage.value = ''
}
}
function getWechatClawBotRequestParams(extraParams: Record<string, any> = {}) { function getWechatClawBotRequestParams(extraParams: Record<string, any> = {}) {
const config = notificationInfo.value.config || {} const config = notificationInfo.value.config || {}
return { return {
@@ -206,9 +256,11 @@ async function fetchWechatClawBotStatus(autoGenerateQrcode = false) {
}) })
if (result.success) { if (result.success) {
wechatClawBotStatus.value = result.data wechatClawBotStatus.value = result.data
await updateWechatClawBotQrImage(result.data)
scheduleWechatClawBotRefresh() scheduleWechatClawBotRefresh()
} else { } else {
wechatClawBotStatus.value = null wechatClawBotStatus.value = null
wechatClawBotQrImage.value = ''
clearWechatClawBotTimer() clearWechatClawBotTimer()
$toast.error(result.message || t('notification.wechatclawbot.statusLoadFailed')) $toast.error(result.message || t('notification.wechatclawbot.statusLoadFailed'))
} }
@@ -232,6 +284,7 @@ async function refreshWechatClawBotQrcode() {
}) })
if (result.success) { if (result.success) {
wechatClawBotStatus.value = result.data wechatClawBotStatus.value = result.data
await updateWechatClawBotQrImage(result.data)
scheduleWechatClawBotRefresh() scheduleWechatClawBotRefresh()
$toast.success(t('notification.wechatclawbot.qrcodeRefreshSuccess')) $toast.success(t('notification.wechatclawbot.qrcodeRefreshSuccess'))
} else { } else {
@@ -327,6 +380,7 @@ function onClose() {
watch(notificationInfoDialog, value => { watch(notificationInfoDialog, value => {
if (!value) { if (!value) {
clearWechatClawBotTimer() clearWechatClawBotTimer()
wechatClawBotQrImage.value = ''
} }
}) })
</script> </script>
@@ -617,8 +671,8 @@ watch(notificationInfoDialog, value => {
<VCol cols="12" md="5"> <VCol cols="12" md="5">
<div class="rounded text-center p-3 border h-100 d-flex align-center justify-center min-h-[16rem]"> <div class="rounded text-center p-3 border h-100 d-flex align-center justify-center min-h-[16rem]">
<VImg <VImg
v-if="wechatClawBotStatus?.qrcode_url" v-if="wechatClawBotQrImage"
:src="wechatClawBotStatus.qrcode_url" :src="wechatClawBotQrImage"
width="220" width="220"
height="220" height="220"
class="mx-auto" class="mx-auto"