flat: 注入全局弹窗

This commit is contained in:
Apcallover
2025-12-17 18:27:59 +08:00
19 changed files with 3132 additions and 509 deletions

View File

@@ -0,0 +1,76 @@
// utils/GlobalInactivityManager.js
export class GlobalInactivityManager {
constructor(callback, timeout = 60000) {
this.callback = callback
this.timeout = timeout
this.timer = null
this.isPaused = false
this.lastActivityTime = 0
this.THROTTLE_DELAY = 300
this.lowFreqEvents = ['mousedown', 'click', 'keydown', 'touchstart']
this.highFreqEvents = ['mousemove', 'scroll', 'wheel', 'pointermove']
}
resetTimer = () => {
if (this.isPaused) return
if (this.timer) clearTimeout(this.timer)
this.timer = setTimeout(() => {
this.callback()
this.pause()
}, this.timeout)
}
handleUserActivity = () => {
const now = Date.now()
if (now - this.lastActivityTime > this.THROTTLE_DELAY) {
this.lastActivityTime = now
this.resetTimer()
}
}
handleVisibilityChange = () => {
if (document.hidden) {
this.pause()
} else {
this.resume()
}
}
start() {
if (this.isPaused) return
this.resetTimer()
this.lowFreqEvents.forEach(event => {
document.addEventListener(event, this.resetTimer, true)
})
this.highFreqEvents.forEach(event => {
document.addEventListener(event, this.handleUserActivity, true)
})
document.addEventListener('visibilitychange', this.handleVisibilityChange)
}
pause() {
this.isPaused = true
if (this.timer) clearTimeout(this.timer)
this.lowFreqEvents.forEach(event => {
document.removeEventListener(event, this.resetTimer, true)
})
this.highFreqEvents.forEach(event => {
document.removeEventListener(event, this.handleUserActivity, true)
})
document.removeEventListener('visibilitychange', this.handleVisibilityChange)
}
resume() {
this.isPaused = false
this.start() // 现在 this 指向正确,事件能正常绑定和触发
}
destroy() {
this.pause()
this.callback = null
}
}

46
utils/modal.js Normal file
View File

@@ -0,0 +1,46 @@
/**
* 全局弹窗调用工具
* @param {Object} options - 配置项 (title, content, type, success, fail, confirmColor...)
*/
export const $confirm = (options = {}) => {
return new Promise((resolve) => {
// 1. 稍微延迟发送,确保注入的页面组件已完成 uni.$on 监听挂载
// 如果是用户点击触发,延迟可以设为 0如果是拦截器自动触发建议保留 200ms
setTimeout(() => {
uni.$emit('show-global-popup', {
title: options.title || '提示',
content: options.content || '',
type: options.type || 'info',
// 核心:重新包装 resolve 逻辑
resolve: (isConfirm) => {
if (isConfirm) {
// 执行成功回调
if (typeof options.success === 'function') {
options.success({
confirm: true,
cancel: false
});
}
resolve(true);
} else {
// 执行失败/取消回调
if (typeof options.fail === 'function') {
options.fail({
confirm: false,
cancel: true
});
}
resolve(false);
}
},
});
}, options.delay || 200);
});
};
// // 页面中使用
// import {
// $confirm
// } from '@/utils/modal.js';
// const ok = await $confirm({
// title: '测试'
// });