Files
zkxw/mobile-h5/pages/oa/start/webview.vue
2026-08-13 16:50:36 +08:00

112 lines
3.4 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<!-- 与表单水槽页保持同一结构:仅整页 web-view,避免额外节点干扰 -->
<web-view v-if="src" :src="src" @message="onMessage" />
</template>
<script>
import {
buildOaStartUrl,
resolveOaReturnPath,
takeOaStartTitle
} from '../../../utils/oa-h5.js'
import { navigateBackFromOaHost } from '../../../utils/oa-navigate-back.js'
import { forceRelogin, getToken } from '../../../utils/auth.js'
import { fetchOaTemplateDetail } from '../../../utils/oa-api.js'
const CLOSE_ACTIONS = new Set([
'oa-start-close',
'oa-start-cancel',
'oa-start-draft',
'oa-start-submitted'
])
export default {
data() {
return { src: '', _closing: false }
},
onLoad(query) {
if (!getToken()) {
forceRelogin('请先登录')
return
}
const appId = String((query && query.appId) || '')
const draftId = String((query && query.draftId) || '')
// 标题:优先读跳转前缓存(无中文 query);否则按 appId 拉详情
const cachedName = takeOaStartTitle()
if (cachedName) {
uni.setNavigationBarTitle({ title: cachedName })
} else if (appId) {
this.resolveTitle(appId)
}
const returnPath = resolveOaReturnPath(query)
const src = buildOaStartUrl({ appId, draftId, returnPath })
if (!/\btoken=/.test(src)) {
forceRelogin('请先登录')
return
}
// 对齐水槽:onLoad 内同步赋值,与 pages/oa/form-sink/index 一致
console.log('[oa-start webview] src=', src, 'returnPath=', returnPath)
this.src = src
// H5:OA 页在 iframe 内,靠 postMessage 通知本页 uni.navigateBack
// (微信小程序由 OA 内 wx.miniProgram.navigateBack,勿在此再退一层)
// #ifdef H5
this._onParentMessage = (e) => {
const d = e && e.data
if (!d || d.source !== 'zkxw-oa-h5') return
console.log('[oa-start webview] iframe message', d)
this.navigateBackFromOa(d)
}
window.addEventListener('message', this._onParentMessage)
// #endif
},
onUnload() {
console.log('[oa-start webview] onUnload')
// #ifdef H5
if (this._onParentMessage) {
window.removeEventListener('message', this._onParentMessage)
this._onParentMessage = null
}
// #endif
},
methods: {
async resolveTitle(appId) {
try {
const detail = await fetchOaTemplateDetail(appId)
const name = String(
(detail && (detail.appName || detail.name)) || ''
).trim()
if (name) uni.setNavigationBarTitle({ title: name })
} catch (_) {
/* 保留 pages.json 兜底「填写审批」 */
}
},
navigateBackFromOa(payload) {
console.log('[oa-start webview] navigateBackFromOa', payload)
if (this._closing) return
const action = String((payload && payload.action) || '')
if (action && !CLOSE_ACTIONS.has(action)) return
this._closing = true
const msg = String((payload && payload.message) || '').trim()
if (msg) {
uni.showToast({ title: msg, icon: 'none', duration: 1200 })
}
setTimeout(() => {
navigateBackFromOaHost({
fallbackUrl: '/pages/oa/start/index',
onStuck: () => {
this._closing = false
}
})
}, msg ? 400 : 0)
},
onMessage(e) {
/* 微信:多在后退/销毁时触发;列表页 onShow 可刷新。勿再 navigateBack */
console.log('[oa-start webview] @message', e && e.detail)
}
}
}
</script>