feat: 新增智能体服务订阅功能(REQ-131~134)
企业、个人用户和 OPC 均可订阅运营商提供的智能体服务: - 智能体服务目录(6 个智能体:电商视觉/AI漫剧/企业智能体/数据标注/硬件供应链/跨境文案) - 订阅管理(月度/季度/年度套餐、用量跟踪、续费/取消) - 调用记录与账单(按月计费、算力券抵扣) - 新增 agent.html 页面,opc/enterprise/personal/operator 角色可见 Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
+171
@@ -0,0 +1,171 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>智能体服务 · OPC 公共服务平台 Demo</title>
|
||||
<link rel="stylesheet" href="assets/style.css">
|
||||
</head>
|
||||
<body data-page="agent">
|
||||
<header class="topnav" id="topnav"></header>
|
||||
|
||||
<div class="container">
|
||||
<div class="page-title">智能体服务</div>
|
||||
<div class="page-sub" id="agent-sub"></div>
|
||||
|
||||
<!-- REQ-131 智能体服务目录 -->
|
||||
<div class="section">
|
||||
<h2>智能体服务目录 <span class="req">REQ-131 · 运营商提供 · 企业/个人/OPC 均可订阅</span></h2>
|
||||
<div class="grid grid-3" id="agt-catalog"></div>
|
||||
<p class="muted" style="margin-top:10px">运营商提供的智能体服务覆盖电商视觉、AI 漫剧、企业智能体、数据标注、硬件供应链、跨境电商等方向。订阅后按调用次数计费,套餐内不另收费。</p>
|
||||
</div>
|
||||
|
||||
<!-- REQ-132 我的订阅 -->
|
||||
<div class="section">
|
||||
<h2>我的订阅 <span class="req">REQ-132 · 订阅管理 · 用量与到期</span></h2>
|
||||
<div class="card"><table id="agt-subs"></table></div>
|
||||
</div>
|
||||
|
||||
<!-- REQ-133 使用记录 -->
|
||||
<div class="section">
|
||||
<div class="two-col">
|
||||
<div class="card">
|
||||
<h3>近期使用记录 <span class="req">REQ-133</span></h3>
|
||||
<table id="agt-usage"></table>
|
||||
</div>
|
||||
<div class="card">
|
||||
<h3>本月账单 <span class="req">REQ-134</span></h3>
|
||||
<ul class="list" id="agt-bill"></ul>
|
||||
<button class="btn sm" style="margin-top:10px" onclick="agentBill()">查看账单明细</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="footer">OPC 公共服务平台 Demo · 智能体服务</div>
|
||||
<script src="assets/app.js"></script>
|
||||
<script src="assets/store.js"></script>
|
||||
<script>
|
||||
function renderPage(DB) {
|
||||
const A = DB.agent || {};
|
||||
const role = currentRole();
|
||||
const roleLabel = { operator: '运营商管理视角 · 智能体服务运营与订阅统计', enterprise: '企业订阅 · 调用智能体提升业务效率', personal: '个人订阅 · 调用智能体辅助工作', opc: 'OPC 订阅 · 调用智能体提升交付效率' }[role] || '智能体服务订阅';
|
||||
document.getElementById('agent-sub').textContent = roleLabel;
|
||||
|
||||
// 目录
|
||||
document.getElementById('agt-catalog').innerHTML = (A.catalog || []).map((a, i) => `
|
||||
<div class="card">
|
||||
<h3>${a.name} ${B(a.status)}</h3>
|
||||
<p class="muted">${a.desc}</p>
|
||||
<div style="margin:8px 0">${a.tags.map(t => `<span class="badge pri">${t}</span> `).join('')}</div>
|
||||
<table style="margin:6px 0">
|
||||
<tr><td class="muted">分类</td><td>${a.category}</td></tr>
|
||||
<tr><td class="muted">价格</td><td><b>${a.price}</b></td></tr>
|
||||
<tr><td class="muted">额度</td><td>${a.calls}</td></tr>
|
||||
<tr><td class="muted">评分</td><td>★ ${a.rating} · ${a.users} 用户</td></tr>
|
||||
</table>
|
||||
<button class="btn sm" onclick="subscribe(${i})">订阅</button>
|
||||
<button class="btn sm ghost" onclick="agentDetail(${i})">详情</button>
|
||||
</div>`).join('');
|
||||
|
||||
// 我的订阅
|
||||
document.getElementById('agt-subs').innerHTML =
|
||||
`<tr><th>订阅号</th><th>智能体</th><th>套餐</th><th>价格</th><th>用量</th><th>到期</th><th>状态</th><th>操作</th></tr>` +
|
||||
(A.mySubs || []).map((s, i) => `<tr>
|
||||
<td>${s.code}</td><td>${s.agent}</td><td>${s.plan}</td><td>${s.price}</td>
|
||||
<td>${s.calls}</td><td>${s.expire}</td><td>${B(s.status)}</td>
|
||||
<td><button class="btn sm ghost" onclick="subDetail(${i})">管理</button> <button class="btn sm ghost" onclick="renew(${i})">续费</button></td>
|
||||
</tr>`).join('');
|
||||
|
||||
// 使用记录
|
||||
document.getElementById('agt-usage').innerHTML =
|
||||
`<tr><th>日期</th><th>智能体</th><th>调用</th><th>任务</th><th>费用</th></tr>` +
|
||||
(A.usage || []).map(u => `<tr><td>${u.date}</td><td>${u.agent}</td><td>${u.calls} 次</td><td class="muted">${u.task}</td><td>${u.cost}</td></tr>`).join('');
|
||||
|
||||
// 账单
|
||||
const bi = A.billing || {};
|
||||
document.getElementById('agt-bill').innerHTML =
|
||||
LI('订阅费', bi.subs || '—') +
|
||||
LI('调用次数', (bi.calls || 0) + ' 次') +
|
||||
LI('超额费用', bi.extra || '¥0') +
|
||||
LI('本月合计', `<b>${bi.total || '—'}</b>`);
|
||||
}
|
||||
|
||||
function subscribe(i) {
|
||||
const a = DB.agent.catalog[i];
|
||||
openModal({
|
||||
title: '订阅 · ' + a.name,
|
||||
body: `<p class="muted">${a.desc}</p>
|
||||
<div class="field"><label>订阅套餐</label>
|
||||
<select><option>${a.price} · 月度</option><option>${a.price.replace('/月','/季')} · 季度(9 折)</option><option>${a.price.replace('/月','/年')} · 年度(8 折)</option></select>
|
||||
</div>
|
||||
<div class="field"><label>支付方式</label><select><option>余额支付</option><option>算力券抵扣</option><option>对公转账</option></select></div>
|
||||
<p class="muted">订阅后立即生效,套餐内调用不另收费,超额按 ¥0.05/次 计费。</p>`,
|
||||
actions: [
|
||||
{ label: '取消', cls: 'ghost' },
|
||||
{ label: '确认订阅', onClick: m => { m.remove(); toast('订阅成功!可在「我的订阅」管理用量与续费'); } },
|
||||
],
|
||||
});
|
||||
}
|
||||
function agentDetail(i) {
|
||||
const a = DB.agent.catalog[i];
|
||||
openModal({
|
||||
title: a.name + ' · 详情',
|
||||
body: `<table>
|
||||
<tr><th>编号</th><td>${a.code}</td></tr>
|
||||
<tr><th>分类</th><td>${a.category}</td></tr>
|
||||
<tr><th>说明</th><td>${a.desc}</td></tr>
|
||||
<tr><th>价格</th><td>${a.price}</td></tr>
|
||||
<tr><th>调用额度</th><td>${a.calls}</td></tr>
|
||||
<tr><th>评分</th><td>★ ${a.rating} · ${a.users} 活跃用户</td></tr>
|
||||
<tr><th>能力标签</th><td>${a.tags.map(t => `<span class="badge pri">${t}</span> `).join('')}</td></tr>
|
||||
</table>
|
||||
<h4 style="margin-top:12px">典型场景</h4>
|
||||
<ul class="list">
|
||||
<li><span>批量商品主图生成(100 张 / 10 分钟)</span></li>
|
||||
<li><span>多语言详情页自动翻译+排版</span></li>
|
||||
<li><span>活动 Banner 模板化批量出图</span></li>
|
||||
</ul>`,
|
||||
});
|
||||
}
|
||||
function subDetail(i) {
|
||||
const s = DB.agent.mySubs[i];
|
||||
openModal({
|
||||
title: '订阅管理 · ' + s.agent,
|
||||
body: `<table>
|
||||
<tr><th>订阅号</th><td>${s.code}</td></tr>
|
||||
<tr><th>套餐</th><td>${s.plan} · ${s.price}</td></tr>
|
||||
<tr><th>用量</th><td>${s.calls}</td></tr>
|
||||
<tr><th>到期</th><td>${s.expire}</td></tr>
|
||||
<tr><th>状态</th><td>${B(s.status)}</td></tr>
|
||||
</table>
|
||||
<p class="muted" style="margin-top:8px">可操作:续费、升级套餐、取消订阅。取消后到期停止服务,期间仍可使用。</p>`,
|
||||
actions: [
|
||||
{ label: '关闭', cls: 'ghost' },
|
||||
{ label: '取消订阅', cls: 'danger', onClick: m => { m.remove(); toast('订阅已取消,到期后停止服务'); } },
|
||||
],
|
||||
});
|
||||
}
|
||||
function renew(i) {
|
||||
const s = DB.agent.mySubs[i];
|
||||
confirmDlg('续费确认', `${s.agent} · ${s.price}。续费后到期日顺延一个月。`, '确认续费', () => {
|
||||
toast('续费成功,到期日已顺延至 ' + s.expire.replace(/\d{2}$/, String(parseInt(s.expire.match(/\d{2}$/)[0]) + 1).padStart(2, '0')));
|
||||
});
|
||||
}
|
||||
function agentBill() {
|
||||
openModal({
|
||||
title: '本月账单明细',
|
||||
body: `<table>
|
||||
<tr><th>项目</th><th>金额</th><th>说明</th></tr>
|
||||
<tr><td>AGT_001 电商视觉 月度</td><td>¥299</td><td class="muted">1000 次额度 · 已用 326</td></tr>
|
||||
<tr><td>AGT_004 数据标注 月度</td><td>¥199</td><td class="muted">5000 次额度 · 已用 1820</td></tr>
|
||||
<tr><td>超额调用</td><td>¥0</td><td class="muted">未超额</td></tr>
|
||||
<tr style="border-top:2px solid var(--primary)"><td><b>合计</b></td><td><b>¥498</b></td><td>—</td></tr>
|
||||
</table>
|
||||
<p class="muted" style="margin-top:8px">账单次月 1 日生成,支持算力券抵扣和对公转账。</p>`,
|
||||
actions: [{ label: '关闭', cls: 'ghost' }],
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -25,6 +25,7 @@ const MENUS = [
|
||||
{ page: 'profile', label: '画像中心', href: 'profile.html', roles: ['operator', 'gov', 'enterprise'], group: '运营管理' },
|
||||
{ page: 'opc', label: 'OPC 工作台', href: 'opc.html', roles: ['opc'], group: '我的工作台' },
|
||||
{ page: 'team', label: '组队协同', href: 'team.html', roles: ['opc', 'operator'], group: '我的工作台' },
|
||||
{ page: 'agent', label: '智能体服务', href: 'agent.html', roles: ['opc', 'enterprise', 'personal', 'operator'], group: '我的工作台' },
|
||||
{ page: 'enterprise', label: '企业工作台', href: 'enterprise.html', roles: ['enterprise', 'personal'], labelMap: { personal: '个人工作台' }, group: '我的工作台' },
|
||||
{ page: 'order', label: '订单与协同', href: 'order.html', roles: ['opc', 'enterprise', 'personal', 'operator'], group: '我的工作台' },
|
||||
{ page: 'market', label: '橙果商城', href: 'market.html', roles: ['opc', 'enterprise', 'personal', 'learner', 'operator'], group: '我的工作台' },
|
||||
@@ -95,6 +96,19 @@ function renderNav() {
|
||||
return;
|
||||
}
|
||||
|
||||
// 门户首页:已登录也不显示侧边栏(公开展示页),顶栏显示品牌 + 帮助 + 角色徽章 + 退出
|
||||
if (page === 'index') {
|
||||
host.innerHTML = `
|
||||
<a class="brand" href="index.html">OPC<span>公共服务平台</span></a>
|
||||
<a href="req-doc.html" class="muted" style="margin-left:auto;font-size:13px" target="_blank">帮助 / 需求文档</a>
|
||||
<span class="role-badge">${ROLES[role].name}</span>
|
||||
<button class="btn sm ghost" onclick="resetDemo()">重置数据</button>
|
||||
<button class="btn sm" onclick="logout()">退出</button>
|
||||
`;
|
||||
document.body.style.paddingLeft = '0';
|
||||
return;
|
||||
}
|
||||
|
||||
// 按分组组织菜单
|
||||
const groups = [];
|
||||
const groupMap = {};
|
||||
|
||||
@@ -3262,5 +3262,186 @@
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"agent": {
|
||||
"catalog": [
|
||||
{
|
||||
"code": "AGT_001",
|
||||
"name": "电商视觉智能体",
|
||||
"desc": "商品主图/详情页/Banner 自动生成,支持批量出图",
|
||||
"category": "电商视觉",
|
||||
"price": "¥299/月",
|
||||
"calls": "1000 次/月",
|
||||
"rating": 4.8,
|
||||
"users": 128,
|
||||
"status": [
|
||||
"热销",
|
||||
"ok"
|
||||
],
|
||||
"tags": [
|
||||
"商品主图",
|
||||
"详情页",
|
||||
"Banner"
|
||||
]
|
||||
},
|
||||
{
|
||||
"code": "AGT_002",
|
||||
"name": "AI 漫剧分镜智能体",
|
||||
"desc": "剧本→分镜→线稿→上色全流程辅助,支持风格切换",
|
||||
"category": "AI 漫剧",
|
||||
"price": "¥499/月",
|
||||
"calls": "500 次/月",
|
||||
"rating": 4.6,
|
||||
"users": 56,
|
||||
"status": [
|
||||
"热销",
|
||||
"ok"
|
||||
],
|
||||
"tags": [
|
||||
"分镜",
|
||||
"上色",
|
||||
"风格"
|
||||
]
|
||||
},
|
||||
{
|
||||
"code": "AGT_003",
|
||||
"name": "企业智能体 FDE",
|
||||
"desc": "企业知识库构建+智能问答+工作流自动化",
|
||||
"category": "企业智能体",
|
||||
"price": "¥999/月",
|
||||
"calls": "不限",
|
||||
"rating": 4.9,
|
||||
"users": 32,
|
||||
"status": [
|
||||
"企业版",
|
||||
"pri"
|
||||
],
|
||||
"tags": [
|
||||
"知识库",
|
||||
"问答",
|
||||
"自动化"
|
||||
]
|
||||
},
|
||||
{
|
||||
"code": "AGT_004",
|
||||
"name": "数据标注智能体",
|
||||
"desc": "图像/文本/音频预标注+人工校验,标注效率提升 5 倍",
|
||||
"category": "数据标注",
|
||||
"price": "¥199/月",
|
||||
"calls": "5000 次/月",
|
||||
"rating": 4.5,
|
||||
"users": 85,
|
||||
"status": [
|
||||
"在售",
|
||||
"ok"
|
||||
],
|
||||
"tags": [
|
||||
"预标注",
|
||||
"校验",
|
||||
"批量"
|
||||
]
|
||||
},
|
||||
{
|
||||
"code": "AGT_005",
|
||||
"name": "硬件方案智能体",
|
||||
"desc": "AI 产品定义→工业设计→BOM 清单→打样建议",
|
||||
"category": "硬件供应链",
|
||||
"price": "¥799/月",
|
||||
"calls": "200 次/月",
|
||||
"rating": 4.7,
|
||||
"users": 18,
|
||||
"status": [
|
||||
"新品",
|
||||
"warn"
|
||||
],
|
||||
"tags": [
|
||||
"产品定义",
|
||||
"BOM",
|
||||
"打样"
|
||||
]
|
||||
},
|
||||
{
|
||||
"code": "AGT_006",
|
||||
"name": "跨境文案智能体",
|
||||
"desc": "多语言商品描述/广告文案/SEO 优化自动生成",
|
||||
"category": "跨境电商",
|
||||
"price": "¥199/月",
|
||||
"calls": "2000 次/月",
|
||||
"rating": 4.4,
|
||||
"users": 142,
|
||||
"status": [
|
||||
"在售",
|
||||
"ok"
|
||||
],
|
||||
"tags": [
|
||||
"多语言",
|
||||
"文案",
|
||||
"SEO"
|
||||
]
|
||||
}
|
||||
],
|
||||
"mySubs": [
|
||||
{
|
||||
"code": "SUB_0001",
|
||||
"agent": "AGT_001 电商视觉智能体",
|
||||
"plan": "月度订阅",
|
||||
"price": "¥299/月",
|
||||
"calls": "326 / 1000",
|
||||
"expire": "2026-10-15",
|
||||
"status": [
|
||||
"使用中",
|
||||
"ok"
|
||||
]
|
||||
},
|
||||
{
|
||||
"code": "SUB_0002",
|
||||
"agent": "AGT_004 数据标注智能体",
|
||||
"plan": "月度订阅",
|
||||
"price": "¥199/月",
|
||||
"calls": "1820 / 5000",
|
||||
"expire": "2026-10-20",
|
||||
"status": [
|
||||
"使用中",
|
||||
"ok"
|
||||
]
|
||||
}
|
||||
],
|
||||
"usage": [
|
||||
{
|
||||
"date": "09-14",
|
||||
"agent": "AGT_001 电商视觉",
|
||||
"calls": 28,
|
||||
"cost": "¥0",
|
||||
"task": "商品主图 ×28"
|
||||
},
|
||||
{
|
||||
"date": "09-13",
|
||||
"agent": "AGT_001 电商视觉",
|
||||
"calls": 45,
|
||||
"cost": "¥0",
|
||||
"task": "详情页 ×15"
|
||||
},
|
||||
{
|
||||
"date": "09-12",
|
||||
"agent": "AGT_004 数据标注",
|
||||
"calls": 320,
|
||||
"cost": "¥0",
|
||||
"task": "图像标注 320 条"
|
||||
},
|
||||
{
|
||||
"date": "09-11",
|
||||
"agent": "AGT_001 电商视觉",
|
||||
"calls": 18,
|
||||
"cost": "¥0",
|
||||
"task": "Banner ×6"
|
||||
}
|
||||
],
|
||||
"billing": {
|
||||
"month": "2026-09",
|
||||
"subs": "¥498/月",
|
||||
"calls": 2211,
|
||||
"extra": "¥0",
|
||||
"total": "¥498"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@
|
||||
* mock.json 结构升级时提升 SCHEMA_VER 使旧存档失效。
|
||||
*/
|
||||
|
||||
const SCHEMA_VER = 5;
|
||||
const SCHEMA_VER = 6;
|
||||
const DB_KEY = 'opc_demo_db';
|
||||
|
||||
let DB = null;
|
||||
|
||||
@@ -95,7 +95,7 @@ a:hover { color: var(--primary-dark); }
|
||||
|
||||
/* body 留出侧边栏空间(login/showcase 无侧边栏除外) */
|
||||
body { padding-left: 220px; }
|
||||
body[data-page="login"], body.screen { padding-left: 0; }
|
||||
body[data-page="login"], body[data-page="index"], body.screen { padding-left: 0; }
|
||||
@media (max-width: 900px) {
|
||||
body { padding-left: 0; }
|
||||
.topnav .nav-toggle { display: inline-block; }
|
||||
|
||||
Reference in New Issue
Block a user