login-modal.vue
2.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
<script lang="ts" setup>
import {Base64} from "js-base64";
import {v4 as uuid4} from "uuid";
import {useEventSource, useLocalStorage} from "@vueuse/core";
import {computed, ref, StyleValue, watch} from 'vue'
import {set} from 'lodash-es'
import vueQr from "vue-qr/src/packages/vue-qr.vue"
defineProps<{ logo?: string }>()
const visible = useLocalStorage('token', '', {})
const bodyStyle: StyleValue = {textAlign: 'center', display: 'flex', flexDirection: 'column', alignItems: 'center'}
const loginCode = ref<string>('')
const loginEvent = ref<any>()
const loginEncryptCode = computed((): string =>
Base64.encode(JSON.stringify({type: 'loginCode', data: loginCode.value})))
const onRefresh = () => {
loginEvent.value?.close()
loginCode.value = uuid4();
loginEvent.value = useEventSource('/app/subscribeLogin?code=' + loginCode.value, ['message'])
set(loginEvent.value, 'eventSource.onmessage', (event: any) => {
if (event.data) {
visible.value = event.data
localStorage.setItem('token', event.data)
loginEvent.value?.close();
}
})
}
watch(visible, (value) => !value && onRefresh(), {immediate: true})
</script>
<template>
<a-modal :visible="!visible" hide-title
:footer="false" :esc-to-close="false" :closable="false" :mask-closable="false"
:body-style="bodyStyle" @before-open="onRefresh"
>
<div style="color: #666666;font-size: 15px;font-weight: 600">用户授权</div>
<div style="color: #666666;font-size: 14px;padding: 10px">
请通过【泡泡留声】App或者小程序,扫描页右上角扫码
<icon-scan/>
授权
</div>
<vue-qr :size="180" :margin="5" :correct-level="3" :text="loginCode?loginEncryptCode:''"
:logo-margin="3" :logo-scale="0.2" :logoSrc="logo"
/>
<icon-refresh class="refresh" :size="18" @click="onRefresh"/>
</a-modal>
</template>
<style scoped>
.refresh {
color: #666666;
margin-top: 4px;
&:hover {
cursor: pointer;
}
}
</style>