更新
This commit is contained in:
+228
-228
@@ -1,10 +1,10 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>后台管理系统</title>
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>后台管理系统</title>
|
||||
<style>
|
||||
* {
|
||||
margin: 0;
|
||||
@@ -50,33 +50,33 @@
|
||||
stroke-dashoffset: -120px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
// 动态加载 Chat UIKit 样式
|
||||
(function() {
|
||||
var link = document.createElement('link');
|
||||
link.rel = 'stylesheet';
|
||||
link.href = 'https://web.sdk.qcloud.com/im/assets/latest/index.css';
|
||||
document.head.appendChild(link);
|
||||
})();
|
||||
</script>
|
||||
<!-- Dify AI 客服机器人(全局悬浮气泡) -->
|
||||
<script>
|
||||
window.difyChatbotConfig = {
|
||||
token: 'OcRvj5VVR76cME9J',
|
||||
baseUrl: 'https://ai.zhenyangtang.com.cn/',
|
||||
draggable: true,
|
||||
dragAxis: 'both',
|
||||
inputs: {},
|
||||
systemVariables: {},
|
||||
userVariables: {}
|
||||
}
|
||||
</script>
|
||||
<script
|
||||
src="https://ai.zhenyangtang.com.cn/embed.min.js"
|
||||
id="OcRvj5VVR76cME9J"
|
||||
defer
|
||||
></script>
|
||||
</style>
|
||||
<script>
|
||||
// 动态加载 Chat UIKit 样式
|
||||
(function() {
|
||||
var link = document.createElement('link');
|
||||
link.rel = 'stylesheet';
|
||||
link.href = 'https://web.sdk.qcloud.com/im/assets/latest/index.css';
|
||||
document.head.appendChild(link);
|
||||
})();
|
||||
</script>
|
||||
<!-- Dify AI 客服机器人(全局悬浮气泡) -->
|
||||
<script>
|
||||
window.difyChatbotConfig = {
|
||||
token: 'OcRvj5VVR76cME9J',
|
||||
baseUrl: 'https://ai.zhenyangtang.com.cn/',
|
||||
draggable: true,
|
||||
dragAxis: 'both',
|
||||
inputs: {},
|
||||
systemVariables: {},
|
||||
userVariables: {}
|
||||
}
|
||||
</script>
|
||||
<script
|
||||
src="https://ai.zhenyangtang.com.cn/embed.min.js"
|
||||
id="OcRvj5VVR76cME9J"
|
||||
defer
|
||||
></script>
|
||||
<style>
|
||||
/* 气泡按钮使用自定义 AI 图标(base 为 /admin/,public 资源在该路径下) */
|
||||
#dify-chatbot-bubble-button {
|
||||
@@ -162,199 +162,199 @@
|
||||
background: #f2f4f7;
|
||||
z-index: 2147483641;
|
||||
}
|
||||
</style>
|
||||
<script type="module" crossorigin src="/admin/assets/index-BWzN7QIb.js"></script>
|
||||
</style>
|
||||
<script type="module" crossorigin src="/admin/assets/index-Cz9kp4CD.js"></script>
|
||||
<link rel="modulepreload" crossorigin href="/admin/assets/.pnpm-9dA1PEvN.js">
|
||||
<link rel="stylesheet" crossorigin href="/admin/assets/.pnpm-LiWq8Xu0.css">
|
||||
<link rel="stylesheet" crossorigin href="/admin/assets/index-or10At3s.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app">
|
||||
<div class="preload">
|
||||
<svg viewBox="25 25 50 50" class="circular">
|
||||
<circle cx="50" cy="50" r="20" fill="none" class="path"></circle>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
// Dify 聊天窗口全屏切换:#dify-chatbot-bubble-window 是 iframe 本身,
|
||||
// 无法往其内部挂按钮,故在气泡旁放一个独立按钮,窗口打开时才显示
|
||||
(function () {
|
||||
var btn = document.createElement('button')
|
||||
btn.type = 'button'
|
||||
btn.id = 'dify-fullscreen-toggle'
|
||||
btn.title = '全屏 / 还原'
|
||||
btn.textContent = '⛶'
|
||||
var transitionUntil = 0
|
||||
// 全屏切换(放大和还原都算)后的过渡期:Dify 内部重排期间版权位置不定,
|
||||
// 用大面积遮盖兜底,并逐帧跟踪窗口尺寸动画
|
||||
function startTransition() {
|
||||
transitionUntil = Date.now() + TRANSITION_MS
|
||||
function loop() {
|
||||
sync()
|
||||
if (Date.now() < transitionUntil) requestAnimationFrame(loop)
|
||||
}
|
||||
loop()
|
||||
}
|
||||
btn.addEventListener('click', function () {
|
||||
var win = document.getElementById('dify-chatbot-bubble-window')
|
||||
if (!win) return
|
||||
win.classList.toggle('dify-chatbot-fullscreen')
|
||||
startTransition()
|
||||
})
|
||||
document.body.appendChild(btn)
|
||||
|
||||
// 自定义关闭按钮:窗口打开时气泡被隐藏,由它代替气泡的关闭功能
|
||||
var closeBtn = document.createElement('button')
|
||||
closeBtn.type = 'button'
|
||||
closeBtn.id = 'dify-chat-close'
|
||||
closeBtn.title = '关闭'
|
||||
closeBtn.textContent = '✕'
|
||||
closeBtn.addEventListener('click', function () {
|
||||
var win = document.getElementById('dify-chatbot-bubble-window')
|
||||
var difyBubble = document.getElementById('dify-chatbot-bubble-button')
|
||||
if (win) win.classList.remove('dify-chatbot-fullscreen')
|
||||
// 复用 embed.min.js 的开关逻辑,保证气泡图标状态同步
|
||||
if (difyBubble) difyBubble.click()
|
||||
sync()
|
||||
})
|
||||
document.body.appendChild(closeBtn)
|
||||
|
||||
// 隐藏 Dify 头部自带的展开按钮:该按钮仅在收到 isToggledByButton:true 时渲染
|
||||
// (embed.min.js 默认发送),在其后补发 false 覆盖即可
|
||||
var DIFY_ORIGIN = 'https://ai.zhenyangtang.com.cn'
|
||||
window.addEventListener('message', function (event) {
|
||||
if (event.origin !== DIFY_ORIGIN) return
|
||||
if (!event.data || event.data.type !== 'dify-chatbot-iframe-ready') return
|
||||
var win = document.getElementById('dify-chatbot-bubble-window')
|
||||
if (!win || event.source !== win.contentWindow) return
|
||||
setTimeout(function () {
|
||||
win.contentWindow.postMessage(
|
||||
{
|
||||
type: 'dify-chatbot-config',
|
||||
payload: { isToggledByButton: false, isDraggable: false }
|
||||
},
|
||||
DIFY_ORIGIN
|
||||
)
|
||||
}, 200)
|
||||
})
|
||||
|
||||
var cover = document.createElement('div')
|
||||
cover.id = 'dify-brand-cover'
|
||||
document.body.appendChild(cover)
|
||||
var transitionCover = document.createElement('div')
|
||||
transitionCover.id = 'dify-brand-transition-cover'
|
||||
document.body.appendChild(transitionCover)
|
||||
|
||||
var BRAND_BAR_HEIGHT = 38
|
||||
// 全屏后 Dify 内部布局重排的过渡时长,期间用大面积遮盖兜底
|
||||
var TRANSITION_MS = 1500
|
||||
// Dify 宽屏布局断点 40rem:窄窗口版权条在底部,宽窗口(展开/全屏)移到顶栏右侧
|
||||
var WIDE_BREAKPOINT = 640
|
||||
|
||||
function sync() {
|
||||
var win = document.getElementById('dify-chatbot-bubble-window')
|
||||
var opened = win && win.style.display !== 'none'
|
||||
var difyBubble = document.getElementById('dify-chatbot-bubble-button')
|
||||
btn.style.display = opened ? 'block' : 'none'
|
||||
closeBtn.style.display = opened ? 'block' : 'none'
|
||||
if (!opened) {
|
||||
cover.style.display = 'none'
|
||||
transitionCover.style.display = 'none'
|
||||
// 窗口关闭后恢复气泡(可拖动)
|
||||
if (difyBubble) difyBubble.style.display = ''
|
||||
return
|
||||
}
|
||||
var rect = win.getBoundingClientRect()
|
||||
var fullscreen = win.classList.contains('dify-chatbot-fullscreen')
|
||||
var inTransition = Date.now() < transitionUntil
|
||||
cover.style.display = 'block'
|
||||
// 窗口打开期间隐藏气泡(气泡可能被拖到任意位置,浮在窗口上很突兀),
|
||||
// 控制按钮统一停靠在窗口顶栏
|
||||
if (difyBubble) difyBubble.style.display = 'none'
|
||||
btn.classList.toggle('is-fullscreen', fullscreen)
|
||||
closeBtn.classList.toggle('is-fullscreen', fullscreen)
|
||||
if (fullscreen) {
|
||||
// 全屏:实色圆钮放左上角,避开右上角版权遮盖区和底部输入区
|
||||
btn.style.top = '12px'
|
||||
btn.style.left = '12px'
|
||||
closeBtn.style.top = '12px'
|
||||
closeBtn.style.left = '60px'
|
||||
} else {
|
||||
// 小窗口:白色幽灵按钮停靠在蓝色顶栏右侧,避开 iframe 内部右上角的重置按钮
|
||||
btn.style.top = rect.top + 12 + 'px'
|
||||
btn.style.left = rect.right - 132 + 'px'
|
||||
closeBtn.style.top = rect.top + 12 + 'px'
|
||||
closeBtn.style.left = rect.right - 92 + 'px'
|
||||
}
|
||||
if (inTransition) {
|
||||
// 过渡期:版权可能出现在顶部或底部,两处都盖住并跟随窗口动画;
|
||||
// 顶部遮盖的配色须与当前状态的 iframe 背景一致
|
||||
cover.style.left = rect.left + 'px'
|
||||
cover.style.top = rect.top + 'px'
|
||||
cover.style.width = rect.width + 'px'
|
||||
cover.style.height = '100px'
|
||||
cover.style.borderRadius = fullscreen ? '0' : '1rem 1rem 0 0'
|
||||
cover.style.background = fullscreen
|
||||
? '#f7f8fc'
|
||||
: 'linear-gradient(to bottom, #1c64f2 0, #1c64f2 56px, #f7f8fc 56px)'
|
||||
transitionCover.style.display = 'block'
|
||||
transitionCover.style.left = rect.left + 'px'
|
||||
transitionCover.style.top = rect.bottom - BRAND_BAR_HEIGHT + 'px'
|
||||
transitionCover.style.bottom = 'auto'
|
||||
transitionCover.style.width = rect.width + 'px'
|
||||
transitionCover.style.height = BRAND_BAR_HEIGHT + 'px'
|
||||
transitionCover.style.background = '#f7f8fc'
|
||||
return
|
||||
}
|
||||
transitionCover.style.display = 'none'
|
||||
if (fullscreen) {
|
||||
// 全屏:版权信息在顶栏右侧,遮到窗口右边缘
|
||||
cover.style.left = rect.right - 390 + 'px'
|
||||
cover.style.top = rect.top + 'px'
|
||||
cover.style.width = '390px'
|
||||
cover.style.height = '56px'
|
||||
cover.style.borderRadius = '0'
|
||||
cover.style.background = '#f7f8fc'
|
||||
} else if (rect.width >= WIDE_BREAKPOINT) {
|
||||
// 宽窗口(浏览器缩放等场景):版权信息在顶栏右侧
|
||||
cover.style.left = rect.right - 390 + 'px'
|
||||
cover.style.top = rect.top + 'px'
|
||||
cover.style.width = '390px'
|
||||
cover.style.height = '84px'
|
||||
cover.style.borderRadius = '0'
|
||||
cover.style.background = '#f7f8fc'
|
||||
} else {
|
||||
// 窄窗口布局:版权条横贯底部
|
||||
cover.style.left = rect.left + 'px'
|
||||
cover.style.top = rect.bottom - BRAND_BAR_HEIGHT + 'px'
|
||||
cover.style.width = rect.width + 'px'
|
||||
cover.style.height = BRAND_BAR_HEIGHT + 'px'
|
||||
cover.style.borderRadius = '0 0 1rem 1rem'
|
||||
cover.style.background = '#f2f4f7'
|
||||
}
|
||||
}
|
||||
// 监听 iframe 的创建及 display 切换(embed.min.js 通过内联 style 开关窗口),
|
||||
// 再加低频轮询兜底,跟住窗口尺寸过渡动画和视口变化
|
||||
var observer = new MutationObserver(sync)
|
||||
observer.observe(document.body, {
|
||||
childList: true,
|
||||
subtree: true,
|
||||
attributes: true,
|
||||
attributeFilter: ['style', 'class']
|
||||
})
|
||||
window.addEventListener('resize', sync)
|
||||
window.addEventListener('keydown', function (event) {
|
||||
if (event.key !== 'Escape') return
|
||||
var win = document.getElementById('dify-chatbot-bubble-window')
|
||||
if (win && win.classList.contains('dify-chatbot-fullscreen')) {
|
||||
win.classList.remove('dify-chatbot-fullscreen')
|
||||
startTransition()
|
||||
}
|
||||
})
|
||||
setInterval(sync, 300)
|
||||
sync()
|
||||
})()
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
<link rel="stylesheet" crossorigin href="/admin/assets/index-ynJZC2Ez.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app">
|
||||
<div class="preload">
|
||||
<svg viewBox="25 25 50 50" class="circular">
|
||||
<circle cx="50" cy="50" r="20" fill="none" class="path"></circle>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// Dify 聊天窗口全屏切换:#dify-chatbot-bubble-window 是 iframe 本身,
|
||||
// 无法往其内部挂按钮,故在气泡旁放一个独立按钮,窗口打开时才显示
|
||||
(function () {
|
||||
var btn = document.createElement('button')
|
||||
btn.type = 'button'
|
||||
btn.id = 'dify-fullscreen-toggle'
|
||||
btn.title = '全屏 / 还原'
|
||||
btn.textContent = '⛶'
|
||||
var transitionUntil = 0
|
||||
// 全屏切换(放大和还原都算)后的过渡期:Dify 内部重排期间版权位置不定,
|
||||
// 用大面积遮盖兜底,并逐帧跟踪窗口尺寸动画
|
||||
function startTransition() {
|
||||
transitionUntil = Date.now() + TRANSITION_MS
|
||||
function loop() {
|
||||
sync()
|
||||
if (Date.now() < transitionUntil) requestAnimationFrame(loop)
|
||||
}
|
||||
loop()
|
||||
}
|
||||
btn.addEventListener('click', function () {
|
||||
var win = document.getElementById('dify-chatbot-bubble-window')
|
||||
if (!win) return
|
||||
win.classList.toggle('dify-chatbot-fullscreen')
|
||||
startTransition()
|
||||
})
|
||||
document.body.appendChild(btn)
|
||||
|
||||
// 自定义关闭按钮:窗口打开时气泡被隐藏,由它代替气泡的关闭功能
|
||||
var closeBtn = document.createElement('button')
|
||||
closeBtn.type = 'button'
|
||||
closeBtn.id = 'dify-chat-close'
|
||||
closeBtn.title = '关闭'
|
||||
closeBtn.textContent = '✕'
|
||||
closeBtn.addEventListener('click', function () {
|
||||
var win = document.getElementById('dify-chatbot-bubble-window')
|
||||
var difyBubble = document.getElementById('dify-chatbot-bubble-button')
|
||||
if (win) win.classList.remove('dify-chatbot-fullscreen')
|
||||
// 复用 embed.min.js 的开关逻辑,保证气泡图标状态同步
|
||||
if (difyBubble) difyBubble.click()
|
||||
sync()
|
||||
})
|
||||
document.body.appendChild(closeBtn)
|
||||
|
||||
// 隐藏 Dify 头部自带的展开按钮:该按钮仅在收到 isToggledByButton:true 时渲染
|
||||
// (embed.min.js 默认发送),在其后补发 false 覆盖即可
|
||||
var DIFY_ORIGIN = 'https://ai.zhenyangtang.com.cn'
|
||||
window.addEventListener('message', function (event) {
|
||||
if (event.origin !== DIFY_ORIGIN) return
|
||||
if (!event.data || event.data.type !== 'dify-chatbot-iframe-ready') return
|
||||
var win = document.getElementById('dify-chatbot-bubble-window')
|
||||
if (!win || event.source !== win.contentWindow) return
|
||||
setTimeout(function () {
|
||||
win.contentWindow.postMessage(
|
||||
{
|
||||
type: 'dify-chatbot-config',
|
||||
payload: { isToggledByButton: false, isDraggable: false }
|
||||
},
|
||||
DIFY_ORIGIN
|
||||
)
|
||||
}, 200)
|
||||
})
|
||||
|
||||
var cover = document.createElement('div')
|
||||
cover.id = 'dify-brand-cover'
|
||||
document.body.appendChild(cover)
|
||||
var transitionCover = document.createElement('div')
|
||||
transitionCover.id = 'dify-brand-transition-cover'
|
||||
document.body.appendChild(transitionCover)
|
||||
|
||||
var BRAND_BAR_HEIGHT = 38
|
||||
// 全屏后 Dify 内部布局重排的过渡时长,期间用大面积遮盖兜底
|
||||
var TRANSITION_MS = 1500
|
||||
// Dify 宽屏布局断点 40rem:窄窗口版权条在底部,宽窗口(展开/全屏)移到顶栏右侧
|
||||
var WIDE_BREAKPOINT = 640
|
||||
|
||||
function sync() {
|
||||
var win = document.getElementById('dify-chatbot-bubble-window')
|
||||
var opened = win && win.style.display !== 'none'
|
||||
var difyBubble = document.getElementById('dify-chatbot-bubble-button')
|
||||
btn.style.display = opened ? 'block' : 'none'
|
||||
closeBtn.style.display = opened ? 'block' : 'none'
|
||||
if (!opened) {
|
||||
cover.style.display = 'none'
|
||||
transitionCover.style.display = 'none'
|
||||
// 窗口关闭后恢复气泡(可拖动)
|
||||
if (difyBubble) difyBubble.style.display = ''
|
||||
return
|
||||
}
|
||||
var rect = win.getBoundingClientRect()
|
||||
var fullscreen = win.classList.contains('dify-chatbot-fullscreen')
|
||||
var inTransition = Date.now() < transitionUntil
|
||||
cover.style.display = 'block'
|
||||
// 窗口打开期间隐藏气泡(气泡可能被拖到任意位置,浮在窗口上很突兀),
|
||||
// 控制按钮统一停靠在窗口顶栏
|
||||
if (difyBubble) difyBubble.style.display = 'none'
|
||||
btn.classList.toggle('is-fullscreen', fullscreen)
|
||||
closeBtn.classList.toggle('is-fullscreen', fullscreen)
|
||||
if (fullscreen) {
|
||||
// 全屏:实色圆钮放左上角,避开右上角版权遮盖区和底部输入区
|
||||
btn.style.top = '12px'
|
||||
btn.style.left = '12px'
|
||||
closeBtn.style.top = '12px'
|
||||
closeBtn.style.left = '60px'
|
||||
} else {
|
||||
// 小窗口:白色幽灵按钮停靠在蓝色顶栏右侧,避开 iframe 内部右上角的重置按钮
|
||||
btn.style.top = rect.top + 12 + 'px'
|
||||
btn.style.left = rect.right - 132 + 'px'
|
||||
closeBtn.style.top = rect.top + 12 + 'px'
|
||||
closeBtn.style.left = rect.right - 92 + 'px'
|
||||
}
|
||||
if (inTransition) {
|
||||
// 过渡期:版权可能出现在顶部或底部,两处都盖住并跟随窗口动画;
|
||||
// 顶部遮盖的配色须与当前状态的 iframe 背景一致
|
||||
cover.style.left = rect.left + 'px'
|
||||
cover.style.top = rect.top + 'px'
|
||||
cover.style.width = rect.width + 'px'
|
||||
cover.style.height = '100px'
|
||||
cover.style.borderRadius = fullscreen ? '0' : '1rem 1rem 0 0'
|
||||
cover.style.background = fullscreen
|
||||
? '#f7f8fc'
|
||||
: 'linear-gradient(to bottom, #1c64f2 0, #1c64f2 56px, #f7f8fc 56px)'
|
||||
transitionCover.style.display = 'block'
|
||||
transitionCover.style.left = rect.left + 'px'
|
||||
transitionCover.style.top = rect.bottom - BRAND_BAR_HEIGHT + 'px'
|
||||
transitionCover.style.bottom = 'auto'
|
||||
transitionCover.style.width = rect.width + 'px'
|
||||
transitionCover.style.height = BRAND_BAR_HEIGHT + 'px'
|
||||
transitionCover.style.background = '#f7f8fc'
|
||||
return
|
||||
}
|
||||
transitionCover.style.display = 'none'
|
||||
if (fullscreen) {
|
||||
// 全屏:版权信息在顶栏右侧,遮到窗口右边缘
|
||||
cover.style.left = rect.right - 390 + 'px'
|
||||
cover.style.top = rect.top + 'px'
|
||||
cover.style.width = '390px'
|
||||
cover.style.height = '56px'
|
||||
cover.style.borderRadius = '0'
|
||||
cover.style.background = '#f7f8fc'
|
||||
} else if (rect.width >= WIDE_BREAKPOINT) {
|
||||
// 宽窗口(浏览器缩放等场景):版权信息在顶栏右侧
|
||||
cover.style.left = rect.right - 390 + 'px'
|
||||
cover.style.top = rect.top + 'px'
|
||||
cover.style.width = '390px'
|
||||
cover.style.height = '84px'
|
||||
cover.style.borderRadius = '0'
|
||||
cover.style.background = '#f7f8fc'
|
||||
} else {
|
||||
// 窄窗口布局:版权条横贯底部
|
||||
cover.style.left = rect.left + 'px'
|
||||
cover.style.top = rect.bottom - BRAND_BAR_HEIGHT + 'px'
|
||||
cover.style.width = rect.width + 'px'
|
||||
cover.style.height = BRAND_BAR_HEIGHT + 'px'
|
||||
cover.style.borderRadius = '0 0 1rem 1rem'
|
||||
cover.style.background = '#f2f4f7'
|
||||
}
|
||||
}
|
||||
// 监听 iframe 的创建及 display 切换(embed.min.js 通过内联 style 开关窗口),
|
||||
// 再加低频轮询兜底,跟住窗口尺寸过渡动画和视口变化
|
||||
var observer = new MutationObserver(sync)
|
||||
observer.observe(document.body, {
|
||||
childList: true,
|
||||
subtree: true,
|
||||
attributes: true,
|
||||
attributeFilter: ['style', 'class']
|
||||
})
|
||||
window.addEventListener('resize', sync)
|
||||
window.addEventListener('keydown', function (event) {
|
||||
if (event.key !== 'Escape') return
|
||||
var win = document.getElementById('dify-chatbot-bubble-window')
|
||||
if (win && win.classList.contains('dify-chatbot-fullscreen')) {
|
||||
win.classList.remove('dify-chatbot-fullscreen')
|
||||
startTransition()
|
||||
}
|
||||
})
|
||||
setInterval(sync, 300)
|
||||
sync()
|
||||
})()
|
||||
</script>
|
||||
</body>
|
||||
|
||||
Reference in New Issue
Block a user