增加内置浏览器打开引导
This commit is contained in:
Vendored
+1
@@ -61,6 +61,7 @@ declare module 'vue' {
|
||||
ElTimelineItem: typeof import('element-plus/es')['ElTimelineItem']
|
||||
ElTimePicker: typeof import('element-plus/es')['ElTimePicker']
|
||||
ElTooltip: typeof import('element-plus/es')['ElTooltip']
|
||||
InAppBrowserPrompt: typeof import('./src/components/InAppBrowserPrompt.vue')['default']
|
||||
MobileBottomNav: typeof import('./src/components/MobileBottomNav.vue')['default']
|
||||
RouterLink: typeof import('vue-router')['RouterLink']
|
||||
RouterView: typeof import('vue-router')['RouterView']
|
||||
|
||||
@@ -3,6 +3,7 @@ import { RouterView } from 'vue-router'
|
||||
import { computed } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
|
||||
import InAppBrowserPrompt from './components/InAppBrowserPrompt.vue'
|
||||
import AdminLayout from './layouts/AdminLayout.vue'
|
||||
import AppLayout from './layouts/AppLayout.vue'
|
||||
|
||||
@@ -24,4 +25,5 @@ const layout = computed(() => {
|
||||
<AppLayout v-else>
|
||||
<RouterView />
|
||||
</AppLayout>
|
||||
<InAppBrowserPrompt />
|
||||
</template>
|
||||
|
||||
@@ -0,0 +1,197 @@
|
||||
<script setup lang="ts">
|
||||
import { onMounted, ref } from 'vue'
|
||||
|
||||
const promptStorageKey = 'hfb_in_app_browser_prompt_seen'
|
||||
const visible = ref(false)
|
||||
const browserName = ref('')
|
||||
|
||||
function detectInAppBrowser(userAgent: string) {
|
||||
const ua = userAgent.toLowerCase()
|
||||
if (ua.includes('micromessenger')) return 'wechat'
|
||||
if (/\bqq\//i.test(userAgent) || ua.includes('mqqbrowser')) return 'qq'
|
||||
return ''
|
||||
}
|
||||
|
||||
function storageGet(key: string) {
|
||||
try {
|
||||
return window.sessionStorage.getItem(key)
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
function storageSet(key: string, value: string) {
|
||||
try {
|
||||
window.sessionStorage.setItem(key, value)
|
||||
} catch {
|
||||
// sessionStorage 不可用时只影响“本次会话只提醒一次”,不阻断页面使用。
|
||||
}
|
||||
}
|
||||
|
||||
function closePrompt() {
|
||||
storageSet(promptStorageKey, '1')
|
||||
visible.value = false
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
const browser = detectInAppBrowser(window.navigator.userAgent)
|
||||
if (!browser || storageGet(promptStorageKey) === '1') return
|
||||
browserName.value = browser === 'wechat' ? '微信' : 'QQ'
|
||||
visible.value = true
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Teleport to="body">
|
||||
<div v-if="visible" class="in-app-browser-mask" role="presentation">
|
||||
<section
|
||||
class="in-app-browser-dialog"
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
aria-labelledby="in-app-browser-title"
|
||||
>
|
||||
<div class="prompt-icon" aria-hidden="true">
|
||||
<van-icon name="guide-o" :size="30" />
|
||||
</div>
|
||||
<div class="prompt-copy">
|
||||
<p class="prompt-kicker">当前为{{ browserName }}内置浏览器</p>
|
||||
<h2 id="in-app-browser-title">建议在系统浏览器打开</h2>
|
||||
<p class="prompt-desc">部分支付、跳转和上传能力在内置浏览器里可能受限。</p>
|
||||
<div class="prompt-tip">
|
||||
<span class="prompt-tip-line">点击右上角 <strong>···</strong></span>
|
||||
<span>选择“在浏览器打开”</span>
|
||||
</div>
|
||||
</div>
|
||||
<button class="prompt-action" type="button" @click="closePrompt">我知道了</button>
|
||||
</section>
|
||||
</div>
|
||||
</Teleport>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.in-app-browser-mask {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
z-index: 10000;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 24px;
|
||||
background: rgb(15 23 42 / 48%);
|
||||
backdrop-filter: blur(1.5px);
|
||||
}
|
||||
|
||||
.in-app-browser-dialog {
|
||||
width: min(78vw, 320px);
|
||||
min-width: 250px;
|
||||
overflow: hidden;
|
||||
border: 1px solid rgb(255 255 255 / 68%);
|
||||
border-radius: 18px;
|
||||
background: #fff;
|
||||
box-shadow: 0 18px 48px rgb(15 23 42 / 24%);
|
||||
color: #1f2937;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.prompt-icon {
|
||||
display: grid;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
margin: 22px auto 12px;
|
||||
place-items: center;
|
||||
border-radius: 16px;
|
||||
background: linear-gradient(135deg, #fff4ec, #ffe1d0);
|
||||
color: #d85b12;
|
||||
}
|
||||
|
||||
.prompt-copy {
|
||||
padding: 0 22px;
|
||||
}
|
||||
|
||||
.prompt-kicker {
|
||||
margin: 0;
|
||||
color: #d85b12;
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.in-app-browser-dialog h2 {
|
||||
margin: 6px 0 0;
|
||||
font-size: 18px;
|
||||
font-weight: 800;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
.prompt-desc {
|
||||
margin: 9px 0 0;
|
||||
color: #6b7280;
|
||||
font-size: 13px;
|
||||
line-height: 1.55;
|
||||
}
|
||||
|
||||
.prompt-tip {
|
||||
display: inline-flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 3px;
|
||||
max-width: 100%;
|
||||
margin: 14px 0 18px;
|
||||
padding: 8px 13px;
|
||||
border-radius: 12px;
|
||||
background: #f6f8fb;
|
||||
color: #4b5563;
|
||||
font-size: 12px;
|
||||
line-height: 1.35;
|
||||
}
|
||||
|
||||
.prompt-tip strong {
|
||||
display: inline-block;
|
||||
color: #111827;
|
||||
font-size: 15px;
|
||||
letter-spacing: 1px;
|
||||
line-height: 1;
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.prompt-tip-line {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
.prompt-action {
|
||||
width: 100%;
|
||||
min-height: 48px;
|
||||
border: 0;
|
||||
background: linear-gradient(135deg, #ff7a1a, #ef5b00);
|
||||
color: #fff;
|
||||
font: inherit;
|
||||
font-size: 15px;
|
||||
font-weight: 700;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.prompt-action:active {
|
||||
filter: brightness(0.96);
|
||||
}
|
||||
|
||||
@media (max-width: 360px) {
|
||||
.in-app-browser-mask {
|
||||
padding: 18px;
|
||||
}
|
||||
|
||||
.in-app-browser-dialog {
|
||||
width: calc(100vw - 36px);
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.prompt-copy {
|
||||
padding: 0 20px;
|
||||
}
|
||||
|
||||
.prompt-tip {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user