177 lines
354 KiB
HTML
177 lines
354 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||
<title>Agent任务系统 v2.1 - 全模块原型</title>
|
||
<style>
|
||
*{margin:0;padding:0;box-sizing:border-box}
|
||
:root{--pri:#6366f1;--side:#1e293b;--bdr:#e2e8f0;--txt:#1e293b;--sub:#64748b;--bg:#f1f5f9}
|
||
body{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI","PingFang SC","Microsoft YaHei",sans-serif;overflow:hidden;height:100vh}
|
||
.shell{display:flex;height:100vh}
|
||
.side{width:220px;background:var(--side);color:#94a3b8;overflow-y:auto;flex-shrink:0;user-select:none;transition:width .3s,opacity .3s;overflow:hidden}
|
||
.side.hide{width:0;opacity:0;pointer-events:none}
|
||
.side .logo{padding:16px 18px;font-size:14px;font-weight:700;color:#fff;border-bottom:1px solid #334155;display:flex;align-items:center;gap:6px;white-space:nowrap}
|
||
.ng-t{padding:10px 18px 4px;font-size:10px;letter-spacing:1px;color:#475569;font-weight:600;text-transform:uppercase;white-space:nowrap}
|
||
.ni{display:flex;align-items:center;gap:8px;padding:9px 18px;font-size:12px;color:#94a3b8;cursor:pointer;border-left:3px solid transparent;transition:all .1s;white-space:nowrap}
|
||
.ni:hover{background:#334155;color:#e2e8f0}
|
||
.ni.ac{background:rgba(99,102,241,.15);color:#818cf8;border-left-color:#818cf8;font-weight:600}
|
||
.frame-wrap{flex:1;position:relative;background:#f1f5f9}
|
||
.frame-wrap iframe{width:100%;height:100%;border:none}
|
||
.badge{display:inline-block;background:#334155;color:#64748b;font-size:9px;padding:1px 5px;border-radius:3px;margin-left:auto}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div class="shell">
|
||
<aside class="side hide" id="sidebar">
|
||
<div class="logo">🤖 Agent任务系统 v2.1</div>
|
||
<div class="ng-t">首页</div>
|
||
<div class="ni ac" data-src="02_仪表盘.html">🏠 仪表盘 <span class="badge">02</span></div>
|
||
<div class="ng-t">权限管理</div>
|
||
<div class="ni" data-src="03_组织架构.html">🏢 组织架构 <span class="badge">03</span></div>
|
||
<div class="ni" data-src="04_角色管理.html">🎭 角色管理 <span class="badge">04</span></div>
|
||
<div class="ni" data-src="05_用户管理.html">👤 用户管理 <span class="badge">05</span></div>
|
||
<div class="ni" data-src="12_菜单管理.html">📋 菜单管理 <span class="badge">12</span></div>
|
||
<div class="ng-t">产品管理</div>
|
||
<div class="ni" data-src="06_产品管理.html">📦 产品管理 <span class="badge">06</span></div>
|
||
<div class="ni" data-src="07_渠道码管理.html">🏷️ 渠道码 <span class="badge">07</span></div>
|
||
<div class="ni" data-src="13_平台套件.html">🔧 平台套件 <span class="badge">13</span></div>
|
||
<div class="ng-t">平台产品账号</div>
|
||
<div class="ni" data-src="08_平台产品账号.html">🔗 账号管理 <span class="badge">08</span></div>
|
||
<div class="ng-t">Skill中心</div>
|
||
<div class="ni" data-src="09_Skill管理.html">🧩 Skill管理 <span class="badge">09</span></div>
|
||
<div class="ni" data-src="14_Skill调用日志.html">📊 调用日志 <span class="badge">14</span></div>
|
||
<div class="ng-t">任务中心</div>
|
||
<div class="ni" data-src="10_任务创建.html">⚡ 任务创建 <span class="badge">10</span></div>
|
||
<div class="ni" data-src="11_任务列表.html">📋 任务列表 <span class="badge">11</span></div>
|
||
<div class="ng-t">日志</div>
|
||
<div class="ni" data-src="15_操作日志.html">📝 操作日志 <span class="badge">15</span></div>
|
||
<div class="ni" data-src="16_统计报表.html">📈 统计报表 <span class="badge">16</span></div>
|
||
<div class="ng-t">系统设置</div>
|
||
<div class="ni" data-src="17_执行器配置.html">⚙️ 执行器配置 <span class="badge">17</span></div>
|
||
<div class="ni" data-src="18_脚本模板管理.html">📜 脚本模板 <span class="badge">18</span></div>
|
||
<div class="ni" data-src="19_定时任务.html">⏰ 定时任务 <span class="badge">19</span></div>
|
||
</aside>
|
||
<div class="frame-wrap">
|
||
<iframe id="mainFrame"></iframe>
|
||
</div>
|
||
</div>
|
||
|
||
<script>
|
||
// 所有页面 HTML 内容内嵌
|
||
const PAGES = {
|
||
"01_登录页.html": "<!DOCTYPE html>\n<html lang=\"zh-CN\">\n<head><script>if(window!==window.top)document.documentElement.classList.add(\"in-iframe\")<\/script><style>.in-iframe .side{display:none!important}.in-iframe .main{margin-left:0!important}.in-iframe .layout{min-height:auto}<\/style>\n<meta charset=\"UTF-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<title>Agent任务系统 v2.0 - 登录<\/title>\n<style>\n*{margin:0;padding:0;box-sizing:border-box}\n:root{--pri:#6366f1;--pri-d:#4f46e5;--bg:#f1f5f9;--card:#fff;--txt:#1e293b;--sub:#64748b;--bdr:#e2e8f0;--err:#ef4444}\nbody{font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,\"PingFang SC\",\"Microsoft YaHei\",sans-serif;background:linear-gradient(135deg,#667eea 0%,#764ba2 100%);min-height:100vh;display:flex;align-items:center;justify-content:center;color:var(--txt)}\n.login-wrap{display:flex;width:900px;max-width:95vw;background:var(--card);border-radius:16px;box-shadow:0 20px 60px rgba(0,0,0,.25);overflow:hidden;min-height:520px}\n.login-left{flex:1;background:linear-gradient(135deg,#4f46e5,#7c3aed);color:#fff;padding:50px 40px;display:flex;flex-direction:column;justify-content:center}\n.login-left h1{font-size:28px;margin-bottom:12px}\n.login-left p{font-size:13px;opacity:.85;line-height:1.8;margin-bottom:20px}\n.login-left .feat{display:flex;flex-direction:column;gap:10px}\n.login-left .feat-i{display:flex;align-items:center;gap:10px;font-size:13px;padding:8px 12px;background:rgba(255,255,255,.12);border-radius:8px}\n.login-left .feat-i span{font-size:18px}\n.login-right{flex:1;padding:50px 40px;display:flex;flex-direction:column;justify-content:center}\n.login-right h2{font-size:22px;font-weight:700;margin-bottom:6px}\n.login-right .sub{font-size:12px;color:var(--sub);margin-bottom:28px}\n.fg{margin-bottom:18px}\n.fl{font-size:12px;font-weight:600;margin-bottom:6px;display:block;color:var(--txt)}\n.fi{width:100%;padding:10px 14px;border:1px solid var(--bdr);border-radius:8px;font-size:13px;outline:none;transition:border .15s}\n.fi:focus{border-color:var(--pri);box-shadow:0 0 0 3px rgba(99,102,241,.12)}\n.fi.err{border-color:var(--err)}\n.err-msg{font-size:11px;color:var(--err);margin-top:4px;display:none}\n.opt{display:flex;justify-content:space-between;align-items:center;margin-bottom:22px;font-size:12px}\n.opt label{display:flex;align-items:center;gap:5px;cursor:pointer;color:var(--sub)}\n.opt a{color:var(--pri);cursor:pointer}\n.btn-login{width:100%;padding:11px;background:var(--pri);color:#fff;border:none;border-radius:8px;font-size:14px;font-weight:600;cursor:pointer;transition:background .15s}\n.btn-login:hover{background:var(--pri-d)}\n.btn-login:disabled{background:#94a3b8;cursor:not-allowed}\n.login-footer{text-align:center;margin-top:20px;font-size:11px;color:var(--sub)}\n.captcha-row{display:flex;gap:10px;align-items:flex-end}\n.captcha-row .fi{flex:1}\n.captcha-img{height:40px;border-radius:6px;border:1px solid var(--bdr);cursor:pointer;background:#f1f5f9;display:flex;align-items:center;justify-content:center;padding:0 16px;font-size:16px;letter-spacing:4px;font-weight:700;color:var(--pri);font-family:monospace;user-select:none}\n/* Toast */\n.toast{position:fixed;top:20px;right:20px;padding:12px 20px;border-radius:8px;font-size:13px;font-weight:500;z-index:300;display:none}\n.toast.show{display:block;animation:tIn .3s}\n.toast.ok{background:#dcfce7;color:#166534;border:1px solid #bbf7d0}\n.toast.er{background:#fee2e2;color:#991b1b;border:1px solid #fecaca}\n@keyframes tIn{from{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}\n/* Loading spinner */\n.spinner{display:inline-block;width:16px;height:16px;border:2px solid rgba(255,255,255,.3);border-top-color:#fff;border-radius:50%;animation:spin .6s linear infinite;margin-right:6px;vertical-align:middle}\n@keyframes spin{to{transform:rotate(360deg)}}\n@media(max-width:768px){.login-left{display:none}.login-wrap{width:95vw}}\n<\/style>\n<\/head>\n<body>\n<div class=\"toast\" id=\"toast\"><\/div>\n<div class=\"login-wrap\">\n<div class=\"login-left\">\n<h1>🤖 Agent任务系统<\/h1>\n<p>企业级Agent任务自动化平台<br>基于角色权限的Skill调度与管理系统 v2.0<\/p>\n<div class=\"feat\">\n<div class=\"feat-i\"><span>🦞<\/span> 龙虾执行器 + 脚本引擎 双执行器架构<\/div>\n<div class=\"feat-i\"><span>🔐<\/span> 部门级角色 + Skill权限 + 多角色并集<\/div>\n<div class=\"feat-i\"><span>📦<\/span> 产品→渠道码→平台账号 全链路管理<\/div>\n<div class=\"feat-i\"><span>⚡<\/span> 三步任务创建 + 交集校验 + 智能调度<\/div>\n<\/div>\n<\/div>\n<div class=\"login-right\">\n<h2>登录<\/h2>\n<p class=\"sub\">欢迎回来,请输入您的账号信息<\/p>\n<form id=\"loginForm\" onsubmit=\"handleLogin(event)\">\n<div class=\"fg\">\n<label class=\"fl\">用户名 / 邮箱 <span style=\"color:var(--err)\">*<\/span><\/label>\n<input class=\"fi\" id=\"username\" type=\"text\" placeholder=\"请输入用户名或邮箱\" value=\"admin\">\n<div class=\"err-msg\" id=\"err-user\">请输入用户名<\/div>\n<\/div>\n<div class=\"fg\">\n<label class=\"fl\">密码 <span style=\"color:var(--err)\">*<\/span><\/label>\n<input class=\"fi\" id=\"password\" type=\"password\" placeholder=\"请输入密码\" value=\"admin123\">\n<div class=\"err-msg\" id=\"err-pass\">请输入密码<\/div>\n<\/div>\n<div class=\"fg\">\n<label class=\"fl\">验证码<\/label>\n<div class=\"captcha-row\">\n<input class=\"fi\" id=\"captcha\" type=\"text\" placeholder=\"请输入验证码\" maxlength=\"4\">\n<div class=\"captcha-img\" id=\"captchaImg\" onclick=\"refreshCaptcha()\" title=\"点击刷新\">A7X2<\/div>\n<\/div>\n<\/div>\n<div class=\"opt\">\n<label><input type=\"checkbox\" checked> 记住登录<\/label>\n<a onclick=\"showToast('请联系管理员重置密码','er')\">忘记密码?<\/a>\n<\/div>\n<button class=\"btn-login\" type=\"submit\" id=\"loginBtn\">登 录<\/button>\n<\/form>\n<div class=\"login-footer\">\nAgent任务系统 v2.0 · 技术栈 Next.js 14 + NestJS + PostgreSQL<br>\n© 2026 星辰科技有限公司\n<\/div>\n<\/div>\n<\/div>\n\n<script>\nfunction refreshCaptcha(){\n const chars='ABCDEFGHJKLMNPQRSTUVWXYZ23456789';\n let c='';for(let i=0;i<4;i++)c+=chars[Math.floor(Math.random()*chars.length)];\n document.getElementById('captchaImg').textContent=c;\n}\n\nfunction showToast(msg,type){\n const t=document.getElementById('toast');\n t.textContent=msg;t.className='toast show '+type;\n setTimeout(()=>t.className='toast',2500);\n}\n\nfunction handleLogin(e){\n e.preventDefault();\n const u=document.getElementById('username').value.trim();\n const p=document.getElementById('password').value.trim();\n const c=document.getElementById('captcha').value.trim();\n let ok=true;\n \n if(!u){document.getElementById('err-user').style.display='block';document.getElementById('username').classList.add('err');ok=false}\n else{document.getElementById('err-user').style.display='none';document.getElementById('username').classList.remove('err')}\n \n if(!p){document.getElementById('err-pass').style.display='block';document.getElementById('password').classList.add('err');ok=false}\n else{document.getElementById('err-pass').style.display='none';document.getElementById('password').classList.remove('err')}\n \n if(!ok)return;\n \n // Simulate login\n const btn=document.getElementById('loginBtn');\n btn.disabled=true;\n btn.innerHTML='<span class=\"spinner\"><\/span>登录中...';\n \n setTimeout(()=>{\n btn.disabled=false;\n btn.textContent='登 录';\n if(u==='admin' && p==='admin123'){\n showToast('✅ 登录成功!正在跳转...','ok');\n setTimeout(()=>{\n if(window.parent&&window.parent!==window){window.parent.postMessage('login-success','*')}else{document.body.innerHTML='<div style=\"display:flex;align-items:center;justify-content:center;height:100vh;flex-direction:column;color:#fff;gap:10px\"><div style=\"font-size:40px\">✅<\/div><div style=\"font-size:18px;font-weight:600\">登录成功<\/div><div style=\"font-size:13px;opacity:.8\">JWT Token 已签发,即将跳转至仪表盘...<\/div><\/div>';}\n },1000);\n }else{\n showToast('❌ 用户名或密码错误','er');\n refreshCaptcha();\n }\n },1500);\n}\n<\/script>\n<\/body>\n<\/html>\n",
|
||
"02_仪表盘.html": "<!DOCTYPE html>\n<html lang=\"zh-CN\">\n<head><script>if(window!==window.top)document.documentElement.classList.add(\"in-iframe\")<\/script><style>.in-iframe .side{display:none!important}.in-iframe .main{margin-left:0!important}.in-iframe .layout{min-height:auto}<\/style>\n<meta charset=\"UTF-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<title>Agent任务系统 v2.0 - 仪表盘<\/title>\n<style>\n*{margin:0;padding:0;box-sizing:border-box}\n:root{--pri:#6366f1;--pri-l:#818cf8;--bg:#f1f5f9;--card:#fff;--txt:#1e293b;--sub:#64748b;--bdr:#e2e8f0;--ok:#22c55e;--warn:#f59e0b;--err:#ef4444;--side:#1e293b}\nbody{font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,\"PingFang SC\",\"Microsoft YaHei\",sans-serif;background:var(--bg);color:var(--txt);line-height:1.6}\n.layout{display:flex;min-height:100vh}\n.side{width:220px;background:var(--side);color:#94a3b8;position:fixed;top:0;left:0;bottom:0;overflow-y:auto;z-index:100}\n.side .logo{padding:16px 18px;font-size:14px;font-weight:700;color:#fff;border-bottom:1px solid #334155;display:flex;align-items:center;gap:6px}\n.ni{display:flex;align-items:center;gap:8px;padding:9px 18px;font-size:12px;color:#94a3b8;cursor:pointer;border-left:3px solid transparent}\n.ni:hover{background:#334155;color:#e2e8f0}\n.ni.ac{background:rgba(99,102,241,.15);color:#818cf8;border-left-color:#818cf8;font-weight:600}\n.ng-t{padding:10px 18px 4px;font-size:10px;text-transform:uppercase;letter-spacing:1px;color:#475569;font-weight:600}\n.main{margin-left:220px;flex:1;display:flex;flex-direction:column}\n.hd{height:52px;background:var(--card);border-bottom:1px solid var(--bdr);display:flex;align-items:center;justify-content:space-between;padding:0 24px;position:sticky;top:0;z-index:50}\n.hd .bc{font-size:12px;color:var(--sub)}.hd .bc b{color:var(--txt)}\n.hd .av{width:30px;height:30px;border-radius:50%;background:var(--pri);color:#fff;display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:600}\n.ct{padding:24px;flex:1}\n.pt{font-size:20px;font-weight:700;margin-bottom:4px}\n.pd{font-size:12px;color:var(--sub);margin-bottom:20px}\n.card{background:var(--card);border-radius:10px;padding:16px;border:1px solid var(--bdr);margin-bottom:14px;box-shadow:0 1px 2px rgba(0,0,0,.03)}\n.ct-t{font-size:13px;font-weight:600;margin-bottom:12px;display:flex;align-items:center;gap:6px}\n.sg{display:grid;grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:12px;margin-bottom:20px}\n.sc{background:var(--card);border:1px solid var(--bdr);border-radius:10px;padding:14px;display:flex;align-items:center;gap:12px;cursor:pointer;transition:box-shadow .15s}\n.sc:hover{box-shadow:0 4px 12px rgba(0,0,0,.08)}\n.si{width:40px;height:40px;border-radius:10px;display:flex;align-items:center;justify-content:center;font-size:18px}\n.sn{font-size:22px;font-weight:700;line-height:1.2}\n.sl2{font-size:10px;color:var(--sub)}\n.tg{display:inline-block;padding:2px 8px;border-radius:99px;font-size:10px;font-weight:600}\n.tg-ok{background:#dcfce7;color:#166534}.tg-w{background:#fef3c7;color:#92400e}.tg-e{background:#fee2e2;color:#991b1b}\n.tg-i{background:#dbeafe;color:#1e40af}.tg-p{background:#f3e8ff;color:#6b21a8}.tg-g{background:#f1f5f9;color:#64748b}\ntable{width:100%;border-collapse:collapse;font-size:12px}\nth,td{padding:8px 12px;text-align:left;border-bottom:1px solid var(--bdr)}\nth{background:#f8fafc;font-weight:600;color:var(--sub);font-size:11px}\ntr:hover td{background:#fafbfc}\n.tw{overflow-x:auto;border:1px solid var(--bdr);border-radius:8px;background:var(--card)}\n.bar-chart{display:flex;align-items:flex-end;gap:8px;height:160px;padding:10px 0}\n.bar-col{flex:1;display:flex;flex-direction:column;align-items:center;gap:4px}\n.bar{width:100%;border-radius:4px 4px 0 0;transition:height .3s;cursor:pointer;position:relative}\n.bar:hover{opacity:.85}\n.bar-label{font-size:10px;color:var(--sub)}\n.bar-val{font-size:10px;font-weight:600;color:var(--txt)}\n.ring{width:120px;height:120px;border-radius:50%;position:relative;display:flex;align-items:center;justify-content:center}\n.ring-center{font-size:20px;font-weight:700}\n.ring-label{font-size:10px;color:var(--sub)}\n.legend{display:flex;flex-direction:column;gap:8px;font-size:12px}\n.legend-i{display:flex;align-items:center;gap:6px}\n.legend-dot{width:10px;height:10px;border-radius:50%;flex-shrink:0}\n.progress-bar{height:6px;background:#e2e8f0;border-radius:99px;overflow:hidden}\n.progress-fill{height:100%;border-radius:99px;transition:width .5s}\n.quick-acts{display:grid;grid-template-columns:repeat(4,1fr);gap:10px;margin-bottom:20px}\n.qa{background:var(--card);border:1px solid var(--bdr);border-radius:10px;padding:14px;text-align:center;cursor:pointer;transition:all .15s}\n.qa:hover{border-color:var(--pri);box-shadow:0 2px 8px rgba(99,102,241,.12)}\n.qa .qa-ic{font-size:24px;margin-bottom:6px}\n.qa .qa-t{font-size:12px;font-weight:500}\n<\/style>\n<\/head>\n<body>\n<div class=\"layout\">\n<aside class=\"side\">\n<div class=\"logo\">🤖 Agent任务系统<\/div>\n<div class=\"ni ac\">🏠 首页/仪表盘<\/div>\n<div class=\"ng-t\">权限管理<\/div>\n<div class=\"ni\" onclick=\"alert('请打开 03_组织架构.html')\">· 组织架构<\/div>\n<div class=\"ni\">· 菜单管理<\/div>\n<div class=\"ni\">· 角色管理<\/div>\n<div class=\"ni\">· 用户管理<\/div>\n<div class=\"ng-t\">产品管理<\/div>\n<div class=\"ni\">· 产品列表<\/div>\n<div class=\"ni\">· 渠道码管理<\/div>\n<div class=\"ni\">· 平台套件<\/div>\n<div class=\"ng-t\">平台账号<\/div>\n<div class=\"ni\">· 平台账号管理<\/div>\n<div class=\"ni\">· 账号模板管理<\/div>\n<div class=\"ng-t\">Skill中心<\/div>\n<div class=\"ni\">· Skill列表<\/div>\n<div class=\"ni\">· 调用日志<\/div>\n<div class=\"ng-t\">任务中心<\/div>\n<div class=\"ni\">· 任务创建<\/div>\n<div class=\"ni\">· 任务列表<\/div>\n<div class=\"ng-t\">日志/设置<\/div>\n<div class=\"ni\">· 操作日志<\/div>\n<div class=\"ni\">· 系统设置<\/div>\n<\/aside>\n<div class=\"main\">\n<div class=\"hd\">\n<div class=\"bc\">🏠 <b>首页<\/b> / 仪表盘<\/div>\n<div style=\"display:flex;align-items:center;gap:10px;font-size:12px\">\n<span>🔔<\/span><span>admin<\/span>\n<div class=\"av\">A<\/div>\n<\/div>\n<\/div>\n<div class=\"ct\">\n<h1 class=\"pt\">仪表盘<\/h1>\n<p class=\"pd\">系统运行概览 · 实时数据统计 · 2026-04-23<\/p>\n\n<!-- Quick Actions -->\n<div class=\"quick-acts\">\n<div class=\"qa\" onclick=\"alert('跳转:任务创建')\"><div class=\"qa-ic\">⚡<\/div><div class=\"qa-t\">创建任务<\/div><\/div>\n<div class=\"qa\" onclick=\"alert('跳转:Skill列表')\"><div class=\"qa-ic\">🧩<\/div><div class=\"qa-t\">管理Skill<\/div><\/div>\n<div class=\"qa\" onclick=\"alert('跳转:平台账号')\"><div class=\"qa-ic\">🔗<\/div><div class=\"qa-t\">平台账号<\/div><\/div>\n<div class=\"qa\" onclick=\"alert('跳转:任务列表')\"><div class=\"qa-ic\">📋<\/div><div class=\"qa-t\">任务列表<\/div><\/div>\n<\/div>\n\n<!-- Stats Cards -->\n<div class=\"sg\">\n<div class=\"sc\" style=\"border-left:3px solid #6366f1\"><div class=\"si\" style=\"background:#ede9fe\">📋<\/div><div><div class=\"sn\" id=\"s-total\">128<\/div><div class=\"sl2\">今日任务总数<\/div><\/div><\/div>\n<div class=\"sc\" style=\"border-left:3px solid #22c55e\"><div class=\"si\" style=\"background:#dcfce7\">✅<\/div><div><div class=\"sn\" id=\"s-ok\">96<\/div><div class=\"sl2\">执行成功<\/div><\/div><\/div>\n<div class=\"sc\" style=\"border-left:3px solid #ef4444\"><div class=\"si\" style=\"background:#fee2e2\">❌<\/div><div><div class=\"sn\" id=\"s-fail\">8<\/div><div class=\"sl2\">执行失败<\/div><\/div><\/div>\n<div class=\"sc\" style=\"border-left:3px solid #f59e0b\"><div class=\"si\" style=\"background:#fef3c7\">⏳<\/div><div><div class=\"sn\" id=\"s-run\">24<\/div><div class=\"sl2\">运行中<\/div><\/div><\/div>\n<div class=\"sc\" style=\"border-left:3px solid #3b82f6\"><div class=\"si\" style=\"background:#dbeafe\">👥<\/div><div><div class=\"sn\">56<\/div><div class=\"sl2\">活跃用户<\/div><\/div><\/div>\n<div class=\"sc\" style=\"border-left:3px solid #8b5cf6\"><div class=\"si\" style=\"background:#f3e8ff\">🧩<\/div><div><div class=\"sn\">23<\/div><div class=\"sl2\">已注册Skill<\/div><\/div><\/div>\n<\/div>\n\n<div style=\"display:grid;grid-template-columns:2fr 1fr;gap:14px\">\n<!-- Bar Chart -->\n<div class=\"card\">\n<div class=\"ct-t\">📊 最近7天任务趋势<\/div>\n<div class=\"bar-chart\" id=\"barChart\"><\/div>\n<\/div>\n\n<!-- Pie / Executor distribution -->\n<div class=\"card\">\n<div class=\"ct-t\">🔄 执行器分布<\/div>\n<div style=\"display:flex;align-items:center;gap:20px;justify-content:center;padding:10px 0\">\n<div class=\"ring\" style=\"background:conic-gradient(#6366f1 0% 62%,#22c55e 62% 100%)\">\n<div style=\"width:80px;height:80px;background:var(--card);border-radius:50%;display:flex;flex-direction:column;align-items:center;justify-content:center\">\n<div class=\"ring-center\">128<\/div>\n<div class=\"ring-label\">总计<\/div>\n<\/div>\n<\/div>\n<div class=\"legend\">\n<div class=\"legend-i\"><div class=\"legend-dot\" style=\"background:#6366f1\"><\/div>🦞 龙虾执行器 <b>62%<\/b> (79)<\/div>\n<div class=\"legend-i\"><div class=\"legend-dot\" style=\"background:#22c55e\"><\/div>📜 脚本引擎 <b>38%<\/b> (49)<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n\n<div style=\"display:grid;grid-template-columns:1fr 1fr;gap:14px\">\n<!-- Skill ranking -->\n<div class=\"card\">\n<div class=\"ct-t\">🔥 热门Skill Top 5<\/div>\n<div style=\"display:flex;flex-direction:column;gap:10px\">\n<div><div style=\"display:flex;justify-content:space-between;font-size:12px;margin-bottom:3px\"><span>🥇 竞品分析Agent<\/span><span>386次<\/span><\/div><div class=\"progress-bar\"><div class=\"progress-fill\" style=\"width:100%;background:#6366f1\"><\/div><\/div><\/div>\n<div><div style=\"display:flex;justify-content:space-between;font-size:12px;margin-bottom:3px\"><span>🥈 数据采集脚本<\/span><span>241次<\/span><\/div><div class=\"progress-bar\"><div class=\"progress-fill\" style=\"width:62%;background:#818cf8\"><\/div><\/div><\/div>\n<div><div style=\"display:flex;justify-content:space-between;font-size:12px;margin-bottom:3px\"><span>🥉 素材生成Agent<\/span><span>198次<\/span><\/div><div class=\"progress-bar\"><div class=\"progress-fill\" style=\"width:51%;background:#a78bfa\"><\/div><\/div><\/div>\n<div><div style=\"display:flex;justify-content:space-between;font-size:12px;margin-bottom:3px\"><span>4. 评论监控脚本<\/span><span>156次<\/span><\/div><div class=\"progress-bar\"><div class=\"progress-fill\" style=\"width:40%;background:#c4b5fd\"><\/div><\/div><\/div>\n<div><div style=\"display:flex;justify-content:space-between;font-size:12px;margin-bottom:3px\"><span>5. 投放优化Agent<\/span><span>132次<\/span><\/div><div class=\"progress-bar\"><div class=\"progress-fill\" style=\"width:34%;background:#ddd6fe\"><\/div><\/div><\/div>\n<\/div>\n<\/div>\n\n<!-- Department task stats -->\n<div class=\"card\">\n<div class=\"ct-t\">🏢 部门任务统计<\/div>\n<div style=\"display:flex;flex-direction:column;gap:10px\">\n<div><div style=\"display:flex;justify-content:space-between;font-size:12px;margin-bottom:3px\"><span>投放部<\/span><span>68次 (53%)<\/span><\/div><div class=\"progress-bar\"><div class=\"progress-fill\" style=\"width:100%;background:#22c55e\"><\/div><\/div><\/div>\n<div><div style=\"display:flex;justify-content:space-between;font-size:12px;margin-bottom:3px\"><span>运营部<\/span><span>35次 (27%)<\/span><\/div><div class=\"progress-bar\"><div class=\"progress-fill\" style=\"width:52%;background:#3b82f6\"><\/div><\/div><\/div>\n<div><div style=\"display:flex;justify-content:space-between;font-size:12px;margin-bottom:3px\"><span>技术部<\/span><span>15次 (12%)<\/span><\/div><div class=\"progress-bar\"><div class=\"progress-fill\" style=\"width:22%;background:#f59e0b\"><\/div><\/div><\/div>\n<div><div style=\"display:flex;justify-content:space-between;font-size:12px;margin-bottom:3px\"><span>产品部<\/span><span>10次 (8%)<\/span><\/div><div class=\"progress-bar\"><div class=\"progress-fill\" style=\"width:15%;background:#ef4444\"><\/div><\/div><\/div>\n<\/div>\n<\/div>\n<\/div>\n\n<!-- Recent tasks table -->\n<div class=\"card\">\n<div class=\"ct-t\">🕒 最新任务动态 <a style=\"margin-left:auto;font-size:11px;color:var(--pri);cursor:pointer\">查看全部 →<\/a><\/div>\n<div class=\"tw\"><table>\n<tr><th>ID<\/th><th>Skill名称<\/th><th>执行器<\/th><th>产品<\/th><th>创建人<\/th><th>状态<\/th><th>耗时<\/th><th>时间<\/th><\/tr>\n<tr><td>#1024<\/td><td>竞品分析Agent<\/td><td><span class=\"tg tg-p\">🦞龙虾<\/span><\/td><td>ProductA<\/td><td>张三<\/td><td><span class=\"tg tg-ok\">成功<\/span><\/td><td>2m18s<\/td><td>09:05<\/td><\/tr>\n<tr><td>#1023<\/td><td>数据采集脚本<\/td><td><span class=\"tg tg-ok\">📜脚本<\/span><\/td><td>ProductB<\/td><td>李四<\/td><td><span class=\"tg tg-w\">运行中<\/span><\/td><td>1m42s<\/td><td>09:02<\/td><\/tr>\n<tr><td>#1022<\/td><td>素材生成Agent<\/td><td><span class=\"tg tg-p\">🦞龙虾<\/span><\/td><td>ProductA<\/td><td>王五<\/td><td><span class=\"tg tg-ok\">成功<\/span><\/td><td>3m05s<\/td><td>08:58<\/td><\/tr>\n<tr><td>#1021<\/td><td>评论监控脚本<\/td><td><span class=\"tg tg-ok\">📜脚本<\/span><\/td><td>ProductC<\/td><td>赵六<\/td><td><span class=\"tg tg-e\">失败<\/span><\/td><td>0m12s<\/td><td>08:50<\/td><\/tr>\n<tr><td>#1020<\/td><td>投放优化Agent<\/td><td><span class=\"tg tg-p\">🦞龙虾<\/span><\/td><td>ProductA<\/td><td>张三<\/td><td><span class=\"tg tg-ok\">成功<\/span><\/td><td>4m30s<\/td><td>08:45<\/td><\/tr>\n<tr><td>#1019<\/td><td>价格监控Agent<\/td><td><span class=\"tg tg-p\">🦞龙虾<\/span><\/td><td>ProductB<\/td><td>钱七<\/td><td><span class=\"tg tg-ok\">成功<\/span><\/td><td>1m56s<\/td><td>08:40<\/td><\/tr>\n<tr><td>#1018<\/td><td>日报生成脚本<\/td><td><span class=\"tg tg-ok\">📜脚本<\/span><\/td><td>-<\/td><td>李四<\/td><td><span class=\"tg tg-ok\">成功<\/span><\/td><td>0m28s<\/td><td>08:35<\/td><\/tr>\n<\/table><\/div>\n<\/div>\n\n<!-- System status -->\n<div class=\"card\">\n<div class=\"ct-t\">🖥️ 系统状态<\/div>\n<div style=\"display:grid;grid-template-columns:repeat(4,1fr);gap:14px\">\n<div style=\"text-align:center;padding:10px\"><div style=\"font-size:11px;color:var(--sub);margin-bottom:4px\">龙虾执行器<\/div><div style=\"font-size:14px;font-weight:700;color:var(--ok)\">🟢 正常<\/div><div style=\"font-size:10px;color:var(--sub);margin-top:2px\">ping: 23ms<\/div><\/div>\n<div style=\"text-align:center;padding:10px\"><div style=\"font-size:11px;color:var(--sub);margin-bottom:4px\">脚本引擎<\/div><div style=\"font-size:14px;font-weight:700;color:var(--ok)\">🟢 正常<\/div><div style=\"font-size:10px;color:var(--sub);margin-top:2px\">并发: 8/20<\/div><\/div>\n<div style=\"text-align:center;padding:10px\"><div style=\"font-size:11px;color:var(--sub);margin-bottom:4px\">数据库<\/div><div style=\"font-size:14px;font-weight:700;color:var(--ok)\">🟢 正常<\/div><div style=\"font-size:10px;color:var(--sub);margin-top:2px\">连接: 12/100<\/div><\/div>\n<div style=\"text-align:center;padding:10px\"><div style=\"font-size:11px;color:var(--sub);margin-bottom:4px\">消息队列<\/div><div style=\"font-size:14px;font-weight:700;color:var(--warn)\">🟡 队列积压<\/div><div style=\"font-size:10px;color:var(--sub);margin-top:2px\">堆积: 42<\/div><\/div>\n<\/div>\n<\/div>\n\n<\/div>\n<\/div>\n<\/div>\n\n<script>\n// Animated bar chart\nconst data=[\n{day:'4/17',val:85},{day:'4/18',val:120},{day:'4/19',val:95},\n{day:'4/20',val:140},{day:'4/21',val:110},{day:'4/22',val:160},{day:'4/23',val:128}\n];\nconst max=Math.max(...data.map(d=>d.val));\nconst chart=document.getElementById('barChart');\ndata.forEach(d=>{\n const col=document.createElement('div');col.className='bar-col';\n const val=document.createElement('div');val.className='bar-val';val.textContent=d.val;\n const bar=document.createElement('div');bar.className='bar';\n bar.style.cssText=`background:linear-gradient(180deg,#6366f1,#a78bfa);height:0px`;\n const lbl=document.createElement('div');lbl.className='bar-label';lbl.textContent=d.day;\n col.append(val,bar,lbl);chart.append(col);\n setTimeout(()=>{bar.style.height=(d.val/max*140)+'px'},100);\n});\n\n// Simulated real-time counter\nlet total=128;\nsetInterval(()=>{\n if(Math.random()>.7){\n total++;document.getElementById('s-total').textContent=total;\n const ok=parseInt(document.getElementById('s-ok').textContent);\n if(Math.random()>.2)document.getElementById('s-ok').textContent=ok+1;\n else{\n const f=parseInt(document.getElementById('s-fail').textContent);\n document.getElementById('s-fail').textContent=f+1;\n }\n }\n},3000);\n<\/script>\n<\/body>\n<\/html>\n",
|
||
"03_组织架构.html": "<!DOCTYPE html>\n<html lang=\"zh-CN\">\n<head><script>if(window!==window.top)document.documentElement.classList.add(\"in-iframe\")<\/script><style>.in-iframe .side{display:none!important}.in-iframe .main{margin-left:0!important}.in-iframe .layout{min-height:auto}<\/style>\n<meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1.0\">\n<title>Agent任务系统 v2.0 - 组织架构<\/title>\n<style>\n*{margin:0;padding:0;box-sizing:border-box}\n:root{--pri:#6366f1;--bg:#f1f5f9;--card:#fff;--txt:#1e293b;--sub:#64748b;--bdr:#e2e8f0;--ok:#22c55e;--err:#ef4444;--side:#1e293b}\nbody{font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",\"PingFang SC\",\"Microsoft YaHei\",sans-serif;background:var(--bg);color:var(--txt);line-height:1.6}\n.layout{display:flex;min-height:100vh}\n.side{width:220px;background:var(--side);color:#94a3b8;position:fixed;top:0;left:0;bottom:0;overflow-y:auto;z-index:100}\n.side .logo{padding:16px 18px;font-size:14px;font-weight:700;color:#fff;border-bottom:1px solid #334155}\n.ni{display:flex;align-items:center;gap:8px;padding:9px 18px;font-size:12px;color:#94a3b8;cursor:pointer;border-left:3px solid transparent}\n.ni:hover{background:#334155;color:#e2e8f0}.ni.ac{background:rgba(99,102,241,.15);color:#818cf8;border-left-color:#818cf8;font-weight:600}\n.ng-t{padding:10px 18px 4px;font-size:10px;letter-spacing:1px;color:#475569;font-weight:600}\n.main{margin-left:220px;flex:1}\n.hd{height:52px;background:var(--card);border-bottom:1px solid var(--bdr);display:flex;align-items:center;padding:0 24px;font-size:12px;color:var(--sub);position:sticky;top:0;z-index:50}\n.ct{padding:24px}\n.pt{font-size:20px;font-weight:700;margin-bottom:4px}.pd{font-size:12px;color:var(--sub);margin-bottom:20px}\n.card{background:var(--card);border-radius:10px;padding:16px;border:1px solid var(--bdr);margin-bottom:14px}\n.ct-t{font-size:13px;font-weight:600;margin-bottom:12px;display:flex;align-items:center;gap:6px}\n.btn{padding:7px 16px;border-radius:7px;font-size:12px;font-weight:500;border:none;cursor:pointer;display:inline-flex;align-items:center;gap:5px;transition:all .12s}\n.btn-p{background:var(--pri);color:#fff}.btn-p:hover{background:#4f46e5}\n.btn-s{background:var(--ok);color:#fff}\n.btn-d{background:#fee2e2;color:#dc2626}.btn-g{background:transparent;color:var(--sub);border:1px solid var(--bdr)}\n.btn-sm{padding:5px 10px;font-size:11px}\n.btn-l{background:none;border:none;color:var(--pri);padding:0;font-size:12px;cursor:pointer}\n.tg{display:inline-block;padding:2px 8px;border-radius:99px;font-size:10px;font-weight:600}\n.tg-ok{background:#dcfce7;color:#166534}.tg-e{background:#fee2e2;color:#991b1b}.tg-i{background:#dbeafe;color:#1e40af}.tg-p{background:#f3e8ff;color:#6b21a8}.tg-g{background:#f1f5f9;color:#64748b}\ntable{width:100%;border-collapse:collapse;font-size:12px}\nth,td{padding:8px 12px;text-align:left;border-bottom:1px solid var(--bdr)}\nth{background:#f8fafc;font-weight:600;color:var(--sub);font-size:11px}\n.tw{overflow-x:auto;border:1px solid var(--bdr);border-radius:8px}\n.fg{margin-bottom:14px}.fl{font-size:12px;font-weight:500;margin-bottom:5px;display:block}\n.fi{width:100%;padding:8px 12px;border:1px solid var(--bdr);border-radius:7px;font-size:12px;outline:none}.fi:focus{border-color:var(--pri)}\n.fs{width:100%;padding:8px 12px;border:1px solid var(--bdr);border-radius:7px;font-size:12px;background:#fff}\n.fr{display:grid;grid-template-columns:1fr 1fr;gap:14px}\n/* Tree */\n.tr-n{padding:3px 0;font-size:12px}\n.tr-r{display:flex;align-items:center;gap:6px;padding:5px 8px;border-radius:6px;cursor:pointer}\n.tr-r:hover{background:#f1f5f9}.tr-r.sel{background:rgba(99,102,241,.1);color:var(--pri)}\n.tr-t{width:14px;text-align:center;color:var(--sub);font-size:10px;cursor:pointer}\n.tr-c{padding-left:22px;border-left:1px dashed var(--bdr);margin-left:11px}\n.tr-c.hide{display:none}\n/* Modal */\n.mo{position:fixed;inset:0;background:rgba(0,0,0,.45);display:none;align-items:center;justify-content:center;z-index:200}\n.mo.show{display:flex}\n.mc{background:var(--card);border-radius:14px;width:90%;max-width:560px;max-height:85vh;overflow-y:auto;box-shadow:0 20px 60px rgba(0,0,0,.2);animation:mIn .2s}\n@keyframes mIn{from{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}\n.mh{padding:14px 20px;border-bottom:1px solid var(--bdr);display:flex;justify-content:space-between;align-items:center}\n.mh h3{font-size:15px}.mx{cursor:pointer;font-size:18px;color:var(--sub);background:none;border:none}\n.mb{padding:20px}.mf{padding:14px 20px;border-top:1px solid var(--bdr);display:flex;justify-content:flex-end;gap:8px}\n.toast{position:fixed;top:20px;right:20px;padding:12px 20px;border-radius:8px;font-size:13px;font-weight:500;z-index:300;display:none}\n.toast.show{display:block;animation:tIn .3s}.toast.ok{background:#dcfce7;color:#166534}.toast.er{background:#fee2e2;color:#991b1b}\n@keyframes tIn{from{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}\n<\/style>\n<\/head>\n<body>\n<div class=\"toast\" id=\"toast\"><\/div>\n\n<!-- Modal: 新增/编辑组织 -->\n<div class=\"mo\" id=\"modal-org\">\n<div class=\"mc\">\n<div class=\"mh\"><h3 id=\"modal-org-title\">新增组织<\/h3><button class=\"mx\" onclick=\"closeModal('modal-org')\">✕<\/button><\/div>\n<div class=\"mb\">\n<div class=\"fg\"><label class=\"fl\">上级组织<\/label><select class=\"fs\"><option>星辰科技有限公司<\/option><option>├ 投放部<\/option><option>├ 运营部<\/option><option>├ 技术部<\/option><option>├ 产品部<\/option><\/select><\/div>\n<div class=\"fr\">\n<div class=\"fg\"><label class=\"fl\">组织名称 <span style=\"color:var(--err)\">*<\/span><\/label><input class=\"fi\" placeholder=\"请输入组织名称\"><\/div>\n<div class=\"fg\"><label class=\"fl\">组织类型 <span style=\"color:var(--err)\">*<\/span><\/label><select class=\"fs\"><option value=\"\">请选择<\/option><option>公司<\/option><option>部门<\/option><option>小组<\/option><\/select><\/div>\n<\/div>\n<div class=\"fr\">\n<div class=\"fg\"><label class=\"fl\">负责人<\/label><select class=\"fs\"><option value=\"\">请选择<\/option><option>张三<\/option><option>李四<\/option><option>王五<\/option><\/select><\/div>\n<div class=\"fg\"><label class=\"fl\">排序号<\/label><input class=\"fi\" type=\"number\" value=\"0\"><\/div>\n<\/div>\n<div class=\"fg\"><label class=\"fl\">状态<\/label><select class=\"fs\"><option>启用<\/option><option>禁用<\/option><\/select><\/div>\n<div class=\"fg\"><label class=\"fl\">备注<\/label><textarea class=\"fi\" rows=\"2\" placeholder=\"可选\"><\/textarea><\/div>\n<\/div>\n<div class=\"mf\"><button class=\"btn btn-g\" onclick=\"closeModal('modal-org')\">取消<\/button><button class=\"btn btn-p\" onclick=\"closeModal('modal-org');showToast('保存成功','ok')\">保存<\/button><\/div>\n<\/div><\/div>\n\n<!-- Modal: 确认删除 -->\n<div class=\"mo\" id=\"modal-del\">\n<div class=\"mc\" style=\"max-width:400px\">\n<div class=\"mh\"><h3>⚠️ 确认删除<\/h3><button class=\"mx\" onclick=\"closeModal('modal-del')\">✕<\/button><\/div>\n<div class=\"mb\" style=\"text-align:center;padding:24px\">\n<div style=\"font-size:40px;margin-bottom:10px\">🗑️<\/div>\n<p style=\"font-size:14px;font-weight:600;margin-bottom:6px\">确定要删除该组织吗?<\/p>\n<p style=\"font-size:12px;color:var(--sub)\">删除后该组织下的子部门和人员将移至上级组织<br>此操作不可恢复<\/p>\n<\/div>\n<div class=\"mf\"><button class=\"btn btn-g\" onclick=\"closeModal('modal-del')\">取消<\/button><button class=\"btn btn-d\" onclick=\"closeModal('modal-del');showToast('已删除','ok')\">确认删除<\/button><\/div>\n<\/div><\/div>\n\n<div class=\"layout\">\n<aside class=\"side\">\n<div class=\"logo\">🤖 Agent任务系统<\/div>\n<div class=\"ni\">🏠 首页<\/div>\n<div class=\"ng-t\">权限管理<\/div>\n<div class=\"ni ac\">· 组织架构<\/div>\n<div class=\"ni\">· 菜单管理<\/div>\n<div class=\"ni\">· 角色管理<\/div>\n<div class=\"ni\">· 用户管理<\/div>\n<div class=\"ng-t\">产品管理<\/div><div class=\"ni\">· 产品列表<\/div><div class=\"ni\">· 渠道码<\/div>\n<div class=\"ng-t\">平台账号<\/div><div class=\"ni\">· 账号管理<\/div><div class=\"ni\">· 账号模板<\/div>\n<div class=\"ng-t\">Skill中心<\/div><div class=\"ni\">· Skill列表<\/div>\n<div class=\"ng-t\">任务中心<\/div><div class=\"ni\">· 任务创建<\/div><div class=\"ni\">· 任务列表<\/div>\n<\/aside>\n<div class=\"main\">\n<div class=\"hd\">🏢 权限管理 / <b style=\"color:var(--txt)\">组织架构<\/b><\/div>\n<div class=\"ct\">\n<h1 class=\"pt\">组织架构管理<\/h1>\n<p class=\"pd\">公司 → 部门 → 小组 三级树形结构 · 支持拖拽排序 · 部门下可挂载角色和成员<\/p>\n\n<div style=\"display:grid;grid-template-columns:300px 1fr;gap:14px\">\n<!-- Left: Tree -->\n<div class=\"card\">\n<div class=\"ct-t\">🏢 组织树 <button class=\"btn btn-p btn-sm\" style=\"margin-left:auto\" onclick=\"openModal('modal-org','新增组织')\">+ 新增<\/button><\/div>\n<div style=\"margin-bottom:8px;padding:6px 10px;background:#f8fafc;border-radius:6px;display:flex;align-items:center;gap:6px\"><span>🔍<\/span><input style=\"border:none;background:none;outline:none;font-size:11px;width:100%\" placeholder=\"搜索组织名称\"><\/div>\n<div id=\"orgTree\">\n<div class=\"tr-n\"><div class=\"tr-r\" onclick=\"toggleTree(this)\"><span class=\"tr-t\">▼<\/span><span>🏢<\/span><span class=\"tr-l\" style=\"font-weight:700\">星辰科技有限公司<\/span><\/div>\n<div class=\"tr-c\">\n <div class=\"tr-n\"><div class=\"tr-r sel\" onclick=\"toggleTree(this);selectOrg('投放部','department',12,4)\"><span class=\"tr-t\">▼<\/span><span>🏬<\/span><span>投放部<\/span><span class=\"tg tg-g\" style=\"margin-left:auto;font-size:9px\">12人<\/span><\/div>\n <div class=\"tr-c\">\n <div class=\"tr-n\"><div class=\"tr-r\" onclick=\"selectOrg('投放一组','team',4,0)\"><span class=\"tr-t\">·<\/span><span>👥<\/span><span>投放一组<\/span><\/div><\/div>\n <div class=\"tr-n\"><div class=\"tr-r\" onclick=\"selectOrg('投放二组','team',5,0)\"><span class=\"tr-t\">·<\/span><span>👥<\/span><span>投放二组<\/span><\/div><\/div>\n <div class=\"tr-n\"><div class=\"tr-r\" onclick=\"selectOrg('投放三组','team',3,0)\"><span class=\"tr-t\">·<\/span><span>👥<\/span><span>投放三组<\/span><\/div><\/div>\n <\/div><\/div>\n <div class=\"tr-n\"><div class=\"tr-r\" onclick=\"toggleTree(this);selectOrg('运营部','department',8,2)\"><span class=\"tr-t\">▼<\/span><span>🏬<\/span><span>运营部<\/span><span class=\"tg tg-g\" style=\"margin-left:auto;font-size:9px\">8人<\/span><\/div>\n <div class=\"tr-c\">\n <div class=\"tr-n\"><div class=\"tr-r\" onclick=\"selectOrg('内容运营组','team',4,0)\"><span class=\"tr-t\">·<\/span><span>👥<\/span><span>内容运营组<\/span><\/div><\/div>\n <div class=\"tr-n\"><div class=\"tr-r\" onclick=\"selectOrg('社区运营组','team',4,0)\"><span class=\"tr-t\">·<\/span><span>👥<\/span><span>社区运营组<\/span><\/div><\/div>\n <\/div><\/div>\n <div class=\"tr-n\"><div class=\"tr-r\" onclick=\"toggleTree(this);selectOrg('技术部','department',10,3)\"><span class=\"tr-t\">▶<\/span><span>🏬<\/span><span>技术部<\/span><span class=\"tg tg-g\" style=\"margin-left:auto;font-size:9px\">10人<\/span><\/div>\n <div class=\"tr-c hide\">\n <div class=\"tr-n\"><div class=\"tr-r\"><span class=\"tr-t\">·<\/span><span>👥<\/span><span>前端组<\/span><\/div><\/div>\n <div class=\"tr-n\"><div class=\"tr-r\"><span class=\"tr-t\">·<\/span><span>👥<\/span><span>后端组<\/span><\/div><\/div>\n <div class=\"tr-n\"><div class=\"tr-r\"><span class=\"tr-t\">·<\/span><span>👥<\/span><span>运维组<\/span><\/div><\/div>\n <\/div><\/div>\n <div class=\"tr-n\"><div class=\"tr-r\" onclick=\"selectOrg('产品部','department',6,1)\"><span class=\"tr-t\">▶<\/span><span>🏬<\/span><span>产品部<\/span><span class=\"tg tg-g\" style=\"margin-left:auto;font-size:9px\">6人<\/span><\/div><div class=\"tr-c hide\"><\/div><\/div>\n<\/div><\/div>\n<\/div><\/div>\n\n<!-- Right: Detail Panel -->\n<div>\n<div class=\"card\" id=\"orgDetail\">\n<div class=\"ct-t\">📝 <span id=\"detailTitle\">投放部<\/span> · 详情\n<div style=\"margin-left:auto;display:flex;gap:6px\">\n<button class=\"btn btn-p btn-sm\" onclick=\"openModal('modal-org','编辑组织')\">编辑<\/button>\n<button class=\"btn btn-sm btn-d\" onclick=\"openModal('modal-del')\">删除<\/button>\n<\/div><\/div>\n<div style=\"display:grid;grid-template-columns:1fr 1fr 1fr;gap:10px;margin-bottom:16px;font-size:12px\">\n<div><span style=\"color:var(--sub)\">类型:<\/span><span class=\"tg tg-i\" id=\"detailType\">部门<\/span><\/div>\n<div><span style=\"color:var(--sub)\">成员数:<\/span><b id=\"detailCount\">12人<\/b><\/div>\n<div><span style=\"color:var(--sub)\">下辖组数:<\/span><b id=\"detailTeams\">4组<\/b><\/div>\n<div><span style=\"color:var(--sub)\">负责人:<\/span><b>张三<\/b><\/div>\n<div><span style=\"color:var(--sub)\">状态:<\/span><span class=\"tg tg-ok\">启用<\/span><\/div>\n<div><span style=\"color:var(--sub)\">创建时间:<\/span>2026-01-15<\/div>\n<\/div>\n<\/div>\n\n<!-- 角色列表 -->\n<div class=\"card\">\n<div class=\"ct-t\">🎭 部门角色 <span class=\"tg tg-g\">部门级角色<\/span><\/div>\n<div class=\"tw\"><table>\n<tr><th>角色名称<\/th><th>角色编码<\/th><th>成员数<\/th><th>Skill数<\/th><th>状态<\/th><\/tr>\n<tr><td><span class=\"tg tg-p\">投放主管<\/span><\/td><td>dept_tf_manager<\/td><td>3<\/td><td>8<\/td><td><span class=\"tg tg-ok\">启用<\/span><\/td><\/tr>\n<tr><td><span class=\"tg tg-i\">投放专员<\/span><\/td><td>dept_tf_staff<\/td><td>9<\/td><td>5<\/td><td><span class=\"tg tg-ok\">启用<\/span><\/td><\/tr>\n<tr><td><span class=\"tg tg-p\">数据分析师<\/span><\/td><td>dept_tf_analyst<\/td><td>2<\/td><td>4<\/td><td><span class=\"tg tg-ok\">启用<\/span><\/td><\/tr>\n<\/table><\/div><\/div>\n\n<!-- 成员列表 -->\n<div class=\"card\">\n<div class=\"ct-t\">👥 部门成员 <span class=\"tg tg-g\" id=\"memberBadge\">12人<\/span>\n<button class=\"btn btn-sm btn-g\" style=\"margin-left:auto\">导出<\/button><\/div>\n<div class=\"tw\"><table>\n<tr><th>姓名<\/th><th>工号<\/th><th>所属小组<\/th><th>角色<\/th><th>入职日期<\/th><th>状态<\/th><\/tr>\n<tr><td>张三<\/td><td>EMP001<\/td><td>投放一组<\/td><td><span class=\"tg tg-p\">投放主管<\/span><\/td><td>2024-03-01<\/td><td><span class=\"tg tg-ok\">在职<\/span><\/td><\/tr>\n<tr><td>李四<\/td><td>EMP002<\/td><td>投放一组<\/td><td><span class=\"tg tg-i\">投放专员<\/span><\/td><td>2024-06-15<\/td><td><span class=\"tg tg-ok\">在职<\/span><\/td><\/tr>\n<tr><td>王五<\/td><td>EMP003<\/td><td>投放二组<\/td><td><span class=\"tg tg-i\">投放专员<\/span><\/td><td>2024-08-20<\/td><td><span class=\"tg tg-ok\">在职<\/span><\/td><\/tr>\n<tr><td>赵六<\/td><td>EMP004<\/td><td>投放二组<\/td><td><span class=\"tg tg-p\">投放主管<\/span> <span class=\"tg tg-i\">数据分析师<\/span><\/td><td>2024-02-10<\/td><td><span class=\"tg tg-ok\">在职<\/span><\/td><\/tr>\n<tr><td>钱七<\/td><td>EMP005<\/td><td>投放三组<\/td><td><span class=\"tg tg-i\">投放专员<\/span><\/td><td>2025-01-05<\/td><td><span class=\"tg tg-ok\">在职<\/span><\/td><\/tr>\n<tr><td>孙八<\/td><td>EMP006<\/td><td>投放一组<\/td><td><span class=\"tg tg-i\">投放专员<\/span><\/td><td>2025-03-18<\/td><td><span class=\"tg tg-ok\">在职<\/span><\/td><\/tr>\n<\/table><\/div><\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n\n<script>\nfunction toggleTree(el){\n const c=el.closest('.tr-n').querySelector('.tr-c');\n if(!c)return;\n const t=el.querySelector('.tr-t');\n if(c.classList.contains('hide')){c.classList.remove('hide');t.textContent='▼'}\n else{c.classList.add('hide');t.textContent='▶'}\n}\nfunction selectOrg(name,type,count,teams){\n document.querySelectorAll('.tr-r').forEach(r=>r.classList.remove('sel'));\n event.currentTarget.classList.add('sel');\n document.getElementById('detailTitle').textContent=name;\n document.getElementById('detailType').textContent=type==='department'?'部门':'小组';\n document.getElementById('detailCount').textContent=count+'人';\n document.getElementById('detailTeams').textContent=teams+'组';\n document.getElementById('memberBadge').textContent=count+'人';\n}\nfunction openModal(id,title){document.getElementById(id).classList.add('show');if(title&&document.getElementById(id.replace('modal-','modal-')+'-title'))document.getElementById('modal-org-title').textContent=title}\nfunction closeModal(id){document.getElementById(id).classList.remove('show')}\nfunction showToast(m,t){const e=document.getElementById('toast');e.textContent=m;e.className='toast show '+t;setTimeout(()=>e.className='toast',2500)}\ndocument.querySelectorAll('.mo').forEach(m=>m.addEventListener('click',e=>{if(e.target===m)m.classList.remove('show')}));\n<\/script>\n<\/body>\n<\/html>\n",
|
||
"04_角色管理.html": "<!DOCTYPE html><html lang=\"zh-CN\"><head><script>if(window!==window.top)document.documentElement.classList.add(\"in-iframe\")<\/script><style>.in-iframe .side{display:none!important}.in-iframe .main{margin-left:0!important}.in-iframe .layout{min-height:auto}<\/style><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1.0\"><title>Agent任务系统 - 角色管理<\/title>\n<style>*{margin:0;padding:0;box-sizing:border-box}:root{--pri:#6366f1;--bg:#f1f5f9;--card:#fff;--txt:#1e293b;--sub:#64748b;--bdr:#e2e8f0;--ok:#22c55e;--err:#ef4444;--side:#1e293b}body{font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",\"PingFang SC\",\"Microsoft YaHei\",sans-serif;background:var(--bg);color:var(--txt);line-height:1.6}.layout{display:flex;min-height:100vh}.side{width:220px;background:var(--side);color:#94a3b8;position:fixed;top:0;left:0;bottom:0;overflow-y:auto;z-index:100}.side .logo{padding:16px 18px;font-size:14px;font-weight:700;color:#fff;border-bottom:1px solid #334155}.ni{display:flex;align-items:center;gap:8px;padding:9px 18px;font-size:12px;color:#94a3b8;cursor:pointer;border-left:3px solid transparent}.ni:hover{background:#334155}.ni.ac{background:rgba(99,102,241,.15);color:#818cf8;border-left-color:#818cf8;font-weight:600}.ng-t{padding:10px 18px 4px;font-size:10px;letter-spacing:1px;color:#475569;font-weight:600}.main{margin-left:220px;flex:1}.hd{height:52px;background:var(--card);border-bottom:1px solid var(--bdr);display:flex;align-items:center;padding:0 24px;font-size:12px;color:var(--sub);position:sticky;top:0;z-index:50}.ct{padding:24px}.pt{font-size:20px;font-weight:700;margin-bottom:4px}.pd{font-size:12px;color:var(--sub);margin-bottom:20px}.card{background:var(--card);border-radius:10px;padding:16px;border:1px solid var(--bdr);margin-bottom:14px}.ct-t{font-size:13px;font-weight:600;margin-bottom:12px;display:flex;align-items:center;gap:6px}.btn{padding:7px 16px;border-radius:7px;font-size:12px;font-weight:500;border:none;cursor:pointer;display:inline-flex;align-items:center;gap:5px}.btn-p{background:var(--pri);color:#fff}.btn-d{background:#fee2e2;color:#dc2626}.btn-g{background:transparent;color:var(--sub);border:1px solid var(--bdr)}.btn-sm{padding:5px 10px;font-size:11px}.btn-l{background:none;border:none;color:var(--pri);padding:0;font-size:12px;cursor:pointer}.tg{display:inline-block;padding:2px 8px;border-radius:99px;font-size:10px;font-weight:600}.tg-ok{background:#dcfce7;color:#166534}.tg-e{background:#fee2e2;color:#991b1b}.tg-i{background:#dbeafe;color:#1e40af}.tg-p{background:#f3e8ff;color:#6b21a8}.tg-g{background:#f1f5f9;color:#64748b}.tg-w{background:#fef3c7;color:#92400e}table{width:100%;border-collapse:collapse;font-size:12px}th,td{padding:8px 12px;text-align:left;border-bottom:1px solid var(--bdr)}th{background:#f8fafc;font-weight:600;color:var(--sub);font-size:11px}.tw{overflow-x:auto;border:1px solid var(--bdr);border-radius:8px}.fg{margin-bottom:14px}.fl{font-size:12px;font-weight:500;margin-bottom:5px;display:block}.fi{width:100%;padding:8px 12px;border:1px solid var(--bdr);border-radius:7px;font-size:12px;outline:none}.fi:focus{border-color:var(--pri)}.fs{width:100%;padding:8px 12px;border:1px solid var(--bdr);border-radius:7px;font-size:12px;background:#fff}.fr{display:grid;grid-template-columns:1fr 1fr;gap:14px}.tb{display:flex;gap:8px;align-items:center;margin-bottom:14px;flex-wrap:wrap}.sb{display:flex;align-items:center;gap:6px;background:#f8fafc;border:1px solid var(--bdr);border-radius:7px;padding:7px 12px;font-size:12px}.sb input{border:none;background:none;outline:none;font-size:12px;width:120px}.sl{border:1px solid var(--bdr);border-radius:7px;padding:7px 12px;font-size:12px;background:#fff}.tabs{display:flex;gap:0;border-bottom:2px solid var(--bdr);margin-bottom:16px}.tab{padding:8px 16px;font-size:12px;font-weight:500;color:var(--sub);cursor:pointer;border-bottom:2px solid transparent;margin-bottom:-2px}.tab.ac{color:var(--pri);border-bottom-color:var(--pri);font-weight:600}.tab:hover{color:var(--txt)}.tab-ct{display:none}.tab-ct.show{display:block}.mo{position:fixed;inset:0;background:rgba(0,0,0,.45);display:none;align-items:center;justify-content:center;z-index:200}.mo.show{display:flex}.mc{background:var(--card);border-radius:14px;width:90%;max-width:720px;max-height:85vh;overflow-y:auto;box-shadow:0 20px 60px rgba(0,0,0,.2)}.mh{padding:14px 20px;border-bottom:1px solid var(--bdr);display:flex;justify-content:space-between;align-items:center}.mh h3{font-size:15px}.mx{cursor:pointer;font-size:18px;color:var(--sub);background:none;border:none}.mb{padding:20px}.mf{padding:14px 20px;border-top:1px solid var(--bdr);display:flex;justify-content:flex-end;gap:8px}.toast{position:fixed;top:20px;right:20px;padding:12px 20px;border-radius:8px;font-size:13px;font-weight:500;z-index:300;display:none}.toast.show{display:block;animation:tIn .3s}.toast.ok{background:#dcfce7;color:#166534}.toast.er{background:#fee2e2;color:#991b1b}@keyframes tIn{from{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}.pg{display:flex;align-items:center;justify-content:space-between;padding:10px 0;font-size:12px;color:var(--sub)}.pgb{padding:4px 10px;border:1px solid var(--bdr);border-radius:5px;font-size:11px;cursor:pointer;background:var(--card);margin:0 2px}.pgb.ac{background:var(--pri);color:#fff;border-color:var(--pri)}.ck label{display:flex;align-items:center;gap:5px;padding:3px 0;cursor:pointer;font-size:12px}.ck .ch{padding-left:22px}<\/style><\/head><body>\n<div class=\"toast\" id=\"toast\"><\/div>\n<!-- Modal: 新增/编辑角色 -->\n<div class=\"mo\" id=\"modal-role\"><div class=\"mc\"><div class=\"mh\"><h3 id=\"mrTitle\">新增角色<\/h3><button class=\"mx\" onclick=\"closeM('modal-role')\">✕<\/button><\/div><div class=\"mb\">\n<div class=\"fr\"><div class=\"fg\"><label class=\"fl\">角色名称 <span style=\"color:var(--err)\">*<\/span><\/label><input class=\"fi\" placeholder=\"如:投放主管\"><\/div><div class=\"fg\"><label class=\"fl\">角色编码 <span style=\"color:var(--err)\">*<\/span><\/label><input class=\"fi\" placeholder=\"如:dept_tf_manager\"><\/div><\/div>\n<div class=\"fr\"><div class=\"fg\"><label class=\"fl\">所属部门 <span style=\"color:var(--err)\">*<\/span><\/label><select class=\"fs\" id=\"roleDept\"><option>投放部<\/option><option>运营部<\/option><option>技术部<\/option><option>产品部<\/option><\/select><\/div><div class=\"fg\"><label class=\"fl\">状态<\/label><select class=\"fs\"><option>启用<\/option><option>禁用<\/option><\/select><\/div><\/div>\n<div class=\"fg\"><label class=\"fl\">描述<\/label><textarea class=\"fi\" rows=\"2\" placeholder=\"角色职责描述\"><\/textarea><\/div>\n<hr style=\"border:none;border-top:1px solid var(--bdr);margin:16px 0\">\n<div class=\"ct-t\">🔑 四要素配置<\/div>\n<!-- Tabs for 4 elements -->\n<div class=\"tabs\"><div class=\"tab ac\" onclick=\"switchRoleTab(0)\">📋 菜单权限<\/div><div class=\"tab\" onclick=\"switchRoleTab(1)\">📦 产品范围<\/div><div class=\"tab\" onclick=\"switchRoleTab(2)\">🧩 Skill权限<\/div><div class=\"tab\" onclick=\"switchRoleTab(3)\">🔗 平台账号<\/div><\/div>\n<div class=\"tab-ct show\" id=\"rtab0\">\n<div class=\"ck\">\n<label><input type=\"checkbox\" checked> <b>全选<\/b><\/label>\n<div class=\"ch\"><label><input type=\"checkbox\" checked> 📁 首页<\/label><\/div>\n<div class=\"ch\"><label><input type=\"checkbox\" checked> 📁 权限管理<\/label>\n<div class=\"ch\"><label><input type=\"checkbox\" checked> 组织架构 (org:view, org:create, org:edit, org:delete)<\/label><\/div>\n<div class=\"ch\"><label><input type=\"checkbox\" checked> 角色管理 (role:view, role:create, role:edit)<\/label><\/div>\n<div class=\"ch\"><label><input type=\"checkbox\"> 用户管理 (user:view, user:create)<\/label><\/div>\n<\/div>\n<div class=\"ch\"><label><input type=\"checkbox\" checked> 📁 产品管理<\/label>\n<div class=\"ch\"><label><input type=\"checkbox\" checked> 产品列表 (product:view, product:create, product:edit)<\/label><\/div>\n<div class=\"ch\"><label><input type=\"checkbox\" checked> 渠道码管理 (channel:view, channel:create)<\/label><\/div>\n<\/div>\n<div class=\"ch\"><label><input type=\"checkbox\" checked> 📁 Skill中心<\/label><\/div>\n<div class=\"ch\"><label><input type=\"checkbox\" checked> 📁 任务中心<\/label><\/div>\n<\/div><\/div>\n<div class=\"tab-ct\" id=\"rtab1\">\n<p style=\"font-size:12px;color:var(--sub);margin-bottom:10px\">勾选该角色可操作的产品范围:<\/p>\n<div class=\"ck\">\n<label><input type=\"checkbox\" checked> ProductA — 跨境电商旗舰店<\/label>\n<label><input type=\"checkbox\" checked> ProductB — 国内直播电商<\/label>\n<label><input type=\"checkbox\"> ProductC — 社交媒体矩阵<\/label>\n<label><input type=\"checkbox\"> ProductD — 搜索引擎营销<\/label>\n<\/div><\/div>\n<div class=\"tab-ct\" id=\"rtab2\">\n<p style=\"font-size:12px;color:var(--sub);margin-bottom:10px\">勾选该角色可调用的Skill:<\/p>\n<div class=\"ck\">\n<label><input type=\"checkbox\" checked> 🦞 竞品分析Agent<\/label>\n<label><input type=\"checkbox\" checked> 📜 数据采集脚本<\/label>\n<label><input type=\"checkbox\" checked> 🦞 素材生成Agent<\/label>\n<label><input type=\"checkbox\"> 📜 评论监控脚本<\/label>\n<label><input type=\"checkbox\"> 🦞 投放优化Agent<\/label>\n<label><input type=\"checkbox\"> 📜 日报生成脚本<\/label>\n<\/div><\/div>\n<div class=\"tab-ct\" id=\"rtab3\">\n<p style=\"font-size:12px;color:var(--sub);margin-bottom:10px\">该角色可使用的平台账号(归属角色级别):<\/p>\n<div class=\"tw\"><table><tr><th>平台<\/th><th>账号名<\/th><th>状态<\/th><th>绑定<\/th><\/tr>\n<tr><td>🔴 小红书<\/td><td>品牌旗舰店_01<\/td><td><span class=\"tg tg-ok\">正常<\/span><\/td><td><input type=\"checkbox\" checked><\/td><\/tr>\n<tr><td>🎵 抖音<\/td><td>官方账号_A<\/td><td><span class=\"tg tg-ok\">正常<\/span><\/td><td><input type=\"checkbox\" checked><\/td><\/tr>\n<tr><td>📘 Facebook<\/td><td>Brand_Page_01<\/td><td><span class=\"tg tg-ok\">正常<\/span><\/td><td><input type=\"checkbox\"><\/td><\/tr>\n<tr><td>🐦 Twitter<\/td><td>@brand_official<\/td><td><span class=\"tg tg-w\">即将过期<\/span><\/td><td><input type=\"checkbox\"><\/td><\/tr>\n<\/table><\/div><\/div>\n<\/div><div class=\"mf\"><button class=\"btn btn-g\" onclick=\"closeM('modal-role')\">取消<\/button><button class=\"btn btn-p\" onclick=\"closeM('modal-role');showT('保存成功','ok')\">保存<\/button><\/div><\/div><\/div>\n\n<div class=\"layout\"><aside class=\"side\"><div class=\"logo\">🤖 Agent任务系统<\/div><div class=\"ni\">🏠 首页<\/div><div class=\"ng-t\">权限管理<\/div><div class=\"ni\">· 组织架构<\/div><div class=\"ni\">· 菜单管理<\/div><div class=\"ni ac\">· 角色管理<\/div><div class=\"ni\">· 用户管理<\/div><div class=\"ng-t\">产品管理<\/div><div class=\"ni\">· 产品列表<\/div><div class=\"ng-t\">平台/Skill/任务<\/div><div class=\"ni\">· 平台账号<\/div><div class=\"ni\">· Skill列表<\/div><div class=\"ni\">· 任务创建<\/div><div class=\"ni\">· 任务列表<\/div><\/aside>\n<div class=\"main\"><div class=\"hd\">🔐 权限管理 / <b style=\"color:var(--txt)\">角色管理<\/b><\/div>\n<div class=\"ct\"><h1 class=\"pt\">角色管理<\/h1><p class=\"pd\">部门级角色 · 四要素配置(菜单权限+产品范围+Skill权限+平台账号)· 用户多角色并集<\/p>\n<div class=\"tb\">\n<div class=\"sb\"><span>🔍<\/span><input placeholder=\"搜索角色名称/编码\"><\/div>\n<select class=\"sl\"><option>全部部门<\/option><option>投放部<\/option><option>运营部<\/option><option>技术部<\/option><option>产品部<\/option><\/select>\n<select class=\"sl\"><option>全部状态<\/option><option>启用<\/option><option>禁用<\/option><\/select>\n<button class=\"btn btn-p\" style=\"margin-left:auto\" onclick=\"openM('modal-role','新增角色')\">+ 新增角色<\/button>\n<\/div>\n<div class=\"tw\"><table>\n<tr><th><input type=\"checkbox\"><\/th><th>角色名称<\/th><th>角色编码<\/th><th>所属部门<\/th><th>菜单权限<\/th><th>产品范围<\/th><th>Skill数<\/th><th>平台账号<\/th><th>成员数<\/th><th>状态<\/th><th>操作<\/th><\/tr>\n<tr><td><input type=\"checkbox\"><\/td><td><b>超级管理员<\/b><\/td><td>super_admin<\/td><td><span class=\"tg tg-g\">全局<\/span><\/td><td><span class=\"tg tg-p\">全部<\/span><\/td><td><span class=\"tg tg-p\">全部<\/span><\/td><td>23<\/td><td>全部<\/td><td>2<\/td><td><span class=\"tg tg-ok\">启用<\/span><\/td><td><button class=\"btn-l\" onclick=\"openM('modal-role','编辑角色')\">编辑<\/button><\/td><\/tr>\n<tr><td><input type=\"checkbox\"><\/td><td><b>投放主管<\/b><\/td><td>dept_tf_mgr<\/td><td><span class=\"tg tg-i\">投放部<\/span><\/td><td>12项<\/td><td>2个产品<\/td><td>8<\/td><td>4个<\/td><td>3<\/td><td><span class=\"tg tg-ok\">启用<\/span><\/td><td><button class=\"btn-l\" onclick=\"openM('modal-role','编辑角色')\">编辑<\/button> <button class=\"btn-l\" style=\"color:var(--err)\">删除<\/button><\/td><\/tr>\n<tr><td><input type=\"checkbox\"><\/td><td><b>投放专员<\/b><\/td><td>dept_tf_staff<\/td><td><span class=\"tg tg-i\">投放部<\/span><\/td><td>8项<\/td><td>2个产品<\/td><td>5<\/td><td>2个<\/td><td>9<\/td><td><span class=\"tg tg-ok\">启用<\/span><\/td><td><button class=\"btn-l\" onclick=\"openM('modal-role','编辑角色')\">编辑<\/button> <button class=\"btn-l\" style=\"color:var(--err)\">删除<\/button><\/td><\/tr>\n<tr><td><input type=\"checkbox\"><\/td><td><b>数据分析师<\/b><\/td><td>dept_tf_analyst<\/td><td><span class=\"tg tg-i\">投放部<\/span><\/td><td>6项<\/td><td>全部<\/td><td>4<\/td><td>0个<\/td><td>2<\/td><td><span class=\"tg tg-ok\">启用<\/span><\/td><td><button class=\"btn-l\" onclick=\"openM('modal-role','编辑角色')\">编辑<\/button> <button class=\"btn-l\" style=\"color:var(--err)\">删除<\/button><\/td><\/tr>\n<tr><td><input type=\"checkbox\"><\/td><td><b>运营主管<\/b><\/td><td>dept_yy_mgr<\/td><td><span class=\"tg tg-p\">运营部<\/span><\/td><td>10项<\/td><td>3个产品<\/td><td>6<\/td><td>3个<\/td><td>2<\/td><td><span class=\"tg tg-ok\">启用<\/span><\/td><td><button class=\"btn-l\" onclick=\"openM('modal-role','编辑角色')\">编辑<\/button> <button class=\"btn-l\" style=\"color:var(--err)\">删除<\/button><\/td><\/tr>\n<tr><td><input type=\"checkbox\"><\/td><td><b>运营专员<\/b><\/td><td>dept_yy_staff<\/td><td><span class=\"tg tg-p\">运营部<\/span><\/td><td>6项<\/td><td>2个产品<\/td><td>3<\/td><td>2个<\/td><td>6<\/td><td><span class=\"tg tg-ok\">启用<\/span><\/td><td><button class=\"btn-l\" onclick=\"openM('modal-role','编辑角色')\">编辑<\/button> <button class=\"btn-l\" style=\"color:var(--err)\">删除<\/button><\/td><\/tr>\n<tr><td><input type=\"checkbox\"><\/td><td><b>开发工程师<\/b><\/td><td>dept_tech_dev<\/td><td><span class=\"tg tg-w\">技术部<\/span><\/td><td>5项<\/td><td>全部<\/td><td>10<\/td><td>0个<\/td><td>7<\/td><td><span class=\"tg tg-ok\">启用<\/span><\/td><td><button class=\"btn-l\" onclick=\"openM('modal-role','编辑角色')\">编辑<\/button> <button class=\"btn-l\" style=\"color:var(--err)\">删除<\/button><\/td><\/tr>\n<tr><td><input type=\"checkbox\"><\/td><td><b>产品经理<\/b><\/td><td>dept_pm_mgr<\/td><td><span class=\"tg tg-g\">产品部<\/span><\/td><td>8项<\/td><td>全部<\/td><td>2<\/td><td>0个<\/td><td>3<\/td><td><span class=\"tg tg-ok\">启用<\/span><\/td><td><button class=\"btn-l\" onclick=\"openM('modal-role','编辑角色')\">编辑<\/button> <button class=\"btn-l\" style=\"color:var(--err)\">删除<\/button><\/td><\/tr>\n<\/table><\/div>\n<div class=\"pg\"><span>共 8 条,每页 10 条<\/span><div><span class=\"pgb ac\">1<\/span><\/div><\/div>\n\n<div class=\"card\" style=\"margin-top:16px;border:2px dashed var(--pri)\">\n<div class=\"ct-t\">💡 角色权限规则说明<\/div>\n<div style=\"font-size:12px;color:var(--sub);line-height:2\">\n<b>RB-01<\/b> 角色必须归属于一个部门(部门级角色)<br>\n<b>RB-02<\/b> 用户可绑定多个角色,最终权限 = 所有角色权限并集<br>\n<b>RB-03<\/b> 角色四要素:菜单权限 + 产品范围 + Skill权限 + 平台账号<br>\n<b>RB-05<\/b> 平台账号归属角色而非用户,角色成员共享<br>\n<b>RB-06<\/b> 任务创建时校验交集(用户产品 ∩ Skill产品 ∩ 账号产品 ≠ ∅)\n<\/div><\/div>\n<\/div><\/div><\/div>\n<script>\nfunction switchRoleTab(i){document.querySelectorAll('.tab').forEach((t,j)=>{t.classList.toggle('ac',j===i)});document.querySelectorAll('.tab-ct').forEach((c,j)=>{c.classList.toggle('show',j===i)})}\nfunction openM(id,t){document.getElementById(id).classList.add('show');if(t)document.getElementById('mrTitle').textContent=t}\nfunction closeM(id){document.getElementById(id).classList.remove('show')}\nfunction showT(m,t){const e=document.getElementById('toast');e.textContent=m;e.className='toast show '+t;setTimeout(()=>e.className='toast',2500)}\ndocument.querySelectorAll('.mo').forEach(m=>m.addEventListener('click',e=>{if(e.target===m)m.classList.remove('show')}));\n<\/script><\/body><\/html>\n",
|
||
"05_用户管理.html": "<!DOCTYPE html><html lang=\"zh-CN\"><head><script>if(window!==window.top)document.documentElement.classList.add(\"in-iframe\")<\/script><style>.in-iframe .side{display:none!important}.in-iframe .main{margin-left:0!important}.in-iframe .layout{min-height:auto}<\/style><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1.0\"><title>Agent任务系统 v2.1 - 用户管理<\/title>\n<style>\n*{margin:0;padding:0;box-sizing:border-box}:root{--pri:#6366f1;--bg:#f1f5f9;--card:#fff;--txt:#1e293b;--sub:#64748b;--bdr:#e2e8f0;--ok:#22c55e;--err:#ef4444;--warn:#f59e0b;--side:#1e293b}body{font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",\"PingFang SC\",\"Microsoft YaHei\",sans-serif;background:var(--bg);color:var(--txt);line-height:1.6;font-size:13px}\n.layout{display:flex;min-height:100vh}.side{width:220px;background:var(--side);color:#94a3b8;position:fixed;top:0;left:0;bottom:0;overflow-y:auto;z-index:100}.side .logo{padding:16px 18px;font-size:14px;font-weight:700;color:#fff;border-bottom:1px solid #334155}.ni{display:flex;align-items:center;gap:8px;padding:9px 18px;font-size:12px;color:#94a3b8;cursor:pointer;border-left:3px solid transparent}.ni:hover{background:#334155;color:#e2e8f0}.ni.ac{background:rgba(99,102,241,.15);color:#818cf8;border-left-color:#818cf8;font-weight:600}.ng-t{padding:10px 18px 4px;font-size:10px;letter-spacing:1px;color:#475569;font-weight:600}\n.main{margin-left:220px;flex:1}.hd{height:52px;background:var(--card);border-bottom:1px solid var(--bdr);display:flex;align-items:center;justify-content:space-between;padding:0 24px;font-size:12px;color:var(--sub);position:sticky;top:0;z-index:50}.ct{padding:24px}\n.pt{font-size:20px;font-weight:700;margin-bottom:4px}.pd{font-size:12px;color:var(--sub);margin-bottom:20px}\n.card{background:var(--card);border-radius:10px;padding:16px;border:1px solid var(--bdr);margin-bottom:14px}\n.tb{display:flex;gap:8px;align-items:center;margin-bottom:14px;flex-wrap:wrap}.sb{display:flex;align-items:center;gap:6px;background:#f8fafc;border:1px solid var(--bdr);border-radius:7px;padding:7px 12px;font-size:12px}.sb input{border:none;background:none;outline:none;font-size:12px;width:120px}\n.sl{border:1px solid var(--bdr);border-radius:7px;padding:7px 12px;font-size:12px;background:#fff;cursor:pointer}\n.btn{padding:7px 16px;border-radius:7px;font-size:12px;font-weight:500;border:none;cursor:pointer;display:inline-flex;align-items:center;gap:5px;transition:all .12s}.btn-p{background:var(--pri);color:#fff}.btn-p:hover{background:#4f46e5}.btn-d{background:#fee2e2;color:#dc2626}.btn-g{background:transparent;color:var(--sub);border:1px solid var(--bdr)}.btn-sm{padding:5px 10px;font-size:11px}.btn-s{background:var(--ok);color:#fff}\n.btn-l{background:none;border:none;color:var(--pri);padding:0;font-size:12px;cursor:pointer}.btn-l:hover{text-decoration:underline}\n.tg{display:inline-block;padding:2px 8px;border-radius:99px;font-size:10px;font-weight:600}.tg-ok{background:#dcfce7;color:#166534}.tg-e{background:#fee2e2;color:#991b1b}.tg-i{background:#dbeafe;color:#1e40af}.tg-p{background:#f3e8ff;color:#6b21a8}.tg-g{background:#f1f5f9;color:#64748b}.tg-w{background:#fef3c7;color:#92400e}\ntable{width:100%;border-collapse:collapse;font-size:12px}th,td{padding:8px 12px;text-align:left;border-bottom:1px solid var(--bdr)}th{background:#f8fafc;font-weight:600;color:var(--sub);font-size:11px;position:sticky;top:0}tr:hover td{background:#fafbfc}.tw{overflow-x:auto;border:1px solid var(--bdr);border-radius:8px}\n.fg{margin-bottom:14px}.fl{font-size:12px;font-weight:500;margin-bottom:5px;display:block}.fl .rq{color:var(--err)}.fi{width:100%;padding:8px 12px;border:1px solid var(--bdr);border-radius:7px;font-size:12px;outline:none;transition:border .12s}.fi:focus{border-color:var(--pri);box-shadow:0 0 0 2px rgba(99,102,241,.1)}.fs{width:100%;padding:8px 12px;border:1px solid var(--bdr);border-radius:7px;font-size:12px;background:#fff}.fr{display:grid;grid-template-columns:1fr 1fr;gap:14px}\n.mo{position:fixed;inset:0;background:rgba(0,0,0,.45);display:none;align-items:center;justify-content:center;z-index:200}.mo.show{display:flex}.mc{background:var(--card);border-radius:14px;width:90%;max-width:680px;max-height:85vh;overflow-y:auto;box-shadow:0 20px 60px rgba(0,0,0,.2);animation:mIn .2s}@keyframes mIn{from{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}.mh{padding:14px 20px;border-bottom:1px solid var(--bdr);display:flex;justify-content:space-between;align-items:center}.mh h3{font-size:15px}.mx{cursor:pointer;font-size:18px;color:var(--sub);background:none;border:none}.mb{padding:20px}.mf{padding:14px 20px;border-top:1px solid var(--bdr);display:flex;justify-content:flex-end;gap:8px}\n.toast{position:fixed;top:20px;right:20px;padding:12px 20px;border-radius:8px;font-size:13px;font-weight:500;z-index:300;display:none}.toast.show{display:block;animation:tIn .3s}.toast.ok{background:#dcfce7;color:#166534}.toast.er{background:#fee2e2;color:#991b1b}@keyframes tIn{from{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}\n.pg{display:flex;align-items:center;justify-content:space-between;padding:10px 0;font-size:12px;color:var(--sub)}.pgb{padding:4px 10px;border:1px solid var(--bdr);border-radius:5px;font-size:11px;cursor:pointer;background:var(--card);margin:0 2px}.pgb.ac{background:var(--pri);color:#fff;border-color:var(--pri)}\n.tabs{display:flex;gap:0;border-bottom:2px solid var(--bdr);margin-bottom:16px}.tab{padding:8px 16px;font-size:12px;font-weight:500;color:var(--sub);cursor:pointer;border-bottom:2px solid transparent;margin-bottom:-2px}.tab.ac{color:var(--pri);border-bottom-color:var(--pri);font-weight:600}.tab:hover{color:var(--txt)}.tab-ct{display:none}.tab-ct.show{display:block}\n.multi-select{display:flex;flex-wrap:wrap;gap:6px;padding:8px;border:1px solid var(--bdr);border-radius:7px;min-height:38px;cursor:pointer}.ms-tag{display:flex;align-items:center;gap:4px;background:#ede9fe;color:#6b21a8;padding:2px 8px;border-radius:4px;font-size:11px}.ms-tag .ms-x{cursor:pointer;font-weight:700;color:#6b21a8}.ms-drop{position:absolute;top:100%;left:0;right:0;background:var(--card);border:1px solid var(--bdr);border-radius:7px;box-shadow:0 4px 12px rgba(0,0,0,.1);z-index:10;max-height:200px;overflow-y:auto;display:none}.ms-drop.show{display:block}.ms-opt{padding:7px 12px;font-size:12px;cursor:pointer;display:flex;align-items:center;gap:6px}.ms-opt:hover{background:#f1f5f9}.ms-opt.sel{background:#ede9fe;color:#6b21a8}\n.grant-row{display:flex;gap:8px;align-items:center;padding:8px;border:1px solid var(--bdr);border-radius:7px;margin-bottom:8px;font-size:12px}\n.note{background:#eff6ff;border-left:3px solid var(--pri);padding:8px 12px;border-radius:0 6px 6px 0;font-size:11px;color:var(--sub);margin-bottom:14px}\n<\/style><\/head><body>\n<div class=\"toast\" id=\"toast\"><\/div>\n\n<!-- Modal: 新增/编辑用户 -->\n<div class=\"mo\" id=\"modal-user\"><div class=\"mc\"><div class=\"mh\"><h3 id=\"muTitle\">新增用户<\/h3><button class=\"mx\" onclick=\"closeM('modal-user')\">✕<\/button><\/div><div class=\"mb\">\n<div class=\"fr\">\n<div class=\"fg\"><label class=\"fl\">用户名 <span class=\"rq\">*<\/span><\/label><input class=\"fi\" id=\"mu-name\" placeholder=\"请输入用户名\"><\/div>\n<div class=\"fg\"><label class=\"fl\">密码 <span class=\"rq\">*<\/span><\/label><input class=\"fi\" id=\"mu-pwd\" type=\"password\" placeholder=\"至少6位\" value=\"\"><\/div>\n<\/div>\n<div class=\"fr\">\n<div class=\"fg\"><label class=\"fl\">邮箱<\/label><input class=\"fi\" type=\"email\" placeholder=\"user@example.com\"><\/div>\n<div class=\"fg\"><label class=\"fl\">手机号<\/label><input class=\"fi\" placeholder=\"13800138000\"><\/div>\n<\/div>\n<div class=\"fr\">\n<div class=\"fg\"><label class=\"fl\">所属部门 <span class=\"rq\">*<\/span><\/label>\n<select class=\"fs\" id=\"mu-dept\" onchange=\"onDeptChange(this.value)\">\n<option value=\"\">请选择部门<\/option>\n<option value=\"tf\">投放部<\/option>\n<option value=\"yy\">运营部<\/option>\n<option value=\"tech\">技术部<\/option>\n<option value=\"pm\">产品部<\/option>\n<\/select>\n<\/div>\n<div class=\"fg\"><label class=\"fl\">状态<\/label><select class=\"fs\"><option>启用<\/option><option>禁用<\/option><\/select><\/div>\n<\/div>\n\n<div class=\"note\">⚠️ RB-02: 用户只能绑定本部门下的角色。切换部门时自动清空已选角色(RB-08)<\/div>\n\n<div class=\"fg\"><label class=\"fl\">绑定角色(多选)<span class=\"rq\">*<\/span><\/label>\n<div style=\"position:relative\" id=\"roleSelectWrap\">\n<div class=\"multi-select\" id=\"roleSelect\" onclick=\"toggleDrop('roleDrop')\">\n<span style=\"color:var(--sub);font-size:11px\" id=\"rolePlaceholder\">请先选择部门<\/span>\n<\/div>\n<div class=\"ms-drop\" id=\"roleDrop\"><\/div>\n<\/div>\n<\/div>\n\n<hr style=\"border:none;border-top:1px solid var(--bdr);margin:16px 0\">\n<div class=\"fg\"><label class=\"fl\">额外产品授权(跨组协作)<\/label>\n<div id=\"grantList\">\n<div class=\"grant-row\"><select class=\"fs\" style=\"width:200px\"><option>ProductC — 社交媒体矩阵<\/option><option>ProductD — 搜索引擎营销<\/option><\/select><input class=\"fi\" type=\"date\" style=\"width:150px\" value=\"2026-12-31\"><button class=\"btn btn-d btn-sm\" onclick=\"this.closest('.grant-row').remove()\">删除<\/button><\/div>\n<\/div>\n<button class=\"btn btn-g btn-sm\" onclick=\"addGrant()\" style=\"margin-top:6px\">+ 添加授权<\/button>\n<\/div>\n<\/div><div class=\"mf\"><button class=\"btn btn-g\" onclick=\"closeM('modal-user')\">取消<\/button><button class=\"btn btn-p\" onclick=\"saveUser()\">保存<\/button><\/div><\/div><\/div>\n\n<!-- Modal: 确认删除 -->\n<div class=\"mo\" id=\"modal-del\"><div class=\"mc\" style=\"max-width:400px\"><div class=\"mh\"><h3>⚠️ 确认删除<\/h3><button class=\"mx\" onclick=\"closeM('modal-del')\">✕<\/button><\/div><div class=\"mb\" style=\"text-align:center;padding:24px\"><div style=\"font-size:40px;margin-bottom:10px\">🗑️<\/div><p style=\"font-size:14px;font-weight:600;margin-bottom:6px\">确定要删除该用户吗?<\/p><p style=\"font-size:12px;color:var(--sub)\">删除后该用户的角色绑定和平台产品账号将一并清除<br>此操作不可恢复<\/p><\/div><div class=\"mf\"><button class=\"btn btn-g\" onclick=\"closeM('modal-del')\">取消<\/button><button class=\"btn btn-d\" onclick=\"closeM('modal-del');showT('✅ 已删除','ok')\">确认删除<\/button><\/div><\/div><\/div>\n\n<!-- Modal: 重置密码 -->\n<div class=\"mo\" id=\"modal-pwd\"><div class=\"mc\" style=\"max-width:420px\"><div class=\"mh\"><h3>🔑 重置密码<\/h3><button class=\"mx\" onclick=\"closeM('modal-pwd')\">✕<\/button><\/div><div class=\"mb\"><div class=\"fg\"><label class=\"fl\">用户<\/label><input class=\"fi\" value=\"张三\" disabled><\/div><div class=\"fg\"><label class=\"fl\">新密码 <span class=\"rq\">*<\/span><\/label><input class=\"fi\" type=\"password\" placeholder=\"至少6位\"><\/div><div class=\"fg\"><label class=\"fl\">确认密码 <span class=\"rq\">*<\/span><\/label><input class=\"fi\" type=\"password\" placeholder=\"再次输入\"><\/div><\/div><div class=\"mf\"><button class=\"btn btn-g\" onclick=\"closeM('modal-pwd')\">取消<\/button><button class=\"btn btn-p\" onclick=\"closeM('modal-pwd');showT('✅ 密码已重置','ok')\">确认重置<\/button><\/div><\/div><\/div>\n\n<div class=\"layout\">\n<aside class=\"side\">\n<div class=\"logo\">🤖 Agent任务系统 v2.1<\/div>\n<div class=\"ni\">🏠 首页<\/div>\n<div class=\"ng-t\">权限管理<\/div>\n<div class=\"ni\">· 组织架构<\/div>\n<div class=\"ni\">· 菜单管理<\/div>\n<div class=\"ni\">· 角色管理<\/div>\n<div class=\"ni ac\">· 用户管理<\/div>\n<div class=\"ng-t\">产品管理<\/div><div class=\"ni\">· 产品列表<\/div><div class=\"ni\">· 渠道码<\/div><div class=\"ni\">· 平台套件<\/div>\n<div class=\"ng-t\">平台产品账号<\/div><div class=\"ni\">· 账号管理<\/div>\n<div class=\"ng-t\">Skill中心<\/div><div class=\"ni\">· Skill列表<\/div><div class=\"ni\">· 调用日志<\/div>\n<div class=\"ng-t\">任务中心<\/div><div class=\"ni\">· 任务创建<\/div><div class=\"ni\">· 任务列表<\/div>\n<div class=\"ng-t\">日志/设置<\/div><div class=\"ni\">· 操作日志<\/div><div class=\"ni\">· 系统设置<\/div>\n<\/aside>\n<div class=\"main\">\n<div class=\"hd\"><div>🔐 权限管理 / <b style=\"color:var(--txt)\">用户管理<\/b><\/div><div style=\"display:flex;align-items:center;gap:10px\"><span>🔔<\/span><span>admin<\/span><div style=\"width:28px;height:28px;border-radius:50%;background:var(--pri);color:#fff;display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:600\">A<\/div><\/div><\/div>\n<div class=\"ct\">\n<h1 class=\"pt\">用户管理<\/h1>\n<p class=\"pd\">用户CRUD · 部门角色绑定(多角色)· 切换部门自动清空角色(RB-08) · 额外产品授权<\/p>\n\n<div class=\"tb\">\n<div class=\"sb\"><span>🔍<\/span><input placeholder=\"搜索用户名/工号\" id=\"searchInput\" oninput=\"filterTable()\"><\/div>\n<select class=\"sl\" id=\"filterDept\" onchange=\"filterTable()\"><option value=\"\">全部部门<\/option><option value=\"投放部\">投放部<\/option><option value=\"运营部\">运营部<\/option><option value=\"技术部\">技术部<\/option><option value=\"产品部\">产品部<\/option><\/select>\n<select class=\"sl\" id=\"filterRole\" onchange=\"filterTable()\"><option value=\"\">全部角色<\/option><option value=\"投放主管\">投放主管<\/option><option value=\"投放专员\">投放专员<\/option><option value=\"运营主管\">运营主管<\/option><option value=\"开发工程师\">开发工程师<\/option><\/select>\n<select class=\"sl\" id=\"filterStatus\" onchange=\"filterTable()\"><option value=\"\">全部状态<\/option><option value=\"启用\">启用<\/option><option value=\"禁用\">禁用<\/option><\/select>\n<button class=\"btn btn-g btn-sm\">导出<\/button>\n<button class=\"btn btn-p\" style=\"margin-left:auto\" onclick=\"openAdd()\">+ 新增用户<\/button>\n<\/div>\n\n<div class=\"tw\"><table id=\"userTable\">\n<thead><tr><th><input type=\"checkbox\" onclick=\"toggleAll(this)\"><\/th><th>用户名<\/th><th>工号<\/th><th>所属部门<\/th><th>角色<\/th><th>平台产品账号<\/th><th>额外授权<\/th><th>状态<\/th><th>创建时间<\/th><th>操作<\/th><\/tr><\/thead>\n<tbody id=\"tbody\">\n<tr data-dept=\"投放部\" data-role=\"投放主管\" data-status=\"启用\" data-name=\"张三\"><td><input type=\"checkbox\"><\/td><td><b>张三<\/b><\/td><td>EMP001<\/td><td><span class=\"tg tg-i\">投放部<\/span> / 投放一组<\/td><td><span class=\"tg tg-p\">投放主管<\/span><\/td><td><span class=\"tg tg-g\">3个<\/span><\/td><td>-<\/td><td><span class=\"tg tg-ok\">启用<\/span><\/td><td>2024-03-01<\/td><td><button class=\"btn-l\" onclick=\"openEdit('张三','投放部','投放主管')\">编辑<\/button> <button class=\"btn-l\" onclick=\"openM('modal-pwd')\">重置密码<\/button> <button class=\"btn-l\" style=\"color:var(--err)\" onclick=\"openM('modal-del')\">删除<\/button><\/td><\/tr>\n<tr data-dept=\"投放部\" data-role=\"投放专员\" data-status=\"启用\" data-name=\"李四\"><td><input type=\"checkbox\"><\/td><td><b>李四<\/b><\/td><td>EMP002<\/td><td><span class=\"tg tg-i\">投放部<\/span> / 投放一组<\/td><td><span class=\"tg tg-i\">投放专员<\/span><\/td><td><span class=\"tg tg-g\">2个<\/span><\/td><td>-<\/td><td><span class=\"tg tg-ok\">启用<\/span><\/td><td>2024-06-15<\/td><td><button class=\"btn-l\" onclick=\"openEdit('李四','投放部','投放专员')\">编辑<\/button> <button class=\"btn-l\" onclick=\"openM('modal-pwd')\">重置密码<\/button> <button class=\"btn-l\" style=\"color:var(--err)\" onclick=\"openM('modal-del')\">删除<\/button><\/td><\/tr>\n<tr data-dept=\"投放部\" data-role=\"投放专员\" data-status=\"启用\" data-name=\"王五\"><td><input type=\"checkbox\"><\/td><td><b>王五<\/b><\/td><td>EMP003<\/td><td><span class=\"tg tg-i\">投放部<\/span> / 投放二组<\/td><td><span class=\"tg tg-i\">投放专员<\/span><\/td><td><span class=\"tg tg-g\">1个<\/span><\/td><td>-<\/td><td><span class=\"tg tg-ok\">启用<\/span><\/td><td>2024-08-20<\/td><td><button class=\"btn-l\" onclick=\"openEdit('王五','投放部','投放专员')\">编辑<\/button> <button class=\"btn-l\" onclick=\"openM('modal-pwd')\">重置密码<\/button> <button class=\"btn-l\" style=\"color:var(--err)\" onclick=\"openM('modal-del')\">删除<\/button><\/td><\/tr>\n<tr data-dept=\"投放部\" data-role=\"投放主管\" data-status=\"启用\" data-name=\"赵六\"><td><input type=\"checkbox\"><\/td><td><b>赵六<\/b><\/td><td>EMP004<\/td><td><span class=\"tg tg-i\">投放部<\/span> / 投放二组<\/td><td><span class=\"tg tg-p\">投放主管<\/span> <span class=\"tg tg-i\">数据分析师<\/span><\/td><td><span class=\"tg tg-g\">4个<\/span><\/td><td><span class=\"tg tg-w\">1项<\/span><\/td><td><span class=\"tg tg-ok\">启用<\/span><\/td><td>2024-02-10<\/td><td><button class=\"btn-l\" onclick=\"openEdit('赵六','投放部','投放主管')\">编辑<\/button> <button class=\"btn-l\" onclick=\"openM('modal-pwd')\">重置密码<\/button> <button class=\"btn-l\" style=\"color:var(--err)\" onclick=\"openM('modal-del')\">删除<\/button><\/td><\/tr>\n<tr data-dept=\"运营部\" data-role=\"运营主管\" data-status=\"启用\" data-name=\"钱七\"><td><input type=\"checkbox\"><\/td><td><b>钱七<\/b><\/td><td>EMP005<\/td><td><span class=\"tg tg-p\">运营部<\/span> / 内容运营组<\/td><td><span class=\"tg tg-p\">运营主管<\/span><\/td><td><span class=\"tg tg-g\">2个<\/span><\/td><td>-<\/td><td><span class=\"tg tg-ok\">启用<\/span><\/td><td>2025-01-05<\/td><td><button class=\"btn-l\" onclick=\"openEdit('钱七','运营部','运营主管')\">编辑<\/button> <button class=\"btn-l\" onclick=\"openM('modal-pwd')\">重置密码<\/button> <button class=\"btn-l\" style=\"color:var(--err)\" onclick=\"openM('modal-del')\">删除<\/button><\/td><\/tr>\n<tr data-dept=\"技术部\" data-role=\"开发工程师\" data-status=\"启用\" data-name=\"孙八\"><td><input type=\"checkbox\"><\/td><td><b>孙八<\/b><\/td><td>EMP006<\/td><td><span class=\"tg tg-w\">技术部<\/span> / 后端组<\/td><td><span class=\"tg tg-i\">开发工程师<\/span><\/td><td><span class=\"tg tg-g\">0个<\/span><\/td><td>-<\/td><td><span class=\"tg tg-ok\">启用<\/span><\/td><td>2025-03-18<\/td><td><button class=\"btn-l\" onclick=\"openEdit('孙八','技术部','开发工程师')\">编辑<\/button> <button class=\"btn-l\" onclick=\"openM('modal-pwd')\">重置密码<\/button> <button class=\"btn-l\" style=\"color:var(--err)\" onclick=\"openM('modal-del')\">删除<\/button><\/td><\/tr>\n<tr data-dept=\"产品部\" data-role=\"产品经理\" data-status=\"禁用\" data-name=\"周九\"><td><input type=\"checkbox\"><\/td><td><b>周九<\/b><\/td><td>EMP007<\/td><td><span class=\"tg tg-g\">产品部<\/span><\/td><td><span class=\"tg tg-g\">产品经理<\/span><\/td><td><span class=\"tg tg-g\">1个<\/span><\/td><td>-<\/td><td><span class=\"tg tg-e\">禁用<\/span><\/td><td>2025-04-01<\/td><td><button class=\"btn-l\" onclick=\"openEdit('周九','产品部','产品经理')\">编辑<\/button> <button class=\"btn-l\" onclick=\"openM('modal-pwd')\">重置密码<\/button> <button class=\"btn-l\" style=\"color:var(--err)\" onclick=\"openM('modal-del')\">删除<\/button><\/td><\/tr>\n<\/tbody>\n<\/table><\/div>\n<div class=\"pg\"><span id=\"pgInfo\">共 7 条,每页 10 条<\/span><div><span class=\"pgb ac\">1<\/span><\/div><\/div>\n\n<div class=\"card\" style=\"margin-top:16px;border:2px dashed var(--pri)\">\n<div style=\"font-size:13px;font-weight:600;margin-bottom:8px\">💡 业务规则说明<\/div>\n<div style=\"font-size:11px;color:var(--sub);line-height:2\">\n<b>RB-02<\/b> 用户只能绑定本部门角色:user.org_id === role.org_id<br>\n<b>RB-03<\/b> 支持多角色:用户可绑定本部门下多个角色<br>\n<b>RB-04<\/b> 多角色权限取并集:有效权限 = ∪所有角色权限<br>\n<b>RB-08<\/b> 切换部门清空角色:切换部门时自动清空原有角色绑定,需重新选择<br>\n<b>额外授权<\/b> 跨组协作产品授权,设置有效期\n<\/div><\/div>\n\n<\/div><\/div><\/div>\n\n<script>\nconst DEPT_ROLES={tf:['投放主管','投放专员','数据分析师'],yy:['运营主管','运营专员'],tech:['开发工程师','运维工程师','测试工程师'],pm:['产品经理','UI设计师']};\nlet selectedRoles=[];\n\nfunction openM(id){document.getElementById(id).classList.add('show')}\nfunction closeM(id){document.getElementById(id).classList.remove('show')}\nfunction showT(m,t){const e=document.getElementById('toast');e.textContent=m;e.className='toast show '+t;setTimeout(()=>e.className='toast',2500)}\n\nfunction openAdd(){\n document.getElementById('muTitle').textContent='新增用户';\n document.getElementById('mu-name').value='';\n document.getElementById('mu-pwd').value='';\n document.getElementById('mu-dept').value='';\n selectedRoles=[];renderRoles();\n document.getElementById('rolePlaceholder').textContent='请先选择部门';\n openM('modal-user');\n}\n\nfunction openEdit(name,dept,role){\n document.getElementById('muTitle').textContent='编辑用户 — '+name;\n document.getElementById('mu-name').value=name;\n document.getElementById('mu-pwd').value='••••••';\n const deptMap={'投放部':'tf','运营部':'yy','技术部':'tech','产品部':'pm'};\n document.getElementById('mu-dept').value=deptMap[dept]||'';\n onDeptChange(deptMap[dept]||'');\n selectedRoles=[role];renderRoles();\n openM('modal-user');\n}\n\nfunction onDeptChange(val){\n selectedRoles=[];\n const drop=document.getElementById('roleDrop');\n const ph=document.getElementById('rolePlaceholder');\n if(!val){drop.innerHTML='';ph.textContent='请先选择部门';ph.style.display='';renderRoles();return}\n ph.style.display='none';\n const roles=DEPT_ROLES[val]||[];\n drop.innerHTML=roles.map(r=>`<div class=\"ms-opt\" onclick=\"toggleRole('${r}')\">${r}<\/div>`).join('');\n renderRoles();\n showT('⚠️ 已切换部门,角色已清空(RB-08)','er');\n}\n\nfunction toggleDrop(id){\n const d=document.getElementById(id);\n if(!document.getElementById('mu-dept').value){showT('请先选择部门','er');return}\n d.classList.toggle('show');\n}\n\nfunction toggleRole(r){\n const i=selectedRoles.indexOf(r);\n if(i>=0)selectedRoles.splice(i,1);else selectedRoles.push(r);\n renderRoles();\n}\n\nfunction removeRole(r){\n selectedRoles=selectedRoles.filter(x=>x!==r);renderRoles();\n}\n\nfunction renderRoles(){\n const sel=document.getElementById('roleSelect');\n const ph=document.getElementById('rolePlaceholder');\n sel.querySelectorAll('.ms-tag').forEach(t=>t.remove());\n if(selectedRoles.length===0){ph.style.display='';if(document.getElementById('mu-dept').value)ph.textContent='点击选择角色(可多选)'}\n else{ph.style.display='none';selectedRoles.forEach(r=>{const t=document.createElement('span');t.className='ms-tag';t.innerHTML=r+` <span class=\"ms-x\" onclick=\"event.stopPropagation();removeRole('${r}')\">×<\/span>`;sel.insertBefore(t,ph)})}\n document.querySelectorAll('#roleDrop .ms-opt').forEach(o=>{const n=o.textContent.replace('✓ ','');o.classList.toggle('sel',selectedRoles.includes(n));o.innerHTML=(selectedRoles.includes(n)?'✓ ':'')+n});\n}\n\nfunction saveUser(){\n const name=document.getElementById('mu-name').value;\n const dept=document.getElementById('mu-dept').value;\n if(!name){showT('请输入用户名','er');return}\n if(!dept){showT('请选择部门','er');return}\n if(!selectedRoles.length){showT('请至少选择一个角色','er');return}\n closeM('modal-user');showT('✅ 保存成功','ok');\n}\n\nfunction addGrant(){\n const list=document.getElementById('grantList');\n const row=document.createElement('div');row.className='grant-row';\n row.innerHTML=`<select class=\"fs\" style=\"width:200px\"><option>ProductC — 社交媒体矩阵<\/option><option>ProductD — 搜索引擎营销<\/option><option>ProductE — 内容营销平台<\/option><\/select><input class=\"fi\" type=\"date\" style=\"width:150px\"><button class=\"btn btn-d btn-sm\" onclick=\"this.closest('.grant-row').remove()\">删除<\/button>`;\n list.appendChild(row);\n}\n\nfunction filterTable(){\n const q=document.getElementById('searchInput').value.toLowerCase();\n const dept=document.getElementById('filterDept').value;\n const role=document.getElementById('filterRole').value;\n const status=document.getElementById('filterStatus').value;\n let count=0;\n document.querySelectorAll('#tbody tr').forEach(tr=>{\n const n=tr.dataset.name.toLowerCase();\n const d=tr.dataset.dept;\n const r=tr.dataset.role;\n const s=tr.dataset.status;\n const show=(!q||n.includes(q))&&(!dept||d===dept)&&(!role||r.includes(role))&&(!status||s===status);\n tr.style.display=show?'':'none';\n if(show)count++;\n });\n document.getElementById('pgInfo').textContent=`共 ${count} 条,每页 10 条`;\n}\n\nfunction toggleAll(cb){document.querySelectorAll('#tbody input[type=checkbox]').forEach(c=>c.checked=cb.checked)}\n\n// Close dropdowns on outside click\ndocument.addEventListener('click',e=>{if(!e.target.closest('#roleSelectWrap'))document.getElementById('roleDrop').classList.remove('show')});\ndocument.querySelectorAll('.mo').forEach(m=>m.addEventListener('click',e=>{if(e.target===m)m.classList.remove('show')}));\n<\/script>\n<\/body><\/html>\n",
|
||
"06_产品管理.html": "<!DOCTYPE html><html lang=\"zh-CN\"><head><script>if(window!==window.top)document.documentElement.classList.add(\"in-iframe\")<\/script><style>.in-iframe .side{display:none!important}.in-iframe .main{margin-left:0!important}.in-iframe .layout{min-height:auto}<\/style><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1.0\"><title>Agent任务系统 v2.1 - 产品管理<\/title>\n<style>\n*{margin:0;padding:0;box-sizing:border-box}:root{--pri:#6366f1;--bg:#f1f5f9;--card:#fff;--txt:#1e293b;--sub:#64748b;--bdr:#e2e8f0;--ok:#22c55e;--err:#ef4444;--warn:#f59e0b;--side:#1e293b}body{font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",\"PingFang SC\",\"Microsoft YaHei\",sans-serif;background:var(--bg);color:var(--txt);line-height:1.6;font-size:13px}\n.layout{display:flex;min-height:100vh}.side{width:220px;background:var(--side);color:#94a3b8;position:fixed;top:0;left:0;bottom:0;overflow-y:auto;z-index:100}.side .logo{padding:16px 18px;font-size:14px;font-weight:700;color:#fff;border-bottom:1px solid #334155}.ni{display:flex;align-items:center;gap:8px;padding:9px 18px;font-size:12px;color:#94a3b8;cursor:pointer;border-left:3px solid transparent}.ni:hover{background:#334155;color:#e2e8f0}.ni.ac{background:rgba(99,102,241,.15);color:#818cf8;border-left-color:#818cf8;font-weight:600}.ng-t{padding:10px 18px 4px;font-size:10px;letter-spacing:1px;color:#475569;font-weight:600}\n.main{margin-left:220px;flex:1}.hd{height:52px;background:var(--card);border-bottom:1px solid var(--bdr);display:flex;align-items:center;justify-content:space-between;padding:0 24px;font-size:12px;color:var(--sub);position:sticky;top:0;z-index:50}.ct{padding:24px}\n.pt{font-size:20px;font-weight:700;margin-bottom:4px}.pd{font-size:12px;color:var(--sub);margin-bottom:20px}\n.card{background:var(--card);border-radius:10px;padding:16px;border:1px solid var(--bdr);margin-bottom:14px}\n.tb{display:flex;gap:8px;align-items:center;margin-bottom:14px;flex-wrap:wrap}.sb{display:flex;align-items:center;gap:6px;background:#f8fafc;border:1px solid var(--bdr);border-radius:7px;padding:7px 12px;font-size:12px}.sb input{border:none;background:none;outline:none;font-size:12px;width:120px}\n.sl{border:1px solid var(--bdr);border-radius:7px;padding:7px 12px;font-size:12px;background:#fff;cursor:pointer}\n.btn{padding:7px 16px;border-radius:7px;font-size:12px;font-weight:500;border:none;cursor:pointer;display:inline-flex;align-items:center;gap:5px;transition:all .12s}.btn-p{background:var(--pri);color:#fff}.btn-p:hover{background:#4f46e5}.btn-d{background:#fee2e2;color:#dc2626}.btn-g{background:transparent;color:var(--sub);border:1px solid var(--bdr)}.btn-sm{padding:5px 10px;font-size:11px}.btn-s{background:var(--ok);color:#fff}.btn-w{background:var(--warn);color:#fff}\n.btn-l{background:none;border:none;color:var(--pri);padding:0;font-size:12px;cursor:pointer}.btn-l:hover{text-decoration:underline}\n.tg{display:inline-block;padding:2px 8px;border-radius:99px;font-size:10px;font-weight:600}.tg-ok{background:#dcfce7;color:#166534}.tg-e{background:#fee2e2;color:#991b1b}.tg-i{background:#dbeafe;color:#1e40af}.tg-p{background:#f3e8ff;color:#6b21a8}.tg-g{background:#f1f5f9;color:#64748b}.tg-w{background:#fef3c7;color:#92400e}\ntable{width:100%;border-collapse:collapse;font-size:12px}th,td{padding:8px 12px;text-align:left;border-bottom:1px solid var(--bdr)}th{background:#f8fafc;font-weight:600;color:var(--sub);font-size:11px;position:sticky;top:0}tr:hover td{background:#fafbfc}.tw{overflow-x:auto;border:1px solid var(--bdr);border-radius:8px}\n.fg{margin-bottom:14px}.fl{font-size:12px;font-weight:500;margin-bottom:5px;display:block}.fl .rq{color:var(--err)}.fi{width:100%;padding:8px 12px;border:1px solid var(--bdr);border-radius:7px;font-size:12px;outline:none;transition:border .12s}.fi:focus{border-color:var(--pri);box-shadow:0 0 0 2px rgba(99,102,241,.1)}.fs{width:100%;padding:8px 12px;border:1px solid var(--bdr);border-radius:7px;font-size:12px;background:#fff}.fr{display:grid;grid-template-columns:1fr 1fr;gap:14px}\n.mo{position:fixed;inset:0;background:rgba(0,0,0,.45);display:none;align-items:center;justify-content:center;z-index:200}.mo.show{display:flex}.mc{background:var(--card);border-radius:14px;width:90%;max-width:680px;max-height:85vh;overflow-y:auto;box-shadow:0 20px 60px rgba(0,0,0,.2);animation:mIn .2s}@keyframes mIn{from{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}.mh{padding:14px 20px;border-bottom:1px solid var(--bdr);display:flex;justify-content:space-between;align-items:center}.mh h3{font-size:15px}.mx{cursor:pointer;font-size:18px;color:var(--sub);background:none;border:none}.mb{padding:20px}.mf{padding:14px 20px;border-top:1px solid var(--bdr);display:flex;justify-content:flex-end;gap:8px}\n.toast{position:fixed;top:20px;right:20px;padding:12px 20px;border-radius:8px;font-size:13px;font-weight:500;z-index:300;display:none}.toast.show{display:block;animation:tIn .3s}.toast.ok{background:#dcfce7;color:#166534}.toast.er{background:#fee2e2;color:#991b1b}.toast.wn{background:#fef3c7;color:#92400e}@keyframes tIn{from{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}\n.pg{display:flex;align-items:center;justify-content:space-between;padding:10px 0;font-size:12px;color:var(--sub)}.pgb{padding:4px 10px;border:1px solid var(--bdr);border-radius:5px;font-size:11px;cursor:pointer;background:var(--card);margin:0 2px}.pgb.ac{background:var(--pri);color:#fff;border-color:var(--pri)}\n.tabs{display:flex;gap:0;border-bottom:2px solid var(--bdr);margin-bottom:16px}.tab{padding:8px 16px;font-size:12px;font-weight:500;color:var(--sub);cursor:pointer;border-bottom:2px solid transparent;margin-bottom:-2px}.tab.ac{color:var(--pri);border-bottom-color:var(--pri);font-weight:600}.tab:hover{color:var(--txt)}\n.stat{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;margin-bottom:16px}.stat-c{background:var(--card);border:1px solid var(--bdr);border-radius:10px;padding:14px 16px}.stat-c .sv{font-size:22px;font-weight:700;color:var(--txt)}.stat-c .sl2{font-size:11px;color:var(--sub)}\n.note{background:#eff6ff;border-left:3px solid var(--pri);padding:8px 12px;border-radius:0 6px 6px 0;font-size:11px;color:var(--sub);margin-bottom:14px}\n.import-zone{border:2px dashed var(--bdr);border-radius:10px;padding:30px;text-align:center;cursor:pointer;transition:border .2s}.import-zone:hover{border-color:var(--pri);background:#f8fafc}\n<\/style><\/head><body>\n<div class=\"toast\" id=\"toast\"><\/div>\n\n<!-- Modal: 新增/编辑产品 -->\n<div class=\"mo\" id=\"modal-prod\"><div class=\"mc\"><div class=\"mh\"><h3 id=\"mpTitle\">新增产品<\/h3><button class=\"mx\" onclick=\"closeM('modal-prod')\">✕<\/button><\/div><div class=\"mb\">\n<div class=\"fr\">\n<div class=\"fg\"><label class=\"fl\">产品名称 <span class=\"rq\">*<\/span><\/label><input class=\"fi\" id=\"mp-name\" placeholder=\"请输入产品名称\"><\/div>\n<div class=\"fg\"><label class=\"fl\">产品代号 <span class=\"rq\">*<\/span><\/label><input class=\"fi\" id=\"mp-code\" placeholder=\"如 PROD001,唯一\"><\/div>\n<\/div>\n<div class=\"fr\">\n<div class=\"fg\"><label class=\"fl\">所属平台 <span class=\"rq\">*<\/span><\/label>\n<select class=\"fs\" id=\"mp-platform\"><option value=\"\">请选择平台<\/option><option value=\"xhs\">小红书<\/option><option value=\"dy\">抖音<\/option><option value=\"wx\">微信公众号<\/option><option value=\"wb\">微博<\/option><option value=\"fb\">Facebook<\/option><option value=\"tt\">TikTok<\/option><\/select><\/div>\n<div class=\"fg\"><label class=\"fl\">所属部门 <span class=\"rq\">*<\/span><\/label>\n<select class=\"fs\" id=\"mp-dept\"><option value=\"\">请选择部门<\/option><option>投放部<\/option><option>运营部<\/option><option>技术部<\/option><\/select><\/div>\n<\/div>\n<div class=\"fr\">\n<div class=\"fg\"><label class=\"fl\">所属小组<\/label>\n<select class=\"fs\" id=\"mp-team\"><option value=\"\">请选择小组<\/option><option>投放一组<\/option><option>投放二组<\/option><option>内容运营组<\/option><\/select><\/div>\n<div class=\"fg\"><label class=\"fl\">负责人<\/label>\n<select class=\"fs\"><option value=\"\">请选择<\/option><option>张三<\/option><option>李四<\/option><option>王五<\/option><\/select><\/div>\n<\/div>\n<div class=\"note\">⚠️ RB-09: 内导渠道码和自然渠道码必填且唯一<\/div>\n<div class=\"fr\">\n<div class=\"fg\"><label class=\"fl\">内导渠道码 <span class=\"rq\">*<\/span><\/label><input class=\"fi\" id=\"mp-ic\" placeholder=\"如 IC20240301A,唯一\"><\/div>\n<div class=\"fg\"><label class=\"fl\">自然渠道码 <span class=\"rq\">*<\/span><\/label><input class=\"fi\" id=\"mp-nc\" placeholder=\"如 NC20240301A,唯一\"><\/div>\n<\/div>\n<div class=\"fg\"><label class=\"fl\">状态<\/label><select class=\"fs\"><option>启用<\/option><option>禁用<\/option><\/select><\/div>\n<\/div><div class=\"mf\"><button class=\"btn btn-g\" onclick=\"closeM('modal-prod')\">取消<\/button><button class=\"btn btn-p\" onclick=\"saveProd()\">保存<\/button><\/div><\/div><\/div>\n\n<!-- Modal: 导入 -->\n<div class=\"mo\" id=\"modal-import\"><div class=\"mc\" style=\"max-width:520px\"><div class=\"mh\"><h3>📤 批量导入产品<\/h3><button class=\"mx\" onclick=\"closeM('modal-import')\">✕<\/button><\/div><div class=\"mb\">\n<div class=\"import-zone\" onclick=\"document.getElementById('fileInput').click()\">\n<div style=\"font-size:36px;margin-bottom:8px\">📂<\/div>\n<p style=\"font-weight:600;font-size:13px\">点击上传 或 拖拽文件到此处<\/p>\n<p style=\"font-size:11px;color:var(--sub);margin-top:4px\">支持 .csv / .xlsx,最大10MB<\/p>\n<input type=\"file\" id=\"fileInput\" accept=\".csv,.xlsx\" style=\"display:none\" onchange=\"onFileSelect(this)\">\n<\/div>\n<div id=\"fileInfo\" style=\"display:none;margin-top:12px;padding:10px;background:#f8fafc;border-radius:7px;font-size:12px\">\n<div style=\"display:flex;justify-content:space-between;align-items:center\"><span id=\"fileName\"><\/span><button class=\"btn-l\" style=\"color:var(--err)\" onclick=\"clearFile()\">移除<\/button><\/div>\n<div style=\"margin-top:8px;padding:8px;background:#ecfdf5;border-radius:5px;font-size:11px;color:#166534\" id=\"previewInfo\"><\/div>\n<\/div>\n<div style=\"margin-top:12px\"><a href=\"#\" class=\"btn-l\" onclick=\"event.preventDefault();showT('📥 模板已下载','ok')\">📥 下载导入模板<\/a><\/div>\n<\/div><div class=\"mf\"><button class=\"btn btn-g\" onclick=\"closeM('modal-import')\">取消<\/button><button class=\"btn btn-p\" id=\"importBtn\" disabled onclick=\"doImport()\">开始导入<\/button><\/div><\/div><\/div>\n\n<!-- Modal: 确认删除 -->\n<div class=\"mo\" id=\"modal-del\"><div class=\"mc\" style=\"max-width:400px\"><div class=\"mh\"><h3>⚠️ 确认删除<\/h3><button class=\"mx\" onclick=\"closeM('modal-del')\">✕<\/button><\/div><div class=\"mb\" style=\"text-align:center;padding:24px\"><div style=\"font-size:40px;margin-bottom:10px\">🗑️<\/div><p style=\"font-size:14px;font-weight:600;margin-bottom:6px\" id=\"delMsg\">确定要删除该产品吗?<\/p><p style=\"font-size:12px;color:var(--sub)\">删除后关联的渠道码绑定将同步解除<\/p><\/div><div class=\"mf\"><button class=\"btn btn-g\" onclick=\"closeM('modal-del')\">取消<\/button><button class=\"btn btn-d\" onclick=\"closeM('modal-del');showT('✅ 已删除','ok')\">确认删除<\/button><\/div><\/div><\/div>\n\n<div class=\"layout\">\n<aside class=\"side\">\n<div class=\"logo\">🤖 Agent任务系统 v2.1<\/div>\n<div class=\"ni\">🏠 首页<\/div>\n<div class=\"ng-t\">权限管理<\/div><div class=\"ni\">· 组织架构<\/div><div class=\"ni\">· 菜单管理<\/div><div class=\"ni\">· 角色管理<\/div><div class=\"ni\">· 用户管理<\/div>\n<div class=\"ng-t\">产品管理<\/div><div class=\"ni ac\">· 产品列表<\/div><div class=\"ni\">· 渠道码<\/div><div class=\"ni\">· 平台套件<\/div>\n<div class=\"ng-t\">平台产品账号<\/div><div class=\"ni\">· 账号管理<\/div>\n<div class=\"ng-t\">Skill中心<\/div><div class=\"ni\">· Skill列表<\/div><div class=\"ni\">· 调用日志<\/div>\n<div class=\"ng-t\">任务中心<\/div><div class=\"ni\">· 任务创建<\/div><div class=\"ni\">· 任务列表<\/div>\n<div class=\"ng-t\">日志/设置<\/div><div class=\"ni\">· 操作日志<\/div><div class=\"ni\">· 系统设置<\/div>\n<\/aside>\n<div class=\"main\">\n<div class=\"hd\"><div>📦 产品管理 / <b style=\"color:var(--txt)\">产品列表<\/b><\/div><div style=\"display:flex;align-items:center;gap:10px\"><span>🔔<\/span><span>admin<\/span><div style=\"width:28px;height:28px;border-radius:50%;background:var(--pri);color:#fff;display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:600\">A<\/div><\/div><\/div>\n<div class=\"ct\">\n<h1 class=\"pt\">产品管理<\/h1>\n<p class=\"pd\">产品CRUD · 内导/自然渠道码 · CSV/Excel批量导入 · 按平台/部门/小组筛选<\/p>\n\n<div class=\"stat\">\n<div class=\"stat-c\"><div class=\"sv\">156<\/div><div class=\"sl2\">产品总数<\/div><\/div>\n<div class=\"stat-c\"><div class=\"sv\" style=\"color:var(--ok)\">142<\/div><div class=\"sl2\">启用中<\/div><\/div>\n<div class=\"stat-c\"><div class=\"sv\" style=\"color:var(--err)\">14<\/div><div class=\"sl2\">已禁用<\/div><\/div>\n<div class=\"stat-c\"><div class=\"sv\" style=\"color:var(--pri)\">6<\/div><div class=\"sl2\">平台数<\/div><\/div>\n<\/div>\n\n<div class=\"tb\">\n<div class=\"sb\"><span>🔍<\/span><input placeholder=\"搜索产品名称/代号/渠道码\" id=\"sInput\" oninput=\"filterT()\"><\/div>\n<select class=\"sl\" id=\"fPlat\" onchange=\"filterT()\"><option value=\"\">全部平台<\/option><option value=\"小红书\">小红书<\/option><option value=\"抖音\">抖音<\/option><option value=\"微信公众号\">微信公众号<\/option><option value=\"微博\">微博<\/option><option value=\"Facebook\">Facebook<\/option><option value=\"TikTok\">TikTok<\/option><\/select>\n<select class=\"sl\" id=\"fDept\" onchange=\"filterT()\"><option value=\"\">全部部门<\/option><option value=\"投放部\">投放部<\/option><option value=\"运营部\">运营部<\/option><\/select>\n<select class=\"sl\" id=\"fSt\" onchange=\"filterT()\"><option value=\"\">全部状态<\/option><option value=\"启用\">启用<\/option><option value=\"禁用\">禁用<\/option><\/select>\n<button class=\"btn btn-g btn-sm\" onclick=\"showT('📥 导出成功','ok')\">导出<\/button>\n<button class=\"btn btn-w btn-sm\" onclick=\"openM('modal-import')\">📤 导入<\/button>\n<button class=\"btn btn-p\" style=\"margin-left:auto\" onclick=\"openAdd()\">+ 新增产品<\/button>\n<\/div>\n\n<div class=\"tw\"><table>\n<thead><tr><th><input type=\"checkbox\" onclick=\"document.querySelectorAll('#ptb input[type=checkbox]').forEach(c=>c.checked=this.checked)\"><\/th><th>产品名称<\/th><th>产品代号<\/th><th>平台<\/th><th>部门/小组<\/th><th>内导渠道码<\/th><th>自然渠道码<\/th><th>负责人<\/th><th>状态<\/th><th>操作<\/th><\/tr><\/thead>\n<tbody id=\"ptb\">\n<tr data-plat=\"小红书\" data-dept=\"投放部\" data-st=\"启用\" data-q=\"美妆种草达人 PROD001 IC001 NC001\"><td><input type=\"checkbox\"><\/td><td><b>美妆种草达人<\/b><\/td><td>PROD001<\/td><td><span class=\"tg tg-e\" style=\"background:#ffe4e6;color:#be123c\">小红书<\/span><\/td><td>投放部 / 投放一组<\/td><td><code>IC001<\/code><\/td><td><code>NC001<\/code><\/td><td>张三<\/td><td><span class=\"tg tg-ok\">启用<\/span><\/td><td><button class=\"btn-l\" onclick=\"openEdit('美妆种草达人','PROD001','IC001','NC001')\">编辑<\/button> <button class=\"btn-l\" style=\"color:var(--err)\" onclick=\"openM('modal-del')\">删除<\/button><\/td><\/tr>\n<tr data-plat=\"小红书\" data-dept=\"投放部\" data-st=\"启用\" data-q=\"护肤品评测 PROD002 IC002 NC002\"><td><input type=\"checkbox\"><\/td><td><b>护肤品评测<\/b><\/td><td>PROD002<\/td><td><span class=\"tg tg-e\" style=\"background:#ffe4e6;color:#be123c\">小红书<\/span><\/td><td>投放部 / 投放一组<\/td><td><code>IC002<\/code><\/td><td><code>NC002<\/code><\/td><td>张三<\/td><td><span class=\"tg tg-ok\">启用<\/span><\/td><td><button class=\"btn-l\" onclick=\"openEdit('护肤品评测','PROD002','IC002','NC002')\">编辑<\/button> <button class=\"btn-l\" style=\"color:var(--err)\" onclick=\"openM('modal-del')\">删除<\/button><\/td><\/tr>\n<tr data-plat=\"抖音\" data-dept=\"投放部\" data-st=\"启用\" data-q=\"抖音带货王 PROD003 IC003 NC003\"><td><input type=\"checkbox\"><\/td><td><b>抖音带货王<\/b><\/td><td>PROD003<\/td><td><span class=\"tg tg-i\">抖音<\/span><\/td><td>投放部 / 投放二组<\/td><td><code>IC003<\/code><\/td><td><code>NC003<\/code><\/td><td>王五<\/td><td><span class=\"tg tg-ok\">启用<\/span><\/td><td><button class=\"btn-l\" onclick=\"openEdit('抖音带货王','PROD003','IC003','NC003')\">编辑<\/button> <button class=\"btn-l\" style=\"color:var(--err)\" onclick=\"openM('modal-del')\">删除<\/button><\/td><\/tr>\n<tr data-plat=\"抖音\" data-dept=\"运营部\" data-st=\"启用\" data-q=\"短视频营销 PROD004 IC004 NC004\"><td><input type=\"checkbox\"><\/td><td><b>短视频营销<\/b><\/td><td>PROD004<\/td><td><span class=\"tg tg-i\">抖音<\/span><\/td><td>运营部 / 内容运营组<\/td><td><code>IC004<\/code><\/td><td><code>NC004<\/code><\/td><td>钱七<\/td><td><span class=\"tg tg-ok\">启用<\/span><\/td><td><button class=\"btn-l\" onclick=\"openEdit('短视频营销','PROD004','IC004','NC004')\">编辑<\/button> <button class=\"btn-l\" style=\"color:var(--err)\" onclick=\"openM('modal-del')\">删除<\/button><\/td><\/tr>\n<tr data-plat=\"微信公众号\" data-dept=\"运营部\" data-st=\"启用\" data-q=\"品牌公众号 PROD005 IC005 NC005\"><td><input type=\"checkbox\"><\/td><td><b>品牌公众号<\/b><\/td><td>PROD005<\/td><td><span class=\"tg tg-ok\" style=\"background:#dcfce7;color:#166534\">微信公众号<\/span><\/td><td>运营部 / 内容运营组<\/td><td><code>IC005<\/code><\/td><td><code>NC005<\/code><\/td><td>钱七<\/td><td><span class=\"tg tg-ok\">启用<\/span><\/td><td><button class=\"btn-l\" onclick=\"openEdit('品牌公众号','PROD005','IC005','NC005')\">编辑<\/button> <button class=\"btn-l\" style=\"color:var(--err)\" onclick=\"openM('modal-del')\">删除<\/button><\/td><\/tr>\n<tr data-plat=\"Facebook\" data-dept=\"投放部\" data-st=\"启用\" data-q=\"海外社媒投放 PROD006 IC006 NC006\"><td><input type=\"checkbox\"><\/td><td><b>海外社媒投放<\/b><\/td><td>PROD006<\/td><td><span class=\"tg tg-p\">Facebook<\/span><\/td><td>投放部 / 投放二组<\/td><td><code>IC006<\/code><\/td><td><code>NC006<\/code><\/td><td>赵六<\/td><td><span class=\"tg tg-ok\">启用<\/span><\/td><td><button class=\"btn-l\" onclick=\"openEdit('海外社媒投放','PROD006','IC006','NC006')\">编辑<\/button> <button class=\"btn-l\" style=\"color:var(--err)\" onclick=\"openM('modal-del')\">删除<\/button><\/td><\/tr>\n<tr data-plat=\"TikTok\" data-dept=\"投放部\" data-st=\"禁用\" data-q=\"TikTok达人推广 PROD007 IC007 NC007\"><td><input type=\"checkbox\"><\/td><td><b>TikTok达人推广<\/b><\/td><td>PROD007<\/td><td><span class=\"tg tg-w\">TikTok<\/span><\/td><td>投放部 / 投放一组<\/td><td><code>IC007<\/code><\/td><td><code>NC007<\/code><\/td><td>李四<\/td><td><span class=\"tg tg-e\">禁用<\/span><\/td><td><button class=\"btn-l\" onclick=\"openEdit('TikTok达人推广','PROD007','IC007','NC007')\">编辑<\/button> <button class=\"btn-l\" style=\"color:var(--err)\" onclick=\"openM('modal-del')\">删除<\/button><\/td><\/tr>\n<tr data-plat=\"微博\" data-dept=\"运营部\" data-st=\"启用\" data-q=\"微博话题营销 PROD008 IC008 NC008\"><td><input type=\"checkbox\"><\/td><td><b>微博话题营销<\/b><\/td><td>PROD008<\/td><td><span class=\"tg tg-w\" style=\"background:#fef3c7;color:#92400e\">微博<\/span><\/td><td>运营部<\/td><td><code>IC008<\/code><\/td><td><code>NC008<\/code><\/td><td>钱七<\/td><td><span class=\"tg tg-ok\">启用<\/span><\/td><td><button class=\"btn-l\" onclick=\"openEdit('微博话题营销','PROD008','IC008','NC008')\">编辑<\/button> <button class=\"btn-l\" style=\"color:var(--err)\" onclick=\"openM('modal-del')\">删除<\/button><\/td><\/tr>\n<\/tbody>\n<\/table><\/div>\n<div class=\"pg\"><span id=\"pgi\">共 8 条,每页 10 条<\/span><div><span class=\"pgb ac\">1<\/span><\/div><\/div>\n\n<\/div><\/div><\/div>\n\n<script>\nfunction openM(id){document.getElementById(id).classList.add('show')}\nfunction closeM(id){document.getElementById(id).classList.remove('show')}\nfunction showT(m,t){const e=document.getElementById('toast');e.textContent=m;e.className='toast show '+t;setTimeout(()=>e.className='toast',2500)}\n\nfunction openAdd(){\n document.getElementById('mpTitle').textContent='新增产品';\n document.getElementById('mp-name').value='';\n document.getElementById('mp-code').value='';\n document.getElementById('mp-ic').value='';\n document.getElementById('mp-nc').value='';\n document.getElementById('mp-platform').value='';\n document.getElementById('mp-dept').value='';\n openM('modal-prod');\n}\n\nfunction openEdit(name,code,ic,nc){\n document.getElementById('mpTitle').textContent='编辑产品 — '+name;\n document.getElementById('mp-name').value=name;\n document.getElementById('mp-code').value=code;\n document.getElementById('mp-ic').value=ic;\n document.getElementById('mp-nc').value=nc;\n openM('modal-prod');\n}\n\nfunction saveProd(){\n const n=document.getElementById('mp-name').value;\n const c=document.getElementById('mp-code').value;\n const ic=document.getElementById('mp-ic').value;\n const nc=document.getElementById('mp-nc').value;\n if(!n){showT('请输入产品名称','er');return}\n if(!c){showT('请输入产品代号','er');return}\n if(!ic){showT('内导渠道码必填(RB-09)','er');return}\n if(!nc){showT('自然渠道码必填(RB-09)','er');return}\n closeM('modal-prod');showT('✅ 保存成功','ok');\n}\n\nfunction filterT(){\n const q=document.getElementById('sInput').value.toLowerCase();\n const plat=document.getElementById('fPlat').value;\n const dept=document.getElementById('fDept').value;\n const st=document.getElementById('fSt').value;\n let c=0;\n document.querySelectorAll('#ptb tr').forEach(tr=>{\n const d=tr.dataset;\n const show=(!q||d.q.toLowerCase().includes(q))&&(!plat||d.plat===plat)&&(!dept||d.dept===dept)&&(!st||d.st===st);\n tr.style.display=show?'':'none';if(show)c++;\n });\n document.getElementById('pgi').textContent=`共 ${c} 条,每页 10 条`;\n}\n\nfunction onFileSelect(input){\n if(input.files.length){\n document.getElementById('fileInfo').style.display='block';\n document.getElementById('fileName').textContent='📄 '+input.files[0].name+' ('+Math.round(input.files[0].size/1024)+'KB)';\n document.getElementById('previewInfo').textContent='✅ 预检通过:解析出 23 条数据,其中 2 条重复将覆盖';\n document.getElementById('importBtn').disabled=false;\n }\n}\nfunction clearFile(){\n document.getElementById('fileInfo').style.display='none';\n document.getElementById('fileInput').value='';\n document.getElementById('importBtn').disabled=true;\n}\nfunction doImport(){\n closeM('modal-import');showT('✅ 成功导入 21 条,覆盖 2 条','ok');\n}\n\ndocument.querySelectorAll('.mo').forEach(m=>m.addEventListener('click',e=>{if(e.target===m)m.classList.remove('show')}));\n<\/script>\n<\/body><\/html>\n",
|
||
"07_渠道码管理.html": "<!DOCTYPE html><html lang=\"zh-CN\"><head><script>if(window!==window.top)document.documentElement.classList.add(\"in-iframe\")<\/script><style>.in-iframe .side{display:none!important}.in-iframe .main{margin-left:0!important}.in-iframe .layout{min-height:auto}<\/style><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1.0\"><title>Agent任务系统 v2.1 - 渠道码管理<\/title>\n<style>\n*{margin:0;padding:0;box-sizing:border-box}:root{--pri:#6366f1;--bg:#f1f5f9;--card:#fff;--txt:#1e293b;--sub:#64748b;--bdr:#e2e8f0;--ok:#22c55e;--err:#ef4444;--warn:#f59e0b;--side:#1e293b}body{font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",\"PingFang SC\",\"Microsoft YaHei\",sans-serif;background:var(--bg);color:var(--txt);line-height:1.6;font-size:13px}\n.layout{display:flex;min-height:100vh}.side{width:220px;background:var(--side);color:#94a3b8;position:fixed;top:0;left:0;bottom:0;overflow-y:auto;z-index:100}.side .logo{padding:16px 18px;font-size:14px;font-weight:700;color:#fff;border-bottom:1px solid #334155}.ni{display:flex;align-items:center;gap:8px;padding:9px 18px;font-size:12px;color:#94a3b8;cursor:pointer;border-left:3px solid transparent}.ni:hover{background:#334155;color:#e2e8f0}.ni.ac{background:rgba(99,102,241,.15);color:#818cf8;border-left-color:#818cf8;font-weight:600}.ng-t{padding:10px 18px 4px;font-size:10px;letter-spacing:1px;color:#475569;font-weight:600}\n.main{margin-left:220px;flex:1}.hd{height:52px;background:var(--card);border-bottom:1px solid var(--bdr);display:flex;align-items:center;justify-content:space-between;padding:0 24px;font-size:12px;color:var(--sub);position:sticky;top:0;z-index:50}.ct{padding:24px}\n.pt{font-size:20px;font-weight:700;margin-bottom:4px}.pd{font-size:12px;color:var(--sub);margin-bottom:20px}\n.card{background:var(--card);border-radius:10px;padding:16px;border:1px solid var(--bdr);margin-bottom:14px}\n.tb{display:flex;gap:8px;align-items:center;margin-bottom:14px;flex-wrap:wrap}.sb{display:flex;align-items:center;gap:6px;background:#f8fafc;border:1px solid var(--bdr);border-radius:7px;padding:7px 12px;font-size:12px}.sb input{border:none;background:none;outline:none;font-size:12px;width:140px}\n.sl{border:1px solid var(--bdr);border-radius:7px;padding:7px 12px;font-size:12px;background:#fff;cursor:pointer}\n.btn{padding:7px 16px;border-radius:7px;font-size:12px;font-weight:500;border:none;cursor:pointer;display:inline-flex;align-items:center;gap:5px;transition:all .12s}.btn-p{background:var(--pri);color:#fff}.btn-p:hover{background:#4f46e5}.btn-d{background:#fee2e2;color:#dc2626}.btn-g{background:transparent;color:var(--sub);border:1px solid var(--bdr)}.btn-sm{padding:5px 10px;font-size:11px}\n.btn-l{background:none;border:none;color:var(--pri);padding:0;font-size:12px;cursor:pointer}.btn-l:hover{text-decoration:underline}\n.tg{display:inline-block;padding:2px 8px;border-radius:99px;font-size:10px;font-weight:600}.tg-ok{background:#dcfce7;color:#166534}.tg-e{background:#fee2e2;color:#991b1b}.tg-i{background:#dbeafe;color:#1e40af}.tg-w{background:#fef3c7;color:#92400e}.tg-p{background:#f3e8ff;color:#6b21a8}.tg-g{background:#f1f5f9;color:#64748b}\ntable{width:100%;border-collapse:collapse;font-size:12px}th,td{padding:8px 12px;text-align:left;border-bottom:1px solid var(--bdr)}th{background:#f8fafc;font-weight:600;color:var(--sub);font-size:11px}tr:hover td{background:#fafbfc}.tw{overflow-x:auto;border:1px solid var(--bdr);border-radius:8px}\n.fg{margin-bottom:14px}.fl{font-size:12px;font-weight:500;margin-bottom:5px;display:block}.fl .rq{color:var(--err)}.fi{width:100%;padding:8px 12px;border:1px solid var(--bdr);border-radius:7px;font-size:12px;outline:none}.fi:focus{border-color:var(--pri)}.fs{width:100%;padding:8px 12px;border:1px solid var(--bdr);border-radius:7px;font-size:12px;background:#fff}.fr{display:grid;grid-template-columns:1fr 1fr;gap:14px}\n.mo{position:fixed;inset:0;background:rgba(0,0,0,.45);display:none;align-items:center;justify-content:center;z-index:200}.mo.show{display:flex}.mc{background:var(--card);border-radius:14px;width:90%;max-width:560px;max-height:85vh;overflow-y:auto;box-shadow:0 20px 60px rgba(0,0,0,.2)}.mh{padding:14px 20px;border-bottom:1px solid var(--bdr);display:flex;justify-content:space-between;align-items:center}.mh h3{font-size:15px}.mx{cursor:pointer;font-size:18px;color:var(--sub);background:none;border:none}.mb{padding:20px}.mf{padding:14px 20px;border-top:1px solid var(--bdr);display:flex;justify-content:flex-end;gap:8px}\n.toast{position:fixed;top:20px;right:20px;padding:12px 20px;border-radius:8px;font-size:13px;font-weight:500;z-index:300;display:none}.toast.show{display:block;animation:tIn .3s}.toast.ok{background:#dcfce7;color:#166534}.toast.er{background:#fee2e2;color:#991b1b}@keyframes tIn{from{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}\n.pg{display:flex;align-items:center;justify-content:space-between;padding:10px 0;font-size:12px;color:var(--sub)}.pgb{padding:4px 10px;border:1px solid var(--bdr);border-radius:5px;font-size:11px;cursor:pointer;background:var(--card);margin:0 2px}.pgb.ac{background:var(--pri);color:#fff;border-color:var(--pri)}\n.tabs{display:flex;gap:0;border-bottom:2px solid var(--bdr);margin-bottom:16px}.tab{padding:10px 20px;font-size:13px;font-weight:500;color:var(--sub);cursor:pointer;border-bottom:2px solid transparent;margin-bottom:-2px}.tab.ac{color:var(--pri);border-bottom-color:var(--pri);font-weight:600}.tab:hover{color:var(--txt)}\n.stat{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;margin-bottom:16px}.stat-c{background:var(--card);border:1px solid var(--bdr);border-radius:10px;padding:14px 16px}.stat-c .sv{font-size:22px;font-weight:700}.stat-c .sl2{font-size:11px;color:var(--sub)}\n<\/style><\/head><body>\n<div class=\"toast\" id=\"toast\"><\/div>\n\n<div class=\"mo\" id=\"modal-ch\"><div class=\"mc\"><div class=\"mh\"><h3 id=\"mcTitle\">新增渠道码<\/h3><button class=\"mx\" onclick=\"closeM('modal-ch')\">✕<\/button><\/div><div class=\"mb\">\n<div class=\"fr\">\n<div class=\"fg\"><label class=\"fl\">渠道码 <span class=\"rq\">*<\/span><\/label><input class=\"fi\" id=\"mc-code\" placeholder=\"如 IC20240301A\"><\/div>\n<div class=\"fg\"><label class=\"fl\">渠道名称 <span class=\"rq\">*<\/span><\/label><input class=\"fi\" id=\"mc-name\" placeholder=\"渠道名称\"><\/div>\n<\/div>\n<div class=\"fr\">\n<div class=\"fg\"><label class=\"fl\">渠道类型 <span class=\"rq\">*<\/span><\/label><select class=\"fs\" id=\"mc-type\"><option>内导(internal)<\/option><option>自然(natural)<\/option><\/select><\/div>\n<div class=\"fg\"><label class=\"fl\">状态<\/label><select class=\"fs\"><option>启用<\/option><option>禁用<\/option><\/select><\/div>\n<\/div>\n<div class=\"fg\"><label class=\"fl\">备注<\/label><input class=\"fi\" placeholder=\"可选备注\"><\/div>\n<\/div><div class=\"mf\"><button class=\"btn btn-g\" onclick=\"closeM('modal-ch')\">取消<\/button><button class=\"btn btn-p\" onclick=\"saveCh()\">保存<\/button><\/div><\/div><\/div>\n\n<div class=\"mo\" id=\"modal-bind\"><div class=\"mc\"><div class=\"mh\"><h3>🔗 渠道码绑定产品<\/h3><button class=\"mx\" onclick=\"closeM('modal-bind')\">✕<\/button><\/div><div class=\"mb\">\n<div class=\"fg\"><label class=\"fl\">渠道码<\/label><input class=\"fi\" value=\"IC001 — 小红书内导A\" disabled><\/div>\n<div class=\"fg\"><label class=\"fl\">已绑定产品<\/label>\n<div id=\"bindList\">\n<div style=\"display:flex;align-items:center;gap:8px;padding:6px;background:#f8fafc;border-radius:6px;margin-bottom:6px;font-size:12px\"><span style=\"flex:1\">美妆种草达人 (PROD001)<\/span><span class=\"tg tg-ok\">已绑定<\/span><button class=\"btn-l\" style=\"color:var(--err);font-size:11px\" onclick=\"this.closest('div').remove();showT('已解绑','ok')\">解绑<\/button><\/div>\n<div style=\"display:flex;align-items:center;gap:8px;padding:6px;background:#f8fafc;border-radius:6px;margin-bottom:6px;font-size:12px\"><span style=\"flex:1\">护肤品评测 (PROD002)<\/span><span class=\"tg tg-ok\">已绑定<\/span><button class=\"btn-l\" style=\"color:var(--err);font-size:11px\" onclick=\"this.closest('div').remove();showT('已解绑','ok')\">解绑<\/button><\/div>\n<\/div><\/div>\n<div class=\"fg\"><label class=\"fl\">添加绑定<\/label>\n<div style=\"display:flex;gap:8px\"><select class=\"fs\" style=\"flex:1\"><option>PROD003 — 抖音带货王<\/option><option>PROD004 — 短视频营销<\/option><option>PROD005 — 品牌公众号<\/option><\/select><button class=\"btn btn-p btn-sm\" onclick=\"addBind()\">绑定<\/button><\/div>\n<\/div>\n<\/div><div class=\"mf\"><button class=\"btn btn-g\" onclick=\"closeM('modal-bind')\">关闭<\/button><\/div><\/div><\/div>\n\n<div class=\"mo\" id=\"modal-del\"><div class=\"mc\" style=\"max-width:400px\"><div class=\"mh\"><h3>⚠️ 确认删除<\/h3><button class=\"mx\" onclick=\"closeM('modal-del')\">✕<\/button><\/div><div class=\"mb\" style=\"text-align:center;padding:20px\"><div style=\"font-size:36px;margin-bottom:8px\">🗑️<\/div><p style=\"font-size:13px;font-weight:600\">确定删除该渠道码?<\/p><p style=\"font-size:11px;color:var(--sub);margin-top:4px\">已绑定产品的渠道码需先解绑<\/p><\/div><div class=\"mf\"><button class=\"btn btn-g\" onclick=\"closeM('modal-del')\">取消<\/button><button class=\"btn btn-d\" onclick=\"closeM('modal-del');showT('✅ 已删除','ok')\">确认删除<\/button><\/div><\/div><\/div>\n\n<div class=\"layout\">\n<aside class=\"side\">\n<div class=\"logo\">🤖 Agent任务系统 v2.1<\/div>\n<div class=\"ni\">🏠 首页<\/div>\n<div class=\"ng-t\">权限管理<\/div><div class=\"ni\">· 组织架构<\/div><div class=\"ni\">· 菜单管理<\/div><div class=\"ni\">· 角色管理<\/div><div class=\"ni\">· 用户管理<\/div>\n<div class=\"ng-t\">产品管理<\/div><div class=\"ni\">· 产品列表<\/div><div class=\"ni ac\">· 渠道码<\/div><div class=\"ni\">· 平台套件<\/div>\n<div class=\"ng-t\">平台产品账号<\/div><div class=\"ni\">· 账号管理<\/div>\n<div class=\"ng-t\">Skill中心<\/div><div class=\"ni\">· Skill列表<\/div><div class=\"ni\">· 调用日志<\/div>\n<div class=\"ng-t\">任务中心<\/div><div class=\"ni\">· 任务创建<\/div><div class=\"ni\">· 任务列表<\/div>\n<div class=\"ng-t\">日志/设置<\/div><div class=\"ni\">· 操作日志<\/div><div class=\"ni\">· 系统设置<\/div>\n<\/aside>\n<div class=\"main\">\n<div class=\"hd\"><div>📦 产品管理 / <b style=\"color:var(--txt)\">渠道码管理<\/b><\/div><div style=\"display:flex;align-items:center;gap:10px\"><span>🔔<\/span><span>admin<\/span><div style=\"width:28px;height:28px;border-radius:50%;background:var(--pri);color:#fff;display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:600\">A<\/div><\/div><\/div>\n<div class=\"ct\">\n<h1 class=\"pt\">渠道码管理<\/h1>\n<p class=\"pd\">内导渠道码 + 自然渠道码独立管理 · 渠道码与产品关联绑定 · 关联产品统计<\/p>\n\n<div class=\"stat\">\n<div class=\"stat-c\"><div class=\"sv\">48<\/div><div class=\"sl2\">渠道码总数<\/div><\/div>\n<div class=\"stat-c\"><div class=\"sv\" style=\"color:var(--pri)\">26<\/div><div class=\"sl2\">内导渠道码<\/div><\/div>\n<div class=\"stat-c\"><div class=\"sv\" style=\"color:var(--ok)\">22<\/div><div class=\"sl2\">自然渠道码<\/div><\/div>\n<div class=\"stat-c\"><div class=\"sv\" style=\"color:var(--warn)\">156<\/div><div class=\"sl2\">关联产品数<\/div><\/div>\n<\/div>\n\n<div class=\"tabs\" id=\"mainTabs\">\n<div class=\"tab ac\" onclick=\"switchTab(0)\">内导渠道码<\/div>\n<div class=\"tab\" onclick=\"switchTab(1)\">自然渠道码<\/div>\n<\/div>\n\n<!-- 内导渠道码 Tab -->\n<div class=\"tab-ct show\" id=\"tab0\">\n<div class=\"tb\">\n<div class=\"sb\"><span>🔍<\/span><input placeholder=\"搜索渠道码/名称\" oninput=\"filterCh(0,this.value)\"><\/div>\n<select class=\"sl\" onchange=\"filterChSt(0,this.value)\"><option value=\"\">全部状态<\/option><option value=\"启用\">启用<\/option><option value=\"禁用\">禁用<\/option><\/select>\n<button class=\"btn btn-p\" style=\"margin-left:auto\" onclick=\"openAddCh('internal')\">+ 新增内导渠道码<\/button>\n<\/div>\n<div class=\"tw\"><table><thead><tr><th>渠道码<\/th><th>渠道名称<\/th><th>类型<\/th><th>关联产品数<\/th><th>状态<\/th><th>创建时间<\/th><th>操作<\/th><\/tr><\/thead>\n<tbody class=\"chBody\" data-tab=\"0\">\n<tr data-q=\"IC001 小红书内导A\" data-st=\"启用\"><td><code>IC001<\/code><\/td><td>小红书内导A<\/td><td><span class=\"tg tg-i\">内导<\/span><\/td><td><b>3<\/b><\/td><td><span class=\"tg tg-ok\">启用<\/span><\/td><td>2024-01-15<\/td><td><button class=\"btn-l\" onclick=\"openEditCh('IC001','小红书内导A','internal')\">编辑<\/button> <button class=\"btn-l\" onclick=\"openM('modal-bind')\">绑定<\/button> <button class=\"btn-l\" style=\"color:var(--err)\" onclick=\"openM('modal-del')\">删除<\/button><\/td><\/tr>\n<tr data-q=\"IC002 小红书内导B\" data-st=\"启用\"><td><code>IC002<\/code><\/td><td>小红书内导B<\/td><td><span class=\"tg tg-i\">内导<\/span><\/td><td><b>2<\/b><\/td><td><span class=\"tg tg-ok\">启用<\/span><\/td><td>2024-02-20<\/td><td><button class=\"btn-l\" onclick=\"openEditCh('IC002','小红书内导B','internal')\">编辑<\/button> <button class=\"btn-l\" onclick=\"openM('modal-bind')\">绑定<\/button> <button class=\"btn-l\" style=\"color:var(--err)\" onclick=\"openM('modal-del')\">删除<\/button><\/td><\/tr>\n<tr data-q=\"IC003 抖音内导A\" data-st=\"启用\"><td><code>IC003<\/code><\/td><td>抖音内导A<\/td><td><span class=\"tg tg-i\">内导<\/span><\/td><td><b>5<\/b><\/td><td><span class=\"tg tg-ok\">启用<\/span><\/td><td>2024-03-10<\/td><td><button class=\"btn-l\" onclick=\"openEditCh('IC003','抖音内导A','internal')\">编辑<\/button> <button class=\"btn-l\" onclick=\"openM('modal-bind')\">绑定<\/button> <button class=\"btn-l\" style=\"color:var(--err)\" onclick=\"openM('modal-del')\">删除<\/button><\/td><\/tr>\n<tr data-q=\"IC004 微信内导A\" data-st=\"禁用\"><td><code>IC004<\/code><\/td><td>微信内导A<\/td><td><span class=\"tg tg-i\">内导<\/span><\/td><td><b>0<\/b><\/td><td><span class=\"tg tg-e\">禁用<\/span><\/td><td>2024-04-01<\/td><td><button class=\"btn-l\" onclick=\"openEditCh('IC004','微信内导A','internal')\">编辑<\/button> <button class=\"btn-l\" onclick=\"openM('modal-bind')\">绑定<\/button> <button class=\"btn-l\" style=\"color:var(--err)\" onclick=\"openM('modal-del')\">删除<\/button><\/td><\/tr>\n<tr data-q=\"IC005 Facebook内导A\" data-st=\"启用\"><td><code>IC005<\/code><\/td><td>Facebook内导A<\/td><td><span class=\"tg tg-i\">内导<\/span><\/td><td><b>1<\/b><\/td><td><span class=\"tg tg-ok\">启用<\/span><\/td><td>2024-05-15<\/td><td><button class=\"btn-l\" onclick=\"openEditCh('IC005','Facebook内导A','internal')\">编辑<\/button> <button class=\"btn-l\" onclick=\"openM('modal-bind')\">绑定<\/button> <button class=\"btn-l\" style=\"color:var(--err)\" onclick=\"openM('modal-del')\">删除<\/button><\/td><\/tr>\n<\/tbody><\/table><\/div>\n<\/div>\n\n<!-- 自然渠道码 Tab -->\n<div class=\"tab-ct\" id=\"tab1\" style=\"display:none\">\n<div class=\"tb\">\n<div class=\"sb\"><span>🔍<\/span><input placeholder=\"搜索渠道码/名称\" oninput=\"filterCh(1,this.value)\"><\/div>\n<select class=\"sl\" onchange=\"filterChSt(1,this.value)\"><option value=\"\">全部状态<\/option><option value=\"启用\">启用<\/option><option value=\"禁用\">禁用<\/option><\/select>\n<button class=\"btn btn-p\" style=\"margin-left:auto\" onclick=\"openAddCh('natural')\">+ 新增自然渠道码<\/button>\n<\/div>\n<div class=\"tw\"><table><thead><tr><th>渠道码<\/th><th>渠道名称<\/th><th>类型<\/th><th>关联产品数<\/th><th>状态<\/th><th>创建时间<\/th><th>操作<\/th><\/tr><\/thead>\n<tbody class=\"chBody\" data-tab=\"1\">\n<tr data-q=\"NC001 小红书自然A\" data-st=\"启用\"><td><code>NC001<\/code><\/td><td>小红书自然A<\/td><td><span class=\"tg tg-ok\">自然<\/span><\/td><td><b>4<\/b><\/td><td><span class=\"tg tg-ok\">启用<\/span><\/td><td>2024-01-15<\/td><td><button class=\"btn-l\" onclick=\"openEditCh('NC001','小红书自然A','natural')\">编辑<\/button> <button class=\"btn-l\" onclick=\"openM('modal-bind')\">绑定<\/button> <button class=\"btn-l\" style=\"color:var(--err)\" onclick=\"openM('modal-del')\">删除<\/button><\/td><\/tr>\n<tr data-q=\"NC002 抖音自然A\" data-st=\"启用\"><td><code>NC002<\/code><\/td><td>抖音自然A<\/td><td><span class=\"tg tg-ok\">自然<\/span><\/td><td><b>3<\/b><\/td><td><span class=\"tg tg-ok\">启用<\/span><\/td><td>2024-02-20<\/td><td><button class=\"btn-l\" onclick=\"openEditCh('NC002','抖音自然A','natural')\">编辑<\/button> <button class=\"btn-l\" onclick=\"openM('modal-bind')\">绑定<\/button> <button class=\"btn-l\" style=\"color:var(--err)\" onclick=\"openM('modal-del')\">删除<\/button><\/td><\/tr>\n<tr data-q=\"NC003 微博自然A\" data-st=\"启用\"><td><code>NC003<\/code><\/td><td>微博自然A<\/td><td><span class=\"tg tg-ok\">自然<\/span><\/td><td><b>1<\/b><\/td><td><span class=\"tg tg-ok\">启用<\/span><\/td><td>2024-03-10<\/td><td><button class=\"btn-l\" onclick=\"openEditCh('NC003','微博自然A','natural')\">编辑<\/button> <button class=\"btn-l\" onclick=\"openM('modal-bind')\">绑定<\/button> <button class=\"btn-l\" style=\"color:var(--err)\" onclick=\"openM('modal-del')\">删除<\/button><\/td><\/tr>\n<tr data-q=\"NC004 TikTok自然A\" data-st=\"禁用\"><td><code>NC004<\/code><\/td><td>TikTok自然A<\/td><td><span class=\"tg tg-ok\">自然<\/span><\/td><td><b>0<\/b><\/td><td><span class=\"tg tg-e\">禁用<\/span><\/td><td>2024-04-05<\/td><td><button class=\"btn-l\" onclick=\"openEditCh('NC004','TikTok自然A','natural')\">编辑<\/button> <button class=\"btn-l\" onclick=\"openM('modal-bind')\">绑定<\/button> <button class=\"btn-l\" style=\"color:var(--err)\" onclick=\"openM('modal-del')\">删除<\/button><\/td><\/tr>\n<\/tbody><\/table><\/div>\n<\/div>\n\n<\/div><\/div><\/div>\n\n<script>\nfunction openM(id){document.getElementById(id).classList.add('show')}\nfunction closeM(id){document.getElementById(id).classList.remove('show')}\nfunction showT(m,t){const e=document.getElementById('toast');e.textContent=m;e.className='toast show '+t;setTimeout(()=>e.className='toast',2500)}\n\nfunction switchTab(i){\n document.querySelectorAll('#mainTabs .tab').forEach((t,j)=>{t.classList.toggle('ac',j===i)});\n document.querySelectorAll('.tab-ct').forEach((c,j)=>{c.style.display=j===i?'block':'none'});\n}\n\nfunction openAddCh(type){\n document.getElementById('mcTitle').textContent='新增'+(type==='internal'?'内导':'自然')+'渠道码';\n document.getElementById('mc-code').value='';\n document.getElementById('mc-name').value='';\n document.getElementById('mc-type').value=type==='internal'?'内导(internal)':'自然(natural)';\n openM('modal-ch');\n}\n\nfunction openEditCh(code,name,type){\n document.getElementById('mcTitle').textContent='编辑渠道码 — '+code;\n document.getElementById('mc-code').value=code;\n document.getElementById('mc-name').value=name;\n document.getElementById('mc-type').value=type==='internal'?'内导(internal)':'自然(natural)';\n openM('modal-ch');\n}\n\nfunction saveCh(){\n if(!document.getElementById('mc-code').value){showT('请输入渠道码','er');return}\n if(!document.getElementById('mc-name').value){showT('请输入渠道名称','er');return}\n closeM('modal-ch');showT('✅ 保存成功','ok');\n}\n\nfunction addBind(){\n const list=document.getElementById('bindList');\n const d=document.createElement('div');\n d.style.cssText='display:flex;align-items:center;gap:8px;padding:6px;background:#f8fafc;border-radius:6px;margin-bottom:6px;font-size:12px';\n d.innerHTML='<span style=\"flex:1\">新绑定产品<\/span><span class=\"tg tg-ok\">已绑定<\/span><button class=\"btn-l\" style=\"color:var(--err);font-size:11px\" onclick=\"this.closest(\\'div\\').remove();showT(\\'已解绑\\',\\'ok\\')\">解绑<\/button>';\n list.appendChild(d);\n showT('✅ 绑定成功','ok');\n}\n\nfunction filterCh(tab,q){\n q=q.toLowerCase();\n document.querySelectorAll(`.chBody[data-tab=\"${tab}\"] tr`).forEach(tr=>{\n tr.style.display=(!q||tr.dataset.q.toLowerCase().includes(q))?'':'none';\n });\n}\nfunction filterChSt(tab,st){\n document.querySelectorAll(`.chBody[data-tab=\"${tab}\"] tr`).forEach(tr=>{\n tr.style.display=(!st||tr.dataset.st===st)?'':'none';\n });\n}\n\ndocument.querySelectorAll('.mo').forEach(m=>m.addEventListener('click',e=>{if(e.target===m)m.classList.remove('show')}));\n<\/script>\n<\/body><\/html>\n",
|
||
"08_平台产品账号.html": "<!DOCTYPE html><html lang=\"zh-CN\"><head><script>if(window!==window.top)document.documentElement.classList.add(\"in-iframe\")<\/script><style>.in-iframe .side{display:none!important}.in-iframe .main{margin-left:0!important}.in-iframe .layout{min-height:auto}<\/style><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1.0\"><title>Agent任务系统 v2.1 - 平台产品账号管理<\/title>\n<style>\n*{margin:0;padding:0;box-sizing:border-box}:root{--pri:#6366f1;--bg:#f1f5f9;--card:#fff;--txt:#1e293b;--sub:#64748b;--bdr:#e2e8f0;--ok:#22c55e;--err:#ef4444;--warn:#f59e0b;--side:#1e293b}body{font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",\"PingFang SC\",\"Microsoft YaHei\",sans-serif;background:var(--bg);color:var(--txt);line-height:1.6;font-size:13px}\n.layout{display:flex;min-height:100vh}.side{width:220px;background:var(--side);color:#94a3b8;position:fixed;top:0;left:0;bottom:0;overflow-y:auto;z-index:100}.side .logo{padding:16px 18px;font-size:14px;font-weight:700;color:#fff;border-bottom:1px solid #334155}.ni{display:flex;align-items:center;gap:8px;padding:9px 18px;font-size:12px;color:#94a3b8;cursor:pointer;border-left:3px solid transparent}.ni:hover{background:#334155;color:#e2e8f0}.ni.ac{background:rgba(99,102,241,.15);color:#818cf8;border-left-color:#818cf8;font-weight:600}.ng-t{padding:10px 18px 4px;font-size:10px;letter-spacing:1px;color:#475569;font-weight:600}\n.main{margin-left:220px;flex:1}.hd{height:52px;background:var(--card);border-bottom:1px solid var(--bdr);display:flex;align-items:center;justify-content:space-between;padding:0 24px;font-size:12px;color:var(--sub);position:sticky;top:0;z-index:50}.ct{padding:24px}\n.pt{font-size:20px;font-weight:700;margin-bottom:4px}.pd{font-size:12px;color:var(--sub);margin-bottom:20px}\n.tb{display:flex;gap:8px;align-items:center;margin-bottom:14px;flex-wrap:wrap}.sb{display:flex;align-items:center;gap:6px;background:#f8fafc;border:1px solid var(--bdr);border-radius:7px;padding:7px 12px;font-size:12px}.sb input{border:none;background:none;outline:none;font-size:12px;width:150px}\n.sl{border:1px solid var(--bdr);border-radius:7px;padding:7px 12px;font-size:12px;background:#fff;cursor:pointer}\n.btn{padding:7px 16px;border-radius:7px;font-size:12px;font-weight:500;border:none;cursor:pointer;display:inline-flex;align-items:center;gap:5px;transition:all .12s}.btn-p{background:var(--pri);color:#fff}.btn-p:hover{background:#4f46e5}.btn-d{background:#fee2e2;color:#dc2626}.btn-g{background:transparent;color:var(--sub);border:1px solid var(--bdr)}.btn-sm{padding:5px 10px;font-size:11px}.btn-s{background:var(--ok);color:#fff}.btn-w{background:var(--warn);color:#fff}\n.btn-l{background:none;border:none;color:var(--pri);padding:0;font-size:12px;cursor:pointer}.btn-l:hover{text-decoration:underline}\n.tg{display:inline-block;padding:2px 8px;border-radius:99px;font-size:10px;font-weight:600}.tg-ok{background:#dcfce7;color:#166534}.tg-e{background:#fee2e2;color:#991b1b}.tg-i{background:#dbeafe;color:#1e40af}.tg-p{background:#f3e8ff;color:#6b21a8}.tg-g{background:#f1f5f9;color:#64748b}.tg-w{background:#fef3c7;color:#92400e}\ntable{width:100%;border-collapse:collapse;font-size:12px}th,td{padding:8px 12px;text-align:left;border-bottom:1px solid var(--bdr)}th{background:#f8fafc;font-weight:600;color:var(--sub);font-size:11px}tr:hover td{background:#fafbfc}.tw{overflow-x:auto;border:1px solid var(--bdr);border-radius:8px}\n.fg{margin-bottom:14px}.fl{font-size:12px;font-weight:500;margin-bottom:5px;display:block}.fl .rq{color:var(--err)}.fi{width:100%;padding:8px 12px;border:1px solid var(--bdr);border-radius:7px;font-size:12px;outline:none}.fi:focus{border-color:var(--pri)}.fs{width:100%;padding:8px 12px;border:1px solid var(--bdr);border-radius:7px;font-size:12px;background:#fff}.fr{display:grid;grid-template-columns:1fr 1fr;gap:14px}\n.mo{position:fixed;inset:0;background:rgba(0,0,0,.45);display:none;align-items:center;justify-content:center;z-index:200}.mo.show{display:flex}.mc{background:var(--card);border-radius:14px;width:90%;max-width:620px;max-height:85vh;overflow-y:auto;box-shadow:0 20px 60px rgba(0,0,0,.2)}.mh{padding:14px 20px;border-bottom:1px solid var(--bdr);display:flex;justify-content:space-between;align-items:center}.mh h3{font-size:15px}.mx{cursor:pointer;font-size:18px;color:var(--sub);background:none;border:none}.mb{padding:20px}.mf{padding:14px 20px;border-top:1px solid var(--bdr);display:flex;justify-content:flex-end;gap:8px}\n.toast{position:fixed;top:20px;right:20px;padding:12px 20px;border-radius:8px;font-size:13px;font-weight:500;z-index:300;display:none}.toast.show{display:block;animation:tIn .3s}.toast.ok{background:#dcfce7;color:#166534}.toast.er{background:#fee2e2;color:#991b1b}.toast.wn{background:#fef3c7;color:#92400e}@keyframes tIn{from{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}\n.pg{display:flex;align-items:center;justify-content:space-between;padding:10px 0;font-size:12px;color:var(--sub)}.pgb{padding:4px 10px;border:1px solid var(--bdr);border-radius:5px;font-size:11px;cursor:pointer;background:var(--card);margin:0 2px}.pgb.ac{background:var(--pri);color:#fff;border-color:var(--pri)}\n.stat{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;margin-bottom:16px}.stat-c{background:var(--card);border:1px solid var(--bdr);border-radius:10px;padding:14px 16px}.stat-c .sv{font-size:22px;font-weight:700}.stat-c .sl2{font-size:11px;color:var(--sub)}\n.note{background:#eff6ff;border-left:3px solid var(--pri);padding:8px 12px;border-radius:0 6px 6px 0;font-size:11px;color:var(--sub);margin-bottom:14px}\n.auto-fill{background:#f0fdf4;border:1px solid #bbf7d0;border-radius:7px;padding:8px 12px;font-size:12px;color:#166534}\n.pwd-wrap{position:relative}.pwd-toggle{position:absolute;right:10px;top:50%;transform:translateY(-50%);cursor:pointer;font-size:14px;background:none;border:none}\n.test-result{padding:8px 12px;border-radius:7px;font-size:12px;margin-top:8px;display:none}\n<\/style><\/head><body>\n<div class=\"toast\" id=\"toast\"><\/div>\n\n<!-- Modal: 添加/编辑平台产品账号 -->\n<div class=\"mo\" id=\"modal-acc\"><div class=\"mc\"><div class=\"mh\"><h3 id=\"maTitle\">添加平台产品账号<\/h3><button class=\"mx\" onclick=\"closeM('modal-acc')\">✕<\/button><\/div><div class=\"mb\">\n\n<div class=\"note\">📋 表单联动:选择平台 → 自动带出地址 → 筛选该平台下产品 → 填写登录凭据<\/div>\n\n<div class=\"fg\"><label class=\"fl\">选择平台 <span class=\"rq\">*<\/span><\/label>\n<select class=\"fs\" id=\"ma-plat\" onchange=\"onPlatChange(this.value)\">\n<option value=\"\">请选择平台<\/option>\n<option value=\"xhs\">小红书<\/option>\n<option value=\"dy\">抖音<\/option>\n<option value=\"wx\">微信公众号<\/option>\n<option value=\"wb\">微博<\/option>\n<option value=\"fb\">Facebook<\/option>\n<option value=\"tt\">TikTok<\/option>\n<\/select><\/div>\n\n<div class=\"fr\">\n<div class=\"fg\"><label class=\"fl\">平台名称<\/label><input class=\"fi auto-fill\" id=\"ma-platname\" readonly placeholder=\"选择平台后自动带出\"><\/div>\n<div class=\"fg\"><label class=\"fl\">平台地址<\/label><input class=\"fi auto-fill\" id=\"ma-platurl\" readonly placeholder=\"选择平台后自动带出\"><\/div>\n<\/div>\n\n<div class=\"fg\"><label class=\"fl\">产品代号 <span class=\"rq\">*<\/span><\/label>\n<select class=\"fs\" id=\"ma-product\" disabled>\n<option value=\"\">请先选择平台<\/option>\n<\/select>\n<div style=\"font-size:10px;color:var(--sub);margin-top:4px\" id=\"prodHint\">仅展示所选平台下且在您产品范围(data_scope)内的产品<\/div>\n<\/div>\n\n<hr style=\"border:none;border-top:1px solid var(--bdr);margin:16px 0\">\n<div style=\"font-size:13px;font-weight:600;margin-bottom:12px\">🔑 登录凭据<\/div>\n\n<div class=\"fg\"><label class=\"fl\">登录账号 <span class=\"rq\">*<\/span><\/label><input class=\"fi\" id=\"ma-login\" placeholder=\"平台登录账号\"><\/div>\n\n<div class=\"fg\"><label class=\"fl\">登录密码 <span class=\"rq\">*<\/span><\/label>\n<div class=\"pwd-wrap\"><input class=\"fi\" id=\"ma-pwd\" type=\"password\" placeholder=\"平台登录密码\"><button class=\"pwd-toggle\" onclick=\"togglePwd('ma-pwd',this)\">👁️<\/button><\/div><\/div>\n\n<div class=\"fg\"><label class=\"fl\">谷歌密钥(二次验证)<\/label>\n<div class=\"pwd-wrap\"><input class=\"fi\" id=\"ma-gkey\" type=\"password\" placeholder=\"可选,谷歌二次验证密钥\"><button class=\"pwd-toggle\" onclick=\"togglePwd('ma-gkey',this)\">👁️<\/button><\/div>\n<div style=\"font-size:10px;color:var(--sub);margin-top:4px\">加密存储,展示时仅显示后4位<\/div><\/div>\n\n<div class=\"fg\"><label class=\"fl\">状态<\/label><select class=\"fs\"><option>启用<\/option><option>禁用<\/option><\/select><\/div>\n\n<\/div><div class=\"mf\"><button class=\"btn btn-g\" onclick=\"closeM('modal-acc')\">取消<\/button><button class=\"btn btn-s btn-sm\" onclick=\"testConn()\" style=\"margin-right:auto\">🔌 连通测试<\/button><button class=\"btn btn-p\" onclick=\"saveAcc()\">保存<\/button><\/div><\/div><\/div>\n\n<!-- Modal: 连通测试结果 -->\n<div class=\"mo\" id=\"modal-test\"><div class=\"mc\" style=\"max-width:420px\"><div class=\"mh\"><h3>🔌 连通测试<\/h3><button class=\"mx\" onclick=\"closeM('modal-test')\">✕<\/button><\/div><div class=\"mb\" style=\"text-align:center;padding:20px\">\n<div id=\"testLoading\" style=\"display:none\"><div style=\"font-size:36px;animation:spin 1s linear infinite\">⏳<\/div><p style=\"margin-top:8px;font-size:13px\">正在测试连通性...<\/p><\/div>\n<div id=\"testOk\" style=\"display:none\"><div style=\"font-size:36px\">✅<\/div><p style=\"margin-top:8px;font-size:14px;font-weight:600;color:var(--ok)\">连通成功!<\/p><p style=\"font-size:12px;color:var(--sub);margin-top:4px\">账号验证通过,可以正常使用<\/p><\/div>\n<div id=\"testFail\" style=\"display:none\"><div style=\"font-size:36px\">❌<\/div><p style=\"margin-top:8px;font-size:14px;font-weight:600;color:var(--err)\">连通失败<\/p><p style=\"font-size:12px;color:var(--sub);margin-top:4px\">账号或密码错误,请检查后重试<\/p><\/div>\n<\/div><div class=\"mf\"><button class=\"btn btn-g\" onclick=\"closeM('modal-test')\">关闭<\/button><\/div><\/div><\/div>\n\n<!-- Modal: 确认删除 -->\n<div class=\"mo\" id=\"modal-del\"><div class=\"mc\" style=\"max-width:400px\"><div class=\"mh\"><h3>⚠️ 确认删除<\/h3><button class=\"mx\" onclick=\"closeM('modal-del')\">✕<\/button><\/div><div class=\"mb\" style=\"text-align:center;padding:20px\"><div style=\"font-size:36px;margin-bottom:8px\">🗑️<\/div><p style=\"font-size:13px;font-weight:600\">确定删除该平台产品账号?<\/p><p style=\"font-size:11px;color:var(--sub);margin-top:4px\">有运行中任务引用的账号不可删除<\/p><\/div><div class=\"mf\"><button class=\"btn btn-g\" onclick=\"closeM('modal-del')\">取消<\/button><button class=\"btn btn-d\" onclick=\"closeM('modal-del');showT('✅ 已删除','ok')\">确认删除<\/button><\/div><\/div><\/div>\n\n<div class=\"layout\">\n<aside class=\"side\">\n<div class=\"logo\">🤖 Agent任务系统 v2.1<\/div>\n<div class=\"ni\">🏠 首页<\/div>\n<div class=\"ng-t\">权限管理<\/div><div class=\"ni\">· 组织架构<\/div><div class=\"ni\">· 菜单管理<\/div><div class=\"ni\">· 角色管理<\/div><div class=\"ni\">· 用户管理<\/div>\n<div class=\"ng-t\">产品管理<\/div><div class=\"ni\">· 产品列表<\/div><div class=\"ni\">· 渠道码<\/div><div class=\"ni\">· 平台套件<\/div>\n<div class=\"ng-t\">平台产品账号<\/div><div class=\"ni ac\">· 账号管理<\/div>\n<div class=\"ng-t\">Skill中心<\/div><div class=\"ni\">· Skill列表<\/div><div class=\"ni\">· 调用日志<\/div>\n<div class=\"ng-t\">任务中心<\/div><div class=\"ni\">· 任务创建<\/div><div class=\"ni\">· 任务列表<\/div>\n<div class=\"ng-t\">日志/设置<\/div><div class=\"ni\">· 操作日志<\/div><div class=\"ni\">· 系统设置<\/div>\n<\/aside>\n<div class=\"main\">\n<div class=\"hd\"><div>🔐 平台产品账号 / <b style=\"color:var(--txt)\">账号管理<\/b><\/div><div style=\"display:flex;align-items:center;gap:10px\"><span>🔔<\/span><span>张三<\/span><div style=\"width:28px;height:28px;border-radius:50%;background:var(--pri);color:#fff;display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:600\">张<\/div><\/div><\/div>\n<div class=\"ct\">\n<h1 class=\"pt\">平台产品账号管理<\/h1>\n<p class=\"pd\">v2.1变更:归属用户 · 选择平台→自动带出地址→选择产品代号→填写登录凭据 · 联动产品管理数据<\/p>\n\n<div class=\"note\">⚠️ <b>v2.1变更<\/b>:平台产品账号归属于<b>用户<\/b>(非角色),用户自行管理各平台的产品登录凭据。管理员可查看所有用户的账号。<\/div>\n\n<div class=\"stat\">\n<div class=\"stat-c\"><div class=\"sv\">12<\/div><div class=\"sl2\">我的账号总数<\/div><\/div>\n<div class=\"stat-c\"><div class=\"sv\" style=\"color:var(--ok)\">10<\/div><div class=\"sl2\">启用中<\/div><\/div>\n<div class=\"stat-c\"><div class=\"sv\" style=\"color:var(--err)\">2<\/div><div class=\"sl2\">已禁用<\/div><\/div>\n<div class=\"stat-c\"><div class=\"sv\" style=\"color:var(--pri)\">4<\/div><div class=\"sl2\">覆盖平台<\/div><\/div>\n<\/div>\n\n<div class=\"tb\">\n<div class=\"sb\"><span>🔍<\/span><input placeholder=\"搜索账号/产品代号\" id=\"sInput\" oninput=\"filterT()\"><\/div>\n<select class=\"sl\" id=\"fPlat\" onchange=\"filterT()\"><option value=\"\">全部平台<\/option><option value=\"小红书\">小红书<\/option><option value=\"抖音\">抖音<\/option><option value=\"Facebook\">Facebook<\/option><option value=\"TikTok\">TikTok<\/option><\/select>\n<select class=\"sl\" id=\"fSt\" onchange=\"filterT()\"><option value=\"\">全部状态<\/option><option value=\"启用\">启用<\/option><option value=\"禁用\">禁用<\/option><\/select>\n<button class=\"btn btn-p\" style=\"margin-left:auto\" onclick=\"openAdd()\">+ 添加平台产品账号<\/button>\n<\/div>\n\n<div class=\"tw\"><table>\n<thead><tr><th>平台<\/th><th>平台地址<\/th><th>产品代号<\/th><th>产品名称<\/th><th>登录账号<\/th><th>登录密码<\/th><th>谷歌密钥<\/th><th>状态<\/th><th>操作<\/th><\/tr><\/thead>\n<tbody id=\"atb\">\n<tr data-plat=\"小红书\" data-st=\"启用\" data-q=\"xhs_user01 PROD001 美妆种草达人\"><td><span class=\"tg tg-e\" style=\"background:#ffe4e6;color:#be123c\">📕 小红书<\/span><\/td><td style=\"font-size:11px\">pro.xiaohongshu.com<\/td><td><code>PROD001<\/code><\/td><td>美妆种草达人<\/td><td>xhs_user01<\/td><td>••••••••<\/td><td>••••5A2F<\/td><td><span class=\"tg tg-ok\">启用<\/span><\/td><td><button class=\"btn-l\" onclick=\"openEdit('小红书','PROD001','xhs_user01')\">编辑<\/button> <button class=\"btn-l\" onclick=\"doTest(true)\">测试<\/button> <button class=\"btn-l\" style=\"color:var(--err)\" onclick=\"openM('modal-del')\">删除<\/button><\/td><\/tr>\n<tr data-plat=\"小红书\" data-st=\"启用\" data-q=\"xhs_user02 PROD002 护肤品评测\"><td><span class=\"tg tg-e\" style=\"background:#ffe4e6;color:#be123c\">📕 小红书<\/span><\/td><td style=\"font-size:11px\">pro.xiaohongshu.com<\/td><td><code>PROD002<\/code><\/td><td>护肤品评测<\/td><td>xhs_user02<\/td><td>••••••••<\/td><td>-<\/td><td><span class=\"tg tg-ok\">启用<\/span><\/td><td><button class=\"btn-l\" onclick=\"openEdit('小红书','PROD002','xhs_user02')\">编辑<\/button> <button class=\"btn-l\" onclick=\"doTest(true)\">测试<\/button> <button class=\"btn-l\" style=\"color:var(--err)\" onclick=\"openM('modal-del')\">删除<\/button><\/td><\/tr>\n<tr data-plat=\"抖音\" data-st=\"启用\" data-q=\"dy_admin01 PROD003 抖音带货王\"><td><span class=\"tg tg-i\">🎵 抖音<\/span><\/td><td style=\"font-size:11px\">business.douyin.com<\/td><td><code>PROD003<\/code><\/td><td>抖音带货王<\/td><td>dy_admin01<\/td><td>••••••••<\/td><td>••••8B3D<\/td><td><span class=\"tg tg-ok\">启用<\/span><\/td><td><button class=\"btn-l\" onclick=\"openEdit('抖音','PROD003','dy_admin01')\">编辑<\/button> <button class=\"btn-l\" onclick=\"doTest(true)\">测试<\/button> <button class=\"btn-l\" style=\"color:var(--err)\" onclick=\"openM('modal-del')\">删除<\/button><\/td><\/tr>\n<tr data-plat=\"抖音\" data-st=\"启用\" data-q=\"dy_ops02 PROD004 短视频营销\"><td><span class=\"tg tg-i\">🎵 抖音<\/span><\/td><td style=\"font-size:11px\">business.douyin.com<\/td><td><code>PROD004<\/code><\/td><td>短视频营销<\/td><td>dy_ops02<\/td><td>••••••••<\/td><td>-<\/td><td><span class=\"tg tg-ok\">启用<\/span><\/td><td><button class=\"btn-l\" onclick=\"openEdit('抖音','PROD004','dy_ops02')\">编辑<\/button> <button class=\"btn-l\" onclick=\"doTest(false)\">测试<\/button> <button class=\"btn-l\" style=\"color:var(--err)\" onclick=\"openM('modal-del')\">删除<\/button><\/td><\/tr>\n<tr data-plat=\"Facebook\" data-st=\"启用\" data-q=\"fb_ads_01 PROD006 海外社媒投放\"><td><span class=\"tg tg-p\">📘 Facebook<\/span><\/td><td style=\"font-size:11px\">business.facebook.com<\/td><td><code>PROD006<\/code><\/td><td>海外社媒投放<\/td><td>fb_ads_01<\/td><td>••••••••<\/td><td>••••C71E<\/td><td><span class=\"tg tg-ok\">启用<\/span><\/td><td><button class=\"btn-l\" onclick=\"openEdit('Facebook','PROD006','fb_ads_01')\">编辑<\/button> <button class=\"btn-l\" onclick=\"doTest(true)\">测试<\/button> <button class=\"btn-l\" style=\"color:var(--err)\" onclick=\"openM('modal-del')\">删除<\/button><\/td><\/tr>\n<tr data-plat=\"TikTok\" data-st=\"禁用\" data-q=\"tt_creator PROD007 TikTok达人推广\"><td><span class=\"tg tg-w\">🎶 TikTok<\/span><\/td><td style=\"font-size:11px\">ads.tiktok.com<\/td><td><code>PROD007<\/code><\/td><td>TikTok达人推广<\/td><td>tt_creator<\/td><td>••••••••<\/td><td>-<\/td><td><span class=\"tg tg-e\">禁用<\/span><\/td><td><button class=\"btn-l\" onclick=\"openEdit('TikTok','PROD007','tt_creator')\">编辑<\/button> <button class=\"btn-l\" onclick=\"doTest(false)\">测试<\/button> <button class=\"btn-l\" style=\"color:var(--err)\" onclick=\"openM('modal-del')\">删除<\/button><\/td><\/tr>\n<\/tbody>\n<\/table><\/div>\n<div class=\"pg\"><span>共 6 条<\/span><div><span class=\"pgb ac\">1<\/span><\/div><\/div>\n\n<\/div><\/div><\/div>\n\n<script>\nconst PLAT_INFO={xhs:{name:'小红书',url:'pro.xiaohongshu.com',products:['PROD001 — 美妆种草达人','PROD002 — 护肤品评测']},dy:{name:'抖音',url:'business.douyin.com',products:['PROD003 — 抖音带货王','PROD004 — 短视频营销']},wx:{name:'微信公众号',url:'mp.weixin.qq.com',products:['PROD005 — 品牌公众号']},wb:{name:'微博',url:'weibo.com',products:['PROD008 — 微博话题营销']},fb:{name:'Facebook',url:'business.facebook.com',products:['PROD006 — 海外社媒投放']},tt:{name:'TikTok',url:'ads.tiktok.com',products:['PROD007 — TikTok达人推广']}};\n\nfunction openM(id){document.getElementById(id).classList.add('show')}\nfunction closeM(id){document.getElementById(id).classList.remove('show')}\nfunction showT(m,t){const e=document.getElementById('toast');e.textContent=m;e.className='toast show '+t;setTimeout(()=>e.className='toast',2500)}\n\nfunction onPlatChange(val){\n const info=PLAT_INFO[val];\n const nameF=document.getElementById('ma-platname');\n const urlF=document.getElementById('ma-platurl');\n const prodS=document.getElementById('ma-product');\n if(!info){nameF.value='';urlF.value='';prodS.innerHTML='<option value=\"\">请先选择平台<\/option>';prodS.disabled=true;return}\n nameF.value=info.name;\n urlF.value=info.url;\n prodS.disabled=false;\n prodS.innerHTML='<option value=\"\">请选择产品代号<\/option>'+info.products.map(p=>`<option>${p}<\/option>`).join('');\n showT('✅ 已加载 '+info.name+' 平台信息','ok');\n}\n\nfunction openAdd(){\n document.getElementById('maTitle').textContent='添加平台产品账号';\n document.getElementById('ma-plat').value='';\n document.getElementById('ma-platname').value='';\n document.getElementById('ma-platurl').value='';\n document.getElementById('ma-product').innerHTML='<option value=\"\">请先选择平台<\/option>';\n document.getElementById('ma-product').disabled=true;\n document.getElementById('ma-login').value='';\n document.getElementById('ma-pwd').value='';\n document.getElementById('ma-gkey').value='';\n openM('modal-acc');\n}\n\nfunction openEdit(plat,code,login){\n document.getElementById('maTitle').textContent='编辑平台产品账号';\n const platKey=Object.keys(PLAT_INFO).find(k=>PLAT_INFO[k].name===plat);\n if(platKey){\n document.getElementById('ma-plat').value=platKey;\n onPlatChange(platKey);\n }\n document.getElementById('ma-login').value=login;\n document.getElementById('ma-pwd').value='••••••••';\n document.getElementById('ma-gkey').value='';\n openM('modal-acc');\n}\n\nfunction saveAcc(){\n const plat=document.getElementById('ma-plat').value;\n const prod=document.getElementById('ma-product').value;\n const login=document.getElementById('ma-login').value;\n const pwd=document.getElementById('ma-pwd').value;\n if(!plat){showT('请选择平台','er');return}\n if(!prod){showT('请选择产品代号','er');return}\n if(!login){showT('请输入登录账号','er');return}\n if(!pwd){showT('请输入登录密码','er');return}\n closeM('modal-acc');showT('✅ 保存成功','ok');\n}\n\nfunction togglePwd(id,btn){\n const f=document.getElementById(id);\n if(f.type==='password'){f.type='text';btn.textContent='🙈'}\n else{f.type='password';btn.textContent='👁️'}\n}\n\nfunction doTest(success){\n openM('modal-test');\n document.getElementById('testLoading').style.display='block';\n document.getElementById('testOk').style.display='none';\n document.getElementById('testFail').style.display='none';\n setTimeout(()=>{\n document.getElementById('testLoading').style.display='none';\n if(success){document.getElementById('testOk').style.display='block'}\n else{document.getElementById('testFail').style.display='block'}\n },1500);\n}\n\nfunction testConn(){\n const plat=document.getElementById('ma-plat').value;\n const login=document.getElementById('ma-login').value;\n if(!plat||!login){showT('请先填写平台和账号信息','er');return}\n doTest(Math.random()>0.3);\n}\n\nfunction filterT(){\n const q=document.getElementById('sInput').value.toLowerCase();\n const plat=document.getElementById('fPlat').value;\n const st=document.getElementById('fSt').value;\n document.querySelectorAll('#atb tr').forEach(tr=>{\n const d=tr.dataset;\n const show=(!q||d.q.toLowerCase().includes(q))&&(!plat||d.plat===plat)&&(!st||d.st===st);\n tr.style.display=show?'':'none';\n });\n}\n\ndocument.querySelectorAll('.mo').forEach(m=>m.addEventListener('click',e=>{if(e.target===m)m.classList.remove('show')}));\n<\/script>\n<style>@keyframes spin{from{transform:rotate(0)}to{transform:rotate(360deg)}}<\/style>\n<\/body><\/html>\n",
|
||
"09_Skill管理.html": "<!DOCTYPE html><html lang=\"zh-CN\"><head><script>if(window!==window.top)document.documentElement.classList.add(\"in-iframe\")<\/script><style>.in-iframe .side{display:none!important}.in-iframe .main{margin-left:0!important}.in-iframe .layout{min-height:auto}<\/style><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1.0\"><title>Agent任务系统 v2.1 - Skill管理<\/title>\n<style>\n*{margin:0;padding:0;box-sizing:border-box}:root{--pri:#6366f1;--bg:#f1f5f9;--card:#fff;--txt:#1e293b;--sub:#64748b;--bdr:#e2e8f0;--ok:#22c55e;--err:#ef4444;--warn:#f59e0b;--side:#1e293b}body{font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",\"PingFang SC\",\"Microsoft YaHei\",sans-serif;background:var(--bg);color:var(--txt);line-height:1.6;font-size:13px}\n.layout{display:flex;min-height:100vh}.side{width:220px;background:var(--side);color:#94a3b8;position:fixed;top:0;left:0;bottom:0;overflow-y:auto;z-index:100}.side .logo{padding:16px 18px;font-size:14px;font-weight:700;color:#fff;border-bottom:1px solid #334155}.ni{display:flex;align-items:center;gap:8px;padding:9px 18px;font-size:12px;color:#94a3b8;cursor:pointer;border-left:3px solid transparent}.ni:hover{background:#334155;color:#e2e8f0}.ni.ac{background:rgba(99,102,241,.15);color:#818cf8;border-left-color:#818cf8;font-weight:600}.ng-t{padding:10px 18px 4px;font-size:10px;letter-spacing:1px;color:#475569;font-weight:600}\n.main{margin-left:220px;flex:1}.hd{height:52px;background:var(--card);border-bottom:1px solid var(--bdr);display:flex;align-items:center;justify-content:space-between;padding:0 24px;font-size:12px;color:var(--sub);position:sticky;top:0;z-index:50}.ct{padding:24px}\n.pt{font-size:20px;font-weight:700;margin-bottom:4px}.pd{font-size:12px;color:var(--sub);margin-bottom:20px}\n.tb{display:flex;gap:8px;align-items:center;margin-bottom:14px;flex-wrap:wrap}.sb{display:flex;align-items:center;gap:6px;background:#f8fafc;border:1px solid var(--bdr);border-radius:7px;padding:7px 12px;font-size:12px}.sb input{border:none;background:none;outline:none;font-size:12px;width:140px}\n.sl{border:1px solid var(--bdr);border-radius:7px;padding:7px 12px;font-size:12px;background:#fff;cursor:pointer}\n.btn{padding:7px 16px;border-radius:7px;font-size:12px;font-weight:500;border:none;cursor:pointer;display:inline-flex;align-items:center;gap:5px;transition:all .12s}.btn-p{background:var(--pri);color:#fff}.btn-p:hover{background:#4f46e5}.btn-d{background:#fee2e2;color:#dc2626}.btn-g{background:transparent;color:var(--sub);border:1px solid var(--bdr)}.btn-sm{padding:5px 10px;font-size:11px}.btn-s{background:var(--ok);color:#fff}.btn-w{background:var(--warn);color:#fff}\n.btn-l{background:none;border:none;color:var(--pri);padding:0;font-size:12px;cursor:pointer}.btn-l:hover{text-decoration:underline}\n.tg{display:inline-block;padding:2px 8px;border-radius:99px;font-size:10px;font-weight:600}.tg-ok{background:#dcfce7;color:#166534}.tg-e{background:#fee2e2;color:#991b1b}.tg-i{background:#dbeafe;color:#1e40af}.tg-p{background:#f3e8ff;color:#6b21a8}.tg-g{background:#f1f5f9;color:#64748b}.tg-w{background:#fef3c7;color:#92400e}\ntable{width:100%;border-collapse:collapse;font-size:12px}th,td{padding:8px 12px;text-align:left;border-bottom:1px solid var(--bdr)}th{background:#f8fafc;font-weight:600;color:var(--sub);font-size:11px}tr:hover td{background:#fafbfc}.tw{overflow-x:auto;border:1px solid var(--bdr);border-radius:8px}\n.fg{margin-bottom:14px}.fl{font-size:12px;font-weight:500;margin-bottom:5px;display:block}.fl .rq{color:var(--err)}.fi{width:100%;padding:8px 12px;border:1px solid var(--bdr);border-radius:7px;font-size:12px;outline:none}.fi:focus{border-color:var(--pri)}.fs{width:100%;padding:8px 12px;border:1px solid var(--bdr);border-radius:7px;font-size:12px;background:#fff}.fr{display:grid;grid-template-columns:1fr 1fr;gap:14px}\n.mo{position:fixed;inset:0;background:rgba(0,0,0,.45);display:none;align-items:center;justify-content:center;z-index:200}.mo.show{display:flex}.mc{background:var(--card);border-radius:14px;width:90%;max-width:720px;max-height:88vh;overflow-y:auto;box-shadow:0 20px 60px rgba(0,0,0,.2)}.mh{padding:14px 20px;border-bottom:1px solid var(--bdr);display:flex;justify-content:space-between;align-items:center}.mh h3{font-size:15px}.mx{cursor:pointer;font-size:18px;color:var(--sub);background:none;border:none}.mb{padding:20px}.mf{padding:14px 20px;border-top:1px solid var(--bdr);display:flex;justify-content:flex-end;gap:8px}\n.toast{position:fixed;top:20px;right:20px;padding:12px 20px;border-radius:8px;font-size:13px;font-weight:500;z-index:300;display:none}.toast.show{display:block;animation:tIn .3s}.toast.ok{background:#dcfce7;color:#166534}.toast.er{background:#fee2e2;color:#991b1b}@keyframes tIn{from{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}\n.tabs{display:flex;gap:0;border-bottom:2px solid var(--bdr);margin-bottom:16px}.tab{padding:10px 20px;font-size:13px;font-weight:500;color:var(--sub);cursor:pointer;border-bottom:2px solid transparent;margin-bottom:-2px}.tab.ac{color:var(--pri);border-bottom-color:var(--pri);font-weight:600}.tab:hover{color:var(--txt)}\n.stat{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;margin-bottom:16px}.stat-c{background:var(--card);border:1px solid var(--bdr);border-radius:10px;padding:14px 16px}.stat-c .sv{font-size:22px;font-weight:700}.stat-c .sl2{font-size:11px;color:var(--sub)}\n.note{background:#eff6ff;border-left:3px solid var(--pri);padding:8px 12px;border-radius:0 6px 6px 0;font-size:11px;color:var(--sub);margin-bottom:14px}\n.exec-box{border:2px solid var(--bdr);border-radius:10px;padding:14px;margin-bottom:14px;transition:border .2s}.exec-box.active{border-color:var(--pri);background:#faf5ff}\n.exec-radio{display:flex;gap:12px;margin-bottom:14px}.er-item{flex:1;border:2px solid var(--bdr);border-radius:10px;padding:14px;cursor:pointer;text-align:center;transition:all .15s}.er-item:hover{border-color:#a5b4fc}.er-item.sel{border-color:var(--pri);background:#ede9fe}.er-item .er-icon{font-size:28px;margin-bottom:6px}.er-item .er-t{font-size:13px;font-weight:600}.er-item .er-d{font-size:10px;color:var(--sub)}\n.param-row{display:flex;gap:8px;align-items:center;padding:8px;border:1px solid var(--bdr);border-radius:6px;margin-bottom:6px;font-size:12px}\n.json-area{width:100%;min-height:100px;padding:10px;border:1px solid var(--bdr);border-radius:7px;font-size:11px;font-family:monospace;resize:vertical}\n.test-log{background:#1e293b;color:#a5f3fc;padding:12px;border-radius:8px;font-family:monospace;font-size:11px;max-height:200px;overflow-y:auto;margin-top:10px}\n.ms-wrap{position:relative}.multi-select{display:flex;flex-wrap:wrap;gap:4px;padding:6px 10px;border:1px solid var(--bdr);border-radius:7px;min-height:36px;cursor:pointer;font-size:11px}.ms-tag{background:#ede9fe;color:#6b21a8;padding:2px 6px;border-radius:3px;display:flex;align-items:center;gap:3px}.ms-tag .x{cursor:pointer;font-weight:700}.ms-drop{position:absolute;top:100%;left:0;right:0;background:var(--card);border:1px solid var(--bdr);border-radius:7px;box-shadow:0 4px 12px rgba(0,0,0,.1);z-index:10;max-height:180px;overflow-y:auto;display:none}.ms-drop.show{display:block}.ms-opt{padding:6px 10px;font-size:11px;cursor:pointer}.ms-opt:hover{background:#f1f5f9}.ms-opt.sel{background:#ede9fe}\n<\/style><\/head><body>\n<div class=\"toast\" id=\"toast\"><\/div>\n\n<!-- Modal: 注册/编辑Skill -->\n<div class=\"mo\" id=\"modal-skill\"><div class=\"mc\"><div class=\"mh\"><h3 id=\"msTitle\">注册Skill<\/h3><button class=\"mx\" onclick=\"closeM('modal-skill')\">✕<\/button><\/div><div class=\"mb\">\n\n<div class=\"tabs\" id=\"skillTabs\"><div class=\"tab ac\" onclick=\"switchST(0)\">基本信息<\/div><div class=\"tab\" onclick=\"switchST(1)\">执行器配置<\/div><div class=\"tab\" onclick=\"switchST(2)\">产品范围<\/div><div class=\"tab\" onclick=\"switchST(3)\">参数映射<\/div><div class=\"tab\" onclick=\"switchST(4)\">测试台<\/div><\/div>\n\n<!-- Tab0: 基本信息 -->\n<div class=\"st-ct\" id=\"st0\">\n<div class=\"fr\"><div class=\"fg\"><label class=\"fl\">Skill名称 <span class=\"rq\">*<\/span><\/label><input class=\"fi\" id=\"ms-name\" placeholder=\"如 小红书笔记发布\"><\/div>\n<div class=\"fg\"><label class=\"fl\">分类<\/label><select class=\"fs\"><option>内容发布<\/option><option>数据采集<\/option><option>账号运营<\/option><option>广告投放<\/option><option>数据分析<\/option><\/select><\/div><\/div>\n<div class=\"fg\"><label class=\"fl\">描述<\/label><textarea class=\"fi\" rows=\"2\" placeholder=\"Skill功能描述\"><\/textarea><\/div>\n<div class=\"fg\"><label class=\"fl\">执行器类型 <span class=\"rq\">*<\/span> (RB-13)<\/label>\n<div class=\"exec-radio\"><div class=\"er-item sel\" onclick=\"selExec('lobster')\"><div class=\"er-icon\">🦞<\/div><div class=\"er-t\">龙虾执行器<\/div><div class=\"er-d\">第三方Agent平台<\/div><\/div><div class=\"er-item\" onclick=\"selExec('script')\"><div class=\"er-icon\">📜<\/div><div class=\"er-t\">脚本执行器<\/div><div class=\"er-d\">系统预置模板<\/div><\/div><\/div>\n<\/div><\/div>\n\n<!-- Tab1: 执行器配置 -->\n<div class=\"st-ct\" id=\"st1\" style=\"display:none\">\n<div id=\"lobsterConfig\">\n<div class=\"note\">🦞 龙虾执行器:配置第三方Agent平台连接参数<\/div>\n<div class=\"fg\"><label class=\"fl\">API地址 <span class=\"rq\">*<\/span><\/label><input class=\"fi\" placeholder=\"https://api.lobster-agent.com/v1\" value=\"https://api.lobster-agent.com/v1\"><\/div>\n<div class=\"fr\"><div class=\"fg\"><label class=\"fl\">API Key <span class=\"rq\">*<\/span><\/label><input class=\"fi\" type=\"password\" value=\"sk-lobster-xxxx\" id=\"lob-key\"><\/div>\n<div class=\"fg\"><label class=\"fl\">Agent ID <span class=\"rq\">*<\/span><\/label><input class=\"fi\" placeholder=\"agent_xxx\" value=\"agent_xhs_publish_01\"><\/div><\/div>\n<button class=\"btn btn-s btn-sm\" onclick=\"showT('✅ 龙虾平台连通成功','ok')\">🔌 测试连通性<\/button>\n<\/div>\n<div id=\"scriptConfig\" style=\"display:none\">\n<div class=\"note\">📜 脚本执行器:选择系统预置脚本模板<\/div>\n<div class=\"fg\"><label class=\"fl\">脚本模板 <span class=\"rq\">*<\/span><\/label><select class=\"fs\" id=\"scriptTpl\" onchange=\"onScriptTpl(this.value)\"><option value=\"\">请选择<\/option><option value=\"py1\">Python - 通用HTTP请求<\/option><option value=\"py2\">Python - 数据清洗脚本<\/option><option value=\"sh1\">Shell - 文件处理<\/option><option value=\"node1\">Node.js - API调用<\/option><\/select><\/div>\n<div class=\"fg\"><label class=\"fl\">环境变量<\/label><div id=\"envVars\"><div class=\"param-row\"><input class=\"fi\" style=\"width:120px\" value=\"API_KEY\" readonly><input class=\"fi\" style=\"flex:1\" placeholder=\"变量值\"><button class=\"btn-l\" style=\"color:var(--err)\" onclick=\"this.closest('.param-row').remove()\">✕<\/button><\/div><\/div><button class=\"btn btn-g btn-sm\" onclick=\"addEnv()\" style=\"margin-top:6px\">+ 添加变量<\/button><\/div>\n<div class=\"fr\"><div class=\"fg\"><label class=\"fl\">超时时间(秒)<\/label><input class=\"fi\" type=\"number\" value=\"30\"><\/div><div class=\"fg\"><label class=\"fl\">脚本类型<\/label><input class=\"fi\" value=\"python\" readonly id=\"scriptType\"><\/div><\/div>\n<\/div><\/div>\n\n<!-- Tab2: 产品范围 -->\n<div class=\"st-ct\" id=\"st2\" style=\"display:none\">\n<div class=\"note\">⚠️ Skill绑定产品范围,执行时 Skill.product_scope ∩ 用户角色.data_scope = 可用产品<\/div>\n<div class=\"fg\"><label class=\"fl\">绑定产品范围<\/label>\n<div class=\"ms-wrap\"><div class=\"multi-select\" id=\"prodSelect\" onclick=\"document.getElementById('prodDrop').classList.toggle('show')\"><span class=\"ms-tag\">PROD001 美妆种草达人 <span class=\"x\" onclick=\"event.stopPropagation();this.closest('.ms-tag').remove()\">×<\/span><\/span><span class=\"ms-tag\">PROD002 护肤品评测 <span class=\"x\" onclick=\"event.stopPropagation();this.closest('.ms-tag').remove()\">×<\/span><\/span><span class=\"ms-tag\">PROD003 抖音带货王 <span class=\"x\" onclick=\"event.stopPropagation();this.closest('.ms-tag').remove()\">×<\/span><\/span><\/div>\n<div class=\"ms-drop\" id=\"prodDrop\"><div class=\"ms-opt sel\" onclick=\"this.classList.toggle('sel')\">✓ PROD001 — 美妆种草达人<\/div><div class=\"ms-opt sel\" onclick=\"this.classList.toggle('sel')\">✓ PROD002 — 护肤品评测<\/div><div class=\"ms-opt sel\" onclick=\"this.classList.toggle('sel')\">✓ PROD003 — 抖音带货王<\/div><div class=\"ms-opt\" onclick=\"this.classList.toggle('sel')\">PROD004 — 短视频营销<\/div><div class=\"ms-opt\" onclick=\"this.classList.toggle('sel')\">PROD005 — 品牌公众号<\/div><div class=\"ms-opt\" onclick=\"this.classList.toggle('sel')\">PROD006 — 海外社媒投放<\/div><\/div><\/div><\/div>\n<\/div>\n\n<!-- Tab3: 参数映射 -->\n<div class=\"st-ct\" id=\"st3\" style=\"display:none\">\n<div class=\"fg\"><label class=\"fl\">inputSchema (JSON Schema)<\/label>\n<textarea class=\"json-area\" id=\"schemaArea\">{\n \"type\": \"object\",\n \"properties\": {\n \"product_id\": {\"type\": \"string\", \"title\": \"产品\", \"x-component\": \"ProductSelector\"},\n \"content\": {\"type\": \"string\", \"title\": \"发布内容\"},\n \"tags\": {\"type\": \"array\", \"title\": \"标签\", \"items\": {\"type\": \"string\"}}\n },\n \"required\": [\"product_id\", \"content\"]\n}<\/textarea><\/div>\n<div class=\"fg\"><label class=\"fl\">参数映射<\/label>\n<div id=\"paramMap\">\n<div class=\"param-row\"><span style=\"width:120px\">product_id<\/span><span>→<\/span><input class=\"fi\" style=\"flex:1\" value=\"{{product.code}}\"><select class=\"sl\" style=\"width:100px\"><option>表达式<\/option><option>常量<\/option><\/select><\/div>\n<div class=\"param-row\"><span style=\"width:120px\">content<\/span><span>→<\/span><input class=\"fi\" style=\"flex:1\" value=\"{{input.content}}\"><select class=\"sl\" style=\"width:100px\"><option>表达式<\/option><option>常量<\/option><\/select><\/div>\n<div class=\"param-row\"><span style=\"width:120px\">tags<\/span><span>→<\/span><input class=\"fi\" style=\"flex:1\" value=\"{{input.tags}}\"><select class=\"sl\" style=\"width:100px\"><option>表达式<\/option><option>常量<\/option><\/select><\/div>\n<\/div><\/div><\/div>\n\n<!-- Tab4: 测试台 -->\n<div class=\"st-ct\" id=\"st4\" style=\"display:none\">\n<div class=\"note\">⚠️ 仅管理员可用测试台<\/div>\n<div class=\"fg\"><label class=\"fl\">测试参数 (JSON)<\/label>\n<textarea class=\"json-area\" rows=\"4\">{\n \"product_id\": \"PROD001\",\n \"content\": \"测试发布内容\",\n \"tags\": [\"美妆\", \"种草\"]\n}<\/textarea><\/div>\n<button class=\"btn btn-p\" onclick=\"runTest()\">▶️ 执行测试<\/button>\n<div class=\"test-log\" id=\"testLog\" style=\"display:none\">\n<div>> 正在连接龙虾执行器...<\/div>\n<div style=\"color:#fbbf24\">> 提交任务到 agent_xhs_publish_01<\/div>\n<div>> 任务ID: task_20260423_001<\/div>\n<div>> 状态: RUNNING → RUNNING → SUCCEEDED<\/div>\n<div style=\"color:#4ade80\">> ✅ 执行成功,耗时 3.2s<\/div>\n<div>> 输出: {\"status\":\"published\",\"post_id\":\"xhs_98765\"}<\/div>\n<\/div><\/div>\n\n<\/div><div class=\"mf\"><button class=\"btn btn-g\" onclick=\"closeM('modal-skill')\">取消<\/button><button class=\"btn btn-p\" onclick=\"closeM('modal-skill');showT('✅ Skill已保存','ok')\">保存<\/button><\/div><\/div><\/div>\n\n<!-- Modal: 删除 -->\n<div class=\"mo\" id=\"modal-del\"><div class=\"mc\" style=\"max-width:400px\"><div class=\"mh\"><h3>⚠️ 确认删除<\/h3><button class=\"mx\" onclick=\"closeM('modal-del')\">✕<\/button><\/div><div class=\"mb\" style=\"text-align:center;padding:20px\"><div style=\"font-size:36px\">🗑️<\/div><p style=\"font-size:13px;font-weight:600;margin-top:8px\">确定删除该Skill?<\/p><p style=\"font-size:11px;color:var(--sub);margin-top:4px\">已有角色引用的Skill需先解除关联<\/p><\/div><div class=\"mf\"><button class=\"btn btn-g\" onclick=\"closeM('modal-del')\">取消<\/button><button class=\"btn btn-d\" onclick=\"closeM('modal-del');showT('✅ 已删除','ok')\">确认删除<\/button><\/div><\/div><\/div>\n\n<div class=\"layout\">\n<aside class=\"side\">\n<div class=\"logo\">🤖 Agent任务系统 v2.1<\/div>\n<div class=\"ni\">🏠 首页<\/div>\n<div class=\"ng-t\">权限管理<\/div><div class=\"ni\">· 组织架构<\/div><div class=\"ni\">· 菜单管理<\/div><div class=\"ni\">· 角色管理<\/div><div class=\"ni\">· 用户管理<\/div>\n<div class=\"ng-t\">产品管理<\/div><div class=\"ni\">· 产品列表<\/div><div class=\"ni\">· 渠道码<\/div><div class=\"ni\">· 平台套件<\/div>\n<div class=\"ng-t\">平台产品账号<\/div><div class=\"ni\">· 账号管理<\/div>\n<div class=\"ng-t\">Skill中心<\/div><div class=\"ni ac\">· Skill列表<\/div><div class=\"ni\">· 调用日志<\/div>\n<div class=\"ng-t\">任务中心<\/div><div class=\"ni\">· 任务创建<\/div><div class=\"ni\">· 任务列表<\/div>\n<div class=\"ng-t\">日志/设置<\/div><div class=\"ni\">· 操作日志<\/div><div class=\"ni\">· 系统设置<\/div>\n<\/aside>\n<div class=\"main\">\n<div class=\"hd\"><div>🧠 Skill中心 / <b style=\"color:var(--txt)\">Skill列表<\/b><\/div><div style=\"display:flex;align-items:center;gap:10px\"><span>🔔<\/span><span>admin<\/span><div style=\"width:28px;height:28px;border-radius:50%;background:var(--pri);color:#fff;display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:600\">A<\/div><\/div><\/div>\n<div class=\"ct\">\n<h1 class=\"pt\">Skill管理<\/h1>\n<p class=\"pd\">双执行器(龙虾🦞+脚本📜)· 产品范围绑定 · 参数映射 · 测试台<\/p>\n\n<div class=\"stat\">\n<div class=\"stat-c\"><div class=\"sv\">18<\/div><div class=\"sl2\">Skill总数<\/div><\/div>\n<div class=\"stat-c\"><div class=\"sv\" style=\"color:#dc2626\">🦞 12<\/div><div class=\"sl2\">龙虾执行器<\/div><\/div>\n<div class=\"stat-c\"><div class=\"sv\" style=\"color:var(--pri)\">📜 6<\/div><div class=\"sl2\">脚本执行器<\/div><\/div>\n<div class=\"stat-c\"><div class=\"sv\" style=\"color:var(--ok)\">16<\/div><div class=\"sl2\">启用中<\/div><\/div>\n<\/div>\n\n<div class=\"tb\">\n<div class=\"sb\"><span>🔍<\/span><input placeholder=\"搜索Skill名称\" id=\"sInput\" oninput=\"filterT()\"><\/div>\n<select class=\"sl\" id=\"fCat\" onchange=\"filterT()\"><option value=\"\">全部分类<\/option><option value=\"内容发布\">内容发布<\/option><option value=\"数据采集\">数据采集<\/option><option value=\"账号运营\">账号运营<\/option><option value=\"广告投放\">广告投放<\/option><\/select>\n<select class=\"sl\" id=\"fExec\" onchange=\"filterT()\"><option value=\"\">全部执行器<\/option><option value=\"lobster\">🦞 龙虾<\/option><option value=\"script\">📜 脚本<\/option><\/select>\n<select class=\"sl\" id=\"fSt\" onchange=\"filterT()\"><option value=\"\">全部状态<\/option><option value=\"启用\">启用<\/option><option value=\"禁用\">禁用<\/option><\/select>\n<button class=\"btn btn-p\" style=\"margin-left:auto\" onclick=\"openAdd()\">+ 注册Skill<\/button>\n<\/div>\n\n<div class=\"tw\"><table><thead><tr><th>Skill名称<\/th><th>分类<\/th><th>执行器<\/th><th>产品范围<\/th><th>调用次数<\/th><th>成功率<\/th><th>状态<\/th><th>操作<\/th><\/tr><\/thead>\n<tbody id=\"stb\">\n<tr data-q=\"小红书笔记发布\" data-cat=\"内容发布\" data-exec=\"lobster\" data-st=\"启用\"><td><b>小红书笔记发布<\/b><\/td><td><span class=\"tg tg-i\">内容发布<\/span><\/td><td><span class=\"tg tg-e\" style=\"background:#fef2f2;color:#dc2626\">🦞 龙虾<\/span><\/td><td>3个产品<\/td><td>1,256<\/td><td><span style=\"color:var(--ok);font-weight:600\">98.2%<\/span><\/td><td><span class=\"tg tg-ok\">启用<\/span><\/td><td><button class=\"btn-l\" onclick=\"openEdit('小红书笔记发布')\">编辑<\/button> <button class=\"btn-l\" style=\"color:var(--err)\" onclick=\"openM('modal-del')\">删除<\/button><\/td><\/tr>\n<tr data-q=\"抖音视频上传\" data-cat=\"内容发布\" data-exec=\"lobster\" data-st=\"启用\"><td><b>抖音视频上传<\/b><\/td><td><span class=\"tg tg-i\">内容发布<\/span><\/td><td><span class=\"tg tg-e\" style=\"background:#fef2f2;color:#dc2626\">🦞 龙虾<\/span><\/td><td>2个产品<\/td><td>892<\/td><td><span style=\"color:var(--ok);font-weight:600\">96.5%<\/span><\/td><td><span class=\"tg tg-ok\">启用<\/span><\/td><td><button class=\"btn-l\" onclick=\"openEdit('抖音视频上传')\">编辑<\/button> <button class=\"btn-l\" style=\"color:var(--err)\" onclick=\"openM('modal-del')\">删除<\/button><\/td><\/tr>\n<tr data-q=\"竞品数据采集\" data-cat=\"数据采集\" data-exec=\"script\" data-st=\"启用\"><td><b>竞品数据采集<\/b><\/td><td><span class=\"tg tg-p\">数据采集<\/span><\/td><td><span class=\"tg tg-p\">📜 脚本<\/span><\/td><td>5个产品<\/td><td>3,401<\/td><td><span style=\"color:var(--ok);font-weight:600\">99.1%<\/span><\/td><td><span class=\"tg tg-ok\">启用<\/span><\/td><td><button class=\"btn-l\" onclick=\"openEdit('竞品数据采集')\">编辑<\/button> <button class=\"btn-l\" style=\"color:var(--err)\" onclick=\"openM('modal-del')\">删除<\/button><\/td><\/tr>\n<tr data-q=\"Facebook广告投放\" data-cat=\"广告投放\" data-exec=\"lobster\" data-st=\"启用\"><td><b>Facebook广告投放<\/b><\/td><td><span class=\"tg tg-w\">广告投放<\/span><\/td><td><span class=\"tg tg-e\" style=\"background:#fef2f2;color:#dc2626\">🦞 龙虾<\/span><\/td><td>1个产品<\/td><td>567<\/td><td><span style=\"color:var(--warn);font-weight:600\">89.3%<\/span><\/td><td><span class=\"tg tg-ok\">启用<\/span><\/td><td><button class=\"btn-l\" onclick=\"openEdit('Facebook广告投放')\">编辑<\/button> <button class=\"btn-l\" style=\"color:var(--err)\" onclick=\"openM('modal-del')\">删除<\/button><\/td><\/tr>\n<tr data-q=\"数据清洗脚本\" data-cat=\"数据采集\" data-exec=\"script\" data-st=\"启用\"><td><b>数据清洗脚本<\/b><\/td><td><span class=\"tg tg-p\">数据采集<\/span><\/td><td><span class=\"tg tg-p\">📜 脚本<\/span><\/td><td>全部产品<\/td><td>5,123<\/td><td><span style=\"color:var(--ok);font-weight:600\">99.8%<\/span><\/td><td><span class=\"tg tg-ok\">启用<\/span><\/td><td><button class=\"btn-l\" onclick=\"openEdit('数据清洗脚本')\">编辑<\/button> <button class=\"btn-l\" style=\"color:var(--err)\" onclick=\"openM('modal-del')\">删除<\/button><\/td><\/tr>\n<tr data-q=\"TikTok达人匹配\" data-cat=\"账号运营\" data-exec=\"lobster\" data-st=\"禁用\"><td><b>TikTok达人匹配<\/b><\/td><td><span class=\"tg tg-ok\" style=\"background:#dcfce7;color:#166534\">账号运营<\/span><\/td><td><span class=\"tg tg-e\" style=\"background:#fef2f2;color:#dc2626\">🦞 龙虾<\/span><\/td><td>1个产品<\/td><td>45<\/td><td><span style=\"color:var(--err);font-weight:600\">72.0%<\/span><\/td><td><span class=\"tg tg-e\">禁用<\/span><\/td><td><button class=\"btn-l\" onclick=\"openEdit('TikTok达人匹配')\">编辑<\/button> <button class=\"btn-l\" style=\"color:var(--err)\" onclick=\"openM('modal-del')\">删除<\/button><\/td><\/tr>\n<\/tbody><\/table><\/div>\n\n<\/div><\/div><\/div>\n\n<script>\nlet curExec='lobster';\nfunction openM(id){document.getElementById(id).classList.add('show')}\nfunction closeM(id){document.getElementById(id).classList.remove('show')}\nfunction showT(m,t){const e=document.getElementById('toast');e.textContent=m;e.className='toast show '+t;setTimeout(()=>e.className='toast',2500)}\n\nfunction switchST(i){document.querySelectorAll('#skillTabs .tab').forEach((t,j)=>t.classList.toggle('ac',j===i));document.querySelectorAll('.st-ct').forEach((c,j)=>{c.style.display=j===i?'block':'none'})}\n\nfunction selExec(type){\n curExec=type;\n document.querySelectorAll('.er-item').forEach(e=>e.classList.remove('sel'));\n event.currentTarget.classList.add('sel');\n document.getElementById('lobsterConfig').style.display=type==='lobster'?'block':'none';\n document.getElementById('scriptConfig').style.display=type==='script'?'block':'none';\n}\n\nfunction onScriptTpl(v){\n const types={py1:'python',py2:'python',sh1:'shell',node1:'node'};\n document.getElementById('scriptType').value=types[v]||'';\n}\n\nfunction openAdd(){\n document.getElementById('msTitle').textContent='注册Skill';\n document.getElementById('ms-name').value='';\n switchST(0);openM('modal-skill');\n}\n\nfunction openEdit(name){\n document.getElementById('msTitle').textContent='编辑Skill — '+name;\n document.getElementById('ms-name').value=name;\n switchST(0);openM('modal-skill');\n}\n\nfunction addEnv(){\n const list=document.getElementById('envVars');\n const d=document.createElement('div');d.className='param-row';\n d.innerHTML='<input class=\"fi\" style=\"width:120px\" placeholder=\"变量名\"><input class=\"fi\" style=\"flex:1\" placeholder=\"变量值\"><button class=\"btn-l\" style=\"color:var(--err)\" onclick=\"this.closest(\\'.param-row\\').remove()\">✕<\/button>';\n list.appendChild(d);\n}\n\nfunction runTest(){\n const log=document.getElementById('testLog');\n log.style.display='block';\n log.innerHTML='<div>> 正在连接执行器...<\/div>';\n setTimeout(()=>log.innerHTML+='<div style=\"color:#fbbf24\">> 提交任务...<\/div>',500);\n setTimeout(()=>log.innerHTML+='<div>> 任务ID: task_'+Date.now()+'<\/div>',1000);\n setTimeout(()=>log.innerHTML+='<div>> 状态: RUNNING<\/div>',1500);\n setTimeout(()=>{log.innerHTML+='<div style=\"color:#4ade80\">> ✅ 执行成功,耗时 2.8s<\/div>';log.innerHTML+='<div>> 输出: {\"status\":\"ok\"}<\/div>'},2500);\n}\n\nfunction filterT(){\n const q=document.getElementById('sInput').value.toLowerCase();\n const cat=document.getElementById('fCat').value;\n const exec=document.getElementById('fExec').value;\n const st=document.getElementById('fSt').value;\n document.querySelectorAll('#stb tr').forEach(tr=>{\n const d=tr.dataset;\n const show=(!q||d.q.toLowerCase().includes(q))&&(!cat||d.cat===cat)&&(!exec||d.exec===exec)&&(!st||d.st===st);\n tr.style.display=show?'':'none';\n });\n}\n\ndocument.querySelectorAll('.mo').forEach(m=>m.addEventListener('click',e=>{if(e.target===m)m.classList.remove('show')}));\ndocument.addEventListener('click',e=>{if(!e.target.closest('.ms-wrap'))document.querySelectorAll('.ms-drop').forEach(d=>d.classList.remove('show'))});\n<\/script>\n<\/body><\/html>\n",
|
||
"10_任务创建.html": "<!DOCTYPE html><html lang=\"zh-CN\"><head><script>if(window!==window.top)document.documentElement.classList.add(\"in-iframe\")<\/script><style>.in-iframe .side{display:none!important}.in-iframe .main{margin-left:0!important}.in-iframe .layout{min-height:auto}<\/style><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1.0\"><title>Agent任务系统 v2.1 - 任务创建<\/title>\n<style>\n*{margin:0;padding:0;box-sizing:border-box}:root{--pri:#6366f1;--bg:#f1f5f9;--card:#fff;--txt:#1e293b;--sub:#64748b;--bdr:#e2e8f0;--ok:#22c55e;--err:#ef4444;--warn:#f59e0b;--side:#1e293b}body{font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",\"PingFang SC\",\"Microsoft YaHei\",sans-serif;background:var(--bg);color:var(--txt);line-height:1.6;font-size:13px}\n.layout{display:flex;min-height:100vh}.side{width:220px;background:var(--side);color:#94a3b8;position:fixed;top:0;left:0;bottom:0;overflow-y:auto;z-index:100}.side .logo{padding:16px 18px;font-size:14px;font-weight:700;color:#fff;border-bottom:1px solid #334155}.ni{display:flex;align-items:center;gap:8px;padding:9px 18px;font-size:12px;color:#94a3b8;cursor:pointer;border-left:3px solid transparent}.ni:hover{background:#334155;color:#e2e8f0}.ni.ac{background:rgba(99,102,241,.15);color:#818cf8;border-left-color:#818cf8;font-weight:600}.ng-t{padding:10px 18px 4px;font-size:10px;letter-spacing:1px;color:#475569;font-weight:600}\n.main{margin-left:220px;flex:1}.hd{height:52px;background:var(--card);border-bottom:1px solid var(--bdr);display:flex;align-items:center;justify-content:space-between;padding:0 24px;font-size:12px;color:var(--sub);position:sticky;top:0;z-index:50}.ct{padding:24px;max-width:900px}\n.pt{font-size:20px;font-weight:700;margin-bottom:4px}.pd{font-size:12px;color:var(--sub);margin-bottom:20px}\n.card{background:var(--card);border-radius:10px;padding:20px;border:1px solid var(--bdr);margin-bottom:14px}\n.btn{padding:7px 16px;border-radius:7px;font-size:12px;font-weight:500;border:none;cursor:pointer;display:inline-flex;align-items:center;gap:5px;transition:all .12s}.btn-p{background:var(--pri);color:#fff}.btn-p:hover{background:#4f46e5}.btn-d{background:#fee2e2;color:#dc2626}.btn-g{background:transparent;color:var(--sub);border:1px solid var(--bdr)}.btn-sm{padding:5px 10px;font-size:11px}.btn-s{background:var(--ok);color:#fff}.btn-lg{padding:10px 28px;font-size:14px}\n.tg{display:inline-block;padding:2px 8px;border-radius:99px;font-size:10px;font-weight:600}.tg-ok{background:#dcfce7;color:#166534}.tg-e{background:#fee2e2;color:#991b1b}.tg-i{background:#dbeafe;color:#1e40af}.tg-p{background:#f3e8ff;color:#6b21a8}.tg-w{background:#fef3c7;color:#92400e}\n.fg{margin-bottom:16px}.fl{font-size:12px;font-weight:600;margin-bottom:6px;display:block}.fl .rq{color:var(--err)}.fi{width:100%;padding:9px 12px;border:1px solid var(--bdr);border-radius:7px;font-size:12px;outline:none}.fi:focus{border-color:var(--pri);box-shadow:0 0 0 2px rgba(99,102,241,.1)}.fs{width:100%;padding:9px 12px;border:1px solid var(--bdr);border-radius:7px;font-size:12px;background:#fff}.fr{display:grid;grid-template-columns:1fr 1fr;gap:14px}\n.note{background:#eff6ff;border-left:3px solid var(--pri);padding:8px 12px;border-radius:0 6px 6px 0;font-size:11px;color:var(--sub);margin-bottom:14px}\n.warn{background:#fef2f2;border-left:3px solid var(--err);padding:8px 12px;border-radius:0 6px 6px 0;font-size:11px;color:#991b1b;margin-bottom:14px}\n.toast{position:fixed;top:20px;right:20px;padding:12px 20px;border-radius:8px;font-size:13px;font-weight:500;z-index:300;display:none}.toast.show{display:block;animation:tIn .3s}.toast.ok{background:#dcfce7;color:#166534}.toast.er{background:#fee2e2;color:#991b1b}@keyframes tIn{from{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}\n.mo{position:fixed;inset:0;background:rgba(0,0,0,.45);display:none;align-items:center;justify-content:center;z-index:200}.mo.show{display:flex}.mc{background:var(--card);border-radius:14px;width:90%;max-width:500px;max-height:85vh;overflow-y:auto;box-shadow:0 20px 60px rgba(0,0,0,.2)}.mh{padding:14px 20px;border-bottom:1px solid var(--bdr);display:flex;justify-content:space-between;align-items:center}.mh h3{font-size:15px}.mx{cursor:pointer;font-size:18px;color:var(--sub);background:none;border:none}.mb{padding:20px}.mf{padding:14px 20px;border-top:1px solid var(--bdr);display:flex;justify-content:flex-end;gap:8px}\n.steps{display:flex;align-items:center;margin-bottom:24px}.step{display:flex;align-items:center;gap:8px;font-size:12px;color:var(--sub)}.step.ac{color:var(--pri);font-weight:600}.step .sn{width:28px;height:28px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:700;border:2px solid var(--bdr);color:var(--sub)}.step.ac .sn{background:var(--pri);color:#fff;border-color:var(--pri)}.step.done .sn{background:var(--ok);color:#fff;border-color:var(--ok)}.step-line{flex:1;height:2px;background:var(--bdr);margin:0 10px}.step-line.done{background:var(--ok)}\n.skill-card{border:2px solid var(--bdr);border-radius:10px;padding:14px;cursor:pointer;transition:all .15s;margin-bottom:8px}.skill-card:hover{border-color:#a5b4fc;background:#faf5ff}.skill-card.sel{border-color:var(--pri);background:#ede9fe}.skill-card .sk-name{font-weight:600;font-size:13px}.skill-card .sk-desc{font-size:11px;color:var(--sub);margin-top:2px}\n.prod-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:8px;max-height:200px;overflow-y:auto}.prod-item{border:1px solid var(--bdr);border-radius:8px;padding:8px 12px;cursor:pointer;font-size:12px;transition:all .12s}.prod-item:hover{border-color:var(--pri)}.prod-item.sel{border-color:var(--pri);background:#ede9fe}.prod-item .pi-name{font-weight:600}.prod-item .pi-code{font-size:10px;color:var(--sub)}\n.ch-fill{background:#f0fdf4;border:1px solid #bbf7d0;border-radius:7px;padding:8px 12px;font-size:12px;color:#166534;margin-top:8px}\n.step-ct{display:none}.step-ct.show{display:block}\n.tag-input{display:flex;flex-wrap:wrap;gap:4px;padding:6px 10px;border:1px solid var(--bdr);border-radius:7px;min-height:36px;align-items:center}.tag-input .tag{background:#ede9fe;color:#6b21a8;padding:2px 6px;border-radius:3px;font-size:11px;display:flex;align-items:center;gap:3px}.tag-input .tag .x{cursor:pointer;font-weight:700}.tag-input input{border:none;outline:none;font-size:12px;flex:1;min-width:80px}\n<\/style><\/head><body>\n<div class=\"toast\" id=\"toast\"><\/div>\n\n<div class=\"mo\" id=\"modal-ok\"><div class=\"mc\" style=\"max-width:440px\"><div class=\"mh\"><h3>🎉 任务已提交<\/h3><button class=\"mx\" onclick=\"closeM('modal-ok')\">✕<\/button><\/div><div class=\"mb\" style=\"text-align:center;padding:20px\">\n<div style=\"font-size:48px;margin-bottom:12px\">✅<\/div>\n<p style=\"font-size:16px;font-weight:700;margin-bottom:4px\">任务创建成功!<\/p>\n<p style=\"font-size:12px;color:var(--sub)\">任务ID: TASK-20260423-001<\/p>\n<div style=\"margin-top:16px;padding:12px;background:#f8fafc;border-radius:8px;font-size:12px;text-align:left\">\n<div style=\"display:flex;justify-content:space-between;margin-bottom:4px\"><span style=\"color:var(--sub)\">Skill<\/span><span style=\"font-weight:600\">小红书笔记发布<\/span><\/div>\n<div style=\"display:flex;justify-content:space-between;margin-bottom:4px\"><span style=\"color:var(--sub)\">执行器<\/span><span>🦞 龙虾执行器<\/span><\/div>\n<div style=\"display:flex;justify-content:space-between;margin-bottom:4px\"><span style=\"color:var(--sub)\">产品<\/span><span>PROD001 美妆种草达人<\/span><\/div>\n<div style=\"display:flex;justify-content:space-between\"><span style=\"color:var(--sub)\">状态<\/span><span class=\"tg tg-w\">PENDING<\/span><\/div>\n<\/div>\n<\/div><div class=\"mf\"><button class=\"btn btn-g\" onclick=\"closeM('modal-ok');resetWizard()\">继续创建<\/button><button class=\"btn btn-p\" onclick=\"closeM('modal-ok')\">查看任务列表<\/button><\/div><\/div><\/div>\n\n<div class=\"layout\">\n<aside class=\"side\">\n<div class=\"logo\">🤖 Agent任务系统 v2.1<\/div>\n<div class=\"ni\">🏠 首页<\/div>\n<div class=\"ng-t\">权限管理<\/div><div class=\"ni\">· 组织架构<\/div><div class=\"ni\">· 菜单管理<\/div><div class=\"ni\">· 角色管理<\/div><div class=\"ni\">· 用户管理<\/div>\n<div class=\"ng-t\">产品管理<\/div><div class=\"ni\">· 产品列表<\/div><div class=\"ni\">· 渠道码<\/div><div class=\"ni\">· 平台套件<\/div>\n<div class=\"ng-t\">平台产品账号<\/div><div class=\"ni\">· 账号管理<\/div>\n<div class=\"ng-t\">Skill中心<\/div><div class=\"ni\">· Skill列表<\/div><div class=\"ni\">· 调用日志<\/div>\n<div class=\"ng-t\">任务中心<\/div><div class=\"ni ac\">· 任务创建<\/div><div class=\"ni\">· 任务列表<\/div>\n<div class=\"ng-t\">日志/设置<\/div><div class=\"ni\">· 操作日志<\/div><div class=\"ni\">· 系统设置<\/div>\n<\/aside>\n<div class=\"main\">\n<div class=\"hd\"><div>📋 任务中心 / <b style=\"color:var(--txt)\">任务创建<\/b><\/div><div style=\"display:flex;align-items:center;gap:10px\"><span>🔔<\/span><span>张三<\/span><div style=\"width:28px;height:28px;border-radius:50%;background:var(--pri);color:#fff;display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:600\">张<\/div><\/div><\/div>\n<div class=\"ct\">\n<h1 class=\"pt\">任务创建<\/h1>\n<p class=\"pd\">选Skill → 选产品 → 填参数 → 提交(双重权限校验:Skill权限 + 产品范围交集)<\/p>\n\n<!-- Steps -->\n<div class=\"steps\" id=\"stepsBar\">\n<div class=\"step ac\" id=\"s1\"><div class=\"sn\">1<\/div>选择Skill<\/div>\n<div class=\"step-line\" id=\"sl1\"><\/div>\n<div class=\"step\" id=\"s2\"><div class=\"sn\">2<\/div>选择产品<\/div>\n<div class=\"step-line\" id=\"sl2\"><\/div>\n<div class=\"step\" id=\"s3\"><div class=\"sn\">3<\/div>填写参数<\/div>\n<div class=\"step-line\" id=\"sl3\"><\/div>\n<div class=\"step\" id=\"s4\"><div class=\"sn\">4<\/div>确认提交<\/div>\n<\/div>\n\n<!-- Step 1: 选择Skill -->\n<div class=\"step-ct show\" id=\"sc1\">\n<div class=\"card\">\n<div class=\"note\">📋 仅展示您角色skill_scope中的Skill(RB-07),合并所有角色取并集<\/div>\n<div style=\"margin-bottom:12px\"><input class=\"fi\" placeholder=\"🔍 搜索Skill名称...\" oninput=\"filterSkills(this.value)\"><\/div>\n<div id=\"skillList\">\n<div class=\"skill-card\" onclick=\"selSkill(this,'小红书笔记发布','🦞 龙虾','内容发布')\"><div style=\"display:flex;justify-content:space-between;align-items:center\"><div class=\"sk-name\">小红书笔记发布<\/div><div><span class=\"tg tg-e\" style=\"background:#fef2f2;color:#dc2626\">🦞 龙虾<\/span> <span class=\"tg tg-i\">内容发布<\/span><\/div><\/div><div class=\"sk-desc\">自动发布小红书笔记,支持图文和视频<\/div><\/div>\n<div class=\"skill-card\" onclick=\"selSkill(this,'抖音视频上传','🦞 龙虾','内容发布')\"><div style=\"display:flex;justify-content:space-between;align-items:center\"><div class=\"sk-name\">抖音视频上传<\/div><div><span class=\"tg tg-e\" style=\"background:#fef2f2;color:#dc2626\">🦞 龙虾<\/span> <span class=\"tg tg-i\">内容发布<\/span><\/div><\/div><div class=\"sk-desc\">批量上传抖音短视频<\/div><\/div>\n<div class=\"skill-card\" onclick=\"selSkill(this,'竞品数据采集','📜 脚本','数据采集')\"><div style=\"display:flex;justify-content:space-between;align-items:center\"><div class=\"sk-name\">竞品数据采集<\/div><div><span class=\"tg tg-p\">📜 脚本<\/span> <span class=\"tg tg-p\">数据采集<\/span><\/div><\/div><div class=\"sk-desc\">采集竞品在各平台的数据指标<\/div><\/div>\n<div class=\"skill-card\" onclick=\"selSkill(this,'Facebook广告投放','🦞 龙虾','广告投放')\"><div style=\"display:flex;justify-content:space-between;align-items:center\"><div class=\"sk-name\">Facebook广告投放<\/div><div><span class=\"tg tg-e\" style=\"background:#fef2f2;color:#dc2626\">🦞 龙虾<\/span> <span class=\"tg tg-w\">广告投放<\/span><\/div><\/div><div class=\"sk-desc\">自动化Facebook广告创建和投放<\/div><\/div>\n<\/div>\n<div style=\"margin-top:14px;text-align:right\"><button class=\"btn btn-p\" id=\"nextBtn1\" disabled onclick=\"goStep(2)\">下一步 →<\/button><\/div>\n<\/div><\/div>\n\n<!-- Step 2: 选择产品 -->\n<div class=\"step-ct\" id=\"sc2\">\n<div class=\"card\">\n<div class=\"note\">⚠️ 产品范围 = Skill.product_scope ∩ 用户角色.data_scope(RB-12交集校验)<\/div>\n<div style=\"margin-bottom:8px;font-size:12px;color:var(--sub)\">已选Skill: <b id=\"selSkillName\" style=\"color:var(--txt)\">-<\/b><\/div>\n<div style=\"margin-bottom:12px\"><input class=\"fi\" placeholder=\"🔍 搜索产品...\" oninput=\"filterProds(this.value)\"><\/div>\n<div class=\"prod-grid\" id=\"prodList\">\n<div class=\"prod-item\" onclick=\"selProd(this,'PROD001')\" data-q=\"PROD001 美妆种草达人 小红书\"><div class=\"pi-name\">📕 美妆种草达人<\/div><div class=\"pi-code\">PROD001 · 小红书 · 投放一组<\/div><\/div>\n<div class=\"prod-item\" onclick=\"selProd(this,'PROD002')\" data-q=\"PROD002 护肤品评测 小红书\"><div class=\"pi-name\">📕 护肤品评测<\/div><div class=\"pi-code\">PROD002 · 小红书 · 投放一组<\/div><\/div>\n<div class=\"prod-item\" onclick=\"selProd(this,'PROD003')\" data-q=\"PROD003 抖音带货王 抖音\"><div class=\"pi-name\">🎵 抖音带货王<\/div><div class=\"pi-code\">PROD003 · 抖音 · 投放二组<\/div><\/div>\n<div class=\"prod-item\" onclick=\"selProd(this,'PROD006')\" data-q=\"PROD006 海外社媒投放 Facebook\"><div class=\"pi-name\">📘 海外社媒投放<\/div><div class=\"pi-code\">PROD006 · Facebook · 投放二组<\/div><\/div>\n<\/div>\n<div class=\"ch-fill\" id=\"chFill\" style=\"display:none\">✅ 渠道码已自动填充 — 内导: <b id=\"chIC\">-<\/b> · 自然: <b id=\"chNC\">-<\/b><\/div>\n<div style=\"margin-top:14px;display:flex;justify-content:space-between\"><button class=\"btn btn-g\" onclick=\"goStep(1)\">← 上一步<\/button><button class=\"btn btn-p\" id=\"nextBtn2\" disabled onclick=\"goStep(3)\">下一步 →<\/button><\/div>\n<\/div><\/div>\n\n<!-- Step 3: 填写参数 -->\n<div class=\"step-ct\" id=\"sc3\">\n<div class=\"card\">\n<div style=\"margin-bottom:12px;font-size:12px;color:var(--sub)\">Skill: <b id=\"s3Skill\" style=\"color:var(--txt)\">-<\/b> | 产品: <b id=\"s3Prod\" style=\"color:var(--txt)\">-<\/b><\/div>\n<div class=\"note\">📋 动态表单由Skill的inputSchema自动渲染(react-jsonschema-form)<\/div>\n<div class=\"fg\"><label class=\"fl\">产品 <span class=\"rq\">*<\/span><\/label><input class=\"fi\" id=\"f-prod\" readonly style=\"background:#f0fdf4;border-color:#bbf7d0;color:#166534\"><\/div>\n<div class=\"fg\"><label class=\"fl\">发布内容 <span class=\"rq\">*<\/span><\/label><textarea class=\"fi\" rows=\"4\" id=\"f-content\" placeholder=\"请输入发布内容...\">今日美妆好物分享!这款面霜太绝了,上脸不油腻,保湿效果超棒✨ #美妆好物 #种草分享<\/textarea><\/div>\n<div class=\"fg\"><label class=\"fl\">标签<\/label>\n<div class=\"tag-input\" id=\"tagInput\"><span class=\"tag\">美妆 <span class=\"x\" onclick=\"this.closest('.tag').remove()\">×<\/span><\/span><span class=\"tag\">种草 <span class=\"x\" onclick=\"this.closest('.tag').remove()\">×<\/span><\/span><input placeholder=\"输入后回车添加\" onkeydown=\"addTag(event)\"><\/div><\/div>\n<div class=\"fr\">\n<div class=\"fg\"><label class=\"fl\">发布时间<\/label><select class=\"fs\"><option>立即发布<\/option><option>定时发布<\/option><\/select><\/div>\n<div class=\"fg\"><label class=\"fl\">内导渠道码<\/label><input class=\"fi\" id=\"f-ic\" readonly style=\"background:#f8fafc\"><\/div>\n<\/div>\n<div style=\"margin-top:14px;display:flex;justify-content:space-between\"><button class=\"btn btn-g\" onclick=\"goStep(2)\">← 上一步<\/button><button class=\"btn btn-p\" onclick=\"goStep(4)\">下一步 →<\/button><\/div>\n<\/div><\/div>\n\n<!-- Step 4: 确认提交 -->\n<div class=\"step-ct\" id=\"sc4\">\n<div class=\"card\">\n<h3 style=\"font-size:15px;margin-bottom:14px\">📋 确认任务信息<\/h3>\n<div style=\"background:#f8fafc;border-radius:8px;padding:14px;font-size:12px;margin-bottom:14px\">\n<div style=\"display:grid;grid-template-columns:100px 1fr;gap:6px 12px\">\n<span style=\"color:var(--sub)\">Skill<\/span><span id=\"c-skill\" style=\"font-weight:600\">-<\/span>\n<span style=\"color:var(--sub)\">执行器<\/span><span id=\"c-exec\">-<\/span>\n<span style=\"color:var(--sub)\">产品<\/span><span id=\"c-prod\">-<\/span>\n<span style=\"color:var(--sub)\">内导渠道码<\/span><span id=\"c-ic\">-<\/span>\n<span style=\"color:var(--sub)\">发布内容<\/span><span id=\"c-content\" style=\"max-width:500px;word-break:break-all\">-<\/span>\n<span style=\"color:var(--sub)\">标签<\/span><span id=\"c-tags\">-<\/span>\n<\/div><\/div>\n<div class=\"note\">✅ Skill权限校验通过 · 产品范围交集校验通过 · 参数校验通过<\/div>\n<div style=\"display:flex;justify-content:space-between\"><button class=\"btn btn-g\" onclick=\"goStep(3)\">← 上一步<\/button><button class=\"btn btn-p btn-lg\" onclick=\"submitTask()\">🚀 提交任务<\/button><\/div>\n<\/div><\/div>\n\n<\/div><\/div><\/div>\n\n<script>\nlet curStep=1,selSkillData=null,selProdData=null;\nconst PROD_CH={PROD001:{ic:'IC001',nc:'NC001'},PROD002:{ic:'IC002',nc:'NC002'},PROD003:{ic:'IC003',nc:'NC003'},PROD006:{ic:'IC006',nc:'NC006'}};\n\nfunction openM(id){document.getElementById(id).classList.add('show')}\nfunction closeM(id){document.getElementById(id).classList.remove('show')}\nfunction showT(m,t){const e=document.getElementById('toast');e.textContent=m;e.className='toast show '+t;setTimeout(()=>e.className='toast',2500)}\n\nfunction goStep(n){\n curStep=n;\n for(let i=1;i<=4;i++){\n document.getElementById('sc'+i).classList.toggle('show',i===n);\n const s=document.getElementById('s'+i);\n s.classList.toggle('ac',i===n);\n s.classList.toggle('done',i<n);\n if(i<4){const l=document.getElementById('sl'+i);l.classList.toggle('done',i<n)}\n }\n if(n===3&&selProdData){\n document.getElementById('s3Skill').textContent=selSkillData.name;\n document.getElementById('s3Prod').textContent=selProdData;\n document.getElementById('f-prod').value=selProdData;\n document.getElementById('f-ic').value=PROD_CH[selProdData]?.ic||'';\n }\n if(n===4){\n document.getElementById('c-skill').textContent=selSkillData.name;\n document.getElementById('c-exec').textContent=selSkillData.exec;\n document.getElementById('c-prod').textContent=selProdData;\n document.getElementById('c-ic').textContent=PROD_CH[selProdData]?.ic||'-';\n document.getElementById('c-content').textContent=document.getElementById('f-content').value||'-';\n const tags=[];document.querySelectorAll('#tagInput .tag').forEach(t=>tags.push(t.textContent.replace('×','')));\n document.getElementById('c-tags').textContent=tags.join(', ')||'-';\n }\n}\n\nfunction selSkill(el,name,exec,cat){\n document.querySelectorAll('.skill-card').forEach(c=>c.classList.remove('sel'));\n el.classList.add('sel');\n selSkillData={name,exec,cat};\n document.getElementById('nextBtn1').disabled=false;\n document.getElementById('selSkillName').textContent=name;\n}\n\nfunction selProd(el,code){\n document.querySelectorAll('.prod-item').forEach(c=>c.classList.remove('sel'));\n el.classList.add('sel');\n selProdData=code;\n document.getElementById('nextBtn2').disabled=false;\n const ch=PROD_CH[code];\n if(ch){\n document.getElementById('chFill').style.display='block';\n document.getElementById('chIC').textContent=ch.ic;\n document.getElementById('chNC').textContent=ch.nc;\n }\n}\n\nfunction filterSkills(q){\n q=q.toLowerCase();\n document.querySelectorAll('.skill-card').forEach(c=>{\n c.style.display=c.querySelector('.sk-name').textContent.toLowerCase().includes(q)?'':'none';\n });\n}\nfunction filterProds(q){\n q=q.toLowerCase();\n document.querySelectorAll('.prod-item').forEach(c=>{\n c.style.display=c.dataset.q.toLowerCase().includes(q)?'':'none';\n });\n}\n\nfunction addTag(e){\n if(e.key==='Enter'&&e.target.value.trim()){\n e.preventDefault();\n const tag=document.createElement('span');tag.className='tag';\n tag.innerHTML=e.target.value.trim()+' <span class=\"x\" onclick=\"this.closest(\\'.tag\\').remove()\">×<\/span>';\n e.target.parentNode.insertBefore(tag,e.target);\n e.target.value='';\n }\n}\n\nfunction submitTask(){openM('modal-ok')}\n\nfunction resetWizard(){\n selSkillData=null;selProdData=null;\n document.querySelectorAll('.skill-card,.prod-item').forEach(c=>c.classList.remove('sel'));\n document.getElementById('nextBtn1').disabled=true;\n document.getElementById('nextBtn2').disabled=true;\n document.getElementById('chFill').style.display='none';\n goStep(1);\n}\n\ndocument.querySelectorAll('.mo').forEach(m=>m.addEventListener('click',e=>{if(e.target===m)m.classList.remove('show')}));\n<\/script>\n<\/body><\/html>\n",
|
||
"11_任务列表.html": "<!DOCTYPE html><html lang=\"zh-CN\"><head><script>if(window!==window.top)document.documentElement.classList.add(\"in-iframe\")<\/script><style>.in-iframe .side{display:none!important}.in-iframe .main{margin-left:0!important}.in-iframe .layout{min-height:auto}<\/style><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1.0\"><title>Agent任务系统 v2.1 - 任务列表<\/title>\n<style>\n*{margin:0;padding:0;box-sizing:border-box}:root{--pri:#6366f1;--bg:#f1f5f9;--card:#fff;--txt:#1e293b;--sub:#64748b;--bdr:#e2e8f0;--ok:#22c55e;--err:#ef4444;--warn:#f59e0b;--side:#1e293b}body{font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",\"PingFang SC\",\"Microsoft YaHei\",sans-serif;background:var(--bg);color:var(--txt);line-height:1.6;font-size:13px}\n.layout{display:flex;min-height:100vh}.side{width:220px;background:var(--side);color:#94a3b8;position:fixed;top:0;left:0;bottom:0;overflow-y:auto;z-index:100}.side .logo{padding:16px 18px;font-size:14px;font-weight:700;color:#fff;border-bottom:1px solid #334155}.ni{display:flex;align-items:center;gap:8px;padding:9px 18px;font-size:12px;color:#94a3b8;cursor:pointer;border-left:3px solid transparent}.ni:hover{background:#334155;color:#e2e8f0}.ni.ac{background:rgba(99,102,241,.15);color:#818cf8;border-left-color:#818cf8;font-weight:600}.ng-t{padding:10px 18px 4px;font-size:10px;letter-spacing:1px;color:#475569;font-weight:600}\n.main{margin-left:220px;flex:1}.hd{height:52px;background:var(--card);border-bottom:1px solid var(--bdr);display:flex;align-items:center;justify-content:space-between;padding:0 24px;font-size:12px;color:var(--sub);position:sticky;top:0;z-index:50}.ct{padding:24px}\n.pt{font-size:20px;font-weight:700;margin-bottom:4px}.pd{font-size:12px;color:var(--sub);margin-bottom:20px}\n.tb{display:flex;gap:8px;align-items:center;margin-bottom:14px;flex-wrap:wrap}.sb{display:flex;align-items:center;gap:6px;background:#f8fafc;border:1px solid var(--bdr);border-radius:7px;padding:7px 12px;font-size:12px}.sb input{border:none;background:none;outline:none;font-size:12px;width:140px}\n.sl{border:1px solid var(--bdr);border-radius:7px;padding:7px 12px;font-size:12px;background:#fff;cursor:pointer}\n.btn{padding:7px 16px;border-radius:7px;font-size:12px;font-weight:500;border:none;cursor:pointer;display:inline-flex;align-items:center;gap:5px;transition:all .12s}.btn-p{background:var(--pri);color:#fff}.btn-d{background:#fee2e2;color:#dc2626}.btn-g{background:transparent;color:var(--sub);border:1px solid var(--bdr)}.btn-sm{padding:5px 10px;font-size:11px}.btn-s{background:var(--ok);color:#fff}.btn-w{background:var(--warn);color:#fff}\n.btn-l{background:none;border:none;color:var(--pri);padding:0;font-size:12px;cursor:pointer}.btn-l:hover{text-decoration:underline}\n.tg{display:inline-block;padding:2px 8px;border-radius:99px;font-size:10px;font-weight:600}.tg-ok{background:#dcfce7;color:#166534}.tg-e{background:#fee2e2;color:#991b1b}.tg-i{background:#dbeafe;color:#1e40af}.tg-p{background:#f3e8ff;color:#6b21a8}.tg-w{background:#fef3c7;color:#92400e}.tg-g{background:#f1f5f9;color:#64748b}.tg-run{background:#bfdbfe;color:#1d4ed8;animation:pulse 2s infinite}\n@keyframes pulse{0%,100%{opacity:1}50%{opacity:.6}}\ntable{width:100%;border-collapse:collapse;font-size:12px}th,td{padding:8px 12px;text-align:left;border-bottom:1px solid var(--bdr)}th{background:#f8fafc;font-weight:600;color:var(--sub);font-size:11px}tr:hover td{background:#fafbfc}.tw{overflow-x:auto;border:1px solid var(--bdr);border-radius:8px}\n.stat{display:grid;grid-template-columns:repeat(5,1fr);gap:12px;margin-bottom:16px}.stat-c{background:var(--card);border:1px solid var(--bdr);border-radius:10px;padding:14px 16px}.stat-c .sv{font-size:22px;font-weight:700}.stat-c .sl2{font-size:11px;color:var(--sub)}\n.toast{position:fixed;top:20px;right:20px;padding:12px 20px;border-radius:8px;font-size:13px;font-weight:500;z-index:300;display:none}.toast.show{display:block;animation:tIn .3s}.toast.ok{background:#dcfce7;color:#166534}.toast.er{background:#fee2e2;color:#991b1b}@keyframes tIn{from{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}\n.pg{display:flex;align-items:center;justify-content:space-between;padding:10px 0;font-size:12px;color:var(--sub)}.pgb{padding:4px 10px;border:1px solid var(--bdr);border-radius:5px;font-size:11px;cursor:pointer;background:var(--card);margin:0 2px}.pgb.ac{background:var(--pri);color:#fff;border-color:var(--pri)}\n.mo{position:fixed;inset:0;background:rgba(0,0,0,.45);display:none;align-items:center;justify-content:center;z-index:200}.mo.show{display:flex}.mc{background:var(--card);border-radius:14px;width:90%;max-width:650px;max-height:88vh;overflow-y:auto;box-shadow:0 20px 60px rgba(0,0,0,.2)}.mh{padding:14px 20px;border-bottom:1px solid var(--bdr);display:flex;justify-content:space-between;align-items:center}.mh h3{font-size:15px}.mx{cursor:pointer;font-size:18px;color:var(--sub);background:none;border:none}.mb{padding:20px}.mf{padding:14px 20px;border-top:1px solid var(--bdr);display:flex;justify-content:flex-end;gap:8px}\n.tabs{display:flex;gap:0;border-bottom:2px solid var(--bdr);margin-bottom:14px}.tab{padding:8px 14px;font-size:12px;font-weight:500;color:var(--sub);cursor:pointer;border-bottom:2px solid transparent;margin-bottom:-2px}.tab.ac{color:var(--pri);border-bottom-color:var(--pri);font-weight:600}.tab:hover{color:var(--txt)}\n.detail-row{display:flex;border-bottom:1px solid var(--bdr);font-size:12px}.detail-row:last-child{border:none}.dr-l{width:100px;padding:8px 0;color:var(--sub);font-weight:500;flex-shrink:0}.dr-v{padding:8px 0;flex:1}\n.log-box{background:#1e293b;color:#a5f3fc;padding:12px;border-radius:8px;font-family:monospace;font-size:11px;max-height:200px;overflow-y:auto}\n.json-box{background:#f8fafc;border:1px solid var(--bdr);border-radius:7px;padding:10px;font-family:monospace;font-size:11px;max-height:160px;overflow-y:auto;white-space:pre-wrap}\n<\/style><\/head><body>\n<div class=\"toast\" id=\"toast\"><\/div>\n\n<!-- Modal: 任务详情 -->\n<div class=\"mo\" id=\"modal-detail\"><div class=\"mc\"><div class=\"mh\"><h3>📋 任务详情<\/h3><button class=\"mx\" onclick=\"closeM('modal-detail')\">✕<\/button><\/div><div class=\"mb\">\n<div class=\"tabs\" id=\"dtTabs\"><div class=\"tab ac\" onclick=\"switchDT(0)\">基本信息<\/div><div class=\"tab\" onclick=\"switchDT(1)\">输入参数<\/div><div class=\"tab\" onclick=\"switchDT(2)\">执行结果<\/div><div class=\"tab\" onclick=\"switchDT(3)\">执行日志<\/div><\/div>\n<div id=\"dt0\">\n<div class=\"detail-row\"><div class=\"dr-l\">任务ID<\/div><div class=\"dr-v\"><code>TASK-001<\/code><\/div><\/div>\n<div class=\"detail-row\"><div class=\"dr-l\">Skill<\/div><div class=\"dr-v\">小红书笔记发布<\/div><\/div>\n<div class=\"detail-row\"><div class=\"dr-l\">执行器<\/div><div class=\"dr-v\"><span class=\"tg tg-e\" style=\"background:#fef2f2;color:#dc2626\">🦞 龙虾<\/span><\/div><\/div>\n<div class=\"detail-row\"><div class=\"dr-l\">产品<\/div><div class=\"dr-v\">PROD001 · 美妆种草达人<\/div><\/div>\n<div class=\"detail-row\"><div class=\"dr-l\">创建人<\/div><div class=\"dr-v\">张三<\/div><\/div>\n<div class=\"detail-row\"><div class=\"dr-l\">状态<\/div><div class=\"dr-v\"><span class=\"tg tg-ok\">SUCCEEDED<\/span><\/div><\/div>\n<div class=\"detail-row\"><div class=\"dr-l\">创建时间<\/div><div class=\"dr-v\">2026-04-23 10:30:15<\/div><\/div>\n<div class=\"detail-row\"><div class=\"dr-l\">耗时<\/div><div class=\"dr-v\">3.2s<\/div><\/div>\n<\/div>\n<div id=\"dt1\" style=\"display:none\"><div class=\"json-box\">{\n \"product_id\": \"PROD001\",\n \"content\": \"今日美妆好物分享!这款面霜太绝了...\",\n \"tags\": [\"美妆\", \"种草\"],\n \"channel_code\": \"IC001\"\n}<\/div><\/div>\n<div id=\"dt2\" style=\"display:none\"><div class=\"json-box\">{\n \"status\": \"published\",\n \"post_id\": \"xhs_98765\",\n \"post_url\": \"https://www.xiaohongshu.com/explore/98765\",\n \"published_at\": \"2026-04-23T10:30:18Z\"\n}<\/div><\/div>\n<div id=\"dt3\" style=\"display:none\"><div class=\"log-box\"><div>[10:30:15] 任务创建,状态: PENDING<\/div><div>[10:30:15] 权限校验通过: Skill=小红书笔记发布, Product=PROD001<\/div><div>[10:30:15] 路由到龙虾执行器: agent_xhs_publish_01<\/div><div style=\"color:#fbbf24\">[10:30:16] 状态变更: PENDING → RUNNING<\/div><div>[10:30:16] 龙虾平台任务ID: lob_task_abc123<\/div><div>[10:30:17] 轮询龙虾状态: RUNNING<\/div><div>[10:30:18] 轮询龙虾状态: SUCCEEDED<\/div><div style=\"color:#4ade80\">[10:30:18] ✅ 任务执行成功,耗时 3.2s<\/div><\/div><\/div>\n<\/div><div class=\"mf\"><button class=\"btn btn-g\" onclick=\"closeM('modal-detail')\">关闭<\/button><\/div><\/div><\/div>\n\n<!-- Modal: 确认取消 -->\n<div class=\"mo\" id=\"modal-cancel\"><div class=\"mc\" style=\"max-width:400px\"><div class=\"mh\"><h3>⚠️ 取消任务<\/h3><button class=\"mx\" onclick=\"closeM('modal-cancel')\">✕<\/button><\/div><div class=\"mb\" style=\"text-align:center;padding:20px\"><div style=\"font-size:36px\">⏹️<\/div><p style=\"font-size:13px;font-weight:600;margin-top:8px\">确定取消运行中的任务?<\/p><p style=\"font-size:11px;color:var(--sub);margin-top:4px\">将向执行器发送停止信号<\/p><\/div><div class=\"mf\"><button class=\"btn btn-g\" onclick=\"closeM('modal-cancel')\">返回<\/button><button class=\"btn btn-d\" onclick=\"closeM('modal-cancel');showT('✅ 任务已取消','ok')\">确认取消<\/button><\/div><\/div><\/div>\n\n<div class=\"layout\">\n<aside class=\"side\">\n<div class=\"logo\">🤖 Agent任务系统 v2.1<\/div>\n<div class=\"ni\">🏠 首页<\/div>\n<div class=\"ng-t\">权限管理<\/div><div class=\"ni\">· 组织架构<\/div><div class=\"ni\">· 菜单管理<\/div><div class=\"ni\">· 角色管理<\/div><div class=\"ni\">· 用户管理<\/div>\n<div class=\"ng-t\">产品管理<\/div><div class=\"ni\">· 产品列表<\/div><div class=\"ni\">· 渠道码<\/div><div class=\"ni\">· 平台套件<\/div>\n<div class=\"ng-t\">平台产品账号<\/div><div class=\"ni\">· 账号管理<\/div>\n<div class=\"ng-t\">Skill中心<\/div><div class=\"ni\">· Skill列表<\/div><div class=\"ni\">· 调用日志<\/div>\n<div class=\"ng-t\">任务中心<\/div><div class=\"ni\">· 任务创建<\/div><div class=\"ni ac\">· 任务列表<\/div>\n<div class=\"ng-t\">日志/设置<\/div><div class=\"ni\">· 操作日志<\/div><div class=\"ni\">· 系统设置<\/div>\n<\/aside>\n<div class=\"main\">\n<div class=\"hd\"><div>📋 任务中心 / <b style=\"color:var(--txt)\">任务列表<\/b><\/div><div style=\"display:flex;align-items:center;gap:10px\"><span>🔔<\/span><span>张三<\/span><div style=\"width:28px;height:28px;border-radius:50%;background:var(--pri);color:#fff;display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:600\">张<\/div><\/div><\/div>\n<div class=\"ct\">\n<h1 class=\"pt\">任务列表<\/h1>\n<p class=\"pd\">按data_scope过滤 · 任务详情抽屉 · 取消/重试操作<\/p>\n\n<div class=\"stat\">\n<div class=\"stat-c\"><div class=\"sv\">1,234<\/div><div class=\"sl2\">任务总数<\/div><\/div>\n<div class=\"stat-c\"><div class=\"sv\" style=\"color:var(--ok)\">1,089<\/div><div class=\"sl2\">成功<\/div><\/div>\n<div class=\"stat-c\"><div class=\"sv\" style=\"color:var(--err)\">45<\/div><div class=\"sl2\">失败<\/div><\/div>\n<div class=\"stat-c\"><div class=\"sv\" style=\"color:#1d4ed8\">8<\/div><div class=\"sl2\">运行中<\/div><\/div>\n<div class=\"stat-c\"><div class=\"sv\" style=\"color:var(--warn)\">92<\/div><div class=\"sl2\">超时<\/div><\/div>\n<\/div>\n\n<div class=\"tb\">\n<div class=\"sb\"><span>🔍<\/span><input placeholder=\"搜索任务ID/Skill名称\" id=\"sInput\" oninput=\"filterT()\"><\/div>\n<select class=\"sl\" id=\"fSt\" onchange=\"filterT()\"><option value=\"\">全部状态<\/option><option value=\"SUCCEEDED\">成功<\/option><option value=\"FAILED\">失败<\/option><option value=\"RUNNING\">运行中<\/option><option value=\"PENDING\">等待中<\/option><option value=\"TIMEOUT\">超时<\/option><\/select>\n<select class=\"sl\" id=\"fExec\" onchange=\"filterT()\"><option value=\"\">全部执行器<\/option><option value=\"lobster\">🦞 龙虾<\/option><option value=\"script\">📜 脚本<\/option><\/select>\n<select class=\"sl\"><option>最近7天<\/option><option>最近30天<\/option><option>全部<\/option><\/select>\n<button class=\"btn btn-g btn-sm\" onclick=\"showT('📥 导出成功','ok')\">导出<\/button>\n<\/div>\n\n<div class=\"tw\"><table>\n<thead><tr><th>任务ID<\/th><th>Skill<\/th><th>执行器<\/th><th>产品<\/th><th>创建人<\/th><th>状态<\/th><th>耗时<\/th><th>创建时间<\/th><th>操作<\/th><\/tr><\/thead>\n<tbody id=\"ttb\">\n<tr data-q=\"TASK-001 小红书笔记发布\" data-st=\"SUCCEEDED\" data-exec=\"lobster\"><td><code>TASK-001<\/code><\/td><td>小红书笔记发布<\/td><td><span class=\"tg tg-e\" style=\"background:#fef2f2;color:#dc2626\">🦞<\/span><\/td><td>PROD001<\/td><td>张三<\/td><td><span class=\"tg tg-ok\">SUCCEEDED<\/span><\/td><td>3.2s<\/td><td>04-23 10:30<\/td><td><button class=\"btn-l\" onclick=\"openM('modal-detail')\">详情<\/button><\/td><\/tr>\n<tr data-q=\"TASK-002 抖音视频上传\" data-st=\"SUCCEEDED\" data-exec=\"lobster\"><td><code>TASK-002<\/code><\/td><td>抖音视频上传<\/td><td><span class=\"tg tg-e\" style=\"background:#fef2f2;color:#dc2626\">🦞<\/span><\/td><td>PROD003<\/td><td>张三<\/td><td><span class=\"tg tg-ok\">SUCCEEDED<\/span><\/td><td>5.8s<\/td><td>04-23 10:15<\/td><td><button class=\"btn-l\" onclick=\"openM('modal-detail')\">详情<\/button><\/td><\/tr>\n<tr data-q=\"TASK-003 竞品数据采集\" data-st=\"RUNNING\" data-exec=\"script\"><td><code>TASK-003<\/code><\/td><td>竞品数据采集<\/td><td><span class=\"tg tg-p\">📜<\/span><\/td><td>PROD002<\/td><td>李四<\/td><td><span class=\"tg tg-run\">RUNNING<\/span><\/td><td>12s...<\/td><td>04-23 10:28<\/td><td><button class=\"btn-l\" onclick=\"openM('modal-detail')\">详情<\/button> <button class=\"btn-l\" style=\"color:var(--err)\" onclick=\"openM('modal-cancel')\">取消<\/button><\/td><\/tr>\n<tr data-q=\"TASK-004 Facebook广告投放\" data-st=\"FAILED\" data-exec=\"lobster\"><td><code>TASK-004<\/code><\/td><td>Facebook广告投放<\/td><td><span class=\"tg tg-e\" style=\"background:#fef2f2;color:#dc2626\">🦞<\/span><\/td><td>PROD006<\/td><td>赵六<\/td><td><span class=\"tg tg-e\">FAILED<\/span><\/td><td>1.5s<\/td><td>04-23 09:45<\/td><td><button class=\"btn-l\" onclick=\"openM('modal-detail')\">详情<\/button> <button class=\"btn-l\" style=\"color:var(--warn)\" onclick=\"showT('🔄 已重新提交','ok')\">重试<\/button><\/td><\/tr>\n<tr data-q=\"TASK-005 数据清洗脚本\" data-st=\"SUCCEEDED\" data-exec=\"script\"><td><code>TASK-005<\/code><\/td><td>数据清洗脚本<\/td><td><span class=\"tg tg-p\">📜<\/span><\/td><td>PROD001<\/td><td>张三<\/td><td><span class=\"tg tg-ok\">SUCCEEDED<\/span><\/td><td>0.8s<\/td><td>04-23 09:30<\/td><td><button class=\"btn-l\" onclick=\"openM('modal-detail')\">详情<\/button><\/td><\/tr>\n<tr data-q=\"TASK-006 小红书笔记发布\" data-st=\"TIMEOUT\" data-exec=\"lobster\"><td><code>TASK-006<\/code><\/td><td>小红书笔记发布<\/td><td><span class=\"tg tg-e\" style=\"background:#fef2f2;color:#dc2626\">🦞<\/span><\/td><td>PROD002<\/td><td>王五<\/td><td><span class=\"tg tg-w\">TIMEOUT<\/span><\/td><td>30s<\/td><td>04-23 09:00<\/td><td><button class=\"btn-l\" onclick=\"openM('modal-detail')\">详情<\/button> <button class=\"btn-l\" style=\"color:var(--warn)\" onclick=\"showT('🔄 已重新提交','ok')\">重试<\/button><\/td><\/tr>\n<tr data-q=\"TASK-007 竞品数据采集\" data-st=\"PENDING\" data-exec=\"script\"><td><code>TASK-007<\/code><\/td><td>竞品数据采集<\/td><td><span class=\"tg tg-p\">📜<\/span><\/td><td>PROD003<\/td><td>张三<\/td><td><span class=\"tg tg-g\">PENDING<\/span><\/td><td>-<\/td><td>04-23 10:29<\/td><td><button class=\"btn-l\" onclick=\"openM('modal-detail')\">详情<\/button> <button class=\"btn-l\" style=\"color:var(--err)\" onclick=\"openM('modal-cancel')\">取消<\/button><\/td><\/tr>\n<tr data-q=\"TASK-008 抖音视频上传\" data-st=\"RUNNING\" data-exec=\"lobster\"><td><code>TASK-008<\/code><\/td><td>抖音视频上传<\/td><td><span class=\"tg tg-e\" style=\"background:#fef2f2;color:#dc2626\">🦞<\/span><\/td><td>PROD004<\/td><td>李四<\/td><td><span class=\"tg tg-run\">RUNNING<\/span><\/td><td>6s...<\/td><td>04-23 10:29<\/td><td><button class=\"btn-l\" onclick=\"openM('modal-detail')\">详情<\/button> <button class=\"btn-l\" style=\"color:var(--err)\" onclick=\"openM('modal-cancel')\">取消<\/button><\/td><\/tr>\n<\/tbody><\/table><\/div>\n<div class=\"pg\"><span>共 8 条<\/span><div><span class=\"pgb ac\">1<\/span><span class=\"pgb\">2<\/span><span class=\"pgb\">3<\/span><\/div><\/div>\n\n<\/div><\/div><\/div>\n\n<script>\nfunction openM(id){document.getElementById(id).classList.add('show')}\nfunction closeM(id){document.getElementById(id).classList.remove('show')}\nfunction showT(m,t){const e=document.getElementById('toast');e.textContent=m;e.className='toast show '+t;setTimeout(()=>e.className='toast',2500)}\nfunction switchDT(i){document.querySelectorAll('#dtTabs .tab').forEach((t,j)=>t.classList.toggle('ac',j===i));['dt0','dt1','dt2','dt3'].forEach((d,j)=>document.getElementById(d).style.display=j===i?'block':'none')}\nfunction filterT(){\n const q=document.getElementById('sInput').value.toLowerCase();\n const st=document.getElementById('fSt').value;\n const exec=document.getElementById('fExec').value;\n document.querySelectorAll('#ttb tr').forEach(tr=>{\n const d=tr.dataset;\n const show=(!q||d.q.toLowerCase().includes(q))&&(!st||d.st===st)&&(!exec||d.exec===exec);\n tr.style.display=show?'':'none';\n });\n}\ndocument.querySelectorAll('.mo').forEach(m=>m.addEventListener('click',e=>{if(e.target===m)m.classList.remove('show')}));\n<\/script>\n<\/body><\/html>\n",
|
||
"12_菜单管理.html": "<!DOCTYPE html><html lang=\"zh-CN\"><head><script>if(window!==window.top)document.documentElement.classList.add(\"in-iframe\")<\/script><style>.in-iframe .side{display:none!important}.in-iframe .main{margin-left:0!important}.in-iframe .layout{min-height:auto}<\/style><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1.0\"><title>Agent任务系统 v2.1 - 菜单管理<\/title>\n<style>\n*{margin:0;padding:0;box-sizing:border-box}:root{--pri:#6366f1;--bg:#f1f5f9;--card:#fff;--txt:#1e293b;--sub:#64748b;--bdr:#e2e8f0;--ok:#22c55e;--err:#ef4444;--warn:#f59e0b;--side:#1e293b}body{font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",\"PingFang SC\",\"Microsoft YaHei\",sans-serif;background:var(--bg);color:var(--txt);line-height:1.6;font-size:13px}\n.layout{display:flex;min-height:100vh}.side{width:220px;background:var(--side);color:#94a3b8;position:fixed;top:0;left:0;bottom:0;overflow-y:auto;z-index:100}.side .logo{padding:16px 18px;font-size:14px;font-weight:700;color:#fff;border-bottom:1px solid #334155}.ni{display:flex;align-items:center;gap:8px;padding:9px 18px;font-size:12px;color:#94a3b8;cursor:pointer;border-left:3px solid transparent}.ni:hover{background:#334155;color:#e2e8f0}.ni.ac{background:rgba(99,102,241,.15);color:#818cf8;border-left-color:#818cf8;font-weight:600}.ng-t{padding:10px 18px 4px;font-size:10px;letter-spacing:1px;color:#475569;font-weight:600}\n.main{margin-left:220px;flex:1}.hd{height:52px;background:var(--card);border-bottom:1px solid var(--bdr);display:flex;align-items:center;justify-content:space-between;padding:0 24px;font-size:12px;color:var(--sub);position:sticky;top:0;z-index:50}.ct{padding:24px}\n.pt{font-size:20px;font-weight:700;margin-bottom:4px}.pd{font-size:12px;color:var(--sub);margin-bottom:20px}\n.btn{padding:7px 16px;border-radius:7px;font-size:12px;font-weight:500;border:none;cursor:pointer;display:inline-flex;align-items:center;gap:5px;transition:all .12s}.btn-p{background:var(--pri);color:#fff}.btn-p:hover{background:#4f46e5}.btn-d{background:#fee2e2;color:#dc2626}.btn-g{background:transparent;color:var(--sub);border:1px solid var(--bdr)}.btn-sm{padding:5px 10px;font-size:11px}\n.btn-l{background:none;border:none;color:var(--pri);padding:0;font-size:12px;cursor:pointer}.btn-l:hover{text-decoration:underline}\n.tg{display:inline-block;padding:2px 8px;border-radius:99px;font-size:10px;font-weight:600}.tg-ok{background:#dcfce7;color:#166534}.tg-e{background:#fee2e2;color:#991b1b}.tg-i{background:#dbeafe;color:#1e40af}.tg-p{background:#f3e8ff;color:#6b21a8}.tg-w{background:#fef3c7;color:#92400e}.tg-g{background:#f1f5f9;color:#64748b}\ntable{width:100%;border-collapse:collapse;font-size:12px}th,td{padding:8px 12px;text-align:left;border-bottom:1px solid var(--bdr)}th{background:#f8fafc;font-weight:600;color:var(--sub);font-size:11px}tr:hover td{background:#fafbfc}.tw{overflow-x:auto;border:1px solid var(--bdr);border-radius:8px}\n.fg{margin-bottom:14px}.fl{font-size:12px;font-weight:500;margin-bottom:5px;display:block}.fl .rq{color:var(--err)}.fi{width:100%;padding:8px 12px;border:1px solid var(--bdr);border-radius:7px;font-size:12px;outline:none}.fi:focus{border-color:var(--pri)}.fs{width:100%;padding:8px 12px;border:1px solid var(--bdr);border-radius:7px;font-size:12px;background:#fff}.fr{display:grid;grid-template-columns:1fr 1fr;gap:14px}\n.mo{position:fixed;inset:0;background:rgba(0,0,0,.45);display:none;align-items:center;justify-content:center;z-index:200}.mo.show{display:flex}.mc{background:var(--card);border-radius:14px;width:90%;max-width:580px;max-height:85vh;overflow-y:auto;box-shadow:0 20px 60px rgba(0,0,0,.2)}.mh{padding:14px 20px;border-bottom:1px solid var(--bdr);display:flex;justify-content:space-between;align-items:center}.mh h3{font-size:15px}.mx{cursor:pointer;font-size:18px;color:var(--sub);background:none;border:none}.mb{padding:20px}.mf{padding:14px 20px;border-top:1px solid var(--bdr);display:flex;justify-content:flex-end;gap:8px}\n.toast{position:fixed;top:20px;right:20px;padding:12px 20px;border-radius:8px;font-size:13px;font-weight:500;z-index:300;display:none}.toast.show{display:block;animation:tIn .3s}.toast.ok{background:#dcfce7;color:#166534}.toast.er{background:#fee2e2;color:#991b1b}@keyframes tIn{from{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}\n.tree-row{display:flex;align-items:center;gap:6px;padding:7px 12px;font-size:12px;border-bottom:1px solid #f1f5f9;cursor:pointer}.tree-row:hover{background:#f8fafc}.tree-toggle{width:18px;text-align:center;cursor:pointer;color:var(--sub);font-size:10px}.tree-icon{font-size:14px}.tree-name{flex:1;font-weight:500}.tree-children{margin-left:24px}.tree-children.hide{display:none}\n.btn-group{display:flex;gap:6px;flex-wrap:wrap;margin-top:8px}\n.tabs{display:flex;gap:0;border-bottom:2px solid var(--bdr);margin-bottom:16px}.tab{padding:8px 16px;font-size:12px;font-weight:500;color:var(--sub);cursor:pointer;border-bottom:2px solid transparent;margin-bottom:-2px}.tab.ac{color:var(--pri);border-bottom-color:var(--pri);font-weight:600}\n<\/style><\/head><body>\n<div class=\"toast\" id=\"toast\"><\/div>\n\n<!-- Modal: 新增/编辑菜单 -->\n<div class=\"mo\" id=\"modal-menu\"><div class=\"mc\"><div class=\"mh\"><h3 id=\"mmTitle\">新增菜单<\/h3><button class=\"mx\" onclick=\"closeM('modal-menu')\">✕<\/button><\/div><div class=\"mb\">\n<div class=\"fg\"><label class=\"fl\">菜单类型 <span class=\"rq\">*<\/span><\/label><select class=\"fs\" id=\"mm-type\" onchange=\"onMenuType(this.value)\"><option value=\"directory\">目录(directory)<\/option><option value=\"menu\">菜单(menu)<\/option><option value=\"link\">外链(link)<\/option><\/select><\/div>\n<div class=\"fr\">\n<div class=\"fg\"><label class=\"fl\">菜单名称 <span class=\"rq\">*<\/span><\/label><input class=\"fi\" id=\"mm-name\" placeholder=\"如 产品管理\"><\/div>\n<div class=\"fg\"><label class=\"fl\">父级菜单<\/label><select class=\"fs\" id=\"mm-parent\"><option value=\"0\">顶级菜单<\/option><option>权限管理<\/option><option>产品管理<\/option><option>Skill中心<\/option><option>任务中心<\/option><option>日志中心<\/option><option>系统设置<\/option><\/select><\/div>\n<\/div>\n<div class=\"fr\">\n<div class=\"fg\"><label class=\"fl\">路由路径 <span class=\"rq\">*<\/span><\/label><input class=\"fi\" id=\"mm-path\" placeholder=\"/product\"><\/div>\n<div class=\"fg\"><label class=\"fl\">图标<\/label><input class=\"fi\" placeholder=\"如 📦 或 icon-product\"><\/div>\n<\/div>\n<div class=\"fr\" id=\"compRow\">\n<div class=\"fg\"><label class=\"fl\">前端组件路径<\/label><input class=\"fi\" placeholder=\"pages/product/index\"><\/div>\n<div class=\"fg\"><label class=\"fl\">排序号 <span class=\"rq\">*<\/span><\/label><input class=\"fi\" type=\"number\" value=\"1\"><\/div>\n<\/div>\n<div class=\"fr\">\n<div class=\"fg\"><label class=\"fl\">是否可见<\/label><select class=\"fs\"><option>显示<\/option><option>隐藏<\/option><\/select><\/div>\n<div class=\"fg\"><label class=\"fl\">状态<\/label><select class=\"fs\"><option>启用<\/option><option>禁用<\/option><\/select><\/div>\n<\/div>\n<\/div><div class=\"mf\"><button class=\"btn btn-g\" onclick=\"closeM('modal-menu')\">取消<\/button><button class=\"btn btn-p\" onclick=\"closeM('modal-menu');showT('✅ 菜单已保存','ok')\">保存<\/button><\/div><\/div><\/div>\n\n<!-- Modal: 新增/编辑按钮 -->\n<div class=\"mo\" id=\"modal-btn\"><div class=\"mc\" style=\"max-width:480px\"><div class=\"mh\"><h3 id=\"mbTitle\">新增按钮<\/h3><button class=\"mx\" onclick=\"closeM('modal-btn')\">✕<\/button><\/div><div class=\"mb\">\n<div class=\"fg\"><label class=\"fl\">所属菜单<\/label><input class=\"fi\" id=\"mb-menu\" readonly value=\"产品列表\"><\/div>\n<div class=\"fg\"><label class=\"fl\">按钮名称 <span class=\"rq\">*<\/span><\/label><input class=\"fi\" id=\"mb-name\" placeholder=\"如 新增\"><\/div>\n<div class=\"fg\"><label class=\"fl\">权限标识 <span class=\"rq\">*<\/span> <span style=\"font-size:10px;color:var(--sub)\">(全局唯一,格式: 模块:操作)<\/span><\/label><input class=\"fi\" id=\"mb-code\" placeholder=\"如 product:create\"><\/div>\n<div class=\"fg\"><label class=\"fl\">按钮类型<\/label><select class=\"fs\"><option>primary<\/option><option>default<\/option><option>danger<\/option><option>warning<\/option><\/select><\/div>\n<div class=\"fg\"><label class=\"fl\">状态<\/label><select class=\"fs\"><option>启用<\/option><option>禁用<\/option><\/select><\/div>\n<\/div><div class=\"mf\"><button class=\"btn btn-g\" onclick=\"closeM('modal-btn')\">取消<\/button><button class=\"btn btn-p\" onclick=\"closeM('modal-btn');showT('✅ 按钮已保存','ok')\">保存<\/button><\/div><\/div><\/div>\n\n<!-- Modal: 删除 -->\n<div class=\"mo\" id=\"modal-del\"><div class=\"mc\" style=\"max-width:400px\"><div class=\"mh\"><h3>⚠️ 确认删除<\/h3><button class=\"mx\" onclick=\"closeM('modal-del')\">✕<\/button><\/div><div class=\"mb\" style=\"text-align:center;padding:20px\"><div style=\"font-size:36px\">🗑️<\/div><p style=\"font-size:13px;font-weight:600;margin-top:8px\" id=\"delMsg\">确定删除?<\/p><p style=\"font-size:11px;color:var(--sub);margin-top:4px\">删除需确保无子菜单、无角色引用<\/p><\/div><div class=\"mf\"><button class=\"btn btn-g\" onclick=\"closeM('modal-del')\">取消<\/button><button class=\"btn btn-d\" onclick=\"closeM('modal-del');showT('✅ 已删除','ok')\">确认删除<\/button><\/div><\/div><\/div>\n\n<div class=\"layout\">\n<aside class=\"side\">\n<div class=\"logo\">🤖 Agent任务系统 v2.1<\/div>\n<div class=\"ni\">🏠 首页<\/div>\n<div class=\"ng-t\">权限管理<\/div><div class=\"ni\">· 组织架构<\/div><div class=\"ni ac\">· 菜单管理<\/div><div class=\"ni\">· 角色管理<\/div><div class=\"ni\">· 用户管理<\/div>\n<div class=\"ng-t\">产品管理<\/div><div class=\"ni\">· 产品列表<\/div><div class=\"ni\">· 渠道码<\/div><div class=\"ni\">· 平台套件<\/div>\n<div class=\"ng-t\">平台产品账号<\/div><div class=\"ni\">· 账号管理<\/div>\n<div class=\"ng-t\">Skill中心<\/div><div class=\"ni\">· Skill列表<\/div><div class=\"ni\">· 调用日志<\/div>\n<div class=\"ng-t\">任务中心<\/div><div class=\"ni\">· 任务创建<\/div><div class=\"ni\">· 任务列表<\/div>\n<div class=\"ng-t\">日志/设置<\/div><div class=\"ni\">· 操作日志<\/div><div class=\"ni\">· 系统设置<\/div>\n<\/aside>\n<div class=\"main\">\n<div class=\"hd\"><div>🔐 权限管理 / <b style=\"color:var(--txt)\">菜单管理<\/b><\/div><div style=\"display:flex;align-items:center;gap:10px\"><span>🔔<\/span><span>admin<\/span><div style=\"width:28px;height:28px;border-radius:50%;background:var(--pri);color:#fff;display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:600\">A<\/div><\/div><\/div>\n<div class=\"ct\">\n<h1 class=\"pt\">菜单管理<\/h1>\n<p class=\"pd\">菜单树形管理(目录/菜单/外链)· 按钮操作管理 · 权限树 · button_code全局唯一<\/p>\n\n<div style=\"display:flex;gap:8px;margin-bottom:14px\">\n<button class=\"btn btn-p\" onclick=\"openAddMenu()\">+ 新增菜单<\/button>\n<button class=\"btn btn-g btn-sm\" onclick=\"expandAll()\">全部展开<\/button>\n<button class=\"btn btn-g btn-sm\" onclick=\"collapseAll()\">全部收起<\/button>\n<\/div>\n\n<div style=\"display:flex;gap:16px\">\n<!-- 左侧: 菜单树 -->\n<div style=\"flex:1;background:var(--card);border:1px solid var(--bdr);border-radius:10px;padding:14px\">\n<div style=\"font-size:13px;font-weight:600;margin-bottom:10px\">📋 菜单树<\/div>\n\n<div class=\"tree-row\" onclick=\"showBtns('dashboard')\"><span class=\"tree-toggle\" onclick=\"event.stopPropagation();toggleTree('t-home')\">▼<\/span><span class=\"tree-icon\">📁<\/span><span class=\"tree-name\">首页<\/span><span class=\"tg tg-i\">目录<\/span><span style=\"margin-left:6px\"><button class=\"btn-l btn-sm\" onclick=\"event.stopPropagation();openEditMenu('首页','directory')\">编辑<\/button><\/span><\/div>\n<div class=\"tree-children\" id=\"t-home\">\n<div class=\"tree-row\" onclick=\"showBtns('dashboard')\"><span class=\"tree-toggle\"><\/span><span class=\"tree-icon\">📄<\/span><span class=\"tree-name\">仪表盘<\/span><span class=\"tg tg-ok\">菜单<\/span><span style=\"margin-left:6px\"><button class=\"btn-l btn-sm\" onclick=\"event.stopPropagation();openEditMenu('仪表盘','menu')\">编辑<\/button><\/span><\/div>\n<\/div>\n\n<div class=\"tree-row\"><span class=\"tree-toggle\" onclick=\"toggleTree('t-perm')\">▼<\/span><span class=\"tree-icon\">📁<\/span><span class=\"tree-name\">权限管理<\/span><span class=\"tg tg-i\">目录<\/span><span style=\"margin-left:6px\"><button class=\"btn-l btn-sm\" onclick=\"event.stopPropagation();openEditMenu('权限管理','directory')\">编辑<\/button><\/span><\/div>\n<div class=\"tree-children\" id=\"t-perm\">\n<div class=\"tree-row\" onclick=\"showBtns('org')\"><span class=\"tree-toggle\"><\/span><span class=\"tree-icon\">📄<\/span><span class=\"tree-name\">组织架构<\/span><span class=\"tg tg-ok\">菜单<\/span><span style=\"margin-left:6px\"><button class=\"btn-l btn-sm\" onclick=\"event.stopPropagation();openEditMenu('组织架构','menu')\">编辑<\/button><\/span><\/div>\n<div class=\"tree-row\" onclick=\"showBtns('menu-mgmt')\"><span class=\"tree-toggle\"><\/span><span class=\"tree-icon\">📄<\/span><span class=\"tree-name\">菜单管理<\/span><span class=\"tg tg-ok\">菜单<\/span><span style=\"margin-left:6px\"><button class=\"btn-l btn-sm\" onclick=\"event.stopPropagation();openEditMenu('菜单管理','menu')\">编辑<\/button><\/span><\/div>\n<div class=\"tree-row\" onclick=\"showBtns('role')\"><span class=\"tree-toggle\"><\/span><span class=\"tree-icon\">📄<\/span><span class=\"tree-name\">角色管理<\/span><span class=\"tg tg-ok\">菜单<\/span><span style=\"margin-left:6px\"><button class=\"btn-l btn-sm\" onclick=\"event.stopPropagation();openEditMenu('角色管理','menu')\">编辑<\/button><\/span><\/div>\n<div class=\"tree-row\" onclick=\"showBtns('user')\"><span class=\"tree-toggle\"><\/span><span class=\"tree-icon\">📄<\/span><span class=\"tree-name\">用户管理<\/span><span class=\"tg tg-ok\">菜单<\/span><span style=\"margin-left:6px\"><button class=\"btn-l btn-sm\" onclick=\"event.stopPropagation();openEditMenu('用户管理','menu')\">编辑<\/button><\/span><\/div>\n<\/div>\n\n<div class=\"tree-row\"><span class=\"tree-toggle\" onclick=\"toggleTree('t-prod')\">▼<\/span><span class=\"tree-icon\">📁<\/span><span class=\"tree-name\">产品管理<\/span><span class=\"tg tg-i\">目录<\/span><span style=\"margin-left:6px\"><button class=\"btn-l btn-sm\" onclick=\"event.stopPropagation();openEditMenu('产品管理','directory')\">编辑<\/button><\/span><\/div>\n<div class=\"tree-children\" id=\"t-prod\">\n<div class=\"tree-row\" onclick=\"showBtns('product')\"><span class=\"tree-toggle\"><\/span><span class=\"tree-icon\">📄<\/span><span class=\"tree-name\">产品列表<\/span><span class=\"tg tg-ok\">菜单<\/span><span style=\"margin-left:6px\"><button class=\"btn-l btn-sm\" onclick=\"event.stopPropagation();openEditMenu('产品列表','menu')\">编辑<\/button><\/span><\/div>\n<div class=\"tree-row\" onclick=\"showBtns('channel')\"><span class=\"tree-toggle\"><\/span><span class=\"tree-icon\">📄<\/span><span class=\"tree-name\">渠道码<\/span><span class=\"tg tg-ok\">菜单<\/span><\/div>\n<div class=\"tree-row\"><span class=\"tree-toggle\"><\/span><span class=\"tree-icon\">📄<\/span><span class=\"tree-name\">平台套件<\/span><span class=\"tg tg-ok\">菜单<\/span><\/div>\n<\/div>\n\n<div class=\"tree-row\"><span class=\"tree-toggle\" onclick=\"toggleTree('t-skill')\">▼<\/span><span class=\"tree-icon\">📁<\/span><span class=\"tree-name\">Skill中心<\/span><span class=\"tg tg-i\">目录<\/span><\/div>\n<div class=\"tree-children\" id=\"t-skill\">\n<div class=\"tree-row\" onclick=\"showBtns('skill')\"><span class=\"tree-toggle\"><\/span><span class=\"tree-icon\">📄<\/span><span class=\"tree-name\">Skill列表<\/span><span class=\"tg tg-ok\">菜单<\/span><\/div>\n<div class=\"tree-row\"><span class=\"tree-toggle\"><\/span><span class=\"tree-icon\">📄<\/span><span class=\"tree-name\">调用日志<\/span><span class=\"tg tg-ok\">菜单<\/span><\/div>\n<\/div>\n\n<div class=\"tree-row\"><span class=\"tree-toggle\" onclick=\"toggleTree('t-task')\">▼<\/span><span class=\"tree-icon\">📁<\/span><span class=\"tree-name\">任务中心<\/span><span class=\"tg tg-i\">目录<\/span><\/div>\n<div class=\"tree-children\" id=\"t-task\">\n<div class=\"tree-row\"><span class=\"tree-toggle\"><\/span><span class=\"tree-icon\">📄<\/span><span class=\"tree-name\">任务创建<\/span><span class=\"tg tg-ok\">菜单<\/span><\/div>\n<div class=\"tree-row\"><span class=\"tree-toggle\"><\/span><span class=\"tree-icon\">📄<\/span><span class=\"tree-name\">任务列表<\/span><span class=\"tg tg-ok\">菜单<\/span><\/div>\n<\/div>\n\n<div class=\"tree-row\"><span class=\"tree-toggle\" onclick=\"toggleTree('t-sys')\">▼<\/span><span class=\"tree-icon\">📁<\/span><span class=\"tree-name\">系统设置<\/span><span class=\"tg tg-i\">目录<\/span><\/div>\n<div class=\"tree-children\" id=\"t-sys\">\n<div class=\"tree-row\"><span class=\"tree-toggle\"><\/span><span class=\"tree-icon\">📄<\/span><span class=\"tree-name\">执行器配置<\/span><span class=\"tg tg-ok\">菜单<\/span><\/div>\n<div class=\"tree-row\"><span class=\"tree-toggle\"><\/span><span class=\"tree-icon\">📄<\/span><span class=\"tree-name\">脚本模板<\/span><span class=\"tg tg-ok\">菜单<\/span><\/div>\n<div class=\"tree-row\"><span class=\"tree-toggle\"><\/span><span class=\"tree-icon\">🔗<\/span><span class=\"tree-name\">龙虾平台<\/span><span class=\"tg tg-w\">外链<\/span><\/div>\n<\/div>\n<\/div>\n\n<!-- 右侧: 按钮管理 -->\n<div style=\"width:380px;background:var(--card);border:1px solid var(--bdr);border-radius:10px;padding:14px\">\n<div style=\"display:flex;justify-content:space-between;align-items:center;margin-bottom:10px\"><div style=\"font-size:13px;font-weight:600\">🔘 按钮管理 — <span id=\"btnMenuName\">产品列表<\/span><\/div><button class=\"btn btn-p btn-sm\" onclick=\"openAddBtn()\">+ 新增按钮<\/button><\/div>\n\n<div class=\"tw\"><table><thead><tr><th>按钮名称<\/th><th>权限标识<\/th><th>类型<\/th><th>状态<\/th><th>操作<\/th><\/tr><\/thead>\n<tbody id=\"btnTb\">\n<tr><td><b>新增<\/b><\/td><td><code>product:create<\/code><\/td><td><span class=\"tg tg-i\">primary<\/span><\/td><td><span class=\"tg tg-ok\">启用<\/span><\/td><td><button class=\"btn-l\" onclick=\"openEditBtn('新增','product:create')\">编辑<\/button> <button class=\"btn-l\" style=\"color:var(--err)\" onclick=\"openM('modal-del')\">删除<\/button><\/td><\/tr>\n<tr><td><b>编辑<\/b><\/td><td><code>product:update<\/code><\/td><td><span class=\"tg tg-g\">default<\/span><\/td><td><span class=\"tg tg-ok\">启用<\/span><\/td><td><button class=\"btn-l\" onclick=\"openEditBtn('编辑','product:update')\">编辑<\/button> <button class=\"btn-l\" style=\"color:var(--err)\" onclick=\"openM('modal-del')\">删除<\/button><\/td><\/tr>\n<tr><td><b>删除<\/b><\/td><td><code>product:delete<\/code><\/td><td><span class=\"tg tg-e\">danger<\/span><\/td><td><span class=\"tg tg-ok\">启用<\/span><\/td><td><button class=\"btn-l\" onclick=\"openEditBtn('删除','product:delete')\">编辑<\/button> <button class=\"btn-l\" style=\"color:var(--err)\" onclick=\"openM('modal-del')\">删除<\/button><\/td><\/tr>\n<tr><td><b>导入<\/b><\/td><td><code>product:import<\/code><\/td><td><span class=\"tg tg-w\">warning<\/span><\/td><td><span class=\"tg tg-ok\">启用<\/span><\/td><td><button class=\"btn-l\" onclick=\"openEditBtn('导入','product:import')\">编辑<\/button> <button class=\"btn-l\" style=\"color:var(--err)\" onclick=\"openM('modal-del')\">删除<\/button><\/td><\/tr>\n<tr><td><b>导出<\/b><\/td><td><code>product:export<\/code><\/td><td><span class=\"tg tg-g\">default<\/span><\/td><td><span class=\"tg tg-ok\">启用<\/span><\/td><td><button class=\"btn-l\" onclick=\"openEditBtn('导出','product:export')\">编辑<\/button> <button class=\"btn-l\" style=\"color:var(--err)\" onclick=\"openM('modal-del')\">删除<\/button><\/td><\/tr>\n<\/tbody><\/table><\/div>\n<\/div>\n<\/div>\n\n<\/div><\/div><\/div>\n\n<script>\nconst BTN_DATA={product:[{n:'新增',c:'product:create',t:'primary'},{n:'编辑',c:'product:update',t:'default'},{n:'删除',c:'product:delete',t:'danger'},{n:'导入',c:'product:import',t:'warning'},{n:'导出',c:'product:export',t:'default'}],role:[{n:'新增',c:'role:create',t:'primary'},{n:'编辑',c:'role:update',t:'default'},{n:'删除',c:'role:delete',t:'danger'},{n:'复制',c:'role:copy',t:'default'}],user:[{n:'新增',c:'user:create',t:'primary'},{n:'编辑',c:'user:update',t:'default'},{n:'删除',c:'user:delete',t:'danger'},{n:'重置密码',c:'user:reset-pwd',t:'warning'}],skill:[{n:'注册',c:'skill:create',t:'primary'},{n:'编辑',c:'skill:update',t:'default'},{n:'删除',c:'skill:delete',t:'danger'},{n:'测试',c:'skill:test',t:'warning'}],org:[{n:'新增',c:'org:create',t:'primary'},{n:'编辑',c:'org:update',t:'default'},{n:'删除',c:'org:delete',t:'danger'}],dashboard:[],channel:[{n:'新增',c:'channel:create',t:'primary'},{n:'编辑',c:'channel:update',t:'default'},{n:'绑定',c:'channel:bindProduct',t:'default'}],'menu-mgmt':[{n:'新增菜单',c:'menu:create',t:'primary'},{n:'编辑菜单',c:'menu:update',t:'default'},{n:'新增按钮',c:'button:create',t:'primary'}]};\n\nfunction openM(id){document.getElementById(id).classList.add('show')}\nfunction closeM(id){document.getElementById(id).classList.remove('show')}\nfunction showT(m,t){const e=document.getElementById('toast');e.textContent=m;e.className='toast show '+t;setTimeout(()=>e.className='toast',2500)}\n\nfunction toggleTree(id){const el=document.getElementById(id);el.classList.toggle('hide');const toggle=el.previousElementSibling.querySelector('.tree-toggle');toggle.textContent=el.classList.contains('hide')?'▶':'▼'}\nfunction expandAll(){document.querySelectorAll('.tree-children').forEach(c=>{c.classList.remove('hide');c.previousElementSibling.querySelector('.tree-toggle').textContent='▼'})}\nfunction collapseAll(){document.querySelectorAll('.tree-children').forEach(c=>{c.classList.add('hide');c.previousElementSibling.querySelector('.tree-toggle').textContent='▶'})}\n\nfunction showBtns(key){\n document.getElementById('btnMenuName').textContent=event?.currentTarget?.querySelector('.tree-name')?.textContent||key;\n const btns=BTN_DATA[key]||[];\n const tb=document.getElementById('btnTb');\n const tgMap={primary:'tg-i',default:'tg-g',danger:'tg-e',warning:'tg-w'};\n tb.innerHTML=btns.length?btns.map(b=>`<tr><td><b>${b.n}<\/b><\/td><td><code>${b.c}<\/code><\/td><td><span class=\"tg ${tgMap[b.t]}\">${b.t}<\/span><\/td><td><span class=\"tg tg-ok\">启用<\/span><\/td><td><button class=\"btn-l\" onclick=\"openEditBtn('${b.n}','${b.c}')\">编辑<\/button> <button class=\"btn-l\" style=\"color:var(--err)\" onclick=\"openM('modal-del')\">删除<\/button><\/td><\/tr>`).join(''):'<tr><td colspan=\"5\" style=\"text-align:center;color:var(--sub);padding:20px\">暂无按钮<\/td><\/tr>';\n}\n\nfunction openAddMenu(){document.getElementById('mmTitle').textContent='新增菜单';document.getElementById('mm-name').value='';document.getElementById('mm-path').value='';openM('modal-menu')}\nfunction openEditMenu(name,type){document.getElementById('mmTitle').textContent='编辑菜单 — '+name;document.getElementById('mm-name').value=name;document.getElementById('mm-type').value=type;openM('modal-menu')}\nfunction openAddBtn(){document.getElementById('mbTitle').textContent='新增按钮';document.getElementById('mb-name').value='';document.getElementById('mb-code').value='';document.getElementById('mb-menu').value=document.getElementById('btnMenuName').textContent;openM('modal-btn')}\nfunction openEditBtn(name,code){document.getElementById('mbTitle').textContent='编辑按钮';document.getElementById('mb-name').value=name;document.getElementById('mb-code').value=code;openM('modal-btn')}\nfunction onMenuType(v){document.getElementById('compRow').style.display=v==='link'?'none':'grid'}\n\ndocument.querySelectorAll('.mo').forEach(m=>m.addEventListener('click',e=>{if(e.target===m)m.classList.remove('show')}));\n<\/script>\n<\/body><\/html>\n",
|
||
"13_平台套件.html": "<!DOCTYPE html><html lang=\"zh-CN\"><head><script>if(window!==window.top)document.documentElement.classList.add(\"in-iframe\")<\/script><style>.in-iframe .side{display:none!important}.in-iframe .main{margin-left:0!important}.in-iframe .layout{min-height:auto}<\/style><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1.0\"><title>Agent任务系统 v2.1 - 平台套件<\/title>\n<style>\n*{margin:0;padding:0;box-sizing:border-box}:root{--pri:#6366f1;--bg:#f1f5f9;--card:#fff;--txt:#1e293b;--sub:#64748b;--bdr:#e2e8f0;--ok:#22c55e;--err:#ef4444;--warn:#f59e0b;--side:#1e293b}body{font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",\"PingFang SC\",\"Microsoft YaHei\",sans-serif;background:var(--bg);color:var(--txt);line-height:1.6;font-size:13px}\n.layout{display:flex;min-height:100vh}.side{width:220px;background:var(--side);color:#94a3b8;position:fixed;top:0;left:0;bottom:0;overflow-y:auto;z-index:100}.side .logo{padding:16px 18px;font-size:14px;font-weight:700;color:#fff;border-bottom:1px solid #334155}.ni{display:flex;align-items:center;gap:8px;padding:9px 18px;font-size:12px;color:#94a3b8;cursor:pointer;border-left:3px solid transparent}.ni:hover{background:#334155;color:#e2e8f0}.ni.ac{background:rgba(99,102,241,.15);color:#818cf8;border-left-color:#818cf8;font-weight:600}.ng-t{padding:10px 18px 4px;font-size:10px;letter-spacing:1px;color:#475569;font-weight:600}\n.main{margin-left:220px;flex:1}.hd{height:52px;background:var(--card);border-bottom:1px solid var(--bdr);display:flex;align-items:center;justify-content:space-between;padding:0 24px;font-size:12px;color:var(--sub);position:sticky;top:0;z-index:50}.ct{padding:24px}\n.pt{font-size:20px;font-weight:700;margin-bottom:4px}.pd{font-size:12px;color:var(--sub);margin-bottom:20px}\n.btn{padding:7px 16px;border-radius:7px;font-size:12px;font-weight:500;border:none;cursor:pointer;display:inline-flex;align-items:center;gap:5px;transition:all .12s}.btn-p{background:var(--pri);color:#fff}.btn-p:hover{background:#4f46e5}.btn-d{background:#fee2e2;color:#dc2626}.btn-g{background:transparent;color:var(--sub);border:1px solid var(--bdr)}.btn-sm{padding:5px 10px;font-size:11px}\n.btn-l{background:none;border:none;color:var(--pri);padding:0;font-size:12px;cursor:pointer}.btn-l:hover{text-decoration:underline}\n.tg{display:inline-block;padding:2px 8px;border-radius:99px;font-size:10px;font-weight:600}.tg-ok{background:#dcfce7;color:#166534}.tg-e{background:#fee2e2;color:#991b1b}.tg-i{background:#dbeafe;color:#1e40af}.tg-p{background:#f3e8ff;color:#6b21a8}\n.sb{display:flex;align-items:center;gap:6px;background:#f8fafc;border:1px solid var(--bdr);border-radius:7px;padding:7px 12px;font-size:12px}.sb input{border:none;background:none;outline:none;font-size:12px;width:140px}\n.sl{border:1px solid var(--bdr);border-radius:7px;padding:7px 12px;font-size:12px;background:#fff;cursor:pointer}\ntable{width:100%;border-collapse:collapse;font-size:12px}th,td{padding:8px 12px;text-align:left;border-bottom:1px solid var(--bdr)}th{background:#f8fafc;font-weight:600;color:var(--sub);font-size:11px}tr:hover td{background:#fafbfc}.tw{overflow-x:auto;border:1px solid var(--bdr);border-radius:8px}\n.fg{margin-bottom:14px}.fl{font-size:12px;font-weight:500;margin-bottom:5px;display:block}.fl .rq{color:var(--err)}.fi{width:100%;padding:8px 12px;border:1px solid var(--bdr);border-radius:7px;font-size:12px;outline:none}.fi:focus{border-color:var(--pri)}.fs{width:100%;padding:8px 12px;border:1px solid var(--bdr);border-radius:7px;font-size:12px;background:#fff}.fr{display:grid;grid-template-columns:1fr 1fr;gap:14px}\n.mo{position:fixed;inset:0;background:rgba(0,0,0,.45);display:none;align-items:center;justify-content:center;z-index:200}.mo.show{display:flex}.mc{background:var(--card);border-radius:14px;width:90%;max-width:560px;max-height:85vh;overflow-y:auto;box-shadow:0 20px 60px rgba(0,0,0,.2)}.mh{padding:14px 20px;border-bottom:1px solid var(--bdr);display:flex;justify-content:space-between;align-items:center}.mh h3{font-size:15px}.mx{cursor:pointer;font-size:18px;color:var(--sub);background:none;border:none}.mb{padding:20px}.mf{padding:14px 20px;border-top:1px solid var(--bdr);display:flex;justify-content:flex-end;gap:8px}\n.toast{position:fixed;top:20px;right:20px;padding:12px 20px;border-radius:8px;font-size:13px;font-weight:500;z-index:300;display:none}.toast.show{display:block;animation:tIn .3s}.toast.ok{background:#dcfce7;color:#166534}.toast.er{background:#fee2e2;color:#991b1b}@keyframes tIn{from{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}\n.card-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:14px;margin-bottom:16px}\n.p-card{background:var(--card);border:1px solid var(--bdr);border-radius:12px;padding:18px;transition:all .15s;cursor:pointer}.p-card:hover{border-color:var(--pri);box-shadow:0 4px 12px rgba(99,102,241,.1)}.p-card .pc-icon{font-size:32px;margin-bottom:8px}.p-card .pc-name{font-size:15px;font-weight:700;margin-bottom:2px}.p-card .pc-url{font-size:11px;color:var(--sub);word-break:break-all}.p-card .pc-stat{display:flex;gap:12px;margin-top:10px;font-size:11px;color:var(--sub)}.pc-stat span{display:flex;align-items:center;gap:3px}\n<\/style><\/head><body>\n<div class=\"toast\" id=\"toast\"><\/div>\n\n<div class=\"mo\" id=\"modal-plat\"><div class=\"mc\"><div class=\"mh\"><h3 id=\"mpTitle\">新增平台<\/h3><button class=\"mx\" onclick=\"closeM('modal-plat')\">✕<\/button><\/div><div class=\"mb\">\n<div class=\"fg\"><label class=\"fl\">平台名称 <span class=\"rq\">*<\/span><\/label><input class=\"fi\" id=\"mp-name\" placeholder=\"如 小红书\"><\/div>\n<div class=\"fg\"><label class=\"fl\">平台地址 <span class=\"rq\">*<\/span><\/label><input class=\"fi\" id=\"mp-url\" placeholder=\"https://www.xiaohongshu.com\"><\/div>\n<div class=\"fg\"><label class=\"fl\">平台图标<\/label><input class=\"fi\" placeholder=\"emoji 或 图标URL\"><\/div>\n<div class=\"fg\"><label class=\"fl\">备注<\/label><textarea class=\"fi\" rows=\"2\" placeholder=\"平台备注信息\"><\/textarea><\/div>\n<div class=\"fg\"><label class=\"fl\">状态<\/label><select class=\"fs\"><option>启用<\/option><option>禁用<\/option><\/select><\/div>\n<\/div><div class=\"mf\"><button class=\"btn btn-g\" onclick=\"closeM('modal-plat')\">取消<\/button><button class=\"btn btn-p\" onclick=\"closeM('modal-plat');showT('✅ 平台已保存','ok')\">保存<\/button><\/div><\/div><\/div>\n\n<div class=\"mo\" id=\"modal-prod\"><div class=\"mc\"><div class=\"mh\"><h3 id=\"mprTitle\">新增产品代号<\/h3><button class=\"mx\" onclick=\"closeM('modal-prod')\">✕<\/button><\/div><div class=\"mb\">\n<div class=\"fg\"><label class=\"fl\">所属平台<\/label><input class=\"fi\" id=\"mpr-plat\" readonly><\/div>\n<div class=\"fg\"><label class=\"fl\">产品代号 <span class=\"rq\">*<\/span><\/label><input class=\"fi\" placeholder=\"如 PROD001\"><\/div>\n<div class=\"fg\"><label class=\"fl\">产品名称 <span class=\"rq\">*<\/span><\/label><input class=\"fi\" placeholder=\"如 美妆种草达人\"><\/div>\n<div class=\"fg\"><label class=\"fl\">状态<\/label><select class=\"fs\"><option>启用<\/option><option>禁用<\/option><\/select><\/div>\n<\/div><div class=\"mf\"><button class=\"btn btn-g\" onclick=\"closeM('modal-prod')\">取消<\/button><button class=\"btn btn-p\" onclick=\"closeM('modal-prod');showT('✅ 产品代号已保存','ok')\">保存<\/button><\/div><\/div><\/div>\n\n<div class=\"mo\" id=\"modal-del\"><div class=\"mc\" style=\"max-width:400px\"><div class=\"mh\"><h3>⚠️ 确认删除<\/h3><button class=\"mx\" onclick=\"closeM('modal-del')\">✕<\/button><\/div><div class=\"mb\" style=\"text-align:center;padding:20px\"><div style=\"font-size:36px\">🗑️<\/div><p style=\"font-size:13px;font-weight:600;margin-top:8px\">确定删除?<\/p><p style=\"font-size:11px;color:var(--sub);margin-top:4px\">已关联账号的平台/产品需先解除<\/p><\/div><div class=\"mf\"><button class=\"btn btn-g\" onclick=\"closeM('modal-del')\">取消<\/button><button class=\"btn btn-d\" onclick=\"closeM('modal-del');showT('✅ 已删除','ok')\">确认删除<\/button><\/div><\/div><\/div>\n\n<div class=\"layout\">\n<aside class=\"side\">\n<div class=\"logo\">🤖 Agent任务系统 v2.1<\/div>\n<div class=\"ni\">🏠 首页<\/div>\n<div class=\"ng-t\">权限管理<\/div><div class=\"ni\">· 组织架构<\/div><div class=\"ni\">· 菜单管理<\/div><div class=\"ni\">· 角色管理<\/div><div class=\"ni\">· 用户管理<\/div>\n<div class=\"ng-t\">产品管理<\/div><div class=\"ni\">· 产品列表<\/div><div class=\"ni\">· 渠道码<\/div><div class=\"ni ac\">· 平台套件<\/div>\n<div class=\"ng-t\">平台产品账号<\/div><div class=\"ni\">· 账号管理<\/div>\n<div class=\"ng-t\">Skill中心<\/div><div class=\"ni\">· Skill列表<\/div><div class=\"ni\">· 调用日志<\/div>\n<div class=\"ng-t\">任务中心<\/div><div class=\"ni\">· 任务创建<\/div><div class=\"ni\">· 任务列表<\/div>\n<div class=\"ng-t\">日志/设置<\/div><div class=\"ni\">· 操作日志<\/div><div class=\"ni\">· 系统设置<\/div>\n<\/aside>\n<div class=\"main\">\n<div class=\"hd\"><div>📦 产品管理 / <b style=\"color:var(--txt)\">平台套件<\/b><\/div><div style=\"display:flex;align-items:center;gap:10px\"><span>🔔<\/span><span>admin<\/span><div style=\"width:28px;height:28px;border-radius:50%;background:var(--pri);color:#fff;display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:600\">A<\/div><\/div><\/div>\n<div class=\"ct\">\n<h1 class=\"pt\">平台套件管理<\/h1>\n<p class=\"pd\">平台(t_platform) → 产品代号(t_product) 两级管理 · 为平台产品账号提供选择源<\/p>\n\n<div style=\"display:flex;gap:8px;margin-bottom:14px;flex-wrap:wrap\">\n<div class=\"sb\"><span>🔍<\/span><input placeholder=\"搜索平台名称\" id=\"sInput\" oninput=\"filterCards()\"><\/div>\n<button class=\"btn btn-p\" onclick=\"openAddPlat()\">+ 新增平台<\/button>\n<\/div>\n\n<!-- 平台卡片 -->\n<div class=\"card-grid\" id=\"platCards\">\n<div class=\"p-card\" data-q=\"小红书\" onclick=\"showPlatDetail('xhs')\"><div class=\"pc-icon\">📕<\/div><div class=\"pc-name\">小红书<\/div><div class=\"pc-url\">https://www.xiaohongshu.com<\/div><div class=\"pc-stat\"><span>📦 3 产品<\/span><span>👤 12 账号<\/span><span class=\"tg tg-ok\">启用<\/span><\/div><\/div>\n<div class=\"p-card\" data-q=\"抖音\" onclick=\"showPlatDetail('douyin')\"><div class=\"pc-icon\">🎵<\/div><div class=\"pc-name\">抖音<\/div><div class=\"pc-url\">https://www.douyin.com<\/div><div class=\"pc-stat\"><span>📦 2 产品<\/span><span>👤 8 账号<\/span><span class=\"tg tg-ok\">启用<\/span><\/div><\/div>\n<div class=\"p-card\" data-q=\"Facebook\" onclick=\"showPlatDetail('fb')\"><div class=\"pc-icon\">📘<\/div><div class=\"pc-name\">Facebook<\/div><div class=\"pc-url\">https://www.facebook.com<\/div><div class=\"pc-stat\"><span>📦 2 产品<\/span><span>👤 5 账号<\/span><span class=\"tg tg-ok\">启用<\/span><\/div><\/div>\n<div class=\"p-card\" data-q=\"TikTok\" onclick=\"showPlatDetail('tiktok')\"><div class=\"pc-icon\">🎬<\/div><div class=\"pc-name\">TikTok<\/div><div class=\"pc-url\">https://www.tiktok.com<\/div><div class=\"pc-stat\"><span>📦 1 产品<\/span><span>👤 3 账号<\/span><span class=\"tg tg-ok\">启用<\/span><\/div><\/div>\n<div class=\"p-card\" data-q=\"微信公众号\" onclick=\"showPlatDetail('wechat')\"><div class=\"pc-icon\">💬<\/div><div class=\"pc-name\">微信公众号<\/div><div class=\"pc-url\">https://mp.weixin.qq.com<\/div><div class=\"pc-stat\"><span>📦 1 产品<\/span><span>👤 2 账号<\/span><span class=\"tg tg-e\">禁用<\/span><\/div><\/div>\n<\/div>\n\n<!-- 平台详情+产品代号 -->\n<div id=\"platDetail\" style=\"display:none\">\n<div style=\"display:flex;align-items:center;gap:8px;margin-bottom:12px\">\n<button class=\"btn btn-g btn-sm\" onclick=\"hidePlatDetail()\">← 返回<\/button>\n<span style=\"font-size:15px;font-weight:700\" id=\"pdName\">小红书<\/span>\n<button class=\"btn btn-g btn-sm\" onclick=\"openEditPlat()\">编辑平台<\/button>\n<button class=\"btn btn-d btn-sm\" onclick=\"openM('modal-del')\">删除平台<\/button>\n<\/div>\n\n<div style=\"background:var(--card);border:1px solid var(--bdr);border-radius:10px;padding:14px;margin-bottom:14px\">\n<div style=\"display:flex;gap:20px;font-size:12px\"><div><span style=\"color:var(--sub)\">平台地址:<\/span><span id=\"pdUrl\">https://www.xiaohongshu.com<\/span><\/div><div><span style=\"color:var(--sub)\">状态:<\/span><span class=\"tg tg-ok\">启用<\/span><\/div><div><span style=\"color:var(--sub)\">关联账号:<\/span><span id=\"pdAcct\">12<\/span><\/div><\/div>\n<\/div>\n\n<div style=\"display:flex;justify-content:space-between;align-items:center;margin-bottom:10px\">\n<span style=\"font-size:13px;font-weight:600\">📦 产品代号列表<\/span>\n<button class=\"btn btn-p btn-sm\" onclick=\"openAddProd()\">+ 新增产品代号<\/button>\n<\/div>\n<div class=\"tw\"><table><thead><tr><th>产品代号<\/th><th>产品名称<\/th><th>关联账号数<\/th><th>状态<\/th><th>操作<\/th><\/tr><\/thead>\n<tbody id=\"prodTb\">\n<tr><td><code>PROD001<\/code><\/td><td>美妆种草达人<\/td><td>5<\/td><td><span class=\"tg tg-ok\">启用<\/span><\/td><td><button class=\"btn-l\">编辑<\/button> <button class=\"btn-l\" style=\"color:var(--err)\" onclick=\"openM('modal-del')\">删除<\/button><\/td><\/tr>\n<tr><td><code>PROD002<\/code><\/td><td>护肤品评测<\/td><td>4<\/td><td><span class=\"tg tg-ok\">启用<\/span><\/td><td><button class=\"btn-l\">编辑<\/button> <button class=\"btn-l\" style=\"color:var(--err)\" onclick=\"openM('modal-del')\">删除<\/button><\/td><\/tr>\n<tr><td><code>PROD007<\/code><\/td><td>母婴好物推荐<\/td><td>3<\/td><td><span class=\"tg tg-ok\">启用<\/span><\/td><td><button class=\"btn-l\">编辑<\/button> <button class=\"btn-l\" style=\"color:var(--err)\" onclick=\"openM('modal-del')\">删除<\/button><\/td><\/tr>\n<\/tbody><\/table><\/div>\n<\/div>\n\n<\/div><\/div><\/div>\n\n<script>\nconst PLAT={xhs:{name:'小红书',url:'https://www.xiaohongshu.com',acct:12,prods:[{c:'PROD001',n:'美妆种草达人',a:5},{c:'PROD002',n:'护肤品评测',a:4},{c:'PROD007',n:'母婴好物推荐',a:3}]},douyin:{name:'抖音',url:'https://www.douyin.com',acct:8,prods:[{c:'PROD003',n:'抖音带货王',a:5},{c:'PROD004',n:'短视频营销',a:3}]},fb:{name:'Facebook',url:'https://www.facebook.com',acct:5,prods:[{c:'PROD006',n:'海外社媒投放',a:3},{c:'PROD008',n:'品牌广告',a:2}]},tiktok:{name:'TikTok',url:'https://www.tiktok.com',acct:3,prods:[{c:'PROD009',n:'TikTok达人',a:3}]},wechat:{name:'微信公众号',url:'https://mp.weixin.qq.com',acct:2,prods:[{c:'PROD005',n:'品牌公众号',a:2}]}};\n\nfunction openM(id){document.getElementById(id).classList.add('show')}\nfunction closeM(id){document.getElementById(id).classList.remove('show')}\nfunction showT(m,t){const e=document.getElementById('toast');e.textContent=m;e.className='toast show '+t;setTimeout(()=>e.className='toast',2500)}\n\nfunction showPlatDetail(key){\n const p=PLAT[key];if(!p)return;\n document.getElementById('platDetail').style.display='block';\n document.getElementById('platCards').style.display='none';\n document.getElementById('pdName').textContent=p.name;\n document.getElementById('pdUrl').textContent=p.url;\n document.getElementById('pdAcct').textContent=p.acct;\n document.getElementById('prodTb').innerHTML=p.prods.map(pr=>`<tr><td><code>${pr.c}<\/code><\/td><td>${pr.n}<\/td><td>${pr.a}<\/td><td><span class=\"tg tg-ok\">启用<\/span><\/td><td><button class=\"btn-l\">编辑<\/button> <button class=\"btn-l\" style=\"color:var(--err)\" onclick=\"openM('modal-del')\">删除<\/button><\/td><\/tr>`).join('');\n}\nfunction hidePlatDetail(){document.getElementById('platDetail').style.display='none';document.getElementById('platCards').style.display='grid'}\nfunction openAddPlat(){document.getElementById('mpTitle').textContent='新增平台';document.getElementById('mp-name').value='';document.getElementById('mp-url').value='';openM('modal-plat')}\nfunction openEditPlat(){document.getElementById('mpTitle').textContent='编辑平台';document.getElementById('mp-name').value=document.getElementById('pdName').textContent;document.getElementById('mp-url').value=document.getElementById('pdUrl').textContent;openM('modal-plat')}\nfunction openAddProd(){document.getElementById('mprTitle').textContent='新增产品代号';document.getElementById('mpr-plat').value=document.getElementById('pdName').textContent;openM('modal-prod')}\nfunction filterCards(){const q=document.getElementById('sInput').value.toLowerCase();document.querySelectorAll('.p-card').forEach(c=>{c.style.display=c.dataset.q.toLowerCase().includes(q)?'':'none'})}\ndocument.querySelectorAll('.mo').forEach(m=>m.addEventListener('click',e=>{if(e.target===m)m.classList.remove('show')}));\n<\/script>\n<\/body><\/html>\n",
|
||
"14_Skill调用日志.html": "<!DOCTYPE html><html lang=\"zh-CN\"><head><script>if(window!==window.top)document.documentElement.classList.add(\"in-iframe\")<\/script><style>.in-iframe .side{display:none!important}.in-iframe .main{margin-left:0!important}.in-iframe .layout{min-height:auto}<\/style><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1.0\"><title>Agent任务系统 v2.1 - Skill调用日志<\/title>\n<style>\n*{margin:0;padding:0;box-sizing:border-box}:root{--pri:#6366f1;--bg:#f1f5f9;--card:#fff;--txt:#1e293b;--sub:#64748b;--bdr:#e2e8f0;--ok:#22c55e;--err:#ef4444;--warn:#f59e0b;--side:#1e293b}body{font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",\"PingFang SC\",\"Microsoft YaHei\",sans-serif;background:var(--bg);color:var(--txt);line-height:1.6;font-size:13px}\n.layout{display:flex;min-height:100vh}.side{width:220px;background:var(--side);color:#94a3b8;position:fixed;top:0;left:0;bottom:0;overflow-y:auto;z-index:100}.side .logo{padding:16px 18px;font-size:14px;font-weight:700;color:#fff;border-bottom:1px solid #334155}.ni{display:flex;align-items:center;gap:8px;padding:9px 18px;font-size:12px;color:#94a3b8;cursor:pointer;border-left:3px solid transparent}.ni:hover{background:#334155;color:#e2e8f0}.ni.ac{background:rgba(99,102,241,.15);color:#818cf8;border-left-color:#818cf8;font-weight:600}.ng-t{padding:10px 18px 4px;font-size:10px;letter-spacing:1px;color:#475569;font-weight:600}\n.main{margin-left:220px;flex:1}.hd{height:52px;background:var(--card);border-bottom:1px solid var(--bdr);display:flex;align-items:center;justify-content:space-between;padding:0 24px;font-size:12px;color:var(--sub);position:sticky;top:0;z-index:50}.ct{padding:24px}\n.pt{font-size:20px;font-weight:700;margin-bottom:4px}.pd{font-size:12px;color:var(--sub);margin-bottom:20px}\n.tb{display:flex;gap:8px;align-items:center;margin-bottom:14px;flex-wrap:wrap}.sb{display:flex;align-items:center;gap:6px;background:#f8fafc;border:1px solid var(--bdr);border-radius:7px;padding:7px 12px;font-size:12px}.sb input{border:none;background:none;outline:none;font-size:12px;width:140px}\n.sl{border:1px solid var(--bdr);border-radius:7px;padding:7px 12px;font-size:12px;background:#fff;cursor:pointer}\n.btn{padding:7px 16px;border-radius:7px;font-size:12px;font-weight:500;border:none;cursor:pointer;display:inline-flex;align-items:center;gap:5px;transition:all .12s}.btn-p{background:var(--pri);color:#fff}.btn-g{background:transparent;color:var(--sub);border:1px solid var(--bdr)}.btn-sm{padding:5px 10px;font-size:11px}\n.btn-l{background:none;border:none;color:var(--pri);padding:0;font-size:12px;cursor:pointer}.btn-l:hover{text-decoration:underline}\n.tg{display:inline-block;padding:2px 8px;border-radius:99px;font-size:10px;font-weight:600}.tg-ok{background:#dcfce7;color:#166534}.tg-e{background:#fee2e2;color:#991b1b}.tg-w{background:#fef3c7;color:#92400e}.tg-i{background:#dbeafe;color:#1e40af}.tg-p{background:#f3e8ff;color:#6b21a8}\ntable{width:100%;border-collapse:collapse;font-size:12px}th,td{padding:8px 12px;text-align:left;border-bottom:1px solid var(--bdr)}th{background:#f8fafc;font-weight:600;color:var(--sub);font-size:11px}tr:hover td{background:#fafbfc}.tw{overflow-x:auto;border:1px solid var(--bdr);border-radius:8px}\n.stat{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;margin-bottom:16px}.stat-c{background:var(--card);border:1px solid var(--bdr);border-radius:10px;padding:14px 16px}.stat-c .sv{font-size:22px;font-weight:700}.stat-c .sl2{font-size:11px;color:var(--sub)}\n.pg{display:flex;align-items:center;justify-content:space-between;padding:10px 0;font-size:12px;color:var(--sub)}.pgb{padding:4px 10px;border:1px solid var(--bdr);border-radius:5px;font-size:11px;cursor:pointer;background:var(--card);margin:0 2px}.pgb.ac{background:var(--pri);color:#fff;border-color:var(--pri)}\n.mo{position:fixed;inset:0;background:rgba(0,0,0,.45);display:none;align-items:center;justify-content:center;z-index:200}.mo.show{display:flex}.mc{background:var(--card);border-radius:14px;width:90%;max-width:650px;max-height:88vh;overflow-y:auto;box-shadow:0 20px 60px rgba(0,0,0,.2)}.mh{padding:14px 20px;border-bottom:1px solid var(--bdr);display:flex;justify-content:space-between;align-items:center}.mh h3{font-size:15px}.mx{cursor:pointer;font-size:18px;color:var(--sub);background:none;border:none}.mb{padding:20px}.mf{padding:14px 20px;border-top:1px solid var(--bdr);display:flex;justify-content:flex-end;gap:8px}\n.toast{position:fixed;top:20px;right:20px;padding:12px 20px;border-radius:8px;font-size:13px;font-weight:500;z-index:300;display:none}.toast.show{display:block;animation:tIn .3s}.toast.ok{background:#dcfce7;color:#166534}@keyframes tIn{from{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}\n.log-box{background:#1e293b;color:#a5f3fc;padding:12px;border-radius:8px;font-family:monospace;font-size:11px;max-height:200px;overflow-y:auto;margin-top:10px}\n.json-box{background:#f8fafc;border:1px solid var(--bdr);border-radius:7px;padding:10px;font-family:monospace;font-size:11px;max-height:160px;overflow-y:auto;white-space:pre-wrap}\n.detail-row{display:flex;border-bottom:1px solid var(--bdr);font-size:12px}.detail-row:last-child{border:none}.dr-l{width:90px;padding:8px 0;color:var(--sub);font-weight:500;flex-shrink:0}.dr-v{padding:8px 0;flex:1}\n.tabs{display:flex;border-bottom:2px solid var(--bdr);margin-bottom:14px}.tab{padding:8px 14px;font-size:12px;font-weight:500;color:var(--sub);cursor:pointer;border-bottom:2px solid transparent;margin-bottom:-2px}.tab.ac{color:var(--pri);border-bottom-color:var(--pri);font-weight:600}\n<\/style><\/head><body>\n<div class=\"toast\" id=\"toast\"><\/div>\n\n<div class=\"mo\" id=\"modal-log\"><div class=\"mc\"><div class=\"mh\"><h3>📋 调用详情<\/h3><button class=\"mx\" onclick=\"closeM('modal-log')\">✕<\/button><\/div><div class=\"mb\">\n<div class=\"tabs\" id=\"lgTabs\"><div class=\"tab ac\" onclick=\"switchLT(0)\">基本信息<\/div><div class=\"tab\" onclick=\"switchLT(1)\">请求参数<\/div><div class=\"tab\" onclick=\"switchLT(2)\">响应结果<\/div><div class=\"tab\" onclick=\"switchLT(3)\">执行日志<\/div><\/div>\n<div id=\"lt0\"><div class=\"detail-row\"><div class=\"dr-l\">调用ID<\/div><div class=\"dr-v\"><code>LOG-20260423-001<\/code><\/div><\/div><div class=\"detail-row\"><div class=\"dr-l\">Skill<\/div><div class=\"dr-v\">小红书笔记发布<\/div><\/div><div class=\"detail-row\"><div class=\"dr-l\">执行器<\/div><div class=\"dr-v\">🦞 龙虾执行器<\/div><\/div><div class=\"detail-row\"><div class=\"dr-l\">调用者<\/div><div class=\"dr-v\">张三(投放一组)<\/div><\/div><div class=\"detail-row\"><div class=\"dr-l\">状态<\/div><div class=\"dr-v\"><span class=\"tg tg-ok\">SUCCESS<\/span><\/div><\/div><div class=\"detail-row\"><div class=\"dr-l\">耗时<\/div><div class=\"dr-v\">3.2s<\/div><\/div><div class=\"detail-row\"><div class=\"dr-l\">时间<\/div><div class=\"dr-v\">2026-04-23 10:30:15<\/div><\/div><\/div>\n<div id=\"lt1\" style=\"display:none\"><div class=\"json-box\">{\n \"product_id\": \"PROD001\",\n \"content\": \"今日美妆好物分享!\",\n \"tags\": [\"美妆\", \"种草\"],\n \"channel_code\": \"IC001\"\n}<\/div><\/div>\n<div id=\"lt2\" style=\"display:none\"><div class=\"json-box\">{\n \"status\": \"published\",\n \"post_id\": \"xhs_98765\",\n \"post_url\": \"https://www.xiaohongshu.com/explore/98765\"\n}<\/div><\/div>\n<div id=\"lt3\" style=\"display:none\"><div class=\"log-box\"><div>[10:30:15] 开始调用 Skill: 小红书笔记发布<\/div><div>[10:30:15] 参数校验通过<\/div><div>[10:30:15] 路由: 龙虾执行器 → agent_xhs_publish_01<\/div><div style=\"color:#fbbf24\">[10:30:16] 执行中...<\/div><div style=\"color:#4ade80\">[10:30:18] ✅ 调用成功 (3.2s)<\/div><\/div><\/div>\n<\/div><div class=\"mf\"><button class=\"btn btn-g\" onclick=\"closeM('modal-log')\">关闭<\/button><\/div><\/div><\/div>\n\n<div class=\"layout\">\n<aside class=\"side\">\n<div class=\"logo\">🤖 Agent任务系统 v2.1<\/div>\n<div class=\"ni\">🏠 首页<\/div>\n<div class=\"ng-t\">权限管理<\/div><div class=\"ni\">· 组织架构<\/div><div class=\"ni\">· 菜单管理<\/div><div class=\"ni\">· 角色管理<\/div><div class=\"ni\">· 用户管理<\/div>\n<div class=\"ng-t\">产品管理<\/div><div class=\"ni\">· 产品列表<\/div><div class=\"ni\">· 渠道码<\/div><div class=\"ni\">· 平台套件<\/div>\n<div class=\"ng-t\">平台产品账号<\/div><div class=\"ni\">· 账号管理<\/div>\n<div class=\"ng-t\">Skill中心<\/div><div class=\"ni\">· Skill列表<\/div><div class=\"ni ac\">· 调用日志<\/div>\n<div class=\"ng-t\">任务中心<\/div><div class=\"ni\">· 任务创建<\/div><div class=\"ni\">· 任务列表<\/div>\n<div class=\"ng-t\">日志/设置<\/div><div class=\"ni\">· 操作日志<\/div><div class=\"ni\">· 系统设置<\/div>\n<\/aside>\n<div class=\"main\">\n<div class=\"hd\"><div>🧠 Skill中心 / <b style=\"color:var(--txt)\">调用日志<\/b><\/div><div style=\"display:flex;align-items:center;gap:10px\"><span>🔔<\/span><span>admin<\/span><div style=\"width:28px;height:28px;border-radius:50%;background:var(--pri);color:#fff;display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:600\">A<\/div><\/div><\/div>\n<div class=\"ct\">\n<h1 class=\"pt\">Skill调用日志<\/h1>\n<p class=\"pd\">全量调用记录 · 请求/响应追踪 · 执行日志<\/p>\n\n<div class=\"stat\">\n<div class=\"stat-c\"><div class=\"sv\">12,456<\/div><div class=\"sl2\">总调用<\/div><\/div>\n<div class=\"stat-c\"><div class=\"sv\" style=\"color:var(--ok)\">12,102<\/div><div class=\"sl2\">成功<\/div><\/div>\n<div class=\"stat-c\"><div class=\"sv\" style=\"color:var(--err)\">354<\/div><div class=\"sl2\">失败<\/div><\/div>\n<div class=\"stat-c\"><div class=\"sv\">2.4s<\/div><div class=\"sl2\">平均耗时<\/div><\/div>\n<\/div>\n\n<div class=\"tb\">\n<div class=\"sb\"><span>🔍<\/span><input placeholder=\"搜索Skill/调用者\" id=\"sInput\" oninput=\"filterT()\"><\/div>\n<select class=\"sl\" id=\"fSt\" onchange=\"filterT()\"><option value=\"\">全部状态<\/option><option value=\"SUCCESS\">成功<\/option><option value=\"FAILED\">失败<\/option><option value=\"TIMEOUT\">超时<\/option><\/select>\n<select class=\"sl\" id=\"fExec\" onchange=\"filterT()\"><option value=\"\">全部执行器<\/option><option value=\"lobster\">🦞 龙虾<\/option><option value=\"script\">📜 脚本<\/option><\/select>\n<select class=\"sl\"><option>最近7天<\/option><option>最近30天<\/option><option>全部<\/option><\/select>\n<button class=\"btn btn-g btn-sm\" style=\"margin-left:auto\" onclick=\"showT('📥 导出成功','ok')\">导出CSV<\/button>\n<\/div>\n\n<div class=\"tw\"><table><thead><tr><th>调用ID<\/th><th>Skill<\/th><th>执行器<\/th><th>产品<\/th><th>调用者<\/th><th>状态<\/th><th>耗时<\/th><th>时间<\/th><th>操作<\/th><\/tr><\/thead>\n<tbody id=\"ltb\">\n<tr data-q=\"LOG-001 小红书笔记发布 张三\" data-st=\"SUCCESS\" data-exec=\"lobster\"><td><code style=\"font-size:10px\">LOG-001<\/code><\/td><td>小红书笔记发布<\/td><td><span class=\"tg tg-e\" style=\"background:#fef2f2;color:#dc2626\">🦞<\/span><\/td><td>PROD001<\/td><td>张三<\/td><td><span class=\"tg tg-ok\">SUCCESS<\/span><\/td><td>3.2s<\/td><td>04-23 10:30<\/td><td><button class=\"btn-l\" onclick=\"openM('modal-log')\">详情<\/button><\/td><\/tr>\n<tr data-q=\"LOG-002 抖音视频上传 张三\" data-st=\"SUCCESS\" data-exec=\"lobster\"><td><code style=\"font-size:10px\">LOG-002<\/code><\/td><td>抖音视频上传<\/td><td><span class=\"tg tg-e\" style=\"background:#fef2f2;color:#dc2626\">🦞<\/span><\/td><td>PROD003<\/td><td>张三<\/td><td><span class=\"tg tg-ok\">SUCCESS<\/span><\/td><td>5.8s<\/td><td>04-23 10:15<\/td><td><button class=\"btn-l\" onclick=\"openM('modal-log')\">详情<\/button><\/td><\/tr>\n<tr data-q=\"LOG-003 竞品数据采集 李四\" data-st=\"SUCCESS\" data-exec=\"script\"><td><code style=\"font-size:10px\">LOG-003<\/code><\/td><td>竞品数据采集<\/td><td><span class=\"tg tg-p\">📜<\/span><\/td><td>PROD002<\/td><td>李四<\/td><td><span class=\"tg tg-ok\">SUCCESS<\/span><\/td><td>1.1s<\/td><td>04-23 10:00<\/td><td><button class=\"btn-l\" onclick=\"openM('modal-log')\">详情<\/button><\/td><\/tr>\n<tr data-q=\"LOG-004 Facebook广告 赵六\" data-st=\"FAILED\" data-exec=\"lobster\"><td><code style=\"font-size:10px\">LOG-004<\/code><\/td><td>Facebook广告投放<\/td><td><span class=\"tg tg-e\" style=\"background:#fef2f2;color:#dc2626\">🦞<\/span><\/td><td>PROD006<\/td><td>赵六<\/td><td><span class=\"tg tg-e\">FAILED<\/span><\/td><td>1.5s<\/td><td>04-23 09:45<\/td><td><button class=\"btn-l\" onclick=\"openM('modal-log')\">详情<\/button><\/td><\/tr>\n<tr data-q=\"LOG-005 数据清洗 王五\" data-st=\"SUCCESS\" data-exec=\"script\"><td><code style=\"font-size:10px\">LOG-005<\/code><\/td><td>数据清洗脚本<\/td><td><span class=\"tg tg-p\">📜<\/span><\/td><td>PROD001<\/td><td>王五<\/td><td><span class=\"tg tg-ok\">SUCCESS<\/span><\/td><td>0.8s<\/td><td>04-23 09:30<\/td><td><button class=\"btn-l\" onclick=\"openM('modal-log')\">详情<\/button><\/td><\/tr>\n<tr data-q=\"LOG-006 小红书笔记 王五\" data-st=\"TIMEOUT\" data-exec=\"lobster\"><td><code style=\"font-size:10px\">LOG-006<\/code><\/td><td>小红书笔记发布<\/td><td><span class=\"tg tg-e\" style=\"background:#fef2f2;color:#dc2626\">🦞<\/span><\/td><td>PROD002<\/td><td>王五<\/td><td><span class=\"tg tg-w\">TIMEOUT<\/span><\/td><td>30s<\/td><td>04-23 09:00<\/td><td><button class=\"btn-l\" onclick=\"openM('modal-log')\">详情<\/button><\/td><\/tr>\n<\/tbody><\/table><\/div>\n<div class=\"pg\"><span>共 6 条(示例)<\/span><div><span class=\"pgb ac\">1<\/span><span class=\"pgb\">2<\/span><\/div><\/div>\n\n<\/div><\/div><\/div>\n\n<script>\nfunction openM(id){document.getElementById(id).classList.add('show')}\nfunction closeM(id){document.getElementById(id).classList.remove('show')}\nfunction showT(m,t){const e=document.getElementById('toast');e.textContent=m;e.className='toast show '+t;setTimeout(()=>e.className='toast',2500)}\nfunction switchLT(i){document.querySelectorAll('#lgTabs .tab').forEach((t,j)=>t.classList.toggle('ac',j===i));['lt0','lt1','lt2','lt3'].forEach((d,j)=>document.getElementById(d).style.display=j===i?'block':'none')}\nfunction filterT(){const q=document.getElementById('sInput').value.toLowerCase();const st=document.getElementById('fSt').value;const exec=document.getElementById('fExec').value;document.querySelectorAll('#ltb tr').forEach(tr=>{const d=tr.dataset;tr.style.display=(!q||d.q.toLowerCase().includes(q))&&(!st||d.st===st)&&(!exec||d.exec===exec)?'':'none'})}\ndocument.querySelectorAll('.mo').forEach(m=>m.addEventListener('click',e=>{if(e.target===m)m.classList.remove('show')}));\n<\/script>\n<\/body><\/html>\n",
|
||
"15_操作日志.html": "<!DOCTYPE html><html lang=\"zh-CN\"><head><script>if(window!==window.top)document.documentElement.classList.add(\"in-iframe\")<\/script><style>.in-iframe .side{display:none!important}.in-iframe .main{margin-left:0!important}.in-iframe .layout{min-height:auto}<\/style><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1.0\"><title>Agent任务系统 v2.1 - 操作日志<\/title>\n<style>\n*{margin:0;padding:0;box-sizing:border-box}:root{--pri:#6366f1;--bg:#f1f5f9;--card:#fff;--txt:#1e293b;--sub:#64748b;--bdr:#e2e8f0;--ok:#22c55e;--err:#ef4444;--warn:#f59e0b;--side:#1e293b}body{font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",\"PingFang SC\",\"Microsoft YaHei\",sans-serif;background:var(--bg);color:var(--txt);line-height:1.6;font-size:13px}\n.layout{display:flex;min-height:100vh}.side{width:220px;background:var(--side);color:#94a3b8;position:fixed;top:0;left:0;bottom:0;overflow-y:auto;z-index:100}.side .logo{padding:16px 18px;font-size:14px;font-weight:700;color:#fff;border-bottom:1px solid #334155}.ni{display:flex;align-items:center;gap:8px;padding:9px 18px;font-size:12px;color:#94a3b8;cursor:pointer;border-left:3px solid transparent}.ni:hover{background:#334155;color:#e2e8f0}.ni.ac{background:rgba(99,102,241,.15);color:#818cf8;border-left-color:#818cf8;font-weight:600}.ng-t{padding:10px 18px 4px;font-size:10px;letter-spacing:1px;color:#475569;font-weight:600}\n.main{margin-left:220px;flex:1}.hd{height:52px;background:var(--card);border-bottom:1px solid var(--bdr);display:flex;align-items:center;justify-content:space-between;padding:0 24px;font-size:12px;color:var(--sub);position:sticky;top:0;z-index:50}.ct{padding:24px}\n.pt{font-size:20px;font-weight:700;margin-bottom:4px}.pd{font-size:12px;color:var(--sub);margin-bottom:20px}\n.tb{display:flex;gap:8px;align-items:center;margin-bottom:14px;flex-wrap:wrap}.sb{display:flex;align-items:center;gap:6px;background:#f8fafc;border:1px solid var(--bdr);border-radius:7px;padding:7px 12px;font-size:12px}.sb input{border:none;background:none;outline:none;font-size:12px;width:140px}\n.sl{border:1px solid var(--bdr);border-radius:7px;padding:7px 12px;font-size:12px;background:#fff;cursor:pointer}\n.btn{padding:7px 16px;border-radius:7px;font-size:12px;font-weight:500;border:none;cursor:pointer;display:inline-flex;align-items:center;gap:5px}.btn-g{background:transparent;color:var(--sub);border:1px solid var(--bdr)}.btn-sm{padding:5px 10px;font-size:11px}\n.btn-l{background:none;border:none;color:var(--pri);padding:0;font-size:12px;cursor:pointer}.btn-l:hover{text-decoration:underline}\n.tg{display:inline-block;padding:2px 8px;border-radius:99px;font-size:10px;font-weight:600}.tg-ok{background:#dcfce7;color:#166534}.tg-e{background:#fee2e2;color:#991b1b}.tg-i{background:#dbeafe;color:#1e40af}.tg-w{background:#fef3c7;color:#92400e}.tg-p{background:#f3e8ff;color:#6b21a8}.tg-g{background:#f1f5f9;color:#64748b}\ntable{width:100%;border-collapse:collapse;font-size:12px}th,td{padding:8px 12px;text-align:left;border-bottom:1px solid var(--bdr)}th{background:#f8fafc;font-weight:600;color:var(--sub);font-size:11px}tr:hover td{background:#fafbfc}.tw{overflow-x:auto;border:1px solid var(--bdr);border-radius:8px}\n.pg{display:flex;align-items:center;justify-content:space-between;padding:10px 0;font-size:12px;color:var(--sub)}.pgb{padding:4px 10px;border:1px solid var(--bdr);border-radius:5px;font-size:11px;cursor:pointer;background:var(--card);margin:0 2px}.pgb.ac{background:var(--pri);color:#fff;border-color:var(--pri)}\n.mo{position:fixed;inset:0;background:rgba(0,0,0,.45);display:none;align-items:center;justify-content:center;z-index:200}.mo.show{display:flex}.mc{background:var(--card);border-radius:14px;width:90%;max-width:600px;max-height:85vh;overflow-y:auto;box-shadow:0 20px 60px rgba(0,0,0,.2)}.mh{padding:14px 20px;border-bottom:1px solid var(--bdr);display:flex;justify-content:space-between;align-items:center}.mh h3{font-size:15px}.mx{cursor:pointer;font-size:18px;color:var(--sub);background:none;border:none}.mb{padding:20px}.mf{padding:14px 20px;border-top:1px solid var(--bdr);display:flex;justify-content:flex-end;gap:8px}\n.toast{position:fixed;top:20px;right:20px;padding:12px 20px;border-radius:8px;font-size:13px;font-weight:500;z-index:300;display:none}.toast.show{display:block;animation:tIn .3s}.toast.ok{background:#dcfce7;color:#166534}@keyframes tIn{from{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}\n.json-box{background:#f8fafc;border:1px solid var(--bdr);border-radius:7px;padding:10px;font-family:monospace;font-size:11px;max-height:200px;overflow-y:auto;white-space:pre-wrap}\n.detail-row{display:flex;border-bottom:1px solid var(--bdr);font-size:12px}.detail-row:last-child{border:none}.dr-l{width:80px;padding:8px 0;color:var(--sub);font-weight:500;flex-shrink:0}.dr-v{padding:8px 0;flex:1}\n<\/style><\/head><body>\n<div class=\"toast\" id=\"toast\"><\/div>\n\n<div class=\"mo\" id=\"modal-detail\"><div class=\"mc\"><div class=\"mh\"><h3>📋 操作详情<\/h3><button class=\"mx\" onclick=\"closeM('modal-detail')\">✕<\/button><\/div><div class=\"mb\">\n<div class=\"detail-row\"><div class=\"dr-l\">日志ID<\/div><div class=\"dr-v\"><code>OPLOG-001<\/code><\/div><\/div>\n<div class=\"detail-row\"><div class=\"dr-l\">操作人<\/div><div class=\"dr-v\">admin<\/div><\/div>\n<div class=\"detail-row\"><div class=\"dr-l\">模块<\/div><div class=\"dr-v\">用户管理<\/div><\/div>\n<div class=\"detail-row\"><div class=\"dr-l\">操作<\/div><div class=\"dr-v\"><span class=\"tg tg-ok\">新增<\/span><\/div><\/div>\n<div class=\"detail-row\"><div class=\"dr-l\">IP<\/div><div class=\"dr-v\">192.168.1.100<\/div><\/div>\n<div class=\"detail-row\"><div class=\"dr-l\">时间<\/div><div class=\"dr-v\">2026-04-23 10:30:15<\/div><\/div>\n<div style=\"margin-top:10px;font-size:12px;font-weight:600;margin-bottom:6px\">请求参数<\/div>\n<div class=\"json-box\">{\n \"username\": \"zhangsan\",\n \"real_name\": \"张三\",\n \"dept_id\": 3,\n \"role_ids\": [1, 2]\n}<\/div>\n<div style=\"margin-top:10px;font-size:12px;font-weight:600;margin-bottom:6px\">变更内容<\/div>\n<div class=\"json-box\">{\n \"before\": null,\n \"after\": {\n \"id\": 15,\n \"username\": \"zhangsan\",\n \"status\": 1\n }\n}<\/div>\n<\/div><div class=\"mf\"><button class=\"btn btn-g\" onclick=\"closeM('modal-detail')\">关闭<\/button><\/div><\/div><\/div>\n\n<div class=\"layout\">\n<aside class=\"side\">\n<div class=\"logo\">🤖 Agent任务系统 v2.1<\/div>\n<div class=\"ni\">🏠 首页<\/div>\n<div class=\"ng-t\">权限管理<\/div><div class=\"ni\">· 组织架构<\/div><div class=\"ni\">· 菜单管理<\/div><div class=\"ni\">· 角色管理<\/div><div class=\"ni\">· 用户管理<\/div>\n<div class=\"ng-t\">产品管理<\/div><div class=\"ni\">· 产品列表<\/div><div class=\"ni\">· 渠道码<\/div><div class=\"ni\">· 平台套件<\/div>\n<div class=\"ng-t\">平台产品账号<\/div><div class=\"ni\">· 账号管理<\/div>\n<div class=\"ng-t\">Skill中心<\/div><div class=\"ni\">· Skill列表<\/div><div class=\"ni\">· 调用日志<\/div>\n<div class=\"ng-t\">任务中心<\/div><div class=\"ni\">· 任务创建<\/div><div class=\"ni\">· 任务列表<\/div>\n<div class=\"ng-t\">日志/设置<\/div><div class=\"ni ac\">· 操作日志<\/div><div class=\"ni\">· 系统设置<\/div>\n<\/aside>\n<div class=\"main\">\n<div class=\"hd\"><div>📝 日志中心 / <b style=\"color:var(--txt)\">操作日志<\/b><\/div><div style=\"display:flex;align-items:center;gap:10px\"><span>🔔<\/span><span>admin<\/span><div style=\"width:28px;height:28px;border-radius:50%;background:var(--pri);color:#fff;display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:600\">A<\/div><\/div><\/div>\n<div class=\"ct\">\n<h1 class=\"pt\">操作日志<\/h1>\n<p class=\"pd\">全局操作审计 · 变更追踪 · 请求参数/变更内容记录<\/p>\n\n<div class=\"tb\">\n<div class=\"sb\"><span>🔍<\/span><input placeholder=\"搜索操作人/模块\" id=\"sInput\" oninput=\"filterT()\"><\/div>\n<select class=\"sl\" id=\"fMod\" onchange=\"filterT()\"><option value=\"\">全部模块<\/option><option value=\"用户管理\">用户管理<\/option><option value=\"角色管理\">角色管理<\/option><option value=\"产品管理\">产品管理<\/option><option value=\"Skill管理\">Skill管理<\/option><option value=\"任务管理\">任务管理<\/option><option value=\"平台产品账号\">平台产品账号<\/option><option value=\"登录\">登录<\/option><\/select>\n<select class=\"sl\" id=\"fAct\" onchange=\"filterT()\"><option value=\"\">全部操作<\/option><option value=\"新增\">新增<\/option><option value=\"编辑\">编辑<\/option><option value=\"删除\">删除<\/option><option value=\"登录\">登录<\/option><option value=\"导出\">导出<\/option><\/select>\n<select class=\"sl\"><option>最近7天<\/option><option>最近30天<\/option><option>全部<\/option><\/select>\n<button class=\"btn btn-g btn-sm\" style=\"margin-left:auto\" onclick=\"showT('📥 导出成功','ok')\">导出<\/button>\n<\/div>\n\n<div class=\"tw\"><table><thead><tr><th>日志ID<\/th><th>操作人<\/th><th>模块<\/th><th>操作<\/th><th>描述<\/th><th>IP<\/th><th>时间<\/th><th>操作<\/th><\/tr><\/thead>\n<tbody id=\"otb\">\n<tr data-q=\"OPLOG-001 admin 用户管理\" data-mod=\"用户管理\" data-act=\"新增\"><td><code style=\"font-size:10px\">OPLOG-001<\/code><\/td><td>admin<\/td><td>用户管理<\/td><td><span class=\"tg tg-ok\">新增<\/span><\/td><td>新增用户: 张三<\/td><td>192.168.1.100<\/td><td>04-23 10:30<\/td><td><button class=\"btn-l\" onclick=\"openM('modal-detail')\">详情<\/button><\/td><\/tr>\n<tr data-q=\"OPLOG-002 admin 角色管理\" data-mod=\"角色管理\" data-act=\"编辑\"><td><code style=\"font-size:10px\">OPLOG-002<\/code><\/td><td>admin<\/td><td>角色管理<\/td><td><span class=\"tg tg-i\">编辑<\/span><\/td><td>修改角色权限: 投放一组主管<\/td><td>192.168.1.100<\/td><td>04-23 10:25<\/td><td><button class=\"btn-l\" onclick=\"openM('modal-detail')\">详情<\/button><\/td><\/tr>\n<tr data-q=\"OPLOG-003 张三 任务管理\" data-mod=\"任务管理\" data-act=\"新增\"><td><code style=\"font-size:10px\">OPLOG-003<\/code><\/td><td>张三<\/td><td>任务管理<\/td><td><span class=\"tg tg-ok\">新增<\/span><\/td><td>创建任务: 小红书笔记发布<\/td><td>192.168.1.105<\/td><td>04-23 10:20<\/td><td><button class=\"btn-l\" onclick=\"openM('modal-detail')\">详情<\/button><\/td><\/tr>\n<tr data-q=\"OPLOG-004 admin Skill管理\" data-mod=\"Skill管理\" data-act=\"编辑\"><td><code style=\"font-size:10px\">OPLOG-004<\/code><\/td><td>admin<\/td><td>Skill管理<\/td><td><span class=\"tg tg-i\">编辑<\/span><\/td><td>更新Skill: 竞品数据采集 执行器配置<\/td><td>192.168.1.100<\/td><td>04-23 10:15<\/td><td><button class=\"btn-l\" onclick=\"openM('modal-detail')\">详情<\/button><\/td><\/tr>\n<tr data-q=\"OPLOG-005 admin 平台产品账号\" data-mod=\"平台产品账号\" data-act=\"新增\"><td><code style=\"font-size:10px\">OPLOG-005<\/code><\/td><td>admin<\/td><td>平台产品账号<\/td><td><span class=\"tg tg-ok\">新增<\/span><\/td><td>新增账号: 小红书-PROD001-beauty01<\/td><td>192.168.1.100<\/td><td>04-23 10:10<\/td><td><button class=\"btn-l\" onclick=\"openM('modal-detail')\">详情<\/button><\/td><\/tr>\n<tr data-q=\"OPLOG-006 admin 产品管理\" data-mod=\"产品管理\" data-act=\"删除\"><td><code style=\"font-size:10px\">OPLOG-006<\/code><\/td><td>admin<\/td><td>产品管理<\/td><td><span class=\"tg tg-e\">删除<\/span><\/td><td>删除产品: 测试产品X<\/td><td>192.168.1.100<\/td><td>04-23 09:50<\/td><td><button class=\"btn-l\" onclick=\"openM('modal-detail')\">详情<\/button><\/td><\/tr>\n<tr data-q=\"OPLOG-007 李四 登录\" data-mod=\"登录\" data-act=\"登录\"><td><code style=\"font-size:10px\">OPLOG-007<\/code><\/td><td>李四<\/td><td>登录<\/td><td><span class=\"tg tg-g\">登录<\/span><\/td><td>用户登录成功<\/td><td>192.168.1.108<\/td><td>04-23 09:30<\/td><td><button class=\"btn-l\" onclick=\"openM('modal-detail')\">详情<\/button><\/td><\/tr>\n<tr data-q=\"OPLOG-008 张三 任务管理\" data-mod=\"任务管理\" data-act=\"导出\"><td><code style=\"font-size:10px\">OPLOG-008<\/code><\/td><td>张三<\/td><td>任务管理<\/td><td><span class=\"tg tg-w\">导出<\/span><\/td><td>导出任务列表(共45条)<\/td><td>192.168.1.105<\/td><td>04-23 09:15<\/td><td><button class=\"btn-l\" onclick=\"openM('modal-detail')\">详情<\/button><\/td><\/tr>\n<\/tbody><\/table><\/div>\n<div class=\"pg\"><span>共 8 条<\/span><div><span class=\"pgb ac\">1<\/span><span class=\"pgb\">2<\/span><\/div><\/div>\n\n<\/div><\/div><\/div>\n\n<script>\nfunction openM(id){document.getElementById(id).classList.add('show')}\nfunction closeM(id){document.getElementById(id).classList.remove('show')}\nfunction showT(m,t){const e=document.getElementById('toast');e.textContent=m;e.className='toast show '+t;setTimeout(()=>e.className='toast',2500)}\nfunction filterT(){const q=document.getElementById('sInput').value.toLowerCase();const mod=document.getElementById('fMod').value;const act=document.getElementById('fAct').value;document.querySelectorAll('#otb tr').forEach(tr=>{const d=tr.dataset;tr.style.display=(!q||d.q.toLowerCase().includes(q))&&(!mod||d.mod===mod)&&(!act||d.act===act)?'':'none'})}\ndocument.querySelectorAll('.mo').forEach(m=>m.addEventListener('click',e=>{if(e.target===m)m.classList.remove('show')}));\n<\/script>\n<\/body><\/html>",
|
||
"16_统计报表.html": "<!DOCTYPE html><html lang=\"zh-CN\"><head><script>if(window!==window.top)document.documentElement.classList.add(\"in-iframe\")<\/script><style>.in-iframe .side{display:none!important}.in-iframe .main{margin-left:0!important}.in-iframe .layout{min-height:auto}<\/style><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1.0\"><title>Agent任务系统 v2.1 - 统计报表<\/title>\n<style>\n*{margin:0;padding:0;box-sizing:border-box}:root{--pri:#6366f1;--bg:#f1f5f9;--card:#fff;--txt:#1e293b;--sub:#64748b;--bdr:#e2e8f0;--ok:#22c55e;--err:#ef4444;--warn:#f59e0b;--side:#1e293b}body{font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",\"PingFang SC\",\"Microsoft YaHei\",sans-serif;background:var(--bg);color:var(--txt);line-height:1.6;font-size:13px}\n.layout{display:flex;min-height:100vh}.side{width:220px;background:var(--side);color:#94a3b8;position:fixed;top:0;left:0;bottom:0;overflow-y:auto;z-index:100}.side .logo{padding:16px 18px;font-size:14px;font-weight:700;color:#fff;border-bottom:1px solid #334155}.ni{display:flex;align-items:center;gap:8px;padding:9px 18px;font-size:12px;color:#94a3b8;cursor:pointer;border-left:3px solid transparent}.ni:hover{background:#334155;color:#e2e8f0}.ni.ac{background:rgba(99,102,241,.15);color:#818cf8;border-left-color:#818cf8;font-weight:600}.ng-t{padding:10px 18px 4px;font-size:10px;letter-spacing:1px;color:#475569;font-weight:600}\n.main{margin-left:220px;flex:1}.hd{height:52px;background:var(--card);border-bottom:1px solid var(--bdr);display:flex;align-items:center;justify-content:space-between;padding:0 24px;font-size:12px;color:var(--sub);position:sticky;top:0;z-index:50}.ct{padding:24px}\n.pt{font-size:20px;font-weight:700;margin-bottom:4px}.pd{font-size:12px;color:var(--sub);margin-bottom:20px}\n.btn{padding:7px 16px;border-radius:7px;font-size:12px;font-weight:500;border:none;cursor:pointer;display:inline-flex;align-items:center;gap:5px}.btn-g{background:transparent;color:var(--sub);border:1px solid var(--bdr)}.btn-sm{padding:5px 10px;font-size:11px}.btn-p{background:var(--pri);color:#fff}\n.sl{border:1px solid var(--bdr);border-radius:7px;padding:7px 12px;font-size:12px;background:#fff;cursor:pointer}\n.stat{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;margin-bottom:20px}.stat-c{background:var(--card);border:1px solid var(--bdr);border-radius:10px;padding:16px}.stat-c .sv{font-size:26px;font-weight:700}.stat-c .sl2{font-size:11px;color:var(--sub)}.stat-c .delta{font-size:11px;margin-top:4px}\n.chart-grid{display:grid;grid-template-columns:1fr 1fr;gap:14px;margin-bottom:14px}.chart-card{background:var(--card);border:1px solid var(--bdr);border-radius:10px;padding:16px}.chart-card h3{font-size:13px;font-weight:600;margin-bottom:12px}\n.bar-chart{display:flex;align-items:flex-end;gap:8px;height:160px;padding-top:10px}.bar-col{display:flex;flex-direction:column;align-items:center;flex:1}.bar-fill{width:100%;border-radius:4px 4px 0 0;transition:height .5s;min-height:4px}.bar-label{font-size:9px;color:var(--sub);margin-top:4px;white-space:nowrap}.bar-val{font-size:10px;font-weight:600;margin-bottom:2px}\n.pie-chart{display:flex;align-items:center;gap:20px}.pie-svg{width:140px;height:140px}.pie-legend{font-size:11px}.pie-legend div{display:flex;align-items:center;gap:6px;margin-bottom:6px}.pie-dot{width:10px;height:10px;border-radius:50%;flex-shrink:0}\n.line-chart{position:relative;height:160px;border-left:1px solid var(--bdr);border-bottom:1px solid var(--bdr)}.line-chart svg{width:100%;height:100%}\n.rank-list{font-size:12px}.rank-item{display:flex;align-items:center;gap:8px;padding:6px 0;border-bottom:1px solid #f1f5f9}.rank-num{width:20px;height:20px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:10px;font-weight:700;color:#fff;flex-shrink:0}.rank-name{flex:1}.rank-val{font-weight:600}\n.toast{position:fixed;top:20px;right:20px;padding:12px 20px;border-radius:8px;font-size:13px;font-weight:500;z-index:300;display:none}.toast.show{display:block;animation:tIn .3s}.toast.ok{background:#dcfce7;color:#166534}@keyframes tIn{from{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}\n.tabs{display:flex;border-bottom:2px solid var(--bdr);margin-bottom:16px}.tab{padding:8px 16px;font-size:12px;font-weight:500;color:var(--sub);cursor:pointer;border-bottom:2px solid transparent;margin-bottom:-2px}.tab.ac{color:var(--pri);border-bottom-color:var(--pri);font-weight:600}\n<\/style><\/head><body>\n<div class=\"toast\" id=\"toast\"><\/div>\n<div class=\"layout\">\n<aside class=\"side\">\n<div class=\"logo\">🤖 Agent任务系统 v2.1<\/div>\n<div class=\"ni\">🏠 首页<\/div>\n<div class=\"ng-t\">权限管理<\/div><div class=\"ni\">· 组织架构<\/div><div class=\"ni\">· 菜单管理<\/div><div class=\"ni\">· 角色管理<\/div><div class=\"ni\">· 用户管理<\/div>\n<div class=\"ng-t\">产品管理<\/div><div class=\"ni\">· 产品列表<\/div><div class=\"ni\">· 渠道码<\/div><div class=\"ni\">· 平台套件<\/div>\n<div class=\"ng-t\">平台产品账号<\/div><div class=\"ni\">· 账号管理<\/div>\n<div class=\"ng-t\">Skill中心<\/div><div class=\"ni\">· Skill列表<\/div><div class=\"ni\">· 调用日志<\/div>\n<div class=\"ng-t\">任务中心<\/div><div class=\"ni\">· 任务创建<\/div><div class=\"ni\">· 任务列表<\/div>\n<div class=\"ng-t\">日志/设置<\/div><div class=\"ni\">· 操作日志<\/div><div class=\"ni ac\">· 统计报表<\/div><div class=\"ni\">· 系统设置<\/div>\n<\/aside>\n<div class=\"main\">\n<div class=\"hd\"><div>📊 日志中心 / <b style=\"color:var(--txt)\">统计报表<\/b><\/div><div style=\"display:flex;align-items:center;gap:10px\"><span>🔔<\/span><span>admin<\/span><div style=\"width:28px;height:28px;border-radius:50%;background:var(--pri);color:#fff;display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:600\">A<\/div><\/div><\/div>\n<div class=\"ct\">\n<h1 class=\"pt\">统计报表<\/h1>\n<p class=\"pd\">任务执行趋势 · Skill调用分布 · 产品/用户排行<\/p>\n\n<div style=\"display:flex;gap:8px;margin-bottom:16px\">\n<select class=\"sl\" id=\"dateRange\" onchange=\"refreshCharts()\"><option>最近7天<\/option><option>最近30天<\/option><option>本月<\/option><option>上月<\/option><\/select>\n<button class=\"btn btn-g btn-sm\" onclick=\"refreshCharts()\">🔄 刷新<\/button>\n<button class=\"btn btn-g btn-sm\" onclick=\"showT('📥 报表已导出','ok')\">导出PDF<\/button>\n<\/div>\n\n<div class=\"stat\">\n<div class=\"stat-c\"><div class=\"sv\">1,234<\/div><div class=\"sl2\">任务总数<\/div><div class=\"delta\" style=\"color:var(--ok)\">↑ 12.5% vs 上周<\/div><\/div>\n<div class=\"stat-c\"><div class=\"sv\" style=\"color:var(--ok)\">96.3%<\/div><div class=\"sl2\">成功率<\/div><div class=\"delta\" style=\"color:var(--ok)\">↑ 1.2%<\/div><\/div>\n<div class=\"stat-c\"><div class=\"sv\">2.4s<\/div><div class=\"sl2\">平均耗时<\/div><div class=\"delta\" style=\"color:var(--ok)\">↓ 0.3s<\/div><\/div>\n<div class=\"stat-c\"><div class=\"sv\">18<\/div><div class=\"sl2\">活跃Skill<\/div><div class=\"delta\" style=\"color:var(--sub)\">— 持平<\/div><\/div>\n<\/div>\n\n<div class=\"chart-grid\">\n<!-- 任务趋势 -->\n<div class=\"chart-card\"><h3>📈 任务执行趋势(7日)<\/h3>\n<div class=\"bar-chart\" id=\"trendChart\">\n<div class=\"bar-col\"><div class=\"bar-val\">156<\/div><div class=\"bar-fill\" style=\"height:65%;background:var(--pri)\"><\/div><div class=\"bar-label\">04-17<\/div><\/div>\n<div class=\"bar-col\"><div class=\"bar-val\">189<\/div><div class=\"bar-fill\" style=\"height:78%;background:var(--pri)\"><\/div><div class=\"bar-label\">04-18<\/div><\/div>\n<div class=\"bar-col\"><div class=\"bar-val\">145<\/div><div class=\"bar-fill\" style=\"height:60%;background:var(--pri)\"><\/div><div class=\"bar-label\">04-19<\/div><\/div>\n<div class=\"bar-col\"><div class=\"bar-val\">201<\/div><div class=\"bar-fill\" style=\"height:84%;background:var(--pri)\"><\/div><div class=\"bar-label\">04-20<\/div><\/div>\n<div class=\"bar-col\"><div class=\"bar-val\">178<\/div><div class=\"bar-fill\" style=\"height:74%;background:var(--pri)\"><\/div><div class=\"bar-label\">04-21<\/div><\/div>\n<div class=\"bar-col\"><div class=\"bar-val\">210<\/div><div class=\"bar-fill\" style=\"height:88%;background:var(--pri)\"><\/div><div class=\"bar-label\">04-22<\/div><\/div>\n<div class=\"bar-col\"><div class=\"bar-val\">155<\/div><div class=\"bar-fill\" style=\"height:64%;background:var(--pri)\"><\/div><div class=\"bar-label\">04-23<\/div><\/div>\n<\/div><\/div>\n\n<!-- 执行器分布 -->\n<div class=\"chart-card\"><h3>🎯 执行器分布<\/h3>\n<div class=\"pie-chart\">\n<svg class=\"pie-svg\" viewBox=\"0 0 42 42\"><circle cx=\"21\" cy=\"21\" r=\"15.9\" fill=\"transparent\" stroke=\"#6366f1\" stroke-width=\"6\" stroke-dasharray=\"67 33\" stroke-dashoffset=\"25\"/><circle cx=\"21\" cy=\"21\" r=\"15.9\" fill=\"transparent\" stroke=\"#f59e0b\" stroke-width=\"6\" stroke-dasharray=\"33 67\" stroke-dashoffset=\"58\"/><\/svg>\n<div class=\"pie-legend\">\n<div><div class=\"pie-dot\" style=\"background:#6366f1\"><\/div>🦞 龙虾执行器 <b>67%<\/b> (827)<\/div>\n<div><div class=\"pie-dot\" style=\"background:#f59e0b\"><\/div>📜 脚本执行器 <b>33%<\/b> (407)<\/div>\n<\/div><\/div><\/div>\n\n<!-- 状态分布 -->\n<div class=\"chart-card\"><h3>📊 任务状态分布<\/h3>\n<div class=\"bar-chart\">\n<div class=\"bar-col\"><div class=\"bar-val\">1,089<\/div><div class=\"bar-fill\" style=\"height:90%;background:var(--ok)\"><\/div><div class=\"bar-label\">成功<\/div><\/div>\n<div class=\"bar-col\"><div class=\"bar-val\">45<\/div><div class=\"bar-fill\" style=\"height:12%;background:var(--err)\"><\/div><div class=\"bar-label\">失败<\/div><\/div>\n<div class=\"bar-col\"><div class=\"bar-val\">8<\/div><div class=\"bar-fill\" style=\"height:6%;background:#3b82f6\"><\/div><div class=\"bar-label\">运行中<\/div><\/div>\n<div class=\"bar-col\"><div class=\"bar-val\">92<\/div><div class=\"bar-fill\" style=\"height:18%;background:var(--warn)\"><\/div><div class=\"bar-label\">超时<\/div><\/div>\n<\/div><\/div>\n\n<!-- Skill排行 -->\n<div class=\"chart-card\"><h3>🏆 Skill调用排行 TOP5<\/h3>\n<div class=\"rank-list\">\n<div class=\"rank-item\"><div class=\"rank-num\" style=\"background:#f59e0b\">1<\/div><div class=\"rank-name\">数据清洗脚本<\/div><div class=\"rank-val\">5,123<\/div><\/div>\n<div class=\"rank-item\"><div class=\"rank-num\" style=\"background:#94a3b8\">2<\/div><div class=\"rank-name\">竞品数据采集<\/div><div class=\"rank-val\">3,401<\/div><\/div>\n<div class=\"rank-item\"><div class=\"rank-num\" style=\"background:#d97706\">3<\/div><div class=\"rank-name\">小红书笔记发布<\/div><div class=\"rank-val\">1,256<\/div><\/div>\n<div class=\"rank-item\"><div class=\"rank-num\" style=\"background:var(--sub)\">4<\/div><div class=\"rank-name\">抖音视频上传<\/div><div class=\"rank-val\">892<\/div><\/div>\n<div class=\"rank-item\"><div class=\"rank-num\" style=\"background:var(--sub)\">5<\/div><div class=\"rank-name\">Facebook广告投放<\/div><div class=\"rank-val\">567<\/div><\/div>\n<\/div><\/div>\n<\/div>\n\n<!-- 产品/用户排行 -->\n<div class=\"chart-grid\">\n<div class=\"chart-card\"><h3>📦 产品任务量排行<\/h3>\n<div class=\"rank-list\">\n<div class=\"rank-item\"><div class=\"rank-num\" style=\"background:#f59e0b\">1<\/div><div class=\"rank-name\">PROD001 美妆种草达人<\/div><div class=\"rank-val\">456<\/div><\/div>\n<div class=\"rank-item\"><div class=\"rank-num\" style=\"background:#94a3b8\">2<\/div><div class=\"rank-name\">PROD003 抖音带货王<\/div><div class=\"rank-val\">312<\/div><\/div>\n<div class=\"rank-item\"><div class=\"rank-num\" style=\"background:#d97706\">3<\/div><div class=\"rank-name\">PROD002 护肤品评测<\/div><div class=\"rank-val\">289<\/div><\/div>\n<div class=\"rank-item\"><div class=\"rank-num\" style=\"background:var(--sub)\">4<\/div><div class=\"rank-name\">PROD006 海外社媒投放<\/div><div class=\"rank-val\">177<\/div><\/div>\n<\/div><\/div>\n<div class=\"chart-card\"><h3>👤 用户活跃排行<\/h3>\n<div class=\"rank-list\">\n<div class=\"rank-item\"><div class=\"rank-num\" style=\"background:#f59e0b\">1<\/div><div class=\"rank-name\">张三(投放一组)<\/div><div class=\"rank-val\">389 任务<\/div><\/div>\n<div class=\"rank-item\"><div class=\"rank-num\" style=\"background:#94a3b8\">2<\/div><div class=\"rank-name\">李四(投放二组)<\/div><div class=\"rank-val\">267 任务<\/div><\/div>\n<div class=\"rank-item\"><div class=\"rank-num\" style=\"background:#d97706\">3<\/div><div class=\"rank-name\">王五(投放一组)<\/div><div class=\"rank-val\">198 任务<\/div><\/div>\n<div class=\"rank-item\"><div class=\"rank-num\" style=\"background:var(--sub)\">4<\/div><div class=\"rank-name\">赵六(投放二组)<\/div><div class=\"rank-val\">156 任务<\/div><\/div>\n<\/div><\/div>\n<\/div>\n\n<\/div><\/div><\/div>\n\n<script>\nfunction showT(m,t){const e=document.getElementById('toast');e.textContent=m;e.className='toast show '+t;setTimeout(()=>e.className='toast',2500)}\nfunction refreshCharts(){\n document.querySelectorAll('.bar-fill').forEach(b=>{\n const h=parseInt(b.style.height);\n b.style.height='0%';\n setTimeout(()=>b.style.height=h+'%',50);\n });\n showT('📊 数据已刷新','ok');\n}\n<\/script>\n<\/body><\/html>",
|
||
"17_执行器配置.html": "<!DOCTYPE html><html lang=\"zh-CN\"><head><script>if(window!==window.top)document.documentElement.classList.add(\"in-iframe\")<\/script><style>.in-iframe .side{display:none!important}.in-iframe .main{margin-left:0!important}.in-iframe .layout{min-height:auto}<\/style><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1.0\"><title>Agent任务系统 v2.1 - 执行器配置<\/title>\n<style>\n*{margin:0;padding:0;box-sizing:border-box}:root{--pri:#6366f1;--bg:#f1f5f9;--card:#fff;--txt:#1e293b;--sub:#64748b;--bdr:#e2e8f0;--ok:#22c55e;--err:#ef4444;--warn:#f59e0b;--side:#1e293b}body{font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",\"PingFang SC\",\"Microsoft YaHei\",sans-serif;background:var(--bg);color:var(--txt);line-height:1.6;font-size:13px}\n.layout{display:flex;min-height:100vh}.side{width:220px;background:var(--side);color:#94a3b8;position:fixed;top:0;left:0;bottom:0;overflow-y:auto;z-index:100}.side .logo{padding:16px 18px;font-size:14px;font-weight:700;color:#fff;border-bottom:1px solid #334155}.ni{display:flex;align-items:center;gap:8px;padding:9px 18px;font-size:12px;color:#94a3b8;cursor:pointer;border-left:3px solid transparent}.ni:hover{background:#334155;color:#e2e8f0}.ni.ac{background:rgba(99,102,241,.15);color:#818cf8;border-left-color:#818cf8;font-weight:600}.ng-t{padding:10px 18px 4px;font-size:10px;letter-spacing:1px;color:#475569;font-weight:600}\n.main{margin-left:220px;flex:1}.hd{height:52px;background:var(--card);border-bottom:1px solid var(--bdr);display:flex;align-items:center;justify-content:space-between;padding:0 24px;font-size:12px;color:var(--sub);position:sticky;top:0;z-index:50}.ct{padding:24px}\n.pt{font-size:20px;font-weight:700;margin-bottom:4px}.pd{font-size:12px;color:var(--sub);margin-bottom:20px}\n.btn{padding:7px 16px;border-radius:7px;font-size:12px;font-weight:500;border:none;cursor:pointer;display:inline-flex;align-items:center;gap:5px;transition:all .12s}.btn-p{background:var(--pri);color:#fff}.btn-p:hover{background:#4f46e5}.btn-d{background:#fee2e2;color:#dc2626}.btn-g{background:transparent;color:var(--sub);border:1px solid var(--bdr)}.btn-sm{padding:5px 10px;font-size:11px}.btn-s{background:var(--ok);color:#fff}.btn-w{background:var(--warn);color:#fff}\n.tg{display:inline-block;padding:2px 8px;border-radius:99px;font-size:10px;font-weight:600}.tg-ok{background:#dcfce7;color:#166534}.tg-e{background:#fee2e2;color:#991b1b}.tg-w{background:#fef3c7;color:#92400e}\n.fg{margin-bottom:14px}.fl{font-size:12px;font-weight:500;margin-bottom:5px;display:block}.fl .rq{color:var(--err)}.fi{width:100%;padding:8px 12px;border:1px solid var(--bdr);border-radius:7px;font-size:12px;outline:none}.fi:focus{border-color:var(--pri)}.fs{width:100%;padding:8px 12px;border:1px solid var(--bdr);border-radius:7px;font-size:12px;background:#fff}.fr{display:grid;grid-template-columns:1fr 1fr;gap:14px}\n.mo{position:fixed;inset:0;background:rgba(0,0,0,.45);display:none;align-items:center;justify-content:center;z-index:200}.mo.show{display:flex}.mc{background:var(--card);border-radius:14px;width:90%;max-width:580px;max-height:85vh;overflow-y:auto;box-shadow:0 20px 60px rgba(0,0,0,.2)}.mh{padding:14px 20px;border-bottom:1px solid var(--bdr);display:flex;justify-content:space-between;align-items:center}.mh h3{font-size:15px}.mx{cursor:pointer;font-size:18px;color:var(--sub);background:none;border:none}.mb{padding:20px}.mf{padding:14px 20px;border-top:1px solid var(--bdr);display:flex;justify-content:flex-end;gap:8px}\n.toast{position:fixed;top:20px;right:20px;padding:12px 20px;border-radius:8px;font-size:13px;font-weight:500;z-index:300;display:none}.toast.show{display:block;animation:tIn .3s}.toast.ok{background:#dcfce7;color:#166534}.toast.er{background:#fee2e2;color:#991b1b}@keyframes tIn{from{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}\n.exec-grid{display:grid;grid-template-columns:1fr 1fr;gap:14px}.exec-card{background:var(--card);border:2px solid var(--bdr);border-radius:12px;padding:20px;transition:all .15s}.exec-card:hover{border-color:#a5b4fc}.exec-card .ec-head{display:flex;justify-content:space-between;align-items:center;margin-bottom:12px}.ec-icon{font-size:36px}.ec-title{font-size:16px;font-weight:700}.ec-desc{font-size:11px;color:var(--sub);margin-bottom:12px}\n.config-row{display:flex;justify-content:space-between;align-items:center;padding:8px 0;border-bottom:1px solid #f1f5f9;font-size:12px}.config-row:last-child{border:none}.cr-label{color:var(--sub)}.cr-val{font-weight:500}\n.health-bar{display:flex;gap:2px;margin-top:8px}.hb-dot{width:8px;height:20px;border-radius:2px}\n.note{background:#eff6ff;border-left:3px solid var(--pri);padding:8px 12px;border-radius:0 6px 6px 0;font-size:11px;color:var(--sub);margin-bottom:14px}\n<\/style><\/head><body>\n<div class=\"toast\" id=\"toast\"><\/div>\n\n<div class=\"mo\" id=\"modal-lobster\"><div class=\"mc\"><div class=\"mh\"><h3>🦞 龙虾执行器配置<\/h3><button class=\"mx\" onclick=\"closeM('modal-lobster')\">✕<\/button><\/div><div class=\"mb\">\n<div class=\"fg\"><label class=\"fl\">API地址 <span class=\"rq\">*<\/span><\/label><input class=\"fi\" value=\"https://api.lobster-agent.com/v1\"><\/div>\n<div class=\"fg\"><label class=\"fl\">API Key <span class=\"rq\">*<\/span><\/label><input class=\"fi\" type=\"password\" value=\"sk-lobster-production-key-xxx\"><\/div>\n<div class=\"fr\"><div class=\"fg\"><label class=\"fl\">超时时间(秒)<\/label><input class=\"fi\" type=\"number\" value=\"30\"><\/div><div class=\"fg\"><label class=\"fl\">重试次数<\/label><input class=\"fi\" type=\"number\" value=\"3\"><\/div><\/div>\n<div class=\"fr\"><div class=\"fg\"><label class=\"fl\">并发上限<\/label><input class=\"fi\" type=\"number\" value=\"10\"><\/div><div class=\"fg\"><label class=\"fl\">轮询间隔(ms)<\/label><input class=\"fi\" type=\"number\" value=\"2000\"><\/div><\/div>\n<div class=\"fg\"><label class=\"fl\">回调URL<\/label><input class=\"fi\" value=\"https://agent.example.com/api/callback/lobster\"><\/div>\n<div style=\"margin-top:10px\"><button class=\"btn btn-s btn-sm\" onclick=\"showT('✅ 龙虾平台连通正常','ok')\">🔌 测试连通性<\/button><\/div>\n<\/div><div class=\"mf\"><button class=\"btn btn-g\" onclick=\"closeM('modal-lobster')\">取消<\/button><button class=\"btn btn-p\" onclick=\"closeM('modal-lobster');showT('✅ 配置已保存','ok')\">保存<\/button><\/div><\/div><\/div>\n\n<div class=\"mo\" id=\"modal-script\"><div class=\"mc\"><div class=\"mh\"><h3>📜 脚本执行器配置<\/h3><button class=\"mx\" onclick=\"closeM('modal-script')\">✕<\/button><\/div><div class=\"mb\">\n<div class=\"fg\"><label class=\"fl\">工作目录 <span class=\"rq\">*<\/span><\/label><input class=\"fi\" value=\"/opt/agent-scripts/\"><\/div>\n<div class=\"fr\"><div class=\"fg\"><label class=\"fl\">Python路径<\/label><input class=\"fi\" value=\"/usr/bin/python3\"><\/div><div class=\"fg\"><label class=\"fl\">Node路径<\/label><input class=\"fi\" value=\"/usr/bin/node\"><\/div><\/div>\n<div class=\"fr\"><div class=\"fg\"><label class=\"fl\">全局超时(秒)<\/label><input class=\"fi\" type=\"number\" value=\"60\"><\/div><div class=\"fg\"><label class=\"fl\">并发上限<\/label><input class=\"fi\" type=\"number\" value=\"5\"><\/div><\/div>\n<div class=\"fg\"><label class=\"fl\">沙箱模式<\/label><select class=\"fs\"><option>Docker容器<\/option><option>本地进程<\/option><option>虚拟环境<\/option><\/select><\/div>\n<div class=\"fg\"><label class=\"fl\">日志目录<\/label><input class=\"fi\" value=\"/var/log/agent-scripts/\"><\/div>\n<\/div><div class=\"mf\"><button class=\"btn btn-g\" onclick=\"closeM('modal-script')\">取消<\/button><button class=\"btn btn-p\" onclick=\"closeM('modal-script');showT('✅ 配置已保存','ok')\">保存<\/button><\/div><\/div><\/div>\n\n<div class=\"layout\">\n<aside class=\"side\">\n<div class=\"logo\">🤖 Agent任务系统 v2.1<\/div>\n<div class=\"ni\">🏠 首页<\/div>\n<div class=\"ng-t\">权限管理<\/div><div class=\"ni\">· 组织架构<\/div><div class=\"ni\">· 菜单管理<\/div><div class=\"ni\">· 角色管理<\/div><div class=\"ni\">· 用户管理<\/div>\n<div class=\"ng-t\">产品管理<\/div><div class=\"ni\">· 产品列表<\/div><div class=\"ni\">· 渠道码<\/div><div class=\"ni\">· 平台套件<\/div>\n<div class=\"ng-t\">平台产品账号<\/div><div class=\"ni\">· 账号管理<\/div>\n<div class=\"ng-t\">Skill中心<\/div><div class=\"ni\">· Skill列表<\/div><div class=\"ni\">· 调用日志<\/div>\n<div class=\"ng-t\">任务中心<\/div><div class=\"ni\">· 任务创建<\/div><div class=\"ni\">· 任务列表<\/div>\n<div class=\"ng-t\">系统设置<\/div><div class=\"ni ac\">· 执行器配置<\/div><div class=\"ni\">· 脚本模板<\/div><div class=\"ni\">· 定时任务<\/div>\n<\/aside>\n<div class=\"main\">\n<div class=\"hd\"><div>⚙️ 系统设置 / <b style=\"color:var(--txt)\">执行器配置<\/b><\/div><div style=\"display:flex;align-items:center;gap:10px\"><span>🔔<\/span><span>admin<\/span><div style=\"width:28px;height:28px;border-radius:50%;background:var(--pri);color:#fff;display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:600\">A<\/div><\/div><\/div>\n<div class=\"ct\">\n<h1 class=\"pt\">执行器配置<\/h1>\n<p class=\"pd\">双执行器管理 · 连接参数 · 健康监控 · 并发/超时/重试策略<\/p>\n\n<div class=\"note\">⚠️ 仅超级管理员可修改执行器配置(RB-13)<\/div>\n\n<div class=\"exec-grid\">\n<!-- 龙虾执行器 -->\n<div class=\"exec-card\" style=\"border-color:#dc2626\">\n<div class=\"ec-head\"><div><div class=\"ec-icon\">🦞<\/div><div class=\"ec-title\">龙虾执行器<\/div><\/div><span class=\"tg tg-ok\">运行中<\/span><\/div>\n<div class=\"ec-desc\">第三方Agent平台,通过API对接龙虾平台执行任务<\/div>\n<div class=\"config-row\"><span class=\"cr-label\">API地址<\/span><span class=\"cr-val\">api.lobster-agent.com<\/span><\/div>\n<div class=\"config-row\"><span class=\"cr-label\">超时<\/span><span class=\"cr-val\">30s<\/span><\/div>\n<div class=\"config-row\"><span class=\"cr-label\">重试<\/span><span class=\"cr-val\">3次<\/span><\/div>\n<div class=\"config-row\"><span class=\"cr-label\">并发<\/span><span class=\"cr-val\">10<\/span><\/div>\n<div class=\"config-row\"><span class=\"cr-label\">当前任务<\/span><span class=\"cr-val\" style=\"color:var(--pri);font-weight:700\">3 / 10<\/span><\/div>\n<div style=\"font-size:11px;color:var(--sub);margin-top:8px\">最近24h健康状态<\/div>\n<div class=\"health-bar\" id=\"hb1\"><\/div>\n<div style=\"margin-top:12px;display:flex;gap:6px\">\n<button class=\"btn btn-p btn-sm\" onclick=\"openM('modal-lobster')\">⚙️ 配置<\/button>\n<button class=\"btn btn-s btn-sm\" onclick=\"showT('✅ 连通正常 (120ms)','ok')\">🔌 测试<\/button>\n<button class=\"btn btn-w btn-sm\" onclick=\"showT('🔄 已重启','ok')\">🔄 重启<\/button>\n<\/div><\/div>\n\n<!-- 脚本执行器 -->\n<div class=\"exec-card\" style=\"border-color:var(--pri)\">\n<div class=\"ec-head\"><div><div class=\"ec-icon\">📜<\/div><div class=\"ec-title\">脚本执行器<\/div><\/div><span class=\"tg tg-ok\">运行中<\/span><\/div>\n<div class=\"ec-desc\">系统内置脚本引擎,支持Python/Node.js/Shell脚本<\/div>\n<div class=\"config-row\"><span class=\"cr-label\">工作目录<\/span><span class=\"cr-val\">/opt/agent-scripts/<\/span><\/div>\n<div class=\"config-row\"><span class=\"cr-label\">超时<\/span><span class=\"cr-val\">60s<\/span><\/div>\n<div class=\"config-row\"><span class=\"cr-label\">并发<\/span><span class=\"cr-val\">5<\/span><\/div>\n<div class=\"config-row\"><span class=\"cr-label\">沙箱<\/span><span class=\"cr-val\">Docker容器<\/span><\/div>\n<div class=\"config-row\"><span class=\"cr-label\">当前任务<\/span><span class=\"cr-val\" style=\"color:var(--pri);font-weight:700\">1 / 5<\/span><\/div>\n<div style=\"font-size:11px;color:var(--sub);margin-top:8px\">最近24h健康状态<\/div>\n<div class=\"health-bar\" id=\"hb2\"><\/div>\n<div style=\"margin-top:12px;display:flex;gap:6px\">\n<button class=\"btn btn-p btn-sm\" onclick=\"openM('modal-script')\">⚙️ 配置<\/button>\n<button class=\"btn btn-s btn-sm\" onclick=\"showT('✅ 脚本引擎正常','ok')\">🔌 测试<\/button>\n<button class=\"btn btn-w btn-sm\" onclick=\"showT('🔄 已重启','ok')\">🔄 重启<\/button>\n<\/div><\/div>\n<\/div>\n\n<\/div><\/div><\/div>\n\n<script>\nfunction openM(id){document.getElementById(id).classList.add('show')}\nfunction closeM(id){document.getElementById(id).classList.remove('show')}\nfunction showT(m,t){const e=document.getElementById('toast');e.textContent=m;e.className='toast show '+t;setTimeout(()=>e.className='toast',2500)}\nfunction initHealth(id){const el=document.getElementById(id);let html='';for(let i=0;i<24;i++){const ok=Math.random()>0.08;html+=`<div class=\"hb-dot\" style=\"background:${ok?'var(--ok)':'var(--err)'}\" title=\"${23-i}h前: ${ok?'正常':'异常'}\"><\/div>`}el.innerHTML=html}\ninitHealth('hb1');initHealth('hb2');\ndocument.querySelectorAll('.mo').forEach(m=>m.addEventListener('click',e=>{if(e.target===m)m.classList.remove('show')}));\n<\/script>\n<\/body><\/html>",
|
||
"18_脚本模板管理.html": "<!DOCTYPE html><html lang=\"zh-CN\"><head><script>if(window!==window.top)document.documentElement.classList.add(\"in-iframe\")<\/script><style>.in-iframe .side{display:none!important}.in-iframe .main{margin-left:0!important}.in-iframe .layout{min-height:auto}<\/style><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1.0\"><title>Agent任务系统 v2.1 - 脚本模板管理<\/title>\n<style>\n*{margin:0;padding:0;box-sizing:border-box}:root{--pri:#6366f1;--bg:#f1f5f9;--card:#fff;--txt:#1e293b;--sub:#64748b;--bdr:#e2e8f0;--ok:#22c55e;--err:#ef4444;--warn:#f59e0b;--side:#1e293b}body{font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",\"PingFang SC\",\"Microsoft YaHei\",sans-serif;background:var(--bg);color:var(--txt);line-height:1.6;font-size:13px}\n.layout{display:flex;min-height:100vh}.side{width:220px;background:var(--side);color:#94a3b8;position:fixed;top:0;left:0;bottom:0;overflow-y:auto;z-index:100}.side .logo{padding:16px 18px;font-size:14px;font-weight:700;color:#fff;border-bottom:1px solid #334155}.ni{display:flex;align-items:center;gap:8px;padding:9px 18px;font-size:12px;color:#94a3b8;cursor:pointer;border-left:3px solid transparent}.ni:hover{background:#334155;color:#e2e8f0}.ni.ac{background:rgba(99,102,241,.15);color:#818cf8;border-left-color:#818cf8;font-weight:600}.ng-t{padding:10px 18px 4px;font-size:10px;letter-spacing:1px;color:#475569;font-weight:600}\n.main{margin-left:220px;flex:1}.hd{height:52px;background:var(--card);border-bottom:1px solid var(--bdr);display:flex;align-items:center;justify-content:space-between;padding:0 24px;font-size:12px;color:var(--sub);position:sticky;top:0;z-index:50}.ct{padding:24px}\n.pt{font-size:20px;font-weight:700;margin-bottom:4px}.pd{font-size:12px;color:var(--sub);margin-bottom:20px}\n.tb{display:flex;gap:8px;align-items:center;margin-bottom:14px;flex-wrap:wrap}.sb{display:flex;align-items:center;gap:6px;background:#f8fafc;border:1px solid var(--bdr);border-radius:7px;padding:7px 12px;font-size:12px}.sb input{border:none;background:none;outline:none;font-size:12px;width:140px}\n.sl{border:1px solid var(--bdr);border-radius:7px;padding:7px 12px;font-size:12px;background:#fff;cursor:pointer}\n.btn{padding:7px 16px;border-radius:7px;font-size:12px;font-weight:500;border:none;cursor:pointer;display:inline-flex;align-items:center;gap:5px;transition:all .12s}.btn-p{background:var(--pri);color:#fff}.btn-p:hover{background:#4f46e5}.btn-d{background:#fee2e2;color:#dc2626}.btn-g{background:transparent;color:var(--sub);border:1px solid var(--bdr)}.btn-sm{padding:5px 10px;font-size:11px}.btn-s{background:var(--ok);color:#fff}\n.btn-l{background:none;border:none;color:var(--pri);padding:0;font-size:12px;cursor:pointer}.btn-l:hover{text-decoration:underline}\n.tg{display:inline-block;padding:2px 8px;border-radius:99px;font-size:10px;font-weight:600}.tg-ok{background:#dcfce7;color:#166534}.tg-e{background:#fee2e2;color:#991b1b}.tg-i{background:#dbeafe;color:#1e40af}.tg-p{background:#f3e8ff;color:#6b21a8}.tg-w{background:#fef3c7;color:#92400e}\ntable{width:100%;border-collapse:collapse;font-size:12px}th,td{padding:8px 12px;text-align:left;border-bottom:1px solid var(--bdr)}th{background:#f8fafc;font-weight:600;color:var(--sub);font-size:11px}tr:hover td{background:#fafbfc}.tw{overflow-x:auto;border:1px solid var(--bdr);border-radius:8px}\n.fg{margin-bottom:14px}.fl{font-size:12px;font-weight:500;margin-bottom:5px;display:block}.fl .rq{color:var(--err)}.fi{width:100%;padding:8px 12px;border:1px solid var(--bdr);border-radius:7px;font-size:12px;outline:none}.fi:focus{border-color:var(--pri)}.fs{width:100%;padding:8px 12px;border:1px solid var(--bdr);border-radius:7px;font-size:12px;background:#fff}.fr{display:grid;grid-template-columns:1fr 1fr;gap:14px}\n.mo{position:fixed;inset:0;background:rgba(0,0,0,.45);display:none;align-items:center;justify-content:center;z-index:200}.mo.show{display:flex}.mc{background:var(--card);border-radius:14px;width:90%;max-width:700px;max-height:88vh;overflow-y:auto;box-shadow:0 20px 60px rgba(0,0,0,.2)}.mh{padding:14px 20px;border-bottom:1px solid var(--bdr);display:flex;justify-content:space-between;align-items:center}.mh h3{font-size:15px}.mx{cursor:pointer;font-size:18px;color:var(--sub);background:none;border:none}.mb{padding:20px}.mf{padding:14px 20px;border-top:1px solid var(--bdr);display:flex;justify-content:flex-end;gap:8px}\n.toast{position:fixed;top:20px;right:20px;padding:12px 20px;border-radius:8px;font-size:13px;font-weight:500;z-index:300;display:none}.toast.show{display:block;animation:tIn .3s}.toast.ok{background:#dcfce7;color:#166534}.toast.er{background:#fee2e2;color:#991b1b}@keyframes tIn{from{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}\n.code-area{width:100%;min-height:200px;padding:12px;border:1px solid var(--bdr);border-radius:7px;font-size:12px;font-family:'Fira Code',monospace;background:#1e293b;color:#e2e8f0;resize:vertical;line-height:1.5;tab-size:4}\n.code-header{display:flex;justify-content:space-between;align-items:center;background:#334155;padding:6px 12px;border-radius:7px 7px 0 0;font-size:11px;color:#94a3b8}.code-area.no-top{border-radius:0 0 7px 7px}\n<\/style><\/head><body>\n<div class=\"toast\" id=\"toast\"><\/div>\n\n<div class=\"mo\" id=\"modal-tpl\"><div class=\"mc\"><div class=\"mh\"><h3 id=\"mtTitle\">新增脚本模板<\/h3><button class=\"mx\" onclick=\"closeM('modal-tpl')\">✕<\/button><\/div><div class=\"mb\">\n<div class=\"fr\"><div class=\"fg\"><label class=\"fl\">模板名称 <span class=\"rq\">*<\/span><\/label><input class=\"fi\" id=\"mt-name\" placeholder=\"如 通用HTTP请求\"><\/div>\n<div class=\"fg\"><label class=\"fl\">脚本类型 <span class=\"rq\">*<\/span><\/label><select class=\"fs\" id=\"mt-type\" onchange=\"onTplType(this.value)\"><option value=\"python\">Python<\/option><option value=\"node\">Node.js<\/option><option value=\"shell\">Shell<\/option><\/select><\/div><\/div>\n<div class=\"fg\"><label class=\"fl\">描述<\/label><textarea class=\"fi\" rows=\"2\" placeholder=\"模板功能描述\"><\/textarea><\/div>\n<div class=\"fg\"><label class=\"fl\">脚本代码 <span class=\"rq\">*<\/span><\/label>\n<div class=\"code-header\"><span id=\"codeLang\">Python<\/span><button class=\"btn btn-g btn-sm\" style=\"color:#94a3b8;border-color:#475569\" onclick=\"formatCode()\">格式化<\/button><\/div>\n<textarea class=\"code-area no-top\" id=\"codeArea\">#!/usr/bin/env python3\nimport requests\nimport json\nimport os\n\ndef main():\n \"\"\"通用HTTP请求模板\"\"\"\n api_key = os.environ.get('API_KEY', '')\n url = os.environ.get('TARGET_URL', '')\n \n headers = {\n 'Authorization': f'Bearer {api_key}',\n 'Content-Type': 'application/json'\n }\n \n response = requests.get(url, headers=headers)\n result = response.json()\n \n print(json.dumps({\n 'status': 'success',\n 'data': result\n }))\n\nif __name__ == '__main__':\n main()<\/textarea><\/div>\n<div class=\"fg\"><label class=\"fl\">环境变量声明<\/label>\n<div id=\"envList\">\n<div style=\"display:flex;gap:6px;margin-bottom:4px;font-size:11px\"><input class=\"fi\" style=\"width:120px\" value=\"API_KEY\" readonly><input class=\"fi\" style=\"flex:1\" value=\"API密钥\"><select class=\"sl\" style=\"width:80px\"><option>必填<\/option><option>可选<\/option><\/select><\/div>\n<div style=\"display:flex;gap:6px;margin-bottom:4px;font-size:11px\"><input class=\"fi\" style=\"width:120px\" value=\"TARGET_URL\" readonly><input class=\"fi\" style=\"flex:1\" value=\"目标URL\"><select class=\"sl\" style=\"width:80px\"><option>必填<\/option><option>可选<\/option><\/select><\/div>\n<\/div>\n<button class=\"btn btn-g btn-sm\" onclick=\"addEnvDecl()\" style=\"margin-top:4px\">+ 添加变量<\/button><\/div>\n<div class=\"fg\"><label class=\"fl\">状态<\/label><select class=\"fs\"><option>启用<\/option><option>禁用<\/option><\/select><\/div>\n<\/div><div class=\"mf\"><button class=\"btn btn-g\" onclick=\"closeM('modal-tpl')\">取消<\/button><button class=\"btn btn-p\" onclick=\"closeM('modal-tpl');showT('✅ 模板已保存','ok')\">保存<\/button><\/div><\/div><\/div>\n\n<div class=\"mo\" id=\"modal-del\"><div class=\"mc\" style=\"max-width:400px\"><div class=\"mh\"><h3>⚠️ 确认删除<\/h3><button class=\"mx\" onclick=\"closeM('modal-del')\">✕<\/button><\/div><div class=\"mb\" style=\"text-align:center;padding:20px\"><div style=\"font-size:36px\">🗑️<\/div><p style=\"font-size:13px;font-weight:600;margin-top:8px\">确定删除该脚本模板?<\/p><p style=\"font-size:11px;color:var(--sub);margin-top:4px\">已被Skill引用的模板需先解除关联<\/p><\/div><div class=\"mf\"><button class=\"btn btn-g\" onclick=\"closeM('modal-del')\">取消<\/button><button class=\"btn btn-d\" onclick=\"closeM('modal-del');showT('✅ 已删除','ok')\">确认删除<\/button><\/div><\/div><\/div>\n\n<div class=\"layout\">\n<aside class=\"side\">\n<div class=\"logo\">🤖 Agent任务系统 v2.1<\/div>\n<div class=\"ni\">🏠 首页<\/div>\n<div class=\"ng-t\">权限管理<\/div><div class=\"ni\">· 组织架构<\/div><div class=\"ni\">· 菜单管理<\/div><div class=\"ni\">· 角色管理<\/div><div class=\"ni\">· 用户管理<\/div>\n<div class=\"ng-t\">产品管理<\/div><div class=\"ni\">· 产品列表<\/div><div class=\"ni\">· 渠道码<\/div><div class=\"ni\">· 平台套件<\/div>\n<div class=\"ng-t\">平台产品账号<\/div><div class=\"ni\">· 账号管理<\/div>\n<div class=\"ng-t\">Skill中心<\/div><div class=\"ni\">· Skill列表<\/div><div class=\"ni\">· 调用日志<\/div>\n<div class=\"ng-t\">任务中心<\/div><div class=\"ni\">· 任务创建<\/div><div class=\"ni\">· 任务列表<\/div>\n<div class=\"ng-t\">系统设置<\/div><div class=\"ni\">· 执行器配置<\/div><div class=\"ni ac\">· 脚本模板<\/div><div class=\"ni\">· 定时任务<\/div>\n<\/aside>\n<div class=\"main\">\n<div class=\"hd\"><div>⚙️ 系统设置 / <b style=\"color:var(--txt)\">脚本模板管理<\/b><\/div><div style=\"display:flex;align-items:center;gap:10px\"><span>🔔<\/span><span>admin<\/span><div style=\"width:28px;height:28px;border-radius:50%;background:var(--pri);color:#fff;display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:600\">A<\/div><\/div><\/div>\n<div class=\"ct\">\n<h1 class=\"pt\">脚本模板管理<\/h1>\n<p class=\"pd\">脚本执行器预置模板 · 代码编辑器 · 环境变量声明 · Skill引用<\/p>\n\n<div class=\"tb\">\n<div class=\"sb\"><span>🔍<\/span><input placeholder=\"搜索模板名称\" id=\"sInput\" oninput=\"filterT()\"><\/div>\n<select class=\"sl\" id=\"fType\" onchange=\"filterT()\"><option value=\"\">全部类型<\/option><option value=\"python\">Python<\/option><option value=\"node\">Node.js<\/option><option value=\"shell\">Shell<\/option><\/select>\n<button class=\"btn btn-p\" style=\"margin-left:auto\" onclick=\"openAdd()\">+ 新增模板<\/button>\n<\/div>\n\n<div class=\"tw\"><table><thead><tr><th>模板名称<\/th><th>脚本类型<\/th><th>环境变量<\/th><th>引用Skill<\/th><th>状态<\/th><th>更新时间<\/th><th>操作<\/th><\/tr><\/thead>\n<tbody id=\"ttb\">\n<tr data-q=\"通用HTTP请求\" data-type=\"python\"><td><b>通用HTTP请求<\/b><\/td><td><span class=\"tg tg-i\">🐍 Python<\/span><\/td><td>API_KEY, TARGET_URL<\/td><td>2个Skill<\/td><td><span class=\"tg tg-ok\">启用<\/span><\/td><td>04-23 10:00<\/td><td><button class=\"btn-l\" onclick=\"openEdit('通用HTTP请求','python')\">编辑<\/button> <button class=\"btn-l\" style=\"color:var(--err)\" onclick=\"openM('modal-del')\">删除<\/button><\/td><\/tr>\n<tr data-q=\"数据清洗脚本\" data-type=\"python\"><td><b>数据清洗脚本<\/b><\/td><td><span class=\"tg tg-i\">🐍 Python<\/span><\/td><td>INPUT_PATH, OUTPUT_PATH<\/td><td>1个Skill<\/td><td><span class=\"tg tg-ok\">启用<\/span><\/td><td>04-22 15:30<\/td><td><button class=\"btn-l\" onclick=\"openEdit('数据清洗脚本','python')\">编辑<\/button> <button class=\"btn-l\" style=\"color:var(--err)\" onclick=\"openM('modal-del')\">删除<\/button><\/td><\/tr>\n<tr data-q=\"文件处理\" data-type=\"shell\"><td><b>文件处理<\/b><\/td><td><span class=\"tg tg-w\">🐚 Shell<\/span><\/td><td>FILE_DIR<\/td><td>0个Skill<\/td><td><span class=\"tg tg-ok\">启用<\/span><\/td><td>04-20 09:00<\/td><td><button class=\"btn-l\" onclick=\"openEdit('文件处理','shell')\">编辑<\/button> <button class=\"btn-l\" style=\"color:var(--err)\" onclick=\"openM('modal-del')\">删除<\/button><\/td><\/tr>\n<tr data-q=\"API调用\" data-type=\"node\"><td><b>API调用<\/b><\/td><td><span class=\"tg tg-p\">📦 Node.js<\/span><\/td><td>API_ENDPOINT, TOKEN<\/td><td>1个Skill<\/td><td><span class=\"tg tg-ok\">启用<\/span><\/td><td>04-19 14:20<\/td><td><button class=\"btn-l\" onclick=\"openEdit('API调用','node')\">编辑<\/button> <button class=\"btn-l\" style=\"color:var(--err)\" onclick=\"openM('modal-del')\">删除<\/button><\/td><\/tr>\n<\/tbody><\/table><\/div>\n\n<\/div><\/div><\/div>\n\n<script>\nconst CODE={python:`#!/usr/bin/env python3\\nimport requests\\nimport json\\nimport os\\n\\ndef main():\\n api_key = os.environ.get('API_KEY', '')\\n url = os.environ.get('TARGET_URL', '')\\n resp = requests.get(url, headers={'Authorization': f'Bearer {api_key}'})\\n print(json.dumps({'status': 'success', 'data': resp.json()}))\\n\\nif __name__ == '__main__':\\n main()`,node:`const axios = require('axios');\\n\\nasync function main() {\\n const endpoint = process.env.API_ENDPOINT;\\n const token = process.env.TOKEN;\\n const res = await axios.get(endpoint, {\\n headers: { Authorization: \\`Bearer \\${token}\\` }\\n });\\n console.log(JSON.stringify({ status: 'success', data: res.data }));\\n}\\n\\nmain().catch(console.error);`,shell:`#!/bin/bash\\nset -e\\n\\nFILE_DIR=\\${FILE_DIR:-/tmp}\\n\\necho \"Processing files in $FILE_DIR\"\\nfor f in \"$FILE_DIR\"/*; do\\n echo \"Processing: $f\"\\ndone\\necho '{\"status\":\"success\"}'`};\nfunction openM(id){document.getElementById(id).classList.add('show')}\nfunction closeM(id){document.getElementById(id).classList.remove('show')}\nfunction showT(m,t){const e=document.getElementById('toast');e.textContent=m;e.className='toast show '+t;setTimeout(()=>e.className='toast',2500)}\nfunction openAdd(){document.getElementById('mtTitle').textContent='新增脚本模板';document.getElementById('mt-name').value='';document.getElementById('mt-type').value='python';document.getElementById('codeArea').value=CODE.python;document.getElementById('codeLang').textContent='Python';openM('modal-tpl')}\nfunction openEdit(name,type){document.getElementById('mtTitle').textContent='编辑模板 — '+name;document.getElementById('mt-name').value=name;document.getElementById('mt-type').value=type;document.getElementById('codeArea').value=CODE[type]||'';document.getElementById('codeLang').textContent={python:'Python',node:'Node.js',shell:'Shell'}[type];openM('modal-tpl')}\nfunction onTplType(v){const labels={python:'Python',node:'Node.js',shell:'Shell'};document.getElementById('codeLang').textContent=labels[v];document.getElementById('codeArea').value=CODE[v]||''}\nfunction formatCode(){showT('✅ 代码已格式化','ok')}\nfunction addEnvDecl(){const list=document.getElementById('envList');const d=document.createElement('div');d.style.cssText='display:flex;gap:6px;margin-bottom:4px;font-size:11px';d.innerHTML='<input class=\"fi\" style=\"width:120px\" placeholder=\"变量名\"><input class=\"fi\" style=\"flex:1\" placeholder=\"描述\"><select class=\"sl\" style=\"width:80px\"><option>必填<\/option><option>可选<\/option><\/select>';list.appendChild(d)}\nfunction filterT(){const q=document.getElementById('sInput').value.toLowerCase();const type=document.getElementById('fType').value;document.querySelectorAll('#ttb tr').forEach(tr=>{const d=tr.dataset;tr.style.display=(!q||d.q.toLowerCase().includes(q))&&(!type||d.type===type)?'':'none'})}\ndocument.querySelectorAll('.mo').forEach(m=>m.addEventListener('click',e=>{if(e.target===m)m.classList.remove('show')}));\n<\/script>\n<\/body><\/html>",
|
||
"19_定时任务.html": "<!DOCTYPE html><html lang=\"zh-CN\"><head><script>if(window!==window.top)document.documentElement.classList.add(\"in-iframe\")<\/script><style>.in-iframe .side{display:none!important}.in-iframe .main{margin-left:0!important}.in-iframe .layout{min-height:auto}<\/style><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1.0\"><title>Agent任务系统 v2.1 - 定时任务<\/title>\n<style>\n*{margin:0;padding:0;box-sizing:border-box}:root{--pri:#6366f1;--bg:#f1f5f9;--card:#fff;--txt:#1e293b;--sub:#64748b;--bdr:#e2e8f0;--ok:#22c55e;--err:#ef4444;--warn:#f59e0b;--side:#1e293b}body{font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",\"PingFang SC\",\"Microsoft YaHei\",sans-serif;background:var(--bg);color:var(--txt);line-height:1.6;font-size:13px}\n.layout{display:flex;min-height:100vh}.side{width:220px;background:var(--side);color:#94a3b8;position:fixed;top:0;left:0;bottom:0;overflow-y:auto;z-index:100}.side .logo{padding:16px 18px;font-size:14px;font-weight:700;color:#fff;border-bottom:1px solid #334155}.ni{display:flex;align-items:center;gap:8px;padding:9px 18px;font-size:12px;color:#94a3b8;cursor:pointer;border-left:3px solid transparent}.ni:hover{background:#334155;color:#e2e8f0}.ni.ac{background:rgba(99,102,241,.15);color:#818cf8;border-left-color:#818cf8;font-weight:600}.ng-t{padding:10px 18px 4px;font-size:10px;letter-spacing:1px;color:#475569;font-weight:600}\n.main{margin-left:220px;flex:1}.hd{height:52px;background:var(--card);border-bottom:1px solid var(--bdr);display:flex;align-items:center;justify-content:space-between;padding:0 24px;font-size:12px;color:var(--sub);position:sticky;top:0;z-index:50}.ct{padding:24px}\n.pt{font-size:20px;font-weight:700;margin-bottom:4px}.pd{font-size:12px;color:var(--sub);margin-bottom:20px}\n.tb{display:flex;gap:8px;align-items:center;margin-bottom:14px;flex-wrap:wrap}.sb{display:flex;align-items:center;gap:6px;background:#f8fafc;border:1px solid var(--bdr);border-radius:7px;padding:7px 12px;font-size:12px}.sb input{border:none;background:none;outline:none;font-size:12px;width:140px}\n.sl{border:1px solid var(--bdr);border-radius:7px;padding:7px 12px;font-size:12px;background:#fff;cursor:pointer}\n.btn{padding:7px 16px;border-radius:7px;font-size:12px;font-weight:500;border:none;cursor:pointer;display:inline-flex;align-items:center;gap:5px;transition:all .12s}.btn-p{background:var(--pri);color:#fff}.btn-p:hover{background:#4f46e5}.btn-d{background:#fee2e2;color:#dc2626}.btn-g{background:transparent;color:var(--sub);border:1px solid var(--bdr)}.btn-sm{padding:5px 10px;font-size:11px}.btn-s{background:var(--ok);color:#fff}.btn-w{background:var(--warn);color:#fff}\n.btn-l{background:none;border:none;color:var(--pri);padding:0;font-size:12px;cursor:pointer}.btn-l:hover{text-decoration:underline}\n.tg{display:inline-block;padding:2px 8px;border-radius:99px;font-size:10px;font-weight:600}.tg-ok{background:#dcfce7;color:#166534}.tg-e{background:#fee2e2;color:#991b1b}.tg-i{background:#dbeafe;color:#1e40af}.tg-p{background:#f3e8ff;color:#6b21a8}.tg-w{background:#fef3c7;color:#92400e}.tg-g{background:#f1f5f9;color:#64748b}\ntable{width:100%;border-collapse:collapse;font-size:12px}th,td{padding:8px 12px;text-align:left;border-bottom:1px solid var(--bdr)}th{background:#f8fafc;font-weight:600;color:var(--sub);font-size:11px}tr:hover td{background:#fafbfc}.tw{overflow-x:auto;border:1px solid var(--bdr);border-radius:8px}\n.fg{margin-bottom:14px}.fl{font-size:12px;font-weight:500;margin-bottom:5px;display:block}.fl .rq{color:var(--err)}.fi{width:100%;padding:8px 12px;border:1px solid var(--bdr);border-radius:7px;font-size:12px;outline:none}.fi:focus{border-color:var(--pri)}.fs{width:100%;padding:8px 12px;border:1px solid var(--bdr);border-radius:7px;font-size:12px;background:#fff}.fr{display:grid;grid-template-columns:1fr 1fr;gap:14px}\n.mo{position:fixed;inset:0;background:rgba(0,0,0,.45);display:none;align-items:center;justify-content:center;z-index:200}.mo.show{display:flex}.mc{background:var(--card);border-radius:14px;width:90%;max-width:620px;max-height:88vh;overflow-y:auto;box-shadow:0 20px 60px rgba(0,0,0,.2)}.mh{padding:14px 20px;border-bottom:1px solid var(--bdr);display:flex;justify-content:space-between;align-items:center}.mh h3{font-size:15px}.mx{cursor:pointer;font-size:18px;color:var(--sub);background:none;border:none}.mb{padding:20px}.mf{padding:14px 20px;border-top:1px solid var(--bdr);display:flex;justify-content:flex-end;gap:8px}\n.toast{position:fixed;top:20px;right:20px;padding:12px 20px;border-radius:8px;font-size:13px;font-weight:500;z-index:300;display:none}.toast.show{display:block;animation:tIn .3s}.toast.ok{background:#dcfce7;color:#166534}.toast.er{background:#fee2e2;color:#991b1b}@keyframes tIn{from{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}\n.stat{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;margin-bottom:16px}.stat-c{background:var(--card);border:1px solid var(--bdr);border-radius:10px;padding:14px 16px}.stat-c .sv{font-size:22px;font-weight:700}.stat-c .sl2{font-size:11px;color:var(--sub)}\n.cron-help{background:#f8fafc;border:1px solid var(--bdr);border-radius:7px;padding:10px;font-size:11px;margin-top:6px}.cron-help code{background:#ede9fe;padding:1px 4px;border-radius:3px;font-size:10px}\n.switch{position:relative;width:36px;height:20px;display:inline-block}.switch input{opacity:0;width:0;height:0}.slider{position:absolute;cursor:pointer;inset:0;background:#cbd5e1;border-radius:20px;transition:.2s}.slider:before{content:'';position:absolute;height:16px;width:16px;left:2px;bottom:2px;background:#fff;border-radius:50%;transition:.2s}.switch input:checked+.slider{background:var(--ok)}.switch input:checked+.slider:before{transform:translateX(16px)}\n.timeline{display:flex;gap:2px;margin-top:4px}.tl-dot{width:6px;height:16px;border-radius:2px;font-size:0}\n<\/style><\/head><body>\n<div class=\"toast\" id=\"toast\"><\/div>\n\n<div class=\"mo\" id=\"modal-cron\"><div class=\"mc\"><div class=\"mh\"><h3 id=\"mcTitle\">新增定时任务<\/h3><button class=\"mx\" onclick=\"closeM('modal-cron')\">✕<\/button><\/div><div class=\"mb\">\n<div class=\"fg\"><label class=\"fl\">任务名称 <span class=\"rq\">*<\/span><\/label><input class=\"fi\" id=\"mc-name\" placeholder=\"如 每日竞品数据采集\"><\/div>\n<div class=\"fg\"><label class=\"fl\">关联Skill <span class=\"rq\">*<\/span><\/label><select class=\"fs\" id=\"mc-skill\"><option>竞品数据采集<\/option><option>小红书笔记发布<\/option><option>数据清洗脚本<\/option><option>抖音视频上传<\/option><option>Facebook广告投放<\/option><\/select><\/div>\n<div class=\"fg\"><label class=\"fl\">关联产品 <span class=\"rq\">*<\/span><\/label><select class=\"fs\"><option>PROD001 — 美妆种草达人<\/option><option>PROD002 — 护肤品评测<\/option><option>PROD003 — 抖音带货王<\/option><option>全部产品<\/option><\/select><\/div>\n<div class=\"fg\"><label class=\"fl\">Cron表达式 <span class=\"rq\">*<\/span><\/label><input class=\"fi\" id=\"cronInput\" value=\"0 8 * * *\" oninput=\"parseCron(this.value)\">\n<div class=\"cron-help\">\n<div id=\"cronDesc\" style=\"font-weight:600;color:var(--pri);margin-bottom:4px\">📅 每天 08:00 执行<\/div>\n常用: <code>0 8 * * *<\/code> 每天8点 · <code>0 */2 * * *<\/code> 每2小时 · <code>0 9 * * 1<\/code> 每周一9点 · <code>0 0 1 * *<\/code> 每月1号\n<\/div><\/div>\n<div class=\"fg\"><label class=\"fl\">执行参数 (JSON)<\/label><textarea class=\"fi\" rows=\"3\" style=\"font-family:monospace;font-size:11px\">{\n \"product_id\": \"PROD001\",\n \"mode\": \"incremental\"\n}<\/textarea><\/div>\n<div class=\"fr\"><div class=\"fg\"><label class=\"fl\">失败重试<\/label><select class=\"fs\"><option>重试3次<\/option><option>重试1次<\/option><option>不重试<\/option><\/select><\/div>\n<div class=\"fg\"><label class=\"fl\">超时(秒)<\/label><input class=\"fi\" type=\"number\" value=\"120\"><\/div><\/div>\n<div class=\"fg\"><label class=\"fl\">状态<\/label><select class=\"fs\"><option>启用<\/option><option>暂停<\/option><\/select><\/div>\n<\/div><div class=\"mf\"><button class=\"btn btn-g\" onclick=\"closeM('modal-cron')\">取消<\/button><button class=\"btn btn-p\" onclick=\"closeM('modal-cron');showT('✅ 定时任务已保存','ok')\">保存<\/button><\/div><\/div><\/div>\n\n<div class=\"mo\" id=\"modal-log\"><div class=\"mc\"><div class=\"mh\"><h3>📋 最近执行记录<\/h3><button class=\"mx\" onclick=\"closeM('modal-log')\">✕<\/button><\/div><div class=\"mb\">\n<table><thead><tr><th>执行时间<\/th><th>状态<\/th><th>耗时<\/th><th>结果<\/th><\/tr><\/thead><tbody>\n<tr><td>04-23 08:00:00<\/td><td><span class=\"tg tg-ok\">成功<\/span><\/td><td>12.3s<\/td><td>采集 156 条<\/td><\/tr>\n<tr><td>04-22 08:00:00<\/td><td><span class=\"tg tg-ok\">成功<\/span><\/td><td>11.8s<\/td><td>采集 142 条<\/td><\/tr>\n<tr><td>04-21 08:00:00<\/td><td><span class=\"tg tg-e\">失败<\/span><\/td><td>30s<\/td><td>超时<\/td><\/tr>\n<tr><td>04-20 08:00:00<\/td><td><span class=\"tg tg-ok\">成功<\/span><\/td><td>10.5s<\/td><td>采集 138 条<\/td><\/tr>\n<tr><td>04-19 08:00:00<\/td><td><span class=\"tg tg-ok\">成功<\/span><\/td><td>13.1s<\/td><td>采集 161 条<\/td><\/tr>\n<\/tbody><\/table>\n<\/div><div class=\"mf\"><button class=\"btn btn-g\" onclick=\"closeM('modal-log')\">关闭<\/button><\/div><\/div><\/div>\n\n<div class=\"mo\" id=\"modal-del\"><div class=\"mc\" style=\"max-width:400px\"><div class=\"mh\"><h3>⚠️ 确认删除<\/h3><button class=\"mx\" onclick=\"closeM('modal-del')\">✕<\/button><\/div><div class=\"mb\" style=\"text-align:center;padding:20px\"><div style=\"font-size:36px\">🗑️<\/div><p style=\"font-size:13px;font-weight:600;margin-top:8px\">确定删除该定时任务?<\/p><\/div><div class=\"mf\"><button class=\"btn btn-g\" onclick=\"closeM('modal-del')\">取消<\/button><button class=\"btn btn-d\" onclick=\"closeM('modal-del');showT('✅ 已删除','ok')\">确认删除<\/button><\/div><\/div><\/div>\n\n<div class=\"layout\">\n<aside class=\"side\">\n<div class=\"logo\">🤖 Agent任务系统 v2.1<\/div>\n<div class=\"ni\">🏠 首页<\/div>\n<div class=\"ng-t\">权限管理<\/div><div class=\"ni\">· 组织架构<\/div><div class=\"ni\">· 菜单管理<\/div><div class=\"ni\">· 角色管理<\/div><div class=\"ni\">· 用户管理<\/div>\n<div class=\"ng-t\">产品管理<\/div><div class=\"ni\">· 产品列表<\/div><div class=\"ni\">· 渠道码<\/div><div class=\"ni\">· 平台套件<\/div>\n<div class=\"ng-t\">平台产品账号<\/div><div class=\"ni\">· 账号管理<\/div>\n<div class=\"ng-t\">Skill中心<\/div><div class=\"ni\">· Skill列表<\/div><div class=\"ni\">· 调用日志<\/div>\n<div class=\"ng-t\">任务中心<\/div><div class=\"ni\">· 任务创建<\/div><div class=\"ni\">· 任务列表<\/div>\n<div class=\"ng-t\">系统设置<\/div><div class=\"ni\">· 执行器配置<\/div><div class=\"ni\">· 脚本模板<\/div><div class=\"ni ac\">· 定时任务<\/div>\n<\/aside>\n<div class=\"main\">\n<div class=\"hd\"><div>⚙️ 系统设置 / <b style=\"color:var(--txt)\">定时任务<\/b><\/div><div style=\"display:flex;align-items:center;gap:10px\"><span>🔔<\/span><span>admin<\/span><div style=\"width:28px;height:28px;border-radius:50%;background:var(--pri);color:#fff;display:flex;align-items:center;justify-content:center;font-size:11px;font-weight:600\">A<\/div><\/div><\/div>\n<div class=\"ct\">\n<h1 class=\"pt\">定时任务管理<\/h1>\n<p class=\"pd\">Cron定时调度 · 关联Skill+产品 · 执行记录 · 启停控制<\/p>\n\n<div class=\"stat\">\n<div class=\"stat-c\"><div class=\"sv\">8<\/div><div class=\"sl2\">定时任务<\/div><\/div>\n<div class=\"stat-c\"><div class=\"sv\" style=\"color:var(--ok)\">6<\/div><div class=\"sl2\">运行中<\/div><\/div>\n<div class=\"stat-c\"><div class=\"sv\" style=\"color:var(--warn)\">2<\/div><div class=\"sl2\">已暂停<\/div><\/div>\n<div class=\"stat-c\"><div class=\"sv\" style=\"color:var(--ok)\">94.2%<\/div><div class=\"sl2\">成功率(7日)<\/div><\/div>\n<\/div>\n\n<div class=\"tb\">\n<div class=\"sb\"><span>🔍<\/span><input placeholder=\"搜索任务名称\" id=\"sInput\" oninput=\"filterT()\"><\/div>\n<select class=\"sl\" id=\"fSt\" onchange=\"filterT()\"><option value=\"\">全部状态<\/option><option value=\"运行中\">运行中<\/option><option value=\"已暂停\">已暂停<\/option><\/select>\n<button class=\"btn btn-p\" style=\"margin-left:auto\" onclick=\"openAdd()\">+ 新增定时任务<\/button>\n<\/div>\n\n<div class=\"tw\"><table><thead><tr><th>任务名称<\/th><th>Skill<\/th><th>Cron<\/th><th>产品<\/th><th>下次执行<\/th><th>最近7次<\/th><th>状态<\/th><th>开关<\/th><th>操作<\/th><\/tr><\/thead>\n<tbody id=\"ctb\">\n<tr data-q=\"每日竞品数据采集\" data-st=\"运行中\"><td><b>每日竞品数据采集<\/b><\/td><td>竞品数据采集<\/td><td><code>0 8 * * *<\/code><\/td><td>PROD001<\/td><td style=\"color:var(--pri)\">明天 08:00<\/td><td><div class=\"timeline\" id=\"tl1\"><\/div><\/td><td><span class=\"tg tg-ok\">运行中<\/span><\/td><td><label class=\"switch\"><input type=\"checkbox\" checked onchange=\"toggleCron(this)\"><span class=\"slider\"><\/span><\/label><\/td><td><button class=\"btn-l\" onclick=\"openEdit('每日竞品数据采集')\">编辑<\/button> <button class=\"btn-l\" onclick=\"openM('modal-log')\">记录<\/button> <button class=\"btn-l\" style=\"color:var(--warn)\" onclick=\"showT('▶️ 手动触发成功','ok')\">触发<\/button> <button class=\"btn-l\" style=\"color:var(--err)\" onclick=\"openM('modal-del')\">删除<\/button><\/td><\/tr>\n<tr data-q=\"定时数据清洗\" data-st=\"运行中\"><td><b>定时数据清洗<\/b><\/td><td>数据清洗脚本<\/td><td><code>0 */4 * * *<\/code><\/td><td>全部<\/td><td style=\"color:var(--pri)\">今天 20:00<\/td><td><div class=\"timeline\" id=\"tl2\"><\/div><\/td><td><span class=\"tg tg-ok\">运行中<\/span><\/td><td><label class=\"switch\"><input type=\"checkbox\" checked onchange=\"toggleCron(this)\"><span class=\"slider\"><\/span><\/label><\/td><td><button class=\"btn-l\" onclick=\"openEdit('定时数据清洗')\">编辑<\/button> <button class=\"btn-l\" onclick=\"openM('modal-log')\">记录<\/button> <button class=\"btn-l\" style=\"color:var(--warn)\" onclick=\"showT('▶️ 手动触发成功','ok')\">触发<\/button> <button class=\"btn-l\" style=\"color:var(--err)\" onclick=\"openM('modal-del')\">删除<\/button><\/td><\/tr>\n<tr data-q=\"每周一小红书发布\" data-st=\"运行中\"><td><b>每周一小红书发布<\/b><\/td><td>小红书笔记发布<\/td><td><code>0 9 * * 1<\/code><\/td><td>PROD001<\/td><td style=\"color:var(--pri)\">下周一 09:00<\/td><td><div class=\"timeline\" id=\"tl3\"><\/div><\/td><td><span class=\"tg tg-ok\">运行中<\/span><\/td><td><label class=\"switch\"><input type=\"checkbox\" checked onchange=\"toggleCron(this)\"><span class=\"slider\"><\/span><\/label><\/td><td><button class=\"btn-l\" onclick=\"openEdit('每周一小红书发布')\">编辑<\/button> <button class=\"btn-l\" onclick=\"openM('modal-log')\">记录<\/button> <button class=\"btn-l\" style=\"color:var(--warn)\" onclick=\"showT('▶️ 手动触发成功','ok')\">触发<\/button> <button class=\"btn-l\" style=\"color:var(--err)\" onclick=\"openM('modal-del')\">删除<\/button><\/td><\/tr>\n<tr data-q=\"抖音视频批量上传\" data-st=\"运行中\"><td><b>抖音视频批量上传<\/b><\/td><td>抖音视频上传<\/td><td><code>30 10 * * *<\/code><\/td><td>PROD003<\/td><td style=\"color:var(--pri)\">明天 10:30<\/td><td><div class=\"timeline\" id=\"tl4\"><\/div><\/td><td><span class=\"tg tg-ok\">运行中<\/span><\/td><td><label class=\"switch\"><input type=\"checkbox\" checked onchange=\"toggleCron(this)\"><span class=\"slider\"><\/span><\/label><\/td><td><button class=\"btn-l\" onclick=\"openEdit('抖音视频批量上传')\">编辑<\/button> <button class=\"btn-l\" onclick=\"openM('modal-log')\">记录<\/button> <button class=\"btn-l\" style=\"color:var(--warn)\" onclick=\"showT('▶️ 手动触发成功','ok')\">触发<\/button> <button class=\"btn-l\" style=\"color:var(--err)\" onclick=\"openM('modal-del')\">删除<\/button><\/td><\/tr>\n<tr data-q=\"Facebook广告效果汇总\" data-st=\"已暂停\"><td><b style=\"color:var(--sub)\">Facebook广告效果汇总<\/b><\/td><td>Facebook广告投放<\/td><td><code>0 18 * * 5<\/code><\/td><td>PROD006<\/td><td style=\"color:var(--sub)\">已暂停<\/td><td><div class=\"timeline\" id=\"tl5\"><\/div><\/td><td><span class=\"tg tg-w\">已暂停<\/span><\/td><td><label class=\"switch\"><input type=\"checkbox\" onchange=\"toggleCron(this)\"><span class=\"slider\"><\/span><\/label><\/td><td><button class=\"btn-l\" onclick=\"openEdit('Facebook广告效果汇总')\">编辑<\/button> <button class=\"btn-l\" onclick=\"openM('modal-log')\">记录<\/button> <button class=\"btn-l\" style=\"color:var(--err)\" onclick=\"openM('modal-del')\">删除<\/button><\/td><\/tr>\n<tr data-q=\"月度报表生成\" data-st=\"已暂停\"><td><b style=\"color:var(--sub)\">月度报表生成<\/b><\/td><td>数据清洗脚本<\/td><td><code>0 0 1 * *<\/code><\/td><td>全部<\/td><td style=\"color:var(--sub)\">已暂停<\/td><td><div class=\"timeline\" id=\"tl6\"><\/div><\/td><td><span class=\"tg tg-w\">已暂停<\/span><\/td><td><label class=\"switch\"><input type=\"checkbox\" onchange=\"toggleCron(this)\"><span class=\"slider\"><\/span><\/label><\/td><td><button class=\"btn-l\" onclick=\"openEdit('月度报表生成')\">编辑<\/button> <button class=\"btn-l\" onclick=\"openM('modal-log')\">记录<\/button> <button class=\"btn-l\" style=\"color:var(--err)\" onclick=\"openM('modal-del')\">删除<\/button><\/td><\/tr>\n<\/tbody><\/table><\/div>\n\n<\/div><\/div><\/div>\n\n<script>\nfunction openM(id){document.getElementById(id).classList.add('show')}\nfunction closeM(id){document.getElementById(id).classList.remove('show')}\nfunction showT(m,t){const e=document.getElementById('toast');e.textContent=m;e.className='toast show '+t;setTimeout(()=>e.className='toast',2500)}\nfunction openAdd(){document.getElementById('mcTitle').textContent='新增定时任务';document.getElementById('mc-name').value='';openM('modal-cron')}\nfunction openEdit(name){document.getElementById('mcTitle').textContent='编辑 — '+name;document.getElementById('mc-name').value=name;openM('modal-cron')}\nfunction toggleCron(el){const tr=el.closest('tr');const st=tr.querySelector('.tg');if(el.checked){st.className='tg tg-ok';st.textContent='运行中';tr.dataset.st='运行中';showT('✅ 已启用','ok')}else{st.className='tg tg-w';st.textContent='已暂停';tr.dataset.st='已暂停';showT('⏸️ 已暂停','ok')}}\nfunction parseCron(v){const desc=document.getElementById('cronDesc');const map={'0 8 * * *':'📅 每天 08:00 执行','0 */2 * * *':'📅 每2小时执行','0 9 * * 1':'📅 每周一 09:00 执行','0 0 1 * *':'📅 每月1号 00:00 执行','30 10 * * *':'📅 每天 10:30 执行','0 18 * * 5':'📅 每周五 18:00 执行','0 */4 * * *':'📅 每4小时执行'};desc.textContent=map[v]||'📅 自定义表达式: '+v}\nfunction filterT(){const q=document.getElementById('sInput').value.toLowerCase();const st=document.getElementById('fSt').value;document.querySelectorAll('#ctb tr').forEach(tr=>{const d=tr.dataset;tr.style.display=(!q||d.q.toLowerCase().includes(q))&&(!st||d.st===st)?'':'none'})}\nfunction initTimelines(){for(let i=1;i<=6;i++){const el=document.getElementById('tl'+i);if(!el)continue;let html='';for(let j=0;j<7;j++){const ok=Math.random()>0.15;html+=`<div class=\"tl-dot\" style=\"background:${ok?'var(--ok)':'var(--err)'}\" title=\"${7-j}天前: ${ok?'成功':'失败'}\"><\/div>`}el.innerHTML=html}}\ninitTimelines();\ndocument.querySelectorAll('.mo').forEach(m=>m.addEventListener('click',e=>{if(e.target===m)m.classList.remove('show')}));\n<\/script>\n<\/body><\/html>"
|
||
};
|
||
|
||
// 页面名映射(用于拦截 alert('跳转:xxx'))
|
||
const NAV_MAP = {"任务创建": "10_任务创建.html", "任务列表": "11_任务列表.html", "Skill列表": "09_Skill管理.html", "Skill管理": "09_Skill管理.html", "平台账号": "08_平台产品账号.html", "组织架构": "03_组织架构.html", "角色管理": "04_角色管理.html", "用户管理": "05_用户管理.html", "菜单管理": "12_菜单管理.html", "产品管理": "06_产品管理.html", "产品列表": "06_产品管理.html", "渠道码管理": "07_渠道码管理.html", "平台套件": "13_平台套件.html", "平台账号管理": "08_平台产品账号.html", "调用日志": "14_Skill调用日志.html", "操作日志": "15_操作日志.html", "统计报表": "16_统计报表.html", "执行器配置": "17_执行器配置.html", "脚本模板": "18_脚本模板管理.html", "脚本模板管理": "18_脚本模板管理.html", "定时任务": "19_定时任务.html", "仪表盘": "02_仪表盘.html"};
|
||
|
||
const frame = document.getElementById('mainFrame');
|
||
const sidebar = document.getElementById('sidebar');
|
||
|
||
// 加载指定页面到 iframe
|
||
function loadPage(name) {
|
||
if (!PAGES[name]) { console.warn('page not found:', name); return; }
|
||
frame.srcdoc = PAGES[name];
|
||
}
|
||
|
||
// 更新侧边栏高亮
|
||
function setActive(name) {
|
||
document.querySelectorAll('.ni').forEach(n => n.classList.remove('ac'));
|
||
const target = document.querySelector('.ni[data-src="' + name + '"]');
|
||
if (target) target.classList.add('ac');
|
||
}
|
||
|
||
// 导航入口
|
||
function navigate(name) {
|
||
if (!PAGES[name]) return;
|
||
loadPage(name);
|
||
setActive(name);
|
||
}
|
||
|
||
// 侧边栏点击
|
||
document.querySelectorAll('.ni[data-src]').forEach(item => {
|
||
item.addEventListener('click', function() {
|
||
navigate(this.dataset.src);
|
||
});
|
||
});
|
||
|
||
// 监听子页面消息(登录成功 + 导航请求)
|
||
window.addEventListener('message', function(e) {
|
||
if (e.data === 'login-success') {
|
||
sidebar.classList.remove('hide');
|
||
navigate('02_仪表盘.html');
|
||
} else if (e.data && e.data.type === 'nav' && e.data.target) {
|
||
navigate(e.data.target);
|
||
}
|
||
});
|
||
|
||
// iframe load 后注入桥接脚本:隐藏子页面自带侧边栏 + 拦截 alert 跳转
|
||
frame.addEventListener('load', function() {
|
||
try {
|
||
const d = frame.contentDocument;
|
||
if (!d) return;
|
||
|
||
// 隐藏子页面自带的侧边栏(它们有自己的 .side,可能样式冲突;外层 .side.hide 已起作用,子页面的 .side 这里隐藏)
|
||
let s = d.getElementById('_injected_style');
|
||
if (!s) { s = d.createElement('style'); s.id = '_injected_style'; d.head && d.head.appendChild(s); }
|
||
s.textContent = '.side{display:none!important}.main{margin-left:0!important}.layout{min-height:auto}';
|
||
|
||
// 注入桥接:把 alert("跳转:XXX") 或 alert("请打开 XX_xxx.html") 转为导航
|
||
if (!d.getElementById('_injected_bridge')) {
|
||
const sc = d.createElement('script');
|
||
sc.id = '_injected_bridge';
|
||
sc.textContent = `
|
||
(function(){
|
||
const NAV_MAP = ${JSON.stringify(NAV_MAP)};
|
||
const origAlert = window.alert;
|
||
window.alert = function(msg) {
|
||
try {
|
||
const s = String(msg);
|
||
// 形如 "请打开 03_组织架构.html"
|
||
let m = s.match(/(\d{2}_[^\s]+\.html)/);
|
||
if (m) { window.parent.postMessage({type:'nav', target: m[1]}, '*'); return; }
|
||
// 形如 "跳转:任务创建" 或 "跳转:任务创建"
|
||
m = s.match(/跳转[::]\s*(.+)/);
|
||
if (m) {
|
||
const key = m[1].trim();
|
||
if (NAV_MAP[key]) { window.parent.postMessage({type:'nav', target: NAV_MAP[key]}, '*'); return; }
|
||
}
|
||
} catch(err) {}
|
||
return origAlert.call(window, msg);
|
||
};
|
||
// 暴露给子页面主动调用
|
||
window.__navigate = function(target) {
|
||
window.parent.postMessage({type:'nav', target: target}, '*');
|
||
};
|
||
})();
|
||
`;
|
||
(d.body || d.documentElement).appendChild(sc);
|
||
}
|
||
} catch (e) { console.warn(e); }
|
||
});
|
||
|
||
// 初始加载登录页
|
||
loadPage('01_登录页.html');
|
||
</script>
|
||
</body>
|
||
</html>
|