mirror of
https://github.com/1Panel-dev/MaxKB.git
synced 2025-12-26 01:33:05 +00:00
feat: enhance WeCom QR code login with iframe creation and improved language handling
This commit is contained in:
parent
5329b44e08
commit
1ede617e06
|
|
@ -3,85 +3,126 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import * as ww from '@wecom/jssdk'
|
||||
import {
|
||||
WWLoginLangType,
|
||||
WWLoginPanelSizeType,
|
||||
WWLoginRedirectType,
|
||||
WWLoginType,
|
||||
} from '@wecom/jssdk'
|
||||
import { ref, nextTick } from 'vue'
|
||||
import { MsgError } from '@/utils/message'
|
||||
import {nextTick, defineProps, onBeforeUnmount} from 'vue'
|
||||
import {useRoute, useRouter} from 'vue-router'
|
||||
import {getBrowserLang} from '@/locales'
|
||||
import useStore from '@/stores'
|
||||
import { getBrowserLang } from '@/locales'
|
||||
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
const {
|
||||
params: { accessToken },
|
||||
} = route as any
|
||||
const wwLogin = ref({})
|
||||
const obj = ref<any>({ isWeComLogin: false })
|
||||
const { chatUser } = useStore()
|
||||
|
||||
const WE_COM_ORIGIN = 'https://login.work.weixin.qq.com'
|
||||
const LOGIN_SUCCESS_EVENT = 'onLoginSuccess'
|
||||
const LOGIN_STATE = 'fit2cloud-wecom-qr'
|
||||
const props = defineProps<{
|
||||
config: {
|
||||
callback_url: string
|
||||
app_secret: string
|
||||
app_key: string
|
||||
corp_id?: string
|
||||
agent_id?: string
|
||||
callback_url: string
|
||||
}
|
||||
}>()
|
||||
|
||||
const init = async () => {
|
||||
await nextTick() // 确保DOM已更新
|
||||
const data = {
|
||||
corpId: props.config.corp_id,
|
||||
agentId: props.config.agent_id,
|
||||
}
|
||||
const lang = localStorage.getItem('MaxKB-locale') || getBrowserLang() || 'en-US'
|
||||
const redirectUri = props.config.callback_url
|
||||
try {
|
||||
wwLogin.value = ww.createWWLoginPanel({
|
||||
el: '#wecom-qr',
|
||||
params: {
|
||||
login_type: WWLoginType.corpApp,
|
||||
appid: data.corpId || '',
|
||||
agentid: data.agentId,
|
||||
redirect_uri: redirectUri,
|
||||
state: 'fit2cloud-wecom-qr',
|
||||
lang: lang === 'zh-CN' || lang === 'zh-Hant' ? WWLoginLangType.zh : WWLoginLangType.en,
|
||||
redirect_type: WWLoginRedirectType.callback,
|
||||
panel_size: WWLoginPanelSizeType.small,
|
||||
},
|
||||
onCheckWeComLogin: obj.value,
|
||||
async onLoginSuccess({ code }: any) {
|
||||
chatUser.wecomCallback(code, accessToken).then(() => {
|
||||
setTimeout(() => {
|
||||
router.push({
|
||||
name: 'chat',
|
||||
params: { accessToken: accessToken },
|
||||
query: route.query,
|
||||
})
|
||||
})
|
||||
})
|
||||
},
|
||||
onLoginFail(err) {
|
||||
MsgError(`${err.errMsg}`)
|
||||
},
|
||||
})
|
||||
} catch (error) {}
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
const {chatUser} = useStore()
|
||||
|
||||
const {
|
||||
params: {accessToken},
|
||||
} = route as any
|
||||
|
||||
let iframe: HTMLIFrameElement | null = null
|
||||
|
||||
function createTransparentIFrame(el: string) {
|
||||
const container = document.querySelector(el)
|
||||
if (!container) return null
|
||||
|
||||
const iframeEl = document.createElement('iframe')
|
||||
iframeEl.style.cssText = `
|
||||
display: block;
|
||||
border: none;
|
||||
background: transparent;
|
||||
`
|
||||
iframeEl.referrerPolicy = 'origin'
|
||||
iframeEl.setAttribute('frameborder', '0')
|
||||
iframeEl.setAttribute('allowtransparency', 'true')
|
||||
|
||||
container.appendChild(iframeEl)
|
||||
return iframeEl
|
||||
}
|
||||
|
||||
function getLang() {
|
||||
const lang = localStorage.getItem('MaxKB-locale') || getBrowserLang()
|
||||
return lang === 'en-US' ? 'en' : 'zh'
|
||||
}
|
||||
|
||||
function safeParse(data: unknown) {
|
||||
try {
|
||||
return typeof data === 'string' ? JSON.parse(data) : data
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
async function handleLoginSuccess(code: string) {
|
||||
await chatUser.wecomCallback(code, accessToken)
|
||||
|
||||
router.push({
|
||||
name: 'chat',
|
||||
params: {accessToken},
|
||||
query: route.query,
|
||||
})
|
||||
}
|
||||
|
||||
function handleWindowMessage(event: MessageEvent) {
|
||||
if (event.origin !== WE_COM_ORIGIN) return
|
||||
|
||||
const payload: any = safeParse(event.data)
|
||||
if (!payload?.args) return
|
||||
|
||||
if (payload.args.name === LOGIN_SUCCESS_EVENT) {
|
||||
const code = payload.args?.data?.code
|
||||
if (!code) return
|
||||
|
||||
handleLoginSuccess(code)
|
||||
cleanup()
|
||||
}
|
||||
}
|
||||
|
||||
function cleanup() {
|
||||
window.removeEventListener('message', handleWindowMessage)
|
||||
iframe?.remove()
|
||||
iframe = null
|
||||
}
|
||||
|
||||
const init = async () => {
|
||||
await nextTick()
|
||||
|
||||
iframe = createTransparentIFrame('#wecom-qr')
|
||||
if (!iframe) return
|
||||
|
||||
const redirectUri = encodeURIComponent(props.config.callback_url)
|
||||
|
||||
iframe.src =
|
||||
`${WE_COM_ORIGIN}/wwlogin/sso/login` +
|
||||
`?login_type=CorpApp` +
|
||||
`&appid=${props.config.corp_id}` +
|
||||
`&agentid=${props.config.agent_id}` +
|
||||
`&redirect_uri=${redirectUri}` +
|
||||
`&state=${LOGIN_STATE}` +
|
||||
`&lang=${getLang()}` +
|
||||
`&panel_size=small` +
|
||||
`&redirect_type=callback`
|
||||
|
||||
window.addEventListener('message', handleWindowMessage)
|
||||
}
|
||||
|
||||
onBeforeUnmount(cleanup)
|
||||
|
||||
init()
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
#wecom-qr {
|
||||
margin-top: -20px;
|
||||
height: 331px;
|
||||
height: 360px;
|
||||
justify-content: center;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
Loading…
Reference in New Issue