| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- <template>
- <view class="web-view-page">
- <web-view v-if="url" :src="url" @message="handleMessage" />
- </view>
- </template>
- <script setup lang="ts">
- import { ref } from 'vue'
- import { onLoad } from '@dcloudio/uni-app'
- import { useSettlementSignStore } from '@/stores/modules/settlementSign'
- interface WebViewPageQuery {
- url?: string
- subjectLocation?: string
- signTraceId?: string
- }
- interface WebViewMessage {
- subjectLocation?: string
- signTraceId?: string
- success?: boolean
- status?: string
- [key: string]: unknown
- }
- interface WebViewMessageEvent {
- detail?: {
- data?: unknown
- }
- }
- const settlementSignStore = useSettlementSignStore()
- const url = ref('')
- const routeSubjectLocation = ref('')
- const routeSignTraceId = ref('')
- const showToast = (title: string) => {
- uni.showToast({
- title,
- icon: 'none',
- })
- }
- const safeDecodeURIComponent = (value: string) => {
- try {
- return decodeURIComponent(value)
- } catch (error) {
- console.error('decodeURIComponent error:', error)
- return value
- }
- }
- const normalizeMessageData = (event: WebViewMessageEvent): WebViewMessage => {
- const rawData = event.detail?.data
- const firstData = Array.isArray(rawData) ? rawData[0] : rawData
- if (!firstData) return {}
- if (typeof firstData === 'string') {
- try {
- return JSON.parse(firstData) as WebViewMessage
- } catch {
- return {
- status: firstData,
- }
- }
- }
- if (typeof firstData === 'object') {
- return firstData as WebViewMessage
- }
- return {}
- }
- const getStringValue = (value: unknown): string => {
- return typeof value === 'string' ? value.trim() : ''
- }
- const resolveSubjectLocation = (message: WebViewMessage): string => {
- const messageSubjectLocation = getStringValue(message.subjectLocation)
- const contextSubjectLocation = settlementSignStore.pendingSubjectLocation
- return messageSubjectLocation || routeSubjectLocation.value || contextSubjectLocation
- }
- const resolveSignTraceId = (message: WebViewMessage): string => {
- const messageSignTraceId = getStringValue(message.signTraceId)
- const contextSignTraceId = settlementSignStore.validContext?.signTraceId || ''
- return messageSignTraceId || routeSignTraceId.value || contextSignTraceId
- }
- const redirectToSettlementSignPage = (subjectLocation: string, signTraceId: string) => {
- if (!subjectLocation) {
- showToast('参数异常')
- return
- }
- const query = [`subjectLocationByUrl=${encodeURIComponent(subjectLocation)}`, `source=webMessage`]
- if (signTraceId) {
- query.push(`signTraceId=${encodeURIComponent(signTraceId)}`)
- }
- uni.redirectTo({
- url: `/pages-auth/settlement-channel-sign/index?${query.join('&')}`,
- })
- }
- const handleMessage = (event: WebViewMessageEvent) => {
- const message = normalizeMessageData(event)
- console.log('web-view message:', message)
- const subjectLocation = resolveSubjectLocation(message)
- const signTraceId = resolveSignTraceId(message)
- redirectToSettlementSignPage(subjectLocation, signTraceId)
- }
- onLoad((query: WebViewPageQuery) => {
- if (!query?.url) {
- showToast('签约地址不存在')
- uni.navigateBack({
- delta: 1,
- })
- return
- }
- url.value = safeDecodeURIComponent(query.url)
- routeSubjectLocation.value = query.subjectLocation || ''
- routeSignTraceId.value = query.signTraceId || ''
- })
- </script>
- <style lang="scss" scoped>
- .web-view-page {
- width: 100%;
- height: 100vh;
- }
- </style>
|