/* v22 part1: DOM dump + header login btn */
(function () {
'use strict';
if (window.__mobV22) return;
window.__mobV22 = true;
function $(id) { return document.getElementById(id); }
var API = 'https://api-gateway.duoweiying.cn';
var GUEST = 'v20_guest';
function logged() {
try { return !!localStorage.getItem('user_token') || localStorage.getItem(GUEST) === '1'; } catch (e) { return false; }
}
/* ---- console 输出当前真实 DOM 结构(供精准修复样式) ---- */
function dumpDOM() {
try {
var lines = [];
function info(el, tag) {
if (!el) return;
lines.push(tag + ' tag=' + el.tagName + ' id=' + (el.id || '-') + ' cls=' + (el.className && String(el.className).slice(0, 90) || '-'));
}
info(document.querySelector('.mobile-header'), 'HEADER');
info(document.querySelector('.mobile-header h1'), 'H1');
var fn = $('function-nav'); if (fn) { info(fn, 'FN-NAV'); var b0 = fn.querySelector('button'); if (b0) { info(b0, 'FN-BTN0'); lines.push('FN-BTN0 style=' + (b0.getAttribute('style') || '').slice(0, 160)); } }
info($('chat-container'), 'CHAT');
info($('ai-chat-wrapper'), 'WRAP');
var w = $('ai-chat-wrapper'); if (w) { var m = w.querySelector('.message-bubble'); if (m) info(m, 'BUBBLE'); }
info($('chat-input'), 'INPUT');
var sb = document.querySelector('button.send-btn, [id*="send"]'); if (sb) { info(sb, 'SEND'); lines.push('SEND style=' + (sb.getAttribute('style') || '').slice(0, 200)); }
var nav = document.querySelector('.bottom-nav'); if (nav) { info(nav, 'BNAV'); var nb = nav.querySelectorAll('button'); lines.push('BNAV buttons=' + nb.length); for (var i = 0; i < nb.length && i < 6; i++) info(nb[i], 'NAV' + i); }
var loginEl = $('login-form-container');
if (loginEl) lines.push('LOGIN-FORM-C display=' + loginEl.style.display + ' (default css class present)');
lines.push('guest=' + (localStorage.getItem(GUEST) || '0') + ' token=' + (localStorage.getItem('user_token') ? 'yes' : 'no'));
lines.forEach(function (l) { console.log('[V22-DOM] ' + l); });
} catch (e) { console.log('[V22-DOM] err ' + e.message); }
}
window.__mobV22Dump = dumpDOM;
/* v22 part2: self login layer + topbar login btn */
/* ---- 自建顶部登录按钮 ---- */
function topLoginBtn() {
try {
if ($('v22LoginBtn')) return;
var bar = document.createElement('div');
bar.style.cssText = 'position:absolute;right:6px;top:50%;transform:translateY(-50%);z-index:5;';
var a = document.createElement('span');
a.id = 'v22LoginBtn';
a.style.cssText = 'font-size:12px;color:#475569;border:1px solid #cbd5e1;border-radius:13px;padding:3px 11px;cursor:pointer;background:#fff;';
a.textContent = '登录';
a.onclick = function () { openLoginLayer(); };
bar.appendChild(a);
var hd = document.querySelector('.mobile-header');
if (hd) { hd.style.position = 'relative'; hd.appendChild(bar); }
} catch (e) {}
}
/* ---- 自建登录层(独立 DOM,不依赖任何旧登录 UI) ---- */
function openLoginLayer() {
try {
if ($('v22Login')) return;
var ov = document.createElement('div');
ov.id = 'v22Login';
ov.style.cssText = 'position:fixed;inset:0;z-index:40000;background:rgba(15,23,42,.55);display:flex;align-items:center;justify-content:center;';
ov.innerHTML =
'
' +
'
多维鹰 · 账号登录' +
'×
' +
'
登录后余额/订阅/素材/任务与桌面、公众号互通
' +
'
' +
'' +
'
' +
'
' +
'' +
'' +
'
' +
'
' +
'
' +
'
';
document.body.appendChild(ov);
var X = $('v22X'); if (X) X.onclick = function () { ov.remove(); };
ov.addEventListener('click', function (e) { if (e.target === ov) ov.remove(); });
$('v22TLogin').onclick = function () { showF('login'); };
$('v22TReg').onclick = function () { showF('reg'); };
$('v22Go').onclick = function () { doAuth('login'); };
$('v22RGo').onclick = function () { doAuth('register'); };
$('v22Guest').onclick = function () { ov.remove(); try { localStorage.setItem(GUEST, '1'); } catch (e) {} location.reload(); };
function showF(k) {
$('v22LoginForm').style.display = k === 'login' ? 'block' : 'none';
$('v22RegForm').style.display = k === 'reg' ? 'block' : 'none';
$('v22TLogin').style.background = k === 'login' ? '#334155' : '#fff';
$('v22TLogin').style.color = k === 'login' ? '#fff' : '#475569';
$('v22TReg').style.background = k === 'reg' ? '#334155' : '#fff';
$('v22TReg').style.color = k === 'reg' ? '#fff' : '#475569';
}
} catch (e) {}
}
function msg22(t) { var m = $('v22Msg'); if (m) m.textContent = t; }
/* v22 part3: auth + boot */
function doAuth(kind) {
var u, p, e, agree;
if (kind === 'login') {
u = ($('v22U') || {}).value || '';
p = ($('v22P') || {}).value || '';
if (!u || !p) { msg22('请输入用户名与密码'); return; }
msg22('登录中…');
fetch(API + '/api/auth/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username: u, password: p }) })
.then(function (r) { return r.json(); })
.then(function (d) {
/* WR-550: 兼容 access_token / data.token,避免登录成功却不落 user_token */
var _tk = (d && (d.token || d.access_token)) || (d && d.data && (d.data.token || d.data.access_token)) || '';
var _u2 = (d && (d.user || d.data)) || {};
if (_tk) {
try {
localStorage.setItem('user_token', _tk);
localStorage.setItem('user_info', JSON.stringify({ id: _u2.id || u, username: _u2.username || _u2.nickname || u }));
localStorage.setItem('user_id', _u2.id || u);
} catch (e2) {}
location.reload();
} else { msg22('登录失败:' + ((d && (d.message || d.detail || d.msg)) || '用户名或密码错误')); }
}).catch(function () { msg22('网络错误,请重试'); });
} else {
u = ($('v22RU') || {}).value || '';
e = ($('v22RE') || {}).value || '';
p = ($('v22RP') || {}).value || '';
agree = $('v22Agree');
if (!u || !p) { msg22('请填写用户名与密码'); return; }
if (p.length < 6) { msg22('密码至少 6 位'); return; }
if (agree && !agree.checked) { msg22('请先勾选同意《用户协议与隐私政策》'); return; }
msg22('注册中…');
var body = { username: u, password: p };
if (e) body.email = e;
fetch(API + '/api/auth/register', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body) })
.then(function (r) { return r.json(); })
.then(function (d) {
if (d && (d.user || d.success || d.id)) {
msg22('✅ 注册成功,正在自动登录…');
fetch(API + '/api/auth/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username: u, password: p }) })
.then(function (r2) { return r2.json(); })
.then(function (d2) {
var _tk2 = (d2 && (d2.token || d2.access_token)) || (d2 && d2.data && (d2.data.token || d2.data.access_token)) || '';
var _u3 = (d2 && (d2.user || d2.data)) || {};
if (_tk2) {
try {
localStorage.setItem('user_token', _tk2);
localStorage.setItem('user_info', JSON.stringify({ id: _u3.id || u, username: _u3.username || _u3.nickname || u }));
localStorage.setItem('user_id', _u3.id || u);
} catch (e3) {}
location.reload();
} else { location.reload(); }
}).catch(function () { location.reload(); });
} else { msg22('注册失败:' + ((d && d.message) || '用户名可能已存在')); }
}).catch(function () { msg22('网络错误,请重试'); });
}
}
function topUserChip() {
try {
if ($('v22UserChip')) return;
var u = null; try { u = JSON.parse(localStorage.getItem('user_info') || '{}'); } catch (e) {}
var nm = (u && (u.nickname || u.username)) || '已登录';
var chip = document.createElement('div');
chip.id = 'v22UserChip';
chip.style.cssText = 'position:absolute;right:6px;top:50%;transform:translateY(-50%);z-index:5;display:flex;align-items:center;gap:5px;font-size:12px;color:#334155;border:1px solid #cbd5e1;border-radius:13px;padding:3px 11px;cursor:pointer;background:#fff;max-width:44%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;';
chip.innerHTML = '👤' + String(nm).replace(/[<>&"]/g, function (c) { return { '<': '<', '>': '>', '&': '&', '"': '"' }[c]; }) + '';
chip.onclick = function () { try { if (typeof window.switchTab === 'function') window.switchTab('profile'); else if (typeof window.mobGo === 'function') window.mobGo('profile'); } catch (e) {} };
var hd = document.querySelector('.mobile-header');
if (hd) { hd.style.position = 'relative'; hd.appendChild(chip); }
} catch (e) {}
}
function bootV22() {
try {
dumpDOM();
var lg = logged();
if (!lg) { topLoginBtn(); }
else if (localStorage.getItem(GUEST) === '1') { topLoginBtn(); }
else { topUserChip(); }
console.log('[MobV22] ready token=' + (localStorage.getItem('user_token') ? 'yes' : 'no') + ' guest=' + (localStorage.getItem(GUEST) || '0'));
} catch (e) { console.log('[MobV22] boot err ' + e.message); }
}
window.__mobV22ShowLogin = openLoginLayer;
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', bootV22);
else bootV22();
setTimeout(bootV22, 1200);
setTimeout(bootV22, 3000);
})();