feat: OPC 社区运营公共服务平台 Demo v1.3

一人公司/超级个体产业社区公共服务基础设施 Demo,包含:
- 18 个角色页面(运营商/OPC/企业/个人/学员/培训机构/服务机构/政府/审计/金融)
- 暖橙活力主题 UI(渐变毛玻璃 + 暖色侧栏)
- 五步运营闭环(选方向→育人才→建平台→立SOP→聚产业)
- 华强北硬件供应链接入
- 蜂群式交付 + 产业集聚效应展示
- 需求文档(REQ-001~118 全覆盖)

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
2026-09-13 09:07:23 +08:00
co-authored by Devin
commit f307e877c9
30 changed files with 11397 additions and 0 deletions
+138
View File
@@ -0,0 +1,138 @@
<!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="leads">
<header class="topnav" id="topnav"></header>
<div class="container">
<div class="page-title">供需对接工作台</div>
<div class="page-sub" id="ld-sub">线索登记 → 跟进 → 需求确认 → 订单转化,全链路可追溯(REQ-095~098)</div>
<div class="grid grid-4" id="ld-stats"></div>
<!-- REQ-097 线索转化漏斗 -->
<div class="section">
<div class="two-col">
<div class="card">
<h3>转化漏斗 <span class="req">REQ-097</span></h3>
<div class="funnel" id="ld-funnel"></div>
<p class="muted" style="margin-top:10px">每场活动自动归集线索并追踪转化贡献(REQ-096)。</p>
</div>
<div class="card">
<h3>运营商跟单动作 <span class="req">REQ-098</span></h3>
<ul class="list">
<li><span>活动后 48h 内完成首次触达</span><span class="badge ok">SOP 执行中</span></li>
<li><span>超 7 天未跟进线索标黄</span><span class="badge warn">4 条待处理</span></li>
<li><span>需求确认后转企业工作台发单</span><span class="badge info">一键转需求</span></li>
<li><span>转化结果回写活动绩效</span><span class="badge pri">自动归集</span></li>
</ul>
</div>
</div>
</div>
<!-- 线索台账 -->
<div class="section">
<h2>线索台账 <span class="req">REQ-097 · LEAD_ 统一编号</span>
<span style="margin-left:auto"><button class="btn sm" onclick="newLead()">+ 登记线索</button></span>
</h2>
<div class="card"><table id="ld-tbl"></table></div>
</div>
</div>
<div class="footer">OPC 公共服务平台 Demo · 供需对接</div>
<script src="assets/app.js"></script>
<script src="assets/store.js"></script>
<script>
let leadSeq = 97;
function renderPage(DB) {
const L = DB.leads;
const role = currentRole();
document.getElementById('ld-sub').textContent = role === 'gov'
? '政府监测视角 · 供需转化成效与漏斗监测(REQ-095~098)'
: '线索登记 → 跟进 → 需求确认 → 订单转化,全链路可追溯(REQ-095~098)';
document.getElementById('ld-stats').innerHTML = L.stats.map(s =>
`<div class="card"><h3>${s.label}</h3><div class="num">${s.num}</div><p class="muted">${s.sub}</p></div>`).join('');
document.getElementById('ld-funnel').innerHTML = L.funnel.map((f, i) => `
<div class="funnel-row">
<span class="funnel-stage">${f.stage}</span>
<div class="funnel-bar" style="width:${f.w}%">${f.num}</div>
${i ? `<span class="funnel-conv">转化 ${(f.num / L.funnel[i-1].num * 100).toFixed(0)}%</span>` : ''}
</div>`).join('');
renderLeads();
}
function leadAction(l, i) {
if (l.action === 'follow') return `<button class="btn sm" onclick="follow(${i})">跟进</button>`;
if (l.action === 'toReq') return `<button class="btn sm" onclick="toReq(${i})">转需求</button>`;
if (l.action === 'order') return `<button class="btn sm ghost" onclick="toast('已关联订单 ${l.order},可在订单与协同查看')">关联订单</button>`;
return '—';
}
function renderLeads() {
document.getElementById('ld-tbl').innerHTML =
`<tr><th>线索编号</th><th>主体</th><th>来源</th><th>意向需求</th><th>阶段</th><th>跟进人</th><th>操作</th></tr>` +
DB.leads.list.map((l, i) => `<tr><td>${l.code}</td><td>${l.party}</td><td>${l.source}</td><td>${l.need}</td><td>${B(l.stage)}</td><td>${l.owner}</td><td>${leadAction(l, i)}</td></tr>`).join('');
}
function newLead() {
openModal({
title: '登记线索(REQ-097)',
body: `
<div class="field"><label>主体名称</label><input id="nl-p" placeholder="企业/个人/OPC"></div>
<div class="field-row">
<div class="field"><label>来源</label><select id="nl-s"><option>门户咨询</option><option>ACT_0001 供需对接会</option><option>政策宣讲</option><option>转介绍</option></select></div>
<div class="field"><label>跟进人</label><select><option>运营·王</option><option>运营·李</option></select></div>
</div>
<div class="field"><label>意向需求</label><textarea id="nl-n" placeholder="一句话描述需求或诉求"></textarea></div>`,
actions: [
{ label: '取消', cls: 'ghost' },
{ label: '登记', onClick: m => {
const p = document.getElementById('nl-p').value.trim();
if (!p) { toast('请填写主体名称', 'warn'); return; }
m.remove();
const code = 'LEAD_' + String(leadSeq++).padStart(4, '0');
DB.leads.list.unshift({ code, party: p, source: document.getElementById('nl-s').value, need: document.getElementById('nl-n').value || '待沟通', stage: ['跟进中', 'info'], owner: '运营·王', action: 'follow' });
DB.leads.funnel[0].num++; DB.leads.funnel[1].num++;
renderPage(DB);
toast(`线索 ${code} 已登记,进入跟进队列`);
} },
],
});
}
function follow(i) {
const l = DB.leads.list[i];
openModal({
title: '跟进记录 · ' + l.code,
body: `<div class="field"><label>跟进方式</label><select><option>电话回访</option><option>上门拜访</option><option>线上会议</option></select></div>
<div class="field"><label>跟进纪要</label><textarea placeholder="将写入线索流转留痕"></textarea></div>`,
actions: [
{ label: '取消', cls: 'ghost' },
{ label: '保存并推进', onClick: m => {
m.remove();
l.stage = ['需求确认', 'warn']; l.action = 'toReq';
DB.leads.funnel[2].num++;
renderPage(DB);
toast('跟进纪要已记录,线索推进至「需求确认」');
} },
],
});
}
function toReq(i) {
const l = DB.leads.list[i];
confirmDlg('转需求确认', `将线索 ${l.code}(${l.party})转为正式需求单?将在企业工作台生成需求并进入询价流程。`, '确认转需求', () => {
l.stage = ['已转化', 'ok']; l.action = 'order'; l.order = 'ORDER_2026091301';
DB.leads.funnel[3].num++;
renderPage(DB);
toast(`已转化:关联订单 ORDER_2026091301,转化记录回写来源活动`);
});
}
</script>
</body>
</html>