|
|
@@ -0,0 +1,74 @@
|
|
|
+<template>
|
|
|
+ <view class="mp-wv-page">
|
|
|
+ <view v-if="errorText" class="mp-wv-error">{{ errorText }}</view>
|
|
|
+ <web-view v-else-if="src" :src="src" />
|
|
|
+ <view v-else class="mp-wv-error">加载中…</view>
|
|
|
+ </view>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup>
|
|
|
+import { ref } from 'vue'
|
|
|
+import { onLoad } from '@dcloudio/uni-app'
|
|
|
+import { AUTH_API, PAGE_PATHS } from '@/config/api'
|
|
|
+import { WEB_ORIGIN } from '@/config/env'
|
|
|
+import { request, parseResponseJson } from '@/utils/request'
|
|
|
+import { useUserStore } from '@/stores/user'
|
|
|
+
|
|
|
+const src = ref('')
|
|
|
+const errorText = ref('')
|
|
|
+
|
|
|
+function isAllowedPath(path) {
|
|
|
+ return typeof path === 'string' && path.startsWith('/m/')
|
|
|
+}
|
|
|
+
|
|
|
+onLoad(async (query) => {
|
|
|
+ const path = decodeURIComponent(String(query?.path || '').trim())
|
|
|
+ if (!isAllowedPath(path)) {
|
|
|
+ errorText.value = '无效地址'
|
|
|
+ uni.showToast({ title: '无效地址', icon: 'none' })
|
|
|
+ setTimeout(() => {
|
|
|
+ uni.navigateBack({
|
|
|
+ fail: () => uni.reLaunch({ url: PAGE_PATHS.workbench })
|
|
|
+ })
|
|
|
+ }, 400)
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ const userStore = useUserStore()
|
|
|
+ userStore.checkLoginStatus()
|
|
|
+ if (!userStore.isLoggedIn) {
|
|
|
+ uni.reLaunch({ url: PAGE_PATHS.login })
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ const res = await request({
|
|
|
+ url: AUTH_API.MP_WEBVIEW_TICKET,
|
|
|
+ method: 'POST'
|
|
|
+ })
|
|
|
+ const result = parseResponseJson(res)
|
|
|
+ const ticket = result && result.code === 200 ? result.data?.ticket : ''
|
|
|
+ if (!ticket) {
|
|
|
+ throw new Error((result && result.message) || '无法打开内嵌页')
|
|
|
+ }
|
|
|
+ const origin = String(WEB_ORIGIN || '').replace(/\/$/, '')
|
|
|
+ src.value = `${origin}/#${path}?mpTicket=${encodeURIComponent(ticket)}`
|
|
|
+ } catch (error) {
|
|
|
+ errorText.value = (error && error.message) || '无法打开内嵌页'
|
|
|
+ uni.showToast({ title: errorText.value, icon: 'none' })
|
|
|
+ }
|
|
|
+})
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+.mp-wv-page {
|
|
|
+ min-height: 100vh;
|
|
|
+ background: #f5f8f7;
|
|
|
+}
|
|
|
+.mp-wv-error {
|
|
|
+ padding: 48px 16px;
|
|
|
+ color: #6b7b74;
|
|
|
+ font-size: 14px;
|
|
|
+ text-align: center;
|
|
|
+}
|
|
|
+</style>
|