Files
Toolbox/public/tools/oss_browser_link/oss_browser_link.js
T
yangxiangyuan 6dc79a2c12 feat: 新增多项功能并添加新工具
- 私人剪贴板新增限时直通URL生成功能
- doc_cloud_keeper新增标题复制按钮
- 新增贪蛇出动游戏工具
- 新增OSS中转直链工具
- 添加批量抽帧测试脚本
2026-08-11 10:22:31 +08:00

237 lines
9.7 KiB
JavaScript

/* OSS中转直链 oss_browser_link 前端逻辑(双模式弹窗 / 交互详情 / 协议拉起) */
;(function () {
'use strict'
var CFG = { ui_mode: 'debug', public_url: '', launch_protocol: 'ossbrowser' }
function $ (id) { return document.getElementById(id) }
function bjNow () {
try { return new Date().toLocaleString('sv-SE', { timeZone: 'Asia/Shanghai' }) } catch (e) { return new Date().toLocaleString() }
}
/* ---------- Toast ---------- */
var toastTimer = null
function showToast (msg, kind) {
var el = $('obl-toast')
el.textContent = msg
el.className = kind || ''
clearTimeout(toastTimer)
toastTimer = setTimeout(function () { el.className = 'obl-hidden' }, 2000)
}
/* ---------- 交互详情弹窗(双模式) ---------- */
var dialogTimer = null
function showDialog (title, text, opts) {
opts = opts || {}
$('obl-dialog-title').textContent = title
$('obl-dialog-body').textContent = text
$('obl-dialog').classList.remove('obl-hidden')
clearTimeout(dialogTimer)
if (opts.error) return // 异常:停留窗口,不自动关闭
var delay = CFG.ui_mode === 'debug' ? 3000 : 2000
dialogTimer = setTimeout(closeDialog, delay)
}
function closeDialog () {
clearTimeout(dialogTimer)
$('obl-dialog').classList.add('obl-hidden')
}
function buildLog (rec) {
return [
'触发动作: ' + rec.action,
'时间: ' + rec.time,
'接口: ' + rec.method + ' ' + rec.url,
'请求参数: ' + JSON.stringify(rec.params || {}),
'状态: ' + rec.status,
'返回结果: ' + rec.result,
rec.error ? '错误信息: ' + rec.error : '',
'耗时: ' + rec.cost + 'ms'
].filter(Boolean).join('\n')
}
/* 包装一次与后台/系统交互的操作,按 ui_mode 分支提示 */
function runTracked (action, url, method, params, fn, opts) {
opts = opts || {}
var t0 = Date.now()
var rec = { action: action, time: bjNow(), url: url, method: method, params: params, status: '进行中', result: '', error: '', cost: 0 }
return Promise.resolve()
.then(fn)
.then(function (result) {
rec.cost = Date.now() - t0
rec.status = '成功'
rec.result = typeof result === 'string' ? result : JSON.stringify(result)
if (CFG.ui_mode === 'debug') showDialog('交互详情 · ' + action, buildLog(rec))
else if (!opts.silent) showToast(action + ' 成功', 'success')
return result
})
.catch(function (err) {
rec.cost = Date.now() - t0
rec.status = '失败'
rec.error = String((err && err.message) || err)
showDialog('交互详情 · ' + action, buildLog(rec), { error: true }) // 异常双模式均强提示
throw err
})
}
/* ---------- 初始化:拉配置 + 文件状态 ---------- */
function init () {
fetch('/api/oss_browser_link/config').then(function (r) { return r.json() }).then(function (j) {
if (j && j.ok && j.data) {
CFG.ui_mode = j.data.ui_mode || 'debug'
CFG.public_url = j.data.public_url || ''
CFG.launch_protocol = j.data.launch_protocol || 'ossbrowser'
}
}).catch(function () {})
$('obl-link-input').value = CFG.public_url || location.origin + '/download_files/oss-browser-win32-x64.zip'
refreshFileInfo()
bindEvents()
}
function fmtSize (n) {
if (!Number.isFinite(n)) return ''
if (n >= 1024 * 1024) return (n / 1024 / 1024).toFixed(2) + ' MB'
if (n >= 1024) return (n / 1024).toFixed(1) + ' KB'
return n + ' B'
}
function refreshFileInfo () {
var t0 = Date.now()
fetch('/api/oss_browser_link/info').then(function (r) { return r.json() }).then(function (j) {
var meta = $('obl-file-meta')
var st = $('obl-file-status')
var cost = Date.now() - t0
if (j && j.ok && j.data && j.data.available) {
meta.textContent = '大小 ' + fmtSize(j.data.size) + ' · 已中转至本站 · 鉴权保护'
st.textContent = '可下载'
st.className = 'obl-status ok'
$('obl-download-btn').disabled = false
} else {
meta.textContent = '尚未检测到中转文件 · 请等待管理员中转后刷新'
st.textContent = '未就绪'
st.className = 'obl-status miss'
$('obl-download-btn').disabled = true
}
if (CFG.ui_mode === 'debug') {
meta.textContent += ' · 检测耗时 ' + cost + 'ms'
}
}).catch(function () {
$('obl-file-meta').textContent = '文件状态检测失败'
$('obl-file-status').textContent = '异常'
$('obl-file-status').className = 'obl-status miss'
})
}
/* ---------- 按钮事件 ---------- */
function bindEvents () {
$('obl-copy-btn').addEventListener('click', function () {
var url = $('obl-link-input').value
var btn = this
btn.disabled = true; btn.textContent = '复制中…'
runTracked('复制直链', location.href, 'CLIPBOARD', { url: url }, function () {
if (navigator.clipboard && navigator.clipboard.writeText) return navigator.clipboard.writeText(url)
$('obl-link-input').select()
document.execCommand('copy')
return 'fallback copy ok'
}).then(function () {
showToast('直链已复制(对方需鉴权才能下载)', 'success')
}).catch(function () {})
btn.disabled = false; btn.textContent = '复制直链'
})
$('obl-download-btn').addEventListener('click', function () {
var btn = this
btn.disabled = true; btn.textContent = '准备下载…'
runTracked('下载安装包', '/download_files/oss-browser-win32-x64.zip', 'GET', {}, function () {
return new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest()
xhr.open('GET', '/download_files/oss-browser-win32-x64.zip')
xhr.responseType = 'blob'
xhr.onload = function () {
if (xhr.status !== 200) return reject(new Error('HTTP ' + xhr.status))
var a = document.createElement('a')
a.href = URL.createObjectURL(xhr.response)
a.download = 'oss-browser-win32-x64.zip'
document.body.appendChild(a)
a.click()
setTimeout(function () { URL.revokeObjectURL(a.href); a.remove() }, 4000)
resolve('下载已触发,大小 ' + (xhr.response ? xhr.response.size : 0) + ' 字节')
}
xhr.onerror = function () { reject(new Error('网络错误')) }
xhr.send()
})
}).catch(function () {})
btn.disabled = false; btn.textContent = '⬇ 下载 oss-browser 安装包'
})
$('obl-launch-btn').addEventListener('click', function () {
launchOssBrowser()
})
$('obl-reg-btn').addEventListener('click', function () {
var btn = this
btn.disabled = true; btn.textContent = '下载中…'
runTracked('下载注册脚本', '/tools/oss_browser_link/assets/register_ossbrowser_launch.bat', 'GET', {}, function () {
var a = document.createElement('a')
a.href = '/tools/oss_browser_link/assets/register_ossbrowser_launch.bat'
a.download = 'register_ossbrowser_launch.bat'
document.body.appendChild(a)
a.click()
setTimeout(function () { a.remove() }, 2000)
return '脚本下载已触发(放入解压目录后双击运行)'
}).catch(function () {})
btn.disabled = false; btn.textContent = '📄 下载一键注册脚本(首次)'
})
$('obl-dialog-close').addEventListener('click', closeDialog)
$('obl-dialog-copy').addEventListener('click', function () {
var text = $('obl-dialog-body').textContent
if (navigator.clipboard && navigator.clipboard.writeText) navigator.clipboard.writeText(text)
showToast('交互日志已复制', 'success')
})
}
/* ---------- 协议拉起:未装则回退下载 ---------- */
function launchOssBrowser () {
var proto = CFG.launch_protocol || 'ossbrowser'
var url = proto + '://launch?t=' + Date.now()
var btn = $('obl-launch-btn')
btn.disabled = true; btn.textContent = '正在打开…'
runTracked('打开 oss-browser', url, 'PROTOCOL', { protocol: proto }, function () {
return new Promise(function (resolve, reject) {
var done = false
var started = false
/* 拉起成功时浏览器通常会模糊/隐藏页面 */
window.addEventListener('blur', onBlur)
document.addEventListener('visibilitychange', onVis)
function onBlur () { started = true }
function onVis () { if (document.hidden) started = true }
try {
var f = document.createElement('iframe')
f.style.display = 'none'
f.src = url
document.body.appendChild(f)
setTimeout(function () { try { f.remove() } catch (e) {} }, 3000)
} catch (e) { location.href = url }
setTimeout(function () {
window.removeEventListener('blur', onBlur)
document.removeEventListener('visibilitychange', onVis)
if (done) return
done = true
if (started) resolve('已触发协议拉起')
else reject(new Error('未检测到已安装的 oss-browser(协议未注册)'))
}, 2500)
})
}).then(function () {
showToast('已尝试打开 oss-browser;若浏览器弹出确认框请勾选"始终允许"', 'success')
}).catch(function () {
/* 未安装:自动回退下载安装包 */
showToast('未检测到 oss-browser,已自动开始下载安装包', 'error')
setTimeout(function () { $('obl-download-btn').click() }, 600)
})
setTimeout(function () { btn.disabled = false; btn.textContent = '🚀 打开 oss-browser' }, 3200)
}
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', init)
else init()
})()