change
This commit is contained in:
@@ -61,6 +61,7 @@
|
||||
<script src="${base!}/assets/platform/js/mixin/styleMixin.js"></script>
|
||||
<script src="${base!}/assets/platform/js/tool/businessTool.js"></script>
|
||||
<script src="${base!}/assets/platform/js/util/h5AutoShowError.js"></script>
|
||||
<script src="${base!}/assets/platform/js/util/h5PopupHistory.js"></script>
|
||||
|
||||
<!--富文本编辑器-->
|
||||
<link rel="stylesheet" href="${base!}/assets/platform/plugins/wangEditor4/wangEditor.css"/>
|
||||
@@ -95,6 +96,152 @@
|
||||
// toast多例模式
|
||||
vant.Toast.allowMultiple()
|
||||
|
||||
/**
|
||||
* H5 弹层历史管理器。
|
||||
* 页面通过 register 注册页面标识和弹层状态回调,通过 open/close/closeAll 维护浏览器历史;
|
||||
* popstate 返回 true 表示本次返回仅用于同步弹层,PJAX 不再执行页面跳转。
|
||||
*/
|
||||
window.h5HistoryLayerManager = {
|
||||
pageKey: "",
|
||||
stack: [],
|
||||
onChange: null,
|
||||
afterClose: null,
|
||||
subscribers: [],
|
||||
pendingNavigation: null,
|
||||
register(pageKey, onChange) {
|
||||
const currentState = window.history.state || {}
|
||||
this.pageKey = pageKey
|
||||
this.stack = []
|
||||
this.onChange = onChange
|
||||
this.afterClose = null
|
||||
this.pendingNavigation = null
|
||||
window.history.replaceState({
|
||||
...currentState,
|
||||
url: currentState.url || window.location.href,
|
||||
h5HistoryLayerPage: pageKey,
|
||||
h5HistoryLayerStack: []
|
||||
}, "", window.location.href)
|
||||
this.notify()
|
||||
},
|
||||
/**
|
||||
* 确保当前页面已初始化弹层历史。
|
||||
* pageKey 传当前页面的稳定标识;返回 boolean,true 表示已有或已完成页面注册。
|
||||
*/
|
||||
ensureRegistered(pageKey) {
|
||||
if (this.pageKey) return true
|
||||
this.register(pageKey, null)
|
||||
return true
|
||||
},
|
||||
/**
|
||||
* 订阅全局弹层栈变化。
|
||||
* onChange 接收当前弹层名称数组;返回 Function 类型的注销方法,组件销毁时必须调用。
|
||||
*/
|
||||
subscribe(onChange) {
|
||||
if (typeof onChange !== "function") return () => {}
|
||||
this.subscribers.push(onChange)
|
||||
onChange(this.stack.slice())
|
||||
return () => {
|
||||
const index = this.subscribers.indexOf(onChange)
|
||||
if (index !== -1) this.subscribers.splice(index, 1)
|
||||
}
|
||||
},
|
||||
unregister(pageKey) {
|
||||
if (pageKey && this.pageKey !== pageKey) return
|
||||
this.reset()
|
||||
},
|
||||
open(layerName) {
|
||||
if (!this.pageKey || !layerName) return false
|
||||
const currentLayer = this.stack[this.stack.length - 1]
|
||||
if (currentLayer === layerName) return true
|
||||
const nextStack = this.stack.concat(layerName)
|
||||
window.history.pushState({
|
||||
...(window.history.state || {}),
|
||||
url: window.location.href,
|
||||
h5HistoryLayerPage: this.pageKey,
|
||||
h5HistoryLayerStack: nextStack
|
||||
}, "", window.location.href)
|
||||
this.stack = nextStack
|
||||
this.notify()
|
||||
return true
|
||||
},
|
||||
close(layerName, afterClose = null) {
|
||||
if (!this.stack.length) {
|
||||
if (typeof afterClose === "function") afterClose()
|
||||
return false
|
||||
}
|
||||
const currentLayer = this.stack[this.stack.length - 1]
|
||||
if (layerName && currentLayer !== layerName) return false
|
||||
this.afterClose = afterClose
|
||||
window.history.back()
|
||||
return true
|
||||
},
|
||||
closeAll(afterClose = null) {
|
||||
if (!this.stack.length) {
|
||||
if (typeof afterClose === "function") afterClose()
|
||||
return false
|
||||
}
|
||||
this.afterClose = afterClose
|
||||
window.history.go(-this.stack.length)
|
||||
return true
|
||||
},
|
||||
/**
|
||||
* 关闭当前页面全部弹层后跳转业务页面。
|
||||
* url 传目标页面地址,data 传可选的 PJAX 请求参数;返回 boolean,true 表示已接管本次跳转。
|
||||
*/
|
||||
closeAllAndNavigate(url, data = null) {
|
||||
if (!url) return false
|
||||
if (!this.stack.length) {
|
||||
pjaxReplace(url, data)
|
||||
return true
|
||||
}
|
||||
this.pendingNavigation = {url: url, data: data}
|
||||
this.afterClose = null
|
||||
window.history.go(-this.stack.length)
|
||||
return true
|
||||
},
|
||||
handlePopState(nativeEvent) {
|
||||
const state = nativeEvent && nativeEvent.state ? nativeEvent.state : {}
|
||||
const targetStack = state.h5HistoryLayerPage === this.pageKey && Array.isArray(state.h5HistoryLayerStack)
|
||||
? state.h5HistoryLayerStack.slice()
|
||||
: []
|
||||
const stackChanged = this.stack.length !== targetStack.length ||
|
||||
this.stack.some((layerName, index) => layerName !== targetStack[index])
|
||||
if (!stackChanged) return false
|
||||
if (!this.stack.length && !targetStack.length) return false
|
||||
this.stack = targetStack
|
||||
this.notify()
|
||||
const callback = this.afterClose
|
||||
const navigation = this.pendingNavigation
|
||||
this.afterClose = null
|
||||
this.pendingNavigation = null
|
||||
if (navigation && navigation.url) {
|
||||
pjaxReplace(navigation.url, navigation.data)
|
||||
return true
|
||||
}
|
||||
if (typeof callback === "function") {
|
||||
setTimeout(() => callback(), 0)
|
||||
}
|
||||
return true
|
||||
},
|
||||
notify() {
|
||||
if (typeof this.onChange === "function") {
|
||||
this.onChange(this.stack.slice())
|
||||
}
|
||||
this.subscribers.slice().forEach((subscriber) => {
|
||||
subscriber(this.stack.slice())
|
||||
})
|
||||
},
|
||||
reset() {
|
||||
this.stack = []
|
||||
this.notify()
|
||||
this.pageKey = ""
|
||||
this.onChange = null
|
||||
this.afterClose = null
|
||||
this.subscribers = []
|
||||
this.pendingNavigation = null
|
||||
}
|
||||
}
|
||||
|
||||
//初始化pjax
|
||||
;(function initPjax() {
|
||||
if ($.support.pjax) {
|
||||
@@ -106,14 +253,19 @@
|
||||
timeout: 8000
|
||||
})
|
||||
$(document).on("pjax:send", function () {
|
||||
window.h5HistoryLayerManager.reset()
|
||||
NProgress.start()
|
||||
window.customStyleList = document.querySelectorAll('style[id^="style-"]')
|
||||
})
|
||||
$(document).on("pjax:complete", function () {
|
||||
// PJAX 替换 #container 时可能已经移除旧样式节点,清理前需兼容节点脱离 DOM 的情况。
|
||||
if (window.customStyleList) {
|
||||
window.customStyleList.forEach((style) => {
|
||||
style.parentNode.removeChild(style)
|
||||
if (style.parentNode) {
|
||||
style.parentNode.removeChild(style)
|
||||
}
|
||||
})
|
||||
window.customStyleList = null
|
||||
}
|
||||
NProgress.done()
|
||||
toggleShowBar()
|
||||
@@ -121,6 +273,9 @@
|
||||
|
||||
// 监听浏览器的前进和后退操作
|
||||
$(window).on("popstate", function (event) {
|
||||
if (window.h5HistoryLayerManager.handlePopState(event.originalEvent)) {
|
||||
return
|
||||
}
|
||||
if (event.originalEvent.state) {
|
||||
// 如果存在历史记录状态,触发 Pjax 加载对应内容
|
||||
$.pjax({
|
||||
@@ -137,7 +292,7 @@
|
||||
})()
|
||||
|
||||
function pjaxReplace(url, data = null) {
|
||||
$.pjax({
|
||||
return $.pjax({
|
||||
url: url,
|
||||
container: "#container",
|
||||
maxCacheLength: 0,
|
||||
@@ -149,14 +304,72 @@
|
||||
})
|
||||
}
|
||||
|
||||
function createListLoading(icon = "https://preview.qiantucdn.com/58pic/35/39/61/62K58PICb88i68HEwVnm5_PIC2018.gif!qt480") {
|
||||
return vant.Toast.loading({
|
||||
icon: icon,
|
||||
forbidClick: true,
|
||||
loadingType: "spinner",
|
||||
duration: 0,
|
||||
className: "custom-list-loading"
|
||||
let h5GlobalLoading = null
|
||||
let h5PendingRequestCount = 0
|
||||
|
||||
function showH5GlobalLoading(icon = "/assets/mobile/img/common/smart-union-loading-red.svg") {
|
||||
if (!h5GlobalLoading) {
|
||||
h5GlobalLoading = vant.Toast.loading({
|
||||
icon: icon,
|
||||
message: "加载中...",
|
||||
forbidClick: true,
|
||||
loadingType: "spinner",
|
||||
duration: 0,
|
||||
className: "custom-list-loading"
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function closeH5GlobalLoading() {
|
||||
if (h5PendingRequestCount > 0 || !h5GlobalLoading) return
|
||||
h5GlobalLoading.clear()
|
||||
h5GlobalLoading = null
|
||||
}
|
||||
|
||||
// 所有 H5 Axios 请求先展示 Loading,等待 200ms 后再真正发出请求。
|
||||
window.bindH5AxiosLoading = function(axiosService) {
|
||||
axiosService.interceptors.request.use((config) => {
|
||||
// 页面自行展示骨架屏时保留请求延迟,但不叠加全局 Loading 遮罩。
|
||||
if (config.h5SkeletonLoading) {
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => resolve(config), 200)
|
||||
})
|
||||
}
|
||||
h5PendingRequestCount++
|
||||
showH5GlobalLoading()
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => resolve(config), 200)
|
||||
})
|
||||
}, (error) => {
|
||||
return Promise.reject(error)
|
||||
})
|
||||
|
||||
axiosService.interceptors.response.use((response) => {
|
||||
if (!response.config || !response.config.h5SkeletonLoading) {
|
||||
h5PendingRequestCount = Math.max(0, h5PendingRequestCount - 1)
|
||||
closeH5GlobalLoading()
|
||||
}
|
||||
return response
|
||||
}, (error) => {
|
||||
if (!error.config || !error.config.h5SkeletonLoading) {
|
||||
h5PendingRequestCount = Math.max(0, h5PendingRequestCount - 1)
|
||||
closeH5GlobalLoading()
|
||||
}
|
||||
return Promise.reject(error)
|
||||
})
|
||||
}
|
||||
|
||||
function createListLoading(icon = "/assets/mobile/img/common/smart-union-loading-red.svg") {
|
||||
showH5GlobalLoading(icon)
|
||||
|
||||
const closeLoading = function() {
|
||||
closeH5GlobalLoading()
|
||||
}
|
||||
|
||||
return {
|
||||
clear: closeLoading,
|
||||
close: closeLoading
|
||||
}
|
||||
}
|
||||
|
||||
function historyBack(func) {
|
||||
@@ -408,7 +621,7 @@
|
||||
</script>
|
||||
|
||||
<script nonce="${cspNonce!}">
|
||||
const h5ComponentVersion = "20260524"
|
||||
const h5ComponentVersion = "20260821_2"
|
||||
Vue.component("rich-text", httpVueLoader("/components/plugins/sysRichTextView/index.vue?v=" + h5ComponentVersion))
|
||||
Vue.component("h5-file-upload", httpVueLoader("/components/plugins/sysUpload/h5Index.vue?v=" + h5ComponentVersion))
|
||||
Vue.component("h5-signature", httpVueLoader("/components/plugins/sysSignature/h5Index.vue?v=" + h5ComponentVersion))
|
||||
@@ -458,10 +671,10 @@
|
||||
<div id="container">${layoutContent}</div>
|
||||
</div>
|
||||
</div>
|
||||
<button type="button" class="h5-voice-menu" id="voice-menu-btn" data-platform="H5" title="语音打开菜单">
|
||||
<i class="fa fa-microphone"></i>
|
||||
<span class="voice-menu-text">语音</span>
|
||||
</button>
|
||||
<!--<button type="button" class="h5-voice-menu" id="voice-menu-btn" data-platform="H5" title="语音打开菜单">-->
|
||||
<!-- <i class="fa fa-microphone"></i>-->
|
||||
<!-- <span class="voice-menu-text">语音</span>-->
|
||||
<!--</button>-->
|
||||
<script nonce="${cspNonce!}">
|
||||
toggleShowBar()
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user