/**
* 多维鹰 手机端 v11 优化补丁(2026-09-08)
* 独立补丁:不改动 index.html 既有逻辑文件;由 index.html 末尾一行 script 引入。
* 功能:视觉字号/品牌/欢迎语压缩 · 左上☰文字导航 · 底部导航压缩 ·
* switchTab 接通(定时任务/视频管理/我的/应用市场场景) · 应用市场(第二页, 目录文字模块) ·
* 点模块全屏操作台壳 · 相机拍摄上传 · 语音输入 · 左右滑动翻页
* 安全:全段 try 包裹,任一步失败不影响原功能;console 前缀 [MobV11]
*/
(function () {
'use strict';
if (window.__mobV11) return; window.__mobV11 = true;
function log() { try { console.log.apply(console, ['[MobV11]'].concat([].slice.call(arguments))); } catch (e) {} }
function $(id) { return document.getElementById(id); }
var API = 'https://api-gateway.duoweiying.cn';
function uid() { try { return (JSON.parse(localStorage.getItem('user_info') || '{}').id) || localStorage.getItem('user_id') || 'anonymous'; } catch (e) { return 'anonymous'; } }
// ============ 1. 样式覆盖(自适应压缩) ============
function injectStyle() {
var s = document.createElement('style');
s.id = 'mobv11css';
s.textContent = [
'html{font-size:16px}',
'.mobile-header{min-height:44px;padding:6px 10px!important}',
'.mobile-header h1{font-size:15px!important;margin:0!important;display:inline-flex;align-items:center;gap:6px}',
'.mobile-header #mobile-user-info button{font-size:18px;width:34px;height:34px;border:none;background:transparent}',
'#mobV11MenuBtn{background:none;border:none;font-size:22px;line-height:1;padding:4px 8px;cursor:pointer;color:#475569}',
'#chat-container h2,#chat-container p.big-intro{font-size:13px!important;font-weight:400;color:#94a3b8!important;margin:4px 0 2px!important}',
'.tab-container h2{font-size:16px!important;margin:0 0 10px 0!important}',
'#function-nav{flex-wrap:wrap;gap:6px;padding:6px 8px!important}',
'#function-nav button{font-size:12px!important;padding:6px 10px!important;margin:0!important;border-radius:14px!important}',
'.bottom-nav{min-height:52px!important;padding:4px 2px!important}',
'.bottom-nav .nav-item{padding:4px 2px!important}',
'.bottom-nav .nav-item span{font-size:12px!important;margin-top:2px!important}',
'.bottom-nav .nav-item span[style*="24px"]{font-size:19px!important}',
'#mobV11Welcome{font-size:12px;color:#94a3b8;padding:0 16px;line-height:1.6}',
'#mobMarketHead{display:flex;align-items:center;gap:6px;padding:8px 14px 0;font-size:13px;color:#0f172a}',
'.mob-app-group{background:#fff;border-radius:12px;margin:8px 10px;overflow:hidden}',
'.mob-app-group-title{font-size:13px;font-weight:600;color:#0f172a;padding:10px 12px 2px}',
'.mob-app-row{display:flex;align-items:center;gap:10px;padding:9px 12px;border-bottom:1px solid #f1f5f9;cursor:pointer}',
'.mob-app-row:last-child{border-bottom:none}',
'.mob-app-row .ic{font-size:17px;width:26px;text-align:center;flex:none}',
'.mob-app-row .nm{font-size:14px;color:#0f172a;flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}',
'.mob-app-row .dc{font-size:11px;color:#94a3b8;max-width:46%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}',
'.mob-app-row .ar{color:#cbd5e1;font-size:14px;flex:none}',
'.mob-app-row.locked{opacity:.55}',
'#mobPanel{position:fixed;inset:0;background:#fff;z-index:20000;display:none;flex-direction:column}',
'#mobPanel.open{display:flex}',
'#mobPanelHead{display:flex;align-items:center;gap:8px;padding:10px 12px;border-bottom:1px solid #f1f5f9;min-height:46px}',
'#mobPanelHead .t{font-size:16px;font-weight:600;color:#0f172a;flex:1}',
'#mobPanelHead button{background:none;border:none;font-size:20px;color:#94a3b8;cursor:pointer;padding:2px 8px}',
'#mobPanelBody{flex:1;overflow-y:auto;padding:12px;font-size:14px;color:#475569;line-height:1.8}',
'#mobV11Menu{position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(15,23,42,.45);z-index:21000;display:none}',
'#mobV11Menu.open{display:block}',
'#mobV11Menu .drawer{position:absolute;left:0;top:0;bottom:0;width:min(76vw,300px);background:#fff;padding:16px 6px;overflow-y:auto}',
'#mobV11Menu .drawer .mi{display:flex;align-items:center;gap:10px;padding:12px 14px;font-size:15px;color:#0f172a;border-radius:10px;cursor:pointer}',
'#mobV11Menu .drawer .mi:hover{background:#f1f5f9}',
'#mobV11Menu .drawer .grp{font-size:11px;color:#94a3b8;padding:10px 14px 4px;font-weight:600}',
'.mob-tab-ind{display:flex;gap:4px;justify-content:center;padding:2px 0 6px}',
'.mob-tab-ind i{width:6px;height:6px;border-radius:3px;background:#dbe3f5;display:inline-block}',
'.mob-tab-ind i.on{background:#667eea;width:14px}',
'#mobV11Mic{background:none;border:none;font-size:20px;cursor:pointer;padding:2px 6px;color:#667eea}',
'#mobV11Brand{color:#667eea;font-weight:700}'
].join('\n');
document.head.appendChild(s);
}
// ============ 2. 头部改造:品牌 + 左上角☰ ============
function fixHeader() {
try {
var h1 = document.querySelector('.mobile-header h1');
if (h1) {
var txt = h1.textContent || '';
h1.innerHTML = '';
var b = document.createElement('button'); b.id = 'mobV11MenuBtn'; b.textContent = '☰'; b.setAttribute('aria-label', '导航菜单');
b.onclick = function (e) { e.stopPropagation(); openMenu(); };
h1.appendChild(b);
var brand = document.createElement('span'); brand.innerHTML = '多维鹰 AI 智能中控台';
h1.appendChild(brand);
}
} catch (e) { log('header', e.message); }
// 欢迎大字 → 小字引导
try {
var w = document.querySelector('#chat-container h2');
if (w) {
w.id = 'mobV11Welcome';
w.innerHTML = '';
w.textContent = '我是多维鹰 AI 助手,可以说说需求,也可以点 ☰ 或滑动进入「应用市场」使用功能';
}
} catch (e) { log('welcome', e.message); }
}
// ============ 3. 左上角文字导航抽屉 ============
var MENU_ITEMS = [
{ grp: '主场景' },
{ t: '🏠 对话首页', go: 'home' },
{ t: '🧩 应用市场', go: 'market' },
{ t: '⏰ 定时任务', go: 'tasks' },
{ t: '🎬 视频管理', go: 'video' },
{ t: '👤 我的', go: 'profile' },
{ grp: '常用工具' },
{ t: '🔔 通知中心', go: 'notify' },
{ t: '📡 发布中心', go: 'publish' },
{ t: '⚙️ 个人设置', go: 'settings' },
{ t: '🔑 API Key', go: 'apikey' },
{ grp: '账号' },
{ t: '❓ 帮助', go: 'help' }
];
function openMenu() {
try {
var old = $('mobV11Menu'); if (old) old.remove();
var m = document.createElement('div'); m.id = 'mobV11Menu'; m.className = 'open';
var d = document.createElement('div'); d.className = 'drawer';
d.innerHTML = MENU_ITEMS.map(function (it) {
if (it.grp) return '
' + it.grp + '
';
return '' + it.t + '
';
}).join('');
d.addEventListener('click', function (e) {
var row = e.target.closest && e.target.closest('.mi');
if (!row) return;
m.remove();
var go = row.getAttribute('data-go');
mobGo(go);
});
m.appendChild(d);
m.addEventListener('click', function (e) { if (e.target === m) m.remove(); });
document.body.appendChild(m);
} catch (e) { log('menu', e.message); }
}
function mobGo(go) {
if (go === 'home' || go === 'market' || go === 'tasks' || go === 'video' || go === 'profile') { switchTabSafe(go === 'tasks' ? 'tasks' : go); return; }
if (go === 'notify') { if (window.mksOpenModule) { window.mksOpenModule({ id: 'tool_notify', name: '通知中心', type: 'tool' }); return; } openMobNotify(); return; }
if (go === 'publish') { if (window.mksOpenModule) { window.mksOpenModule({ id: 'multi_platform', name: '多平台发布', type: 'tool' }); return; } openMobPanel('📡 多平台发布', '绑定您的各平台账号(抖音/快手/B站/小红书/视频号等)后,由桌面自动化电脑员工代发。此处可查看绑定与申请开通。', [{ t: '打开账号管理', go: 'publish_acc' }, { t: '申请开通桌面自动化', go: 'publish_apply' }]); return; }
if (go === 'settings') { if (typeof window.switchTab === 'function') { try { window.switchTab('profile'); } catch (e) {} } return; }
if (go === 'apikey') { if (window.mksOpenModule) { window.mksOpenModule({ id: 'tool_api_key', name: 'API Key', type: 'tool' }); return; } openMobPanel('🔑 API Key', 'API Key 的创建与用量请先在电脑端「工具 → API Key」完成配置,手机端用于查看消耗概览。', []); return; }
if (go === 'help') { if (window.mksOpenModule) { window.mksOpenModule({ id: 'tool_help', name: '帮助中心', type: 'tool' }); return; } openMobPanel('❓ 帮助', '1. 本页 ☰ 可进入所有场景;2. 应用市场模块点击后全屏操作;3. 素材可直接用相机拍摄上传;4. 余额/订阅在「我的」查看。', []); return; }
// ⚠️ 修复20260909:default 分支——应用市场卡片(item.id)/未识别入口不再静默无反应
openMobPanel('🧩 ' + String(go || ''), '「' + String(go || '该功能') + '」操作台在电脑端已可用(中控台对应工具);手机端正在接入中。\n\n也可以回到对话页直接对 AI 说需求,例如:「帮我写一篇关于 AI 的文章」。', [{ t: '💬 去对话页说明需求', go: 'chat:' + String(go || '') }]);
}
// ============ 4. switchTab 接通(覆盖) ============
function hideScenes() {
['chat-container', 'market-container', 'workflow-container', 'video-container', 'tasks-container', 'profile-container'].forEach(function (id) {
var el = $(id); if (el) el.style.display = 'none';
});
var fn = $('function-nav'); if (fn) fn.style.display = 'none';
}
function showScene(id) {
var el = $(id); if (el) el.style.display = 'block';
}
function switchTabSafe(tab) {
try {
var t = String(tab || 'home');
curTab = t;
hideScenes();
var fn = $('function-nav');
var nav = { home: 1, market: 2, tasks: 3, workflow: 3, video: 4, profile: 5 };
if (t === 'home') { showScene('chat-container'); if (fn) fn.style.display = 'flex'; }
else if (t === 'market') { ensureMarket(); showScene('market-container'); loadMobileMarket(); }
else if (t === 'tasks' || t === 'workflow') { showScene('tasks-container'); try { if (typeof loadScheduledTasks === 'function') loadScheduledTasks(); } catch (e) {} }
else if (t === 'video') { showScene('video-container'); try { if (typeof loadVideoList === 'function') loadVideoList(); } catch (e) {} }
else if (t === 'profile') { showScene('profile-container'); try { if (typeof loadUserProfile === 'function') loadUserProfile(); } catch (e) {} }
else { showScene('chat-container'); if (fn) fn.style.display = 'flex'; }
// 底部激活态
var btns = document.querySelectorAll('.bottom-nav .nav-item');
btns.forEach(function (b) { b.classList.remove('active'); b.style.color = '#999'; });
var key = t === 'workflow' ? 'tasks' : t;
var target = null;
btns.forEach(function (b) { if ((b.getAttribute('data-tab') || '') === key) target = b; });
if (target) { target.classList.add('active'); target.style.color = '#667eea'; }
paintTabInd(nav[t] || 1);
} catch (e) { log('switchTabSafe', e.message); }
}
// 底部导航按钮补齐 data-tab 与“应用市场”
function upgradeNav() {
try {
var nav = document.querySelector('.bottom-nav');
if (!nav) return;
var map = { home: 'home', workflow: 'tasks', tasks: 'tasks', video: 'video', profile: 'profile' };
nav.querySelectorAll('.nav-item').forEach(function (b) {
var oc = (b.getAttribute('onclick') || '');
var mt = oc.match(/switchTab\('([^']+)'\)/);
var key = mt ? (map[mt[1]] || mt[1]) : '';
if (key) b.setAttribute('data-tab', key);
b.onclick = function () { switchTabSafe(key || 'home'); };
});
// 插入“应用市场”按钮(第二位)
var hasM = nav.querySelector('[data-tab="market"]');
if (!hasM) {
var nb = document.createElement('button');
nb.className = 'nav-item';
nb.setAttribute('data-tab', 'market');
nb.innerHTML = '🧩应用市场';
nb.onclick = function () { switchTabSafe('market'); };
var second = nav.querySelector('[data-tab="tasks"], [data-tab="workflow"]');
nav.insertBefore(nb, second || nav.children[1]);
}
} catch (e) { log('nav', e.message); }
}
// ============ 5. 应用市场(第二页:目录文字模块,8001 同源 catalog) ============
var marketLoaded = false;
function ensureMarket() {
if ($('market-container')) return;
var c = document.createElement('div');
c.id = 'market-container';
c.style.cssText = 'display:none;';
c.innerHTML = '🧩 应用市场 · 点模块进入操作台
';
var chat = $('chat-container');
if (chat && chat.parentNode) chat.parentNode.appendChild(c);
}
function loadMobileMarket() {
try {
ensureMarket();
var box = $('mobMarketList'); if (!box) return;
if (marketLoaded && box._ok) { renderMarket(box._data); return; }
fetch(API + '/user/modules/authorized?user_id=' + encodeURIComponent(window.__dwyUid ? window.__dwyUid() : uid())).then(function (r) { return r.json(); }).then(function (d) {
var cat = (d && (d.catalog || d.data)) || [];
if (!cat.length) { box.innerHTML = '暂无可用模块
'; return; }
marketLoaded = true; box._data = cat; box._ok = true;
renderMarket(cat);
}).catch(function () { box.innerHTML = '市场加载失败,请检查网络
'; });
} catch (e) { log('market', e.message); }
}
var GRP_T = { studio: '创作台', modules: '功能模块', market: '应用', tools: '工具' };
function renderMarket(cat) {
var box = $('mobMarketList'); if (!box) return;
var groups = {};
cat.forEach(function (m) { (groups[m.group] = groups[m.group] || []).push(m); });
var order = ['studio', 'modules', 'market', 'tools'];
var html = order.filter(function (g) { return groups[g] && groups[g].length; }).map(function (g) {
var rows = groups[g].map(function (m) {
var locked = (m.authorized === false) || (m.unlocked === false);
var lock = locked ? ' locked' : '';
var bdg = m.badge ? '' + m.badge + '' : '';
return '' +
'' + (m.icon || '🧩') + '' +
'' + (m.name || m.id) + bdg + '' +
'' + (m.desc || '') + '›
';
}).join('');
return '' + (GRP_T[g] || g) + '
' + rows + '
';
}).join('');
box.innerHTML = html || '暂无模块
';
box.onclick = function (e) {
var row = e.target.closest && e.target.closest('.mob-app-row');
if (!row) return;
var id = decodeURIComponent(row.getAttribute('data-id'));
var item = null;
(box._data || []).forEach(function (m) { if (m.id === id) item = m; });
if (!item) return;
if (item.authorized === false) { openMobPanel(item.name || id, '该功能未授权。可联系运营开通,或在中控台后端为您的账号授权后刷新使用。', []); return; }
if (item.unlocked === false) {
if (window.dwyPayGuide) { window.dwyPayGuide(item); return; }
openMobPanel('🔒 ' + (item.name || id), (item.hint || '当前额度不足:订阅套餐或充值后即可使用。'), [{ t: '💎 去订阅/充值', go: 'sub' }]); return;
}
openMobApp(item);
};
}
// 操作台注册表(M1:通用壳 + 已接基础项;M2 逐卡接入桌面同款操作台)
function openMobApp(item) {
var id = item.id || '';
var h = MOB_HANDLERS[id];
if (h) { h(item); return; }
// v24 全屏操作台优先(桌面同款字段表单 + 全屏分页);旧半屏面板兜底
if (typeof window.mksOpenModule === 'function') { try { window.mksOpenModule(item); return; } catch (e) {} }
buildMobExec(item);
}
/* 市场操作台(20260909):与桌面同源——需求输入 + dispatch 协调员执行 + 结果展示 */
function buildMobExec(item) {
try {
var old = $('mobPanel'); if (old) old.remove();
var p = document.createElement('div'); p.id = 'mobPanel'; p.className = 'open';
p.innerHTML =
'' +
'' +
'
' +
'
' + (item.icon ? item.icon + ' ' : '') + (item.name || id) + '
' +
'
' + (item.desc || '与电脑端同一套 AI 能力') + '
' +
'
' +
'
' +
'
' +
'
';
p.querySelector('#mobPanelHead .t').textContent = (item.icon ? item.icon + ' ' : '') + (item.name || id) + ' · 操作台';
p.querySelector('#mobPanelBack').onclick = function () { p.remove(); };
p.querySelector('#mobExecGo').onclick = function () { mobExecRun(p, item); };
var inp = p.querySelector('#mobExecInput');
inp.addEventListener('keydown', function (e) { if (e.key === 'Enter' && !e.shiftKey && !e.isComposing) { e.preventDefault(); mobExecRun(p, item); } });
document.body.appendChild(p);
setTimeout(function () { try { inp.focus(); } catch (e) {} }, 150);
} catch (e) { log('exec', e.message); }
}
function mobExecRun(p, item) {
try {
var inp = p.querySelector('#mobExecInput');
var res = p.querySelector('#mobExecRes');
var txt = (inp.value || '').trim();
if (!txt) { if (res) { res.style.display = 'block'; res.textContent = '请先输入你的需求'; } return; }
var goBtn = p.querySelector('#mobExecGo');
if (goBtn) { goBtn.disabled = true; goBtn.textContent = '⏳ 执行中…'; }
if (res) { res.style.display = 'block'; res.textContent = '⏳ 正在安排 AI 军团执行…'; }
var u = null;
try { u = JSON.parse(localStorage.getItem('user_info') || '{}'); } catch (e) {}
var uidS = (u && (u.id || u.username)) || localStorage.getItem('user_id') || 'anonymous';
fetch(API + '/ai-army/dispatch?agent_id=frontend_content_coordinator_agent', {
method: 'POST', headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ user_input: '【' + (item.name || item.id || '') + '】' + txt, user_id: uidS, task_type: 'studio_card', module_id: item.id || '' })
}).then(function (r) { return r.json().catch(function () { return {}; }); })
.then(function (d) {
var reply = '';
if (d && d.reply) reply = d.reply;
else if (d && d.data && (d.data.reply || d.data.message)) reply = d.data.reply || d.data.message;
else if (d && d.message) reply = d.message;
else if (d && d.task_id) reply = '任务已提交(' + d.task_id + '),可稍后在「定时任务/我的」查看进度。';
else reply = '执行完成,但未收到可读结果,请稍后在「我的-任务记录」查看或重试。';
if (res) { res.style.display = 'block'; res.textContent = reply; }
if (goBtn) { goBtn.disabled = false; goBtn.textContent = '▶ 再次执行'; }
}).catch(function () {
if (res) { res.style.display = 'block'; res.textContent = '执行网络错误,请重试'; }
if (goBtn) { goBtn.disabled = false; goBtn.textContent = '▶ 立即执行'; }
});
} catch (e) { log('execRun', e.message); }
}
var MOB_HANDLERS = {};
function openMobPanel(title, bodyText, actions) {
try {
var old = $('mobPanel'); if (old) old.remove();
var p = document.createElement('div'); p.id = 'mobPanel'; p.className = 'open';
var acts = (actions || []).map(function (a, i) {
return '';
}).join('');
p.innerHTML = '' +
'';
p.querySelector('#mobPanelHead .t').textContent = title;
p.querySelector('#mobPanelBody pre').textContent = bodyText || '';
p.querySelector('#mobPanelBack').onclick = function () { p.remove(); };
p._actions = actions || [];
p.addEventListener('click', function (e) {
var b = e.target.closest && e.target.closest('[data-a]');
if (!b) return;
var a = p._actions[parseInt(b.getAttribute('data-a'), 10)];
if (!a) return;
var go = a.go || '';
if (go.indexOf('chat:') === 0) { var need = go.slice(5); p.remove(); goHomeWithNeed(need); }
else if (go === 'photo') { triggerPhoto(p); }
else if (go === 'publish_acc') { p.remove(); openPublishAcc(); }
else if (go === 'publish_apply') { p.remove(); submitApply(); }
else if (go === 'sub') { p.remove(); try { window.open('https://ai.duoweiying.cn/subscribe', '_blank'); } catch (e) {} }
});
document.body.appendChild(p);
} catch (e) { log('panel', e.message); }
}
function goHomeWithNeed(need) {
try { switchTabSafe('home'); } catch (e) {}
setTimeout(function () {
var inp = $('chat-input');
if (inp && need) { inp.value = (inp.value ? inp.value + ';' : '') + '我想用【' + need + '】,请帮我:'; try { inp.focus(); } catch (e) {} }
}, 350);
}
function triggerPhoto(panel) {
var i = panel.querySelector('#mobPhotoInput');
if (i) i.click();
// 拍照/选择后上传并回填对话
if (!panel._photoBinded) {
panel._photoBinded = true;
i.onchange = function () {
var f = i.files && i.files[0]; if (!f) return;
var fd = new FormData(); fd.append('file', f);
var tip = panel.querySelector('#mobPanelBody pre');
if (tip) tip.textContent = '⏳ 素材上传中…';
fetch(API + '/ai-army/upload?user_id=' + encodeURIComponent(uid()) + '&material_type=image', { method: 'POST', body: fd })
.then(function (r) { return r.json(); }).then(function (d) {
var url = d && (d.url || (d.data && d.data.url) || d.file_path);
if (!url) { if (tip) tip.textContent = '上传失败'; return; }
if (tip) tip.textContent = '✅ 素材已上传,正在帮你发送给 AI 分析…';
setTimeout(function () {
panel.remove();
try { switchTabSafe('home'); } catch (e) {}
setTimeout(function () {
var inp = $('chat-input');
if (inp) { inp.value = '请帮我分析这张素材(已上传:' + url + ')'; }
try { if (typeof sendMessage === 'function') sendMessage(); } catch (e) {}
}, 350);
}, 500);
}).catch(function () { if (tip) tip.textContent = '上传网络错误'; });
};
}
}
function submitApply() {
try {
fetch(API + '/api/feedback/submit', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ user_id: uid(), type: 'feature', category: 'desktop_automation', content: '手机端申请开通桌面自动化(电脑员工)。' }) })
.then(function (r) { return r.json(); }).then(function (d) {
alert(d && d.success ? '✅ 申请已提交(' + (d.feedback_id || '') + '),运营会与您联系。' : ('提交失败:' + ((d && d.message) || '未知')));
}).catch(function () { alert('网络错误'); });
} catch (e) { alert('提交失败'); }
}
function openPublishAcc() {
try {
fetch(API + '/api/platform-accounts?owner_user_id=' + encodeURIComponent(uid())).then(function (r) { return r.json(); }).then(function (d) {
var items = (d && d.items) || [];
var body = items.length ? items.map(function (x) { return '· ' + (x.platform || '') + ' / ' + (x.account_name || '') + (x.has_password ? '(密码已加密)' : '') + ' / ' + String(x.created_at || '').substring(0, 10); }).join('\n') : '尚未绑定平台账号。\n\n在电脑端「多平台发布 → 账号管理」添加后,手机端同步可见(同一账号)。';
openMobPanel('📡 我的平台账号', body, [{ t: '申请开通桌面自动化', go: 'publish_apply' }]);
}).catch(function () { openMobPanel('📡 我的平台账号', '加载失败', []); });
} catch (e) { log('pubacc', e.message); }
}
function openMobNotify() {
try {
fetch(API + '/notifications?user_id=' + encodeURIComponent(uid()) + '&limit=30').then(function (r) { return r.json(); }).then(function (list) {
var body = (Array.isArray(list) && list.length) ? list.map(function (n) {
return (n.is_read ? '· ' : '· [新] ') + (n.title || '') + ' ' + (n.created_at || '') + '\n ' + String(n.content || '').substring(0, 120);
}).join('\n') : '暂无通知';
var panel = document.createElement('div');
openMobPanel('🔔 通知中心', body, []);
}).catch(function () { openMobPanel('🔔 通知中心', '加载失败', []); });
} catch (e) { log('notify', e.message); }
}
function openMobSettings() {
openMobPanel('⚙️ 个人设置', '资料/头像/改密/偏好/余额·订阅·订单查询在电脑端「个人设置」已完整支持,手机端同账号互通。\n\n快捷查看服务状态:', [{ t: '💰 我的余额/订阅/订单', go: 'chat:查询我的服务状态' }]);
}
// ============ 6. 语音输入 ============
function addMic() {
try {
var inp = $('chat-input'); if (!inp) return;
var wrap = inp.parentNode; if (!wrap) return;
var btn = document.createElement('button'); btn.id = 'mobV11Mic'; btn.textContent = '🎤'; btn.title = '语音输入';
btn.onclick = function () {
var SR = window.SpeechRecognition || window.webkitSpeechRecognition;
if (!SR) { alert('当前浏览器不支持语音输入,请用手机自带浏览器'); return; }
var rec = new SR(); rec.lang = 'zh-CN';
btn.textContent = '🔴';
rec.onresult = function (ev) {
var txt = '';
for (var i = 0; i < ev.results.length; i++) txt += ev.results[i][0].transcript;
if (txt) inp.value = (inp.value ? inp.value + ' ' : '') + txt;
btn.textContent = '🎤';
};
rec.onend = function () { btn.textContent = '🎤'; };
rec.onerror = function () { btn.textContent = '🎤'; };
rec.start();
};
wrap.appendChild(btn);
} catch (e) { log('mic', e.message); }
}
// ============ 7. 左右滑动翻页 ============
var TAB_ORDER = ['home', 'market', 'tasks', 'video', 'profile'];
function paintTabInd(idx) {
var host = $('tabInd');
if (!host) return;
host.innerHTML = TAB_ORDER.map(function (_, i) { return ''; }).join('');
}
function addTabInd() {
try {
if ($('tabInd')) return;
var d = document.createElement('div'); d.id = 'tabInd'; d.className = 'mob-tab-ind';
var chat = $('chat-container');
if (chat && chat.parentNode) chat.parentNode.insertBefore(d, chat);
} catch (e) { log('tabind', e.message); }
}
var curTab = 'home';
function bindSwipe() {
var x0 = null, y0 = null, t0 = 0;
document.addEventListener('touchstart', function (e) {
if (e.touches.length !== 1) { x0 = null; return; }
x0 = e.touches[0].clientX; y0 = e.touches[0].clientY; t0 = Date.now();
}, { passive: true });
document.addEventListener('touchend', function (e) {
if (x0 === null) return;
var dx = e.changedTouches[0].clientX - x0;
var dy = e.changedTouches[0].clientY - y0;
x0 = null;
if (Math.abs(dx) < 60 || Math.abs(dx) < Math.abs(dy) * 1.4) return;
var idx = TAB_ORDER.indexOf(curTab);
if (idx < 0) idx = 0;
if (dx < 0) idx = Math.min(idx + 1, TAB_ORDER.length - 1);
else idx = Math.max(idx - 1, 0);
if (TAB_ORDER[idx] !== curTab) switchTabSafe(TAB_ORDER[idx]);
}, { passive: true });
}
// ⚠️ 修复20260909:原下方重复声明 function switchTabSafe(tab){curTab=tab;return _st(tab);} 覆盖上方完整实现致 "_st is not a function",已删除
// 视窗滚动位置重置
// ============ 8. 启动 ============
function boot() {
try {
injectStyle();
fixHeader();
addTabInd();
upgradeNav();
addMic();
bindSwipe();
// 记录原 switchTab(可能重复定义,只接管一次)
window.switchTab = switchTabSafe;
// 面板相关
window.mobGo = mobGo;
log('ready');
} catch (e) { log('boot', e.message); }
}
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', boot);
else boot();
// 组件动态渲染(function-nav 内容等)完成后补一次压缩/欢迎处理
setTimeout(function () { try { fixHeader(); } catch (e) {} }, 800);
setTimeout(function () { try { fixHeader(); } catch (e) {} }, 2600);
})();