diff --git a/assets/inject/recovery.js b/assets/inject/recovery.js index 9637b63..0646aa9 100644 --- a/assets/inject/recovery.js +++ b/assets/inject/recovery.js @@ -35,63 +35,55 @@ var st = document.createElement('style'); st.id = '__dshRecoverCss'; // 档案 77 视觉升级:整套样式一次性注入(含 prefers-reduced-motion 回退)。 + // 2026-09-21 二次改造:浮层标记换成**用户提供的标记本体**(六边形芯片 + 节点网络 + 青紫辉光)。 + // 上一版是按 web/favicon.svg 复刻的三辐条 hub —— 那是错源:该 svg 已不是站点图标, + // 页面 head 早已改引 /favicon.png。现在浮层直接引用**与站点图标同一份**静态资源 + // (/favicon-192.png),从根上消除"浮层图标 ≠ 站点图标"。 + // 动画职责改由标记外围承担:虚线环缓转 + 青紫光晕呼吸 + 标记脉冲; + // 进入 = 缩放淡入;失败 = .__dsh-fail(标记转灰 + 环/晕转 --danger #e5484d)。 + // ⛔ 不再出现旧 DeepSeek 品牌蓝 #4d7cfe(紫色统一用新标记的 #7c58ff)。 // ⚠️ 本文件是注入脚本的模板字面量 —— 内容不得含反引号 / 美元花括号; // 故 CSS 里的字体名一律用单引号('Segoe UI'),JS 字符串用双引号。 st.textContent = [ + "@keyframes __dshr-in{0%{transform:scale(.8)}60%{transform:scale(1.05)}100%{transform:scale(1)}}", "@keyframes __dshr-spin{to{transform:rotate(360deg)}}", - "@keyframes __dshr-spin-rev{to{transform:rotate(-360deg)}}", - "@keyframes __dshr-core{0%,100%{transform:scale(.82);opacity:.6}50%{transform:scale(1.12);opacity:1}}", - "@keyframes __dshr-halo{0%,100%{opacity:.45;transform:scale(.96)}50%{opacity:.9;transform:scale(1.04)}}", + "@keyframes __dshr-halo{0%,100%{opacity:.42;transform:scale(.94)}50%{opacity:.85;transform:scale(1.08)}}", "@keyframes __dshr-scan{0%{transform:translateX(-115%)}100%{transform:translateX(275%)}}", - "@keyframes __dshr-dot{0%,100%{opacity:.25}50%{opacity:1}}", "@keyframes __dshr-sheen{0%{background-position:190% 0}100%{background-position:-90% 0}}", ".__dsh-ov{", "position:fixed;inset:0;z-index:2147483647;display:flex;align-items:center;justify-content:center;", - "background:radial-gradient(900px 460px at 50% 26%, rgba(88,166,255,.13), transparent 62%),radial-gradient(760px 420px at 50% 84%, rgba(163,113,247,.13), transparent 62%),rgba(9,11,16,.9);", + "background:radial-gradient(880px 460px at 50% 26%, rgba(56,214,208,.12), transparent 62%),radial-gradient(720px 420px at 50% 86%, rgba(124,88,255,.12), transparent 64%),rgba(8,15,28,.92);", "}", ".__dsh-card{", "position:relative;display:flex;flex-direction:column;align-items:center;gap:13px;", "padding:26px 34px 22px;border-radius:16px;", - "background:linear-gradient(180deg, rgba(26,31,43,.86), rgba(17,21,30,.86));", - "box-shadow:0 1px 0 rgba(255,255,255,.06) inset,0 0 0 1px rgba(120,150,210,.16),0 18px 48px rgba(0,0,0,.5);", + "background:linear-gradient(180deg, rgba(18,31,52,.88), rgba(10,18,33,.92));", + "box-shadow:0 1px 0 rgba(255,255,255,.05) inset,0 0 0 1px rgba(56,214,208,.20),0 18px 48px rgba(0,0,0,.55);", "-webkit-backdrop-filter:blur(9px);backdrop-filter:blur(9px);", "}", - ".__dsh-orb{position:relative;width:86px;height:86px}", - ".__dsh-halo{", - "position:absolute;inset:-20px;border-radius:50%;", - "background:radial-gradient(circle, rgba(88,166,255,.30), rgba(163,113,247,.17) 46%, transparent 70%);", - "animation:__dshr-halo 2.6s ease-in-out infinite;", - "}", - ".__dsh-arc{", - "position:absolute;inset:0;border-radius:50%;", - "background:conic-gradient(from 0deg, rgba(88,166,255,0) 0deg, rgba(88,166,255,.06) 110deg, #58a6ff 296deg, #a371f7 342deg, rgba(163,113,247,0) 360deg);", - "-webkit-mask:radial-gradient(farthest-side, transparent calc(100% - 3px), #000 calc(100% - 2px));", - "mask:radial-gradient(farthest-side, transparent calc(100% - 3px), #000 calc(100% - 2px));", - "animation:__dshr-spin 1.5s linear infinite;", - "}", - ".__dsh-arc2{position:absolute;inset:13px;border-radius:50%;border:1px dashed rgba(163,113,247,.42);animation:__dshr-spin-rev 7s linear infinite}", - ".__dsh-ring{position:absolute;inset:24px;border-radius:50%;border:1px solid rgba(120,160,230,.20)}", - ".__dsh-core{", - "position:absolute;left:50%;top:50%;width:14px;height:14px;margin:-7px 0 0 -7px;border-radius:50%;", - "background:radial-gradient(circle, #eaf3ff 0%, #66b0ff 46%, rgba(88,166,255,0) 74%);", - "box-shadow:0 0 12px rgba(88,166,255,.85),0 0 34px rgba(163,113,247,.45);", - "animation:__dshr-core 1.6s ease-in-out infinite;", - "}", - ".__dsh-dots{position:absolute;inset:0;animation:__dshr-spin 3.4s linear infinite}", - ".__dsh-dots i{position:absolute;left:50%;top:-2px;width:5px;height:5px;margin-left:-2.5px;border-radius:50%;background:#a371f7;box-shadow:0 0 8px #a371f7;animation:__dshr-dot 1.4s ease-in-out infinite}", - ".__dsh-dots i:nth-child(2){top:auto;bottom:-2px;animation-delay:.35s;background:#58a6ff;box-shadow:0 0 8px #58a6ff}", - ".__dsh-dots i:nth-child(3){left:-2px;top:50%;margin:-2.5px 0 0 0;animation-delay:.7s;background:#7ee0c0;box-shadow:0 0 8px #7ee0c0}", + ".__dsh-hub{position:relative;width:132px;height:132px;display:flex;align-items:center;justify-content:center}", + ".__dsh-hub-halo{position:absolute;inset:-20px;border-radius:50%;background:radial-gradient(circle, rgba(56,214,208,.30), rgba(124,88,255,.16) 46%, transparent 70%);animation:__dshr-halo 2.8s ease-in-out infinite}", + ".__dsh-hub-ring{position:absolute;inset:-9px;border-radius:50%;border:1px dashed rgba(56,214,208,.42);animation:__dshr-spin 9s linear infinite}", + "/* 标记上只挂一个动画:两个动画抢同一属性时后声明的会覆盖前者,会让标记停在 0% 不可见 */", + "/* (2026-09-21 实测:pulse 覆盖 in 的 opacity 后 opacity=0,图片已加载也照样看不见)。 */", + "/* 呼吸感由 .__dsh-hub-halo 的 __dshr-halo 负责,旋转感由 .__dsh-hub-ring 负责。 */", + "/* ⛔ 抠底标记禁用 box-shadow:它沿**元素矩形边界**绘制 ⇒ 会在透明图外面画出一圈方形光晕, */", + "/* 看起来就像又加了个矩形底(2026-09-21 实测)。发光必须用 filter:drop-shadow,它跟随 alpha 轮廓。 */", + ".__dsh-hub-icon{position:relative;z-index:2;display:block;width:132px;height:132px;filter:drop-shadow(0 0 16px rgba(56,214,208,.55)) drop-shadow(0 0 40px rgba(124,88,255,.42));animation:__dshr-in .62s cubic-bezier(.22,.9,.24,1) both}", + ".__dsh-fail .__dsh-hub-icon{filter:grayscale(.75) brightness(.62) contrast(1.05) drop-shadow(0 0 16px rgba(229,72,77,.5));animation:none}", + ".__dsh-fail .__dsh-hub-ring{border-color:rgba(229,72,77,.5);animation:none}", + ".__dsh-fail .__dsh-hub-halo{background:radial-gradient(circle, rgba(229,72,77,.24), transparent 70%);animation:none}", ".__dsh-msg{", "font:14.5px/1.6 system-ui,-apple-system,'Segoe UI',sans-serif;color:#e9f1fa;letter-spacing:.2px;text-align:center;", - "background:linear-gradient(90deg, rgba(233,241,250,.94) 0%, #ffffff 48%, rgba(233,241,250,.94) 96%);", + "background:linear-gradient(90deg, rgba(233,241,250,.94) 0%, #ffffff 48%, rgba(214,247,245,.94) 96%);", "-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;", "background-size:230% 100%;animation:__dshr-sheen 3s linear infinite;", "}", - ".__dsh-label{font:11px/1.4 ui-monospace,SFMono-Regular,Menlo,monospace;letter-spacing:.16em;color:rgba(150,175,215,.72);text-transform:uppercase}", + ".__dsh-label{font:11px/1.4 ui-monospace,SFMono-Regular,Menlo,monospace;letter-spacing:.16em;color:rgba(140,192,196,.72);text-transform:uppercase}", ".__dsh-track{position:relative;width:208px;height:3px;border-radius:3px;background:rgba(255,255,255,.09);overflow:hidden}", - ".__dsh-track i{position:absolute;top:0;bottom:0;width:42%;border-radius:3px;background:linear-gradient(90deg, transparent, #58a6ff 45%, #a371f7 70%, transparent);animation:__dshr-scan 1.45s ease-in-out infinite}", + ".__dsh-track i{position:absolute;top:0;bottom:0;width:42%;border-radius:3px;background:linear-gradient(90deg, transparent, #38d6d0 45%, #7c58ff 70%, transparent);animation:__dshr-scan 1.45s ease-in-out infinite}", "@media (prefers-reduced-motion: reduce){", - ".__dsh-arc,.__dsh-arc2,.__dsh-dots,.__dsh-dots i,.__dsh-core,.__dsh-halo,.__dsh-track i,.__dsh-msg{animation:none!important}", + ".__dsh-hub-icon,.__dsh-hub-ring,.__dsh-hub-halo,.__dsh-track i,.__dsh-msg{animation:none!important}", "}" ].join(String.fromCharCode(10)); (document.head || document.documentElement).appendChild(st); @@ -105,22 +97,36 @@ box = document.createElement('div'); box.id = '__dshRecover'; box.className = '__dsh-ov'; - // 「AI 核心」加载体:扫描弧(conic 渐变)+ 反向虚线环 + 脉冲核心 + 三颗轨道粒子。 + // 品牌标记 = 与站点 favicon 同一份静态资源(web/favicon-192.png,平台在实例子域同源提供)。 // 全部 createElement 构建(不用 innerHTML —— 实例页可能启用 Trusted Types)。 var card = document.createElement('div'); card.className = '__dsh-card'; var orb = document.createElement('div'); - orb.className = '__dsh-orb'; - var parts = ['__dsh-halo', '__dsh-arc', '__dsh-arc2', '__dsh-ring', '__dsh-core']; - for (var i = 0; i < parts.length; i++) { - var el = document.createElement('div'); - el.className = parts[i]; - orb.appendChild(el); - } - var dots = document.createElement('div'); - dots.className = '__dsh-dots'; - for (var j = 0; j < 3; j++) dots.appendChild(document.createElement('i')); - orb.appendChild(dots); + orb.className = '__dsh-hub'; + var halo = document.createElement('div'); + halo.className = '__dsh-hub-halo'; + orb.appendChild(halo); + var ring = document.createElement('div'); + ring.className = '__dsh-hub-ring'; + orb.appendChild(ring); + // 静态资源取不到时只隐藏标记、保留光环(不出现破图)—— halo/ring 负责兜住存在感。 + var mark = document.createElement('img'); + mark.className = '__dsh-hub-icon'; + // 用**抠底发光版**(无方形底),不是带深色矩形底的 favicon-192.png —— 后者在浮层里 + // 是一块方块,与"发光标记"的观感不符(用户 2026-09-21 指正)。资源 = 用户标记的 + // transparent-glow 加工版(luma 斜坡抠底,只适合叠在深/中低明度底上,浮层正好是深底)。 + // ⚠️ 不能用子域相对路径:实例子域只放行 /favicon.svg,其它静态资源会被鉴权拦成 401 + // (实测 guest.ai1net.com/favicon-192.png = 401、design.css = 401)。改取**门户根域** + // (实测 https://ai1net.com/favicon-192.png = 200,且无 CORP/CORS 限制 ⇒ 跨域 img 可加载)。 + // 根域由当前 host 去掉首段推出(IP 或两级以内域名则原样使用)。 + var _hn = location.hostname, _hp = _hn.split('.'); + var _root = location.protocol + '//' + (/^[\d.]+$/.test(_hn) || _hp.length <= 2 ? _hn : _hp.slice(-2).join('.')) + + (location.port ? ':' + location.port : ''); + mark.src = _root + '/mark-glow-192.png'; + mark.alt = ''; + mark.decoding = 'async'; + mark.onerror = function () { mark.style.display = 'none'; }; + orb.appendChild(mark); var tx = document.createElement('div'); tx.id = '__dshRecoverMsg'; tx.className = '__dsh-msg'; @@ -287,9 +293,9 @@ b.textContent = '重试'; b.setAttribute( 'style', - 'margin-top:14px;padding:8px 18px;border:0;border-radius:8px;cursor:pointer;' + - 'font:14px/1 system-ui,-apple-system,sans-serif;color:#fff;' + - 'background:linear-gradient(135deg,#58a6ff,#a371f7);box-shadow:0 0 18px rgba(88,166,255,.35)' + 'margin-top:14px;padding:8px 18px;border:0;border-radius:8px;cursor:pointer;' + + 'font:14px/1 system-ui,-apple-system,sans-serif;color:#062028;font-weight:600;' + + 'background:linear-gradient(135deg,#38d6d0,#8af0e6);box-shadow:0 0 18px rgba(56,214,208,.4)' ); b.addEventListener('click', function () { recFirstAt = 0; // 手动重试 = 重置预算 @@ -305,6 +311,11 @@ recovering = true; // 保持在"不再自动恢复"的状态 hideBar(); ensureBox(); // 只建覆盖层,不启动 showPending 的秒表 + // 视觉切「失败态」:中心节点转警示红、辐条与外环节点熄灭(配色见 ensureCss 的 .__dsh-fail)。 + // 用宽匹配(不带 __dsh-hub 前缀)以兼容 hub 容器同时带两个类名的情况。 + var hub = document.getElementById('__dshRecover'); + hub = hub && hub.querySelector('.__dsh-hub'); + if (hub) hub.className = '__dsh-hub __dsh-fail'; setMsg('工作区暂时不可用(已连续尝试恢复 ' + RECOVER_MAX + ' 次)。可能是实例反复重启或资源不足 —— 可点下方「重试」,或稍后再来。'); addRetryButton(); } diff --git a/web/admin.html b/web/admin.html index 7e5f8bf..5caed30 100644 --- a/web/admin.html +++ b/web/admin.html @@ -4,7 +4,9 @@