LINGXI · 企业版
`; settingsPanels["权限设置"] = `

🔐 权限设置

基于角色+部门的权限控制

角色权限矩阵

功能管理员经理员工查看者
查看KPI
查看模块
数据导出
系统设置
用户管理
权限修改

部门数据隔离

部门可见系统数据范围
生产部MES/QMS/WMS/SCADA/APS/TPM本部门+关联
技术部PLM/PDM/EDM/DMS/BI全部技术数据
质量部QMS/视觉检测/ERP(质量相关)质量相关
销售部CRM/ERP(销售)/BI销售数据
财务部ERP(财务)/BI财务数据
HR部HR管理/办公管理人事数据
仓储部WMS/ERP(库存)/SCM仓储数据
设备部TPM/IoT/SCADA设备数据
当前用户: 加载中...
`; settingsPanels["计费管理"] = `

💰 计费管理

本月概览

总消费
¥12.85
API调用
1,284,567
活跃天数
21天

各系统费用明细

系统/模块API调用Tokens费用(元)趋势
🤖 小德对话12,456485,230¥4.85↑12%
🏭 ERP管理3,890156,780¥1.57↑8%
👤 HR管理2,45098,450¥0.98↑5%
📈 销售管理2,18087,320¥0.87↑3%
⚙️ MES1,89076,540¥0.77→0%
📦 WMS1,13045,210¥0.45↓2%
✅ QMS96738,670¥0.39→0%
📊 APS82232,890¥0.33→1%
🌐 IoT70828,340¥0.28↑15%
🔧 TPM56422,560¥0.23→0%
📚 知识库1,28051,200¥0.51↑10%
🔍 AI搜索3,45086,250¥0.86↑20%
🖼️ 文生图89035,600¥0.36↑6%
其他2,78039,527¥0.40→0%
合计35,4571,284,567¥12.85↑8%

费用趋势

套餐信息

当前: 企业版
¥4,980/月
50个系统 | 不限API调用
专业版
¥1,980/月
10个系统 | 5万Token/日
`; settingsPanels["审计日志"] = `

📜 审计日志

时间操作用户操作类型IP地址详情
2026-06-12 14:32:10zhangsan用户创建192.168.1.100创建用户 wangwu
2026-06-12 13:18:05lisi权限修改192.168.1.101修改角色"编辑者"权限
2026-06-12 11:45:22admin系统配置10.0.0.1更新模型切换配置
2026-06-11 16:20:48zhangsan数据导出192.168.1.100导出审计日志报表
2026-06-11 09:05:33zhaoliu登录失败172.16.0.50密码错误 3 次
`; settingsPanels["个人中心"] = `

⚙️ 个人中心

账户信息

用户名管理员
角色企业管理员
版本企业版 V9.5.0

个人设置

个人使用趋势

`; settingsPanels["模型切换"] = `

🤖 模型切换与Token管理

API密钥配置

DeepSeek API Key
备用Key
Token用量本月已用 1,284,567 tokens
已用 42%剩余 1,715,433 tokens

模型选择

DeepSeek Chat
当前使用
速度: 快 | 价格: ¥0.001/1K tokens
GPT-4o
需配置OpenAI Key
速度: 中 | 价格: ¥0.015/1K tokens
Claude 4
需配置Anthropic Key
速度: 中 | 价格: ¥0.02/1K tokens
本地Ollama
本地部署 无需API费用
速度: 取决于硬件

各系统Token用量

业务系统本月Tokens占比预估费用
小德对话485,23037.8%¥4.85
ERP管理156,78012.2%¥1.57
HR管理98,4507.7%¥0.98
销售管理(CRM)87,3206.8%¥0.87
MES76,5406.0%¥0.77
WMS45,2103.5%¥0.45
QMS38,6703.0%¥0.39
APS32,8902.6%¥0.33
IoT28,3402.2%¥0.28
TPM22,5601.8%¥0.23
其他系统212,56716.6%¥2.13
合计1,284,567100%¥12.85
`; settingsPanels["聊天记录"] = `

💭 聊天记录

聊天记录功能开发中

后续版本将支持按系统、按时间检索历史对话
`; // --- 系统运维 --- settingsPanels["系统总览"] = `

系统总览

`;
47%
CPU 使用率
12.4GB
内存占用 / 32GB
256GB
磁盘可用 / 512GB
1.2Gbps
网络吞吐

服务状态

服务名状态运行时长
AI 推理引擎● 运行中127 天
数据库集群● 运行中312 天
消息队列● 运行中89 天
文件存储服务⚠ 降级45 天
缓存服务● 运行中203 天

系统负载趋势

`; settingsPanels["智脑分析"] = `

🧪 智脑分析

系统监控趋势

analysis-input-row">
最近分析结果
异常日志模式检测
发现3处潜在内存泄漏信号...
2026-06-12 08:00
已完成
服务响应延迟诊断
文件存储服务平均延迟上升 35%...
2026-06-11 14:30
待处理
数据库慢查询分析
订单查询TOP 10语句识别完成...
2026-06-10 10:15
已完成
`; settingsPanels["测查巡检"] = `

🔎 测查巡检

任务名称目标节点最后执行状态操作
核心服务健康检查node-01~052026-06-12 14:00正常
数据库备份验证db-master2026-06-12 02:00正常
磁盘空间巡检all-nodes2026-06-12 12:00告警
SSL证书到期检查gateway-012026-06-11 08:00正常
日志轮转检查log-svr-01~032026-06-12 06:00失败
`; settingsPanels["性能优化"] = `

⚡ 性能优化

86ms
平均响应时间
↓ 12% 较上周
3,420rps
吞吐量
↑ 8% 较上周
0.12%
错误率
↓ 0.05% 较上周

优化建议

启用查询结果缓存
预计减少数据库负载 40%,响应时间降低 25ms
建议执行
图片资源CDN加速
静态资源加载时间可缩短 60%
已规划
API网关连接池优化
当前连接池利用率 78%,建议扩容至 200
评估中
`; settingsPanels["云警察·自愈"] = `

🛡️ 云警察·自愈

规则名称触发条件执行动作状态操作
内存溢出自动重启内存 > 85% 持续 5 分钟重启服务实例
磁盘空间自动清理磁盘 < 10% 可用清理过期日志
服务无响应自愈健康检查连续失败 3 次隔离节点 + 流量切换
数据库连接池扩容连接池使用率 > 90%动态扩容 50%
`; settingsPanels["清洁工"] = `

🧹 清洁工

~ 2.3 GB
~ 8.7 GB
~ 1.5 GB
~ 340 MB
上次清理:2026-06-05 03:00
`; settingsPanels["Agent管理"] = `

Agent管理 加载中...

加载Agent列表...
\`; ;(function(){ var stored=JSON.parse(localStorage.getItem("lingxi_users")||"[]"); if(stored.length>0){window._users=stored;return} var defaults=[{id:1,username:"admin",password:"admin123",name:"管理员",department:"综合管理",position:"管理员",role:"boss",email:"admin@hengde.com",active:true},{id:2,username:"zhao",password:"123456",name:"赵总",department:"综合管理",position:"总经理",role:"boss",email:"zhao@hengde.com",active:true},{id:3,username:"demo",password:"demo123",name:"演示用户",department:"演示部",position:"演示员",role:"viewer",email:"demo@hengde.com",active:true}]; window._users=defaults; localStorage.setItem("lingxi_users",JSON.stringify(window._users)); })(); 用户名已存在' }; } var newUser = { id: window._users.length + 1, username: username, password: password, name: name || username, department: department || '综合管理', position: position || '员工', role: 'employee', email: username + '@hengde.com', active: true, lastLogin: new Date().toISOString() }; window._users.push(newUser); window._currentUser = newUser; localStorage.setItem('lingxi_current_user', JSON.stringify(newUser));localStorage.setItem('lingxi_users',JSON.stringify(window._users)); return { ok: true, user: newUser }; }; // Get current user info (with dept/role for filtering) window.getCurrentUser = function() { return window._currentUser || { id: 0, name: '访客', department: '综合管理', role: 'viewer', position: '访客' }; }; // // Auto-login enhancement // (function() { // if (!window._currentUser && window._users && window._users.length > 0) { // var r = window.doLogin("admin", "admin123"); // if (r && r.ok) { // if (typeof updateUserBadge === "function") updateUserBadge(); // } // } // })(); // Show login modal function showLoginModal() { var overlay = document.getElementById('authOverlay'); if (!overlay) { overlay = document.createElement('div'); overlay.id = 'authOverlay'; overlay.innerHTML = '
' + '
' + '
灵犀
' + '
企业操作系统 · 登录
' + '
'; document.body.appendChild(overlay); } overlay.style.display = 'flex'; } // Handle login function handleLogin() { var tabCode = document.getElementById('tabCode'); var err = document.getElementById('loginError'); if (tabCode && tabCode.style.background.includes('var(--pri)')) { var phone = document.getElementById('loginPhone'); var code = document.getElementById('loginCode'); if (!phone || !validatePhone(phone.value.trim())) { if (err) err.textContent = '请输入正确的11位手机号'; return; } if (!code || !code.value.trim()) { if (err) err.textContent = '请输入验证码'; return; } if (!code.value.trim()) { if (err) err.textContent = '请输入验证码'; return; } if (code.value.trim() !== window._pendingCode) { if (err) err.textContent = '验证码错误'; return; } if (phone.value.trim() !== window._pendingPhone) { if (err) err.textContent = '手机号不一致,请重新获取'; return; } var r = window.doLogin('demo', 'demo123'); if (r.ok) { document.querySelector('.app').style.display='';document.getElementById('authOverlay').style.display = 'none'; updateUserBadge(); if (window.v4Sys && window.renderV4) window.renderV4(window.v4Sys); } return; } var u = document.getElementById('loginUser').value.trim(); var p = document.getElementById('loginPass').value.trim(); if (!u || !p) { if(err) err.textContent = '请输入用户名和密码'; return; } var result = window.doLogin(u, p); if (result.ok) { document.querySelector('.app').style.display='';document.getElementById('authOverlay').style.display = 'none'; updateUserBadge(); if (window.v4Sys && window.renderV4) window.renderV4(window.v4Sys); } else { if(err) err.textContent = result.msg; } } // Verification code functions window._pendingCode = null; window._pendingPhone = null; window._codeTimer = null; function switchLoginTab(tab) { var tp = document.getElementById('tabPwd'); var tc = document.getElementById('tabCode'); var cr = document.getElementById('codeLoginRow'); var ci = document.getElementById('codeInputRow'); var pi = document.getElementById('loginPass'); if (tab === 'pwd') { tp.style.background = 'var(--pri)'; tp.style.color = '#000'; tp.style.fontWeight = '600'; tc.style.background = 'rgba(255,255,255,0.04)'; tc.style.color = 'var(--text-muted)'; tc.style.fontWeight = '400'; cr.style.display = 'none'; ci.style.display = 'none'; if(pi) pi.style.display = 'block'; } else { tc.style.background = 'var(--pri)'; tc.style.color = '#000'; tc.style.fontWeight = '600'; tp.style.background = 'rgba(255,255,255,0.04)'; tp.style.color = 'var(--text-muted)'; tp.style.fontWeight = '400'; cr.style.display = 'flex'; ci.style.display = 'block'; if(pi) pi.style.display = 'none'; } } function sendVerificationCode() { var phone = document.getElementById('loginPhone'); if (!phone || !validatePhone(phone.value.trim())) { var err = document.getElementById('loginError'); if(err) err.textContent = '请输入正确的11位手机号'; return; } window._pendingCode = String(100000 + Math.floor(Math.random() * 900000)); window._pendingPhone = phone.value.trim(); var btn = document.getElementById('sendCodeBtn'); if (!btn) return; btn.disabled = true; var cnt = 60; btn.textContent = cnt + 's'; if (window._codeTimer) clearInterval(window._codeTimer); window._codeTimer = setInterval(function() { cnt--; btn.textContent = cnt + 's'; if (cnt <= 0) { clearInterval(window._codeTimer); btn.disabled = false; btn.textContent = '重新发送'; } }, 1000); var err = document.getElementById('loginError'); if(err) err.textContent = '验证码已发送到 ' + phone.value.trim(); } // Demo login function demoLogin() { var r = window.doLogin('zhao', '123456'); if (r.ok) { document.querySelector('.app').style.display='';document.getElementById('authOverlay').style.display = 'none'; updateUserBadge(); if (window.v4Sys && window.renderV4) window.renderV4(window.v4Sys); } } // Show register form function showRegisterForm() { var card = document.querySelector('.login-card'); if (!card) return; card.innerHTML = '
灵犀
' + '
注册新账号
' + '
' + '' + '' + '' + '' + '' + '
' + '' + '
返回登录
' + '
'; } // Handle register function handleRegister() { var u = document.getElementById('regUser').value.trim(); var p = document.getElementById('regPass').value.trim(); var n = document.getElementById('regName').value.trim(); var d = document.getElementById('regDept') ? document.getElementById('regDept').value : '综合管理'; var pos = document.getElementById('regPos') ? document.getElementById('regPos').value.trim() : '员工'; var err = document.getElementById('regError'); if (!u || !p) { err.textContent = '用户名和密码为必填'; return; } var result = window.doRegister(u, p, n, d, pos); if (result.ok) { document.querySelector('.app').style.display='';document.getElementById('authOverlay').style.display = 'none'; updateUserBadge(); if (window.v4Sys && window.renderV4) window.renderV4(window.v4Sys); } else { err.textContent = result.msg; } } // Update user badge in sidebar // ============ HELP CENTER ============ function showHelp() { var panel = document.getElementById('sidePanel'); var title = document.getElementById('sidePanelTitle'); var body = document.getElementById('sidePanelBody'); if (!panel || !title || !body) return; panel.classList.add('open'); title.textContent = '\u5e2e\u52a9\u4e2d\u5fc3'; body.innerHTML = HELP_CONTENT; } var HELP_CONTENT = '
' + '
\u7075\u7280\u5de5\u4f5c\u53f0 \u00b7 \u4f7f\u7528\u624b\u518c
' + // 快速入门 '
' + '
\ud83d\ude80 \u5feb\u901f\u5165\u95e8
' + '
' + '
\ud83d\udcdd \u5207\u6362\u7cfb\u7edf
' + '
\u70b9\u51fb\u5de6\u4fa7\u5bfc\u822a\u83dc\u5355\uff0c\u5207\u6362\u4e0d\u540c\u4e1a\u52a1\u7cfb\u7edf
' + '
' + '
\ud83e\udd16 \u4f7f\u7528AI\u52a9\u624b
' + '
\u5728\u5e95\u90e8\u804a\u5929\u6846\u8f93\u5165\u95ee\u9898\uff0c\u5c0f\u5fb7\u4f1a\u81ea\u52a8\u56de\u7b54
' + '
' + '
\ud83d\udcca \u67e5\u770bKPI
' + '
\u70b9\u51fb\u7cfb\u7edf\u540e\uff0c\u9876\u90e8\u81ea\u52a8\u663e\u793a\u8be5\u7cfb\u7edf\u7684\u5173\u952e\u6307\u6807
' + '
' + '
\ud83d\udcf1 \u79fb\u52a8\u7aef\u4f7f\u7528
' + '
\u70b9\u51fb\u5de6\u4e0a\u89d2\u6c49\u5821\u83dc\u5355\u6253\u5f00\u5bfc\u822a
' + '
' + // 个人工具 '
' + '
\ud83d\udee0\ufe0f \u4e2a\u4eba\u5de5\u5177
' + '' + '' + '' + '' + '' + '' + '' + '
AI\u5199\u4f5c\u6587\u7ae0/\u62a5\u544a/\u65b9\u6848/\u90ae\u4ef6\u751f\u6210
AI\u7ffb\u8bd1\u591a\u8bed\u79cd\u7ffb\u8bd1
\u7b14\u8bb0\u7ba1\u7406\u521b\u5efa/\u641c\u7d22/\u5206\u7c7b/\u6807\u7b7e
\u5f85\u529e\u7ba1\u7406\u4efb\u52a1/\u63d0\u9192/\u4f18\u5148\u7ea7
\u65e5\u7a0b\u7ba1\u7406\u65e5/\u5468/\u6708\u89c6\u56fe
\u6587\u6863\u5206\u6790OCR/\u5bf9\u6bd4/\u60c5\u611f\u5206\u6790
' + // 业务系统 '
' + '
\ud83c\udf93 \u4e1a\u52a1\u7cfb\u7edf
' + '
\u5168\u5e73\u53f0\u5305\u542b60+\u4e1a\u52a1\u7cfb\u7edf\uff0c\u6bcf\u4e2a\u7cfb\u7edf\u914d\u59071\u7ec4\u957f+12\u5b50Agent
' + '
' + '
\u4e3b\u8981\u7c7b\u522b\uff1a
' + '
\ud83d\udcc1 \u7ba1\u7406\u7c7b\uff1aERP/CRM/HR/OA/BPM/KMS
' + '
\ud83c\udfed \u751f\u4ea7\u7c7b\uff1aMES/WMS/QMS/APS/TPM/IoT
' + '
\ud83d\ude80 \u8fd0\u8425\u7c7b\uff1a\u6307\u6325\u4e2d\u5fc3/\u8425\u9500/\u7ade\u4e89\u60c5\u62a5
' + '
' + // 小德AI助手 '
' + '
\ud83e\udd16 \u5c0f\u5fb7AI\u52a9\u624b
' + '
\u5c0f\u5fb7\u8986\u76d659\u4e2a\u7cfb\u7edf\uff0c\u652f\u6301\u4ee5\u4e0b\u80fd\u529b\uff1a
' + '
' + '
L1 \u67e5\u8be2 \u2014 \"\u67e5ERP\u5e93\u5b58\" \"CRM\u5ba2\u6237\u60c5\u51b5\"
' + '
L2 \u5206\u6790 \u2014 \"\u5206\u6790\u672c\u6708\u8ba2\u5355\u8d8b\u52bf\"
' + '
L3 \u64cd\u4f5c \u2014 \"\u521b\u5efa\u5de5\u5355\" \"\u63d0\u4ea4\u5ba1\u6279\"
' + '
L4 \u8054\u52a8 \u2014 \"\u6240\u6709\u7cfb\u7edf\u6982\u51b5\"
' + '
L5 \u81ea\u4e3b \u2014 \u81ea\u52a8\u9884\u8b66/\u667a\u80fd\u63a8\u8350
' + '
' + // 快捷键 '
' + '
\u2328 \u5feb\u6377\u952e
' + '
' + '
Enter \u53d1\u9001\u6d88\u606f
' + '
Shift+Enter \u6362\u884c
' + '
' + // 版本信息 '
' + '
\ud83d\udce1 \u5173\u4e8e
' + '
\u7075\u7280AIOS V17.6.0
' + '
\u4f01\u4e1a\u7ea7AI\u64cd\u4f5c\u7cfb\u7edf
' + '
\u6280\u672f\u652f\u6301\uff1a\u901a\u8fc7\u5c0f\u5fb7\u76f4\u63a5\u63d0\u95ee
' + '
' + '
'; function updateUserBadge() { var user = window.getCurrentUser(); var badge = document.getElementById('userBadge'); if (!badge) { var brand = document.querySelector('.brand'); if (!brand) return; badge = document.createElement('div'); badge.id = 'userBadge'; badge.style.cssText = 'display:flex;align-items:center;gap:6px;padding:6px 14px;border-top:1px solid var(--border);font-size:11px;cursor:pointer;flex-shrink:0'; badge.onclick = function() { showSettingsPanel('个人中心'); }; brand.parentNode.appendChild(badge); } badge.innerHTML = '' + user.name.charAt(0) + '' + '
' + user.name + '
' + '
' + user.department + ' · ' + user.position + '
' + ''; } // Init: load users on page load (function() { if (typeof window.loadUsers === 'function') { window.loadUsers(function() { // Check if already logged in var saved = localStorage.getItem('lingxi_current_user'); if (saved) { try { var u = JSON.parse(saved); // Verify user still exists if (window._users) { for (var i = 0; i < window._users.length; i++) { if (window._users[i].username === u.username) { window._currentUser = window._users[i]; break; } } } } catch(e) {} } if (!window._currentUser) { updateUserBadge(); } else { updateUserBadge(); } }); } })(); // ============ END AUTH SYSTEM ============ // Expose settingsPanels to template engine try { window.settingsPanels = settingsPanels; } catch(e) {} // ============ SIDE PANEL ============ /* dup */ activePanel = null; function toggleFloatPanel(bubble) { if (!bubble) return; var panelType = bubble.dataset.panel; if (!panelType) return; if (activePanel === panelType) { closeSidePanel(); return; } var panel = document.getElementById('sidePanel'); var title = document.getElementById('sidePanelTitle'); var body = document.getElementById('sidePanelBody'); if (!panel || !title || !body) return; if (panelType === 'chatHistory') { title.textContent = '💭 聊天记录'; body.innerHTML = '
聊天记录功能开发中
'; } else if (panelType === 'artifacts') { title.textContent = '📦 产出物料'; body.innerHTML = '
产出物料功能开发中
'; } else if (panelType === 'notif') { title.textContent = '通知中心'; body.innerHTML = '
飞书群实时通知
'; getNotifContent(function(html) { var nb = document.getElementById('notifBody'); if (nb) nb.innerHTML = html; }); } else if (panelType === 'help') { title.textContent = '帮助中心'; body.innerHTML = '
帮助中心内容加载中...
'; } panel.classList.add('open'); activePanel = panelType; document.querySelectorAll('.float-bubble').forEach(function(b) { b.classList.remove('active'); }); if (bubble) bubble.classList.add('active'); } // ============ BUBBLE CLICK BINDING ============ (function() { var bubbles = document.querySelectorAll('.float-bubble'); for (var i = 0; i < bubbles.length; i++) { bubbles[i].addEventListener('click', function() { toggleFloatPanel(this); }); } })(); function closeSidePanel() { var panel = document.getElementById('sidePanel'); if (!panel) return; panel.classList.remove('open'); activePanel = null; document.querySelectorAll('.float-bubble').forEach(function(b) { b.classList.remove('active'); }); } function getChatHistoryContent(){var h='';h+='

💬 产线OEE分析讨论

L1产线本周OEE为92.3%,较上周提升1.2个百分点。

06-12 14:30
';h+='

💬 库存预警排查

中转仓库存偏低,建议启动补货流程。

06-11 16:20
';h+='

💬 销售数据汇总

本月销售总额2,847,600,环比+15.2%。

06-10 10:05
';h+='

💬 财务预算审核

本月收入超预算6.5%,材料成本低于预算8.3%。

06-09 09:45
';h+='

💬 设备维护计划

TPM系统显示L3线需要季度保养。

06-08 15:12
';return h} function getArtifactContent(){var h='';try{var arts=JSON.parse(localStorage.getItem('lingxi_artifacts')||'[]');if(arts.length===0){return '
暂无偿出物料
';}for(var i=0;i=0?'📊':(a.name.toLowerCase().indexOf('.xlsx')>=0||a.name.toLowerCase().indexOf('.pdf')>=0?'📄':'📋');h+='

'+icon+' '+a.name.replace(/&/g,'&').replace(//g,'>')+'

'+a.desc+' · '+a.size+' · '+a.time+'

';}}catch(e){h='
读取失败
';}return h} function getHelpContent(){var h='';h+='

💡 快速入门

灵犀企业版是覆盖企业全领域的智能指挥中枢。

';h+='

💡 常用功能

AI对话 · AI写作 · AI翻译 · AI总结 · AI搜索

';h+='

💡 版本信息

灵犀AIOS v17.6 V17.6.0

';return h} // ============ CHAT HISTORY (retained for nav item "聊天记录") ============ // ============ NAV ITEM CLICK ============ let lastSysMsg = null; function showSettingsPanel(sysName) { const msgs = document.getElementById('chatMessages'); if (!msgs) return; const panelHtml = settingsPanels[sysName]; if (panelHtml) { msgs.innerHTML = '
' + escHtml(panelHtml) + '
'; msgs.scrollTop = 0; return; } // 通用面板回退 - 无专用面板时显示通用状态界面 msgs.innerHTML = '

' + escHtml(sysName) + '

' + '
' + Math.floor(Math.random()*100+50) + '
运行天数
' + '
' + Math.floor(Math.random()*24+1) + '
今日访问
' + '
' + Math.floor(Math.random()*10+1) + '
待处理
' + '
OK
系统状态
' + '
'; msgs.scrollTop = 0; } // ============ 用户设置 ============ function updateUserProfile() { var dept = document.getElementById('setUserDept')?.value || '综合管理'; var role = document.getElementById('setUserRole')?.value || 'employee'; var name = document.getElementById('setUserName')?.value || '用户'; var profile = { department: dept, role: role, name: name }; localStorage.setItem('lingxi_user_profile', JSON.stringify(profile)); localStorage.setItem('lingxi_user_settings', JSON.stringify(profile)); // Refresh current view if in a V4 system if (window.v4Sys && typeof window.renderV4 === 'function') { window.renderV4(window.v4Sys); } } function saveUserSettings() { var name = document.getElementById('setUserName')?.value || '用户'; var account = document.getElementById('setUserAccount')?.value || 'admin'; var dept = document.getElementById('setUserDept')?.value || '综合管理'; var role = document.getElementById('setUserRole')?.value || 'employee'; var settings = { name: name, account: account, department: dept, role: role }; localStorage.setItem('lingxi_user_settings', JSON.stringify(settings)); // Also update profile updateUserProfile(); var result = document.getElementById('saveResult'); if (result) { result.textContent = '✅ 设置已保存!当前部门:' + dept + ',角色:' + role; result.style.color = '#34d399'; setTimeout(function() { if(result) result.textContent = ''; }, 3000); } } // Load saved settings on page load (function() { try { var saved = localStorage.getItem('lingxi_user_settings'); if (saved) { var s = JSON.parse(saved); setTimeout(function() { if (document.getElementById('setUserName')) document.getElementById('setUserName').value = s.name || '管理员'; if (document.getElementById('setUserAccount')) document.getElementById('setUserAccount').value = s.account || 'admin'; if (document.getElementById('setUserDept')) document.getElementById('setUserDept').value = s.department || '综合管理'; if (document.getElementById('setUserRole')) document.getElementById('setUserRole').value = s.role || 'admin'; // Update dynamicData if (window.dynamicData) window.dynamicData.setProfile(s.department, s.role, s.name); }, 500); } } catch(e) {} })(); // ============ 用户设置函数 ============ function mapSysName(displayName) { // Strip suffixes like PRO, NEW, 免费, 试用, HOT, New, temp var clean = displayName.replace(/\s*(PRO|NEW|New|HOT|试用|免费|temp|免费|AUTO)$/i, '').trim(); return SYS_NAME_MAP[clean] || clean; } document.querySelectorAll('.nav-item').forEach(item => { item.addEventListener('click', function(e) { try { if (this.classList.contains('nav-sub-parent')) { toggleSubNav(this); return; } document.querySelectorAll('.nav-item').forEach(i => i.classList.remove('active')); this.classList.add('active'); const spans = this.querySelectorAll('span'); const sysName = spans[1]?.textContent || '通用'; const navGroupEl = this.closest('.nav-group'); const groupTitle = navGroupEl?.querySelector('.group-title')?.textContent || ''; const groupClean = (groupTitle.replace(/^[^\w\u4e00-\u9fff]+/, '') || '').trim() || '工具类'; document.getElementById('currentSystem').textContent = groupClean; document.getElementById('topStatusText').textContent = sysName + ' — 就绪'; if (lastSysMsg) { lastSysMsg.remove(); lastSysMsg = null; } // Auto-expand parent group if collapsed try { var parentGroup = this.closest('.nav-group'); if (parentGroup && !parentGroup.classList.contains('open')) { parentGroup.classList.add('open'); } } catch(e) {} // 模板路由:调用renderV4,模板引擎自动处理 var mappedName = mapSysName(sysName); if (typeof window.renderV4 === 'function') { window.renderV4(mappedName); if (textarea) textarea.placeholder = (sysPlaceholders[sysName] || defaultPh); return; } // Fallback: 系统就绪 var ph = sysPlaceholders[sysName] || defaultPh; if (textarea) textarea.placeholder = ph; var msgs = document.getElementById('chatMessages'); if (msgs) { msgs.innerHTML = ''; var div = document.createElement('div'); div.className = 'system-ready-msg'; div.innerHTML = '
系统就绪
'; msgs.appendChild(div); lastSysMsg = div; msgs.scrollTop = msgs.scrollHeight; try{saveChat();}catch(e){} revealObserver.observe(div); div.classList.add('reveal', 'visible'); } } catch(e) { console.error('Nav handler error:', e); } }); }); // ============ SEND MESSAGE ============ // ============ CHAT PERSISTENCE ============ (function() { try { var saved = localStorage.getItem('lingxi_chat'); var msgs = document.getElementById('chatMessages'); if (saved && saved.length > 50 && msgs) { if (!msgs.querySelector('.settings-panel-wrapper')) { msgs.innerHTML = saved; msgs.scrollTop = msgs.scrollHeight; } } } catch(e) {} })(); function saveChat() { try { var msgs = document.getElementById('chatMessages'); if (msgs) { var html = msgs.innerHTML; if (html && !html.includes('settings-panel-wrapper') && !html.includes('v4-ph')) { localStorage.setItem('lingxi_chat', html); localStorage.setItem('lingxi_chat_time', Date.now().toString()); } } } catch(e) {} } function sendMessage() { var ta = _getTextarea(); if (!ta) return; const text = ta.value.trim(); if (!text) return; const sendBtn = document.querySelector('.ia-btn.send'); if (!sendBtn) return; const msgs = document.getElementById('chatMessages'); if (!msgs) return; const welcome = msgs.querySelector('.welcome-msg'); if (welcome) welcome.remove(); const now = new Date(); const time = now.getHours().toString().padStart(2,'0') + ':' + now.getMinutes().toString().padStart(2,'0'); // Switch to loading icon sendBtn.classList.add('loading'); sendBtn.innerHTML = ''; // User message const userRow = document.createElement('div'); userRow.className = 'msg-row user reveal visible'; userRow.innerHTML = `
U
${text}
${time}
`; msgs.appendChild(userRow); ta.value = ''; msgs.scrollTop = msgs.scrollHeight; // Thinking const thinkId = 'think_' + Date.now(); const thinkRow = document.createElement('div'); thinkRow.className = 'msg-row'; thinkRow.id = thinkId; thinkRow.innerHTML = `
正在分析
`; msgs.appendChild(thinkRow); msgs.scrollTop = msgs.scrollHeight; fetch('/api/v1/xiaode/chat', { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({message: text, session_id: localStorage.getItem('lingxi_sid')||'', user_id: localStorage.getItem('lingxi_user')||'anonymous', context: {system: window.v4Sys||'', module: window.v4Mod||''}}) }) .then(function(r) { try { return r.json(); } catch(e) { return {success:false}; } }) .then(function(d) { var el = document.getElementById(thinkId); if (el) el.remove(); var txt = ''; if(d && d.success && d.data && d.data.reply) { txt = d.data.reply.content; } else { txt = '小德思考中...\n' + text; } var row = document.createElement('div'); row.className = 'msg-row reveal'; row.innerHTML = '
' + txt + '
' + time + '
'; msgs.appendChild(row); msgs.scrollTop = msgs.scrollHeight; }) .catch(function() { var el = document.getElementById(thinkId); if (el) el.remove(); var txt = '服务暂时不可用,请稍候再试'; var row = document.createElement('div'); row.className = 'msg-row reveal'; row.innerHTML = '
' + escHtml(txt) + '
'; msgs.appendChild(row); msgs.scrollTop = msgs.scrollHeight; }) .finally(function() { if (sendBtn) { sendBtn.classList.remove('loading'); sendBtn.innerHTML = '↑'; } }); } // ============ ENTER TO SEND ============ if (textarea) { _getTextarea().addEventListener('keydown', e => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); sendMessage(); } }); } // ============ HINT CHIP CLICK ============ document.querySelectorAll('.hint-chip').forEach(chip => { chip.addEventListener('click', function() { if (textarea) { _getTextarea().value = this.textContent; sendMessage(); } }); }); // ============ INIT PLACEHOLDER ============ (function(){ const activeItem = document.querySelector('.nav-item.active'); if (activeItem && textarea) { const sysName = activeItem.querySelectorAll('span')[1]?.textContent || ''; const ph = sysPlaceholders[sysName] || defaultPh; textarea.placeholder = ph; } })(); // ============ FULLSCREEN TOGGLE ============ (function(){ const toggleBtn = document.getElementById('fullscreenToggle'); const app = document.querySelector('.app'); if (!toggleBtn || !app) return; toggleBtn.addEventListener('click', function() { app.classList.toggle('is-fullscreen'); toggleBtn.textContent = app.classList.contains('is-fullscreen') ? '退出全屏' : '全屏显示'; }); })(); // ============ AUTO-COLLAPSE ON NAV CLICK ============ document.querySelectorAll('.nav-item').forEach(item => { item.addEventListener('click', function() { if (this.classList.contains('nav-sub-parent')) return; // Skip auto-fullscreen for 系统设置 and 系统运维 groups const navGroup = this.closest('.nav-group'); const groupTitle = navGroup?.querySelector('.group-title')?.textContent || ''; if (groupTitle.includes('系统设置') || groupTitle.includes('系统运维')) return; const app = document.querySelector('.app'); const toggleBtn = document.getElementById('fullscreenToggle'); if (app && toggleBtn) { app.classList.add('is-fullscreen'); toggleBtn.textContent = '全屏显示'; } }); }); // ============ OUTPUT PANEL ============ function toggleOutputPanel() { const panel = document.getElementById('outputPanel'); const btn = document.querySelector('.output-toggle'); if (!panel || !btn) return; panel.classList.toggle('open'); btn.classList.toggle('active'); } // ============ ARTIFACT PANEL (动态读取 localStorage) ============ function renderArtifactRows() { var h='';try{ var arts=JSON.parse(localStorage.getItem('lingxi_artifacts')||'[]'); if(arts.length===0){return '暂无偿出物料';} for(var i=0;i=0?'table':(a.name.toLowerCase().indexOf('.xlsx')>=0||a.name.toLowerCase().indexOf('.pdf')>=0?'report':'doc'); var typeLabel=typeCls==='table'?'表格':(typeCls==='report'?'报表':'文档'); var escName=a.name.replace(/&/g,'&').replace(//g,'>').replace(/"/g,'"'); h+=''+escName+''+typeLabel+''+a.time+''+a.size+'
'; } }catch(e){h='读取失败';} return h; } window.downloadArtifact=function(btn){ var url=btn.getAttribute('data-url');var name=btn.getAttribute('data-name'); var a=document.createElement('a');a.href=url;a.download=name;a.click(); }; window.deleteArtifactPanel=function(btn,filename){ try{ var arts=JSON.parse(localStorage.getItem('lingxi_artifacts')||'[]'); arts=arts.filter(function(a){return a.name!==filename;}); localStorage.setItem('lingxi_artifacts',JSON.stringify(arts)); }catch(e){} var row=btn.closest('tr');if(row)row.remove(); // 也删除聊天区对应的产出卡片 var msgs=document.getElementById('chatMessages');if(msgs){ var card=msgs.querySelector('.xda[data-file="'+filename.replace(/"/g,'"').replace(/'/g,"\\'")+'"]'); if(card)card.remove(); } // 刷新右侧面板 refreshArtifactViews(); }; window.refreshArtifactViews=function(){ var ap=document.getElementById('artifactPanel');if(ap){ var tbody=ap.querySelector('tbody');if(tbody)tbody.innerHTML=renderArtifactRows(); } var sp=document.getElementById('sidePanelBody');if(sp){ sp.innerHTML=getArtifactContent(); } }; window.renderArtifacts=function(){refreshArtifactViews();}; function toggleArtifactPanel() { const msgs = document.getElementById('chatMessages'); const btn = document.querySelector('.artifact-btn'); if (!msgs || !btn) return; const existing = document.getElementById('artifactPanel'); if (existing) { existing.remove(); btn.classList.remove('open'); return; } const panel = document.createElement('div'); panel.id = 'artifactPanel'; panel.innerHTML = '

产出物料

'+renderArtifactRows()+'
文件名类型生成时间大小操作
'; msgs.insertBefore(panel, msgs.firstChild); btn.classList.add('open'); } window.clearAllArtifacts=function(){ localStorage.setItem('lingxi_artifacts','[]'); var ap=document.getElementById('artifactPanel');if(ap)ap.remove(); var btn=document.querySelector('.artifact-btn');if(btn)btn.classList.remove('open'); refreshArtifactViews(); }; document.getElementById('chatMessages')?.addEventListener('click', function(e) { const panel = document.getElementById('outputPanel'); if (panel && panel.classList.contains('open')) { if (!e.target.closest('.output-panel') && !e.target.closest('.output-toggle')) { panel.classList.remove('open'); document.querySelector('.output-toggle')?.classList.remove('active'); } } }); 'color:#34d399;font-size:14px;font-weight:bold', 'color:#fff', 'color:#5f6878', 'color:#06b6d4'); try { var x = new XMLHttpRequest(); x.open('GET', '/api/v1/xiaode/status', false); x.send(); if(x.status === 200) { var d = JSON.parse(x.responseText); // Try to extract version if(d && d.data && d.data.version) { var v = document.getElementById('versionDisplay'); if(v) v.textContent = 'V' + d.data.version; } } } catch(e) {} // Also try health endpoint try { var x = new XMLHttpRequest(); x.open('GET', '/api/v1/xiaode/index', false); x.send(); if(x.status === 200) { var d = JSON.parse(x.responseText); if(d && d.data && d.data.version) { var v = document.getElementById('versionDisplay'); if(v) v.textContent = 'V' + d.data.version; } } } catch(e) {} // Fallback: read from version_manager.json via health try { var x = new XMLHttpRequest(); x.open('GET', '/api/version/latest', false); x.send(); if(x.status === 200) { var d = JSON.parse(x.responseText); if(d && d.label) { var v = document.getElementById('versionDisplay'); if(v) v.textContent = d.label; } } } catch(e) {} })();