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:
+285
@@ -0,0 +1,285 @@
|
||||
<!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="order">
|
||||
<header class="topnav" id="topnav"></header>
|
||||
|
||||
<div class="container">
|
||||
<div class="page-title" id="od-title"></div>
|
||||
<div class="page-sub" id="od-sub"></div>
|
||||
|
||||
<!-- REQ-030 订单状态机 -->
|
||||
<div class="card">
|
||||
<h3>订单状态 <span class="req">REQ-030</span>
|
||||
<span style="margin-left:auto">
|
||||
<button class="btn sm" onclick="submitDeliver()">提交交付物</button>
|
||||
<button class="btn sm ghost" onclick="toast('流转留痕:09-01 签约 → 09-03 开工 → 09-08 里程碑1验收通过(演示)')">流转留痕</button>
|
||||
</span>
|
||||
</h3>
|
||||
<div id="od-steps"></div>
|
||||
</div>
|
||||
|
||||
<!-- REQ-033/034 任务拆解与协作组 -->
|
||||
<div class="section">
|
||||
<h2>任务拆解 <span class="req">REQ-033/034 · 协作组 3 人</span></h2>
|
||||
<div class="card">
|
||||
<table id="task-tbl"></table>
|
||||
<div class="notice" style="margin-top:12px" id="risk-notice"></div>
|
||||
<p class="muted" style="margin-top:8px">订单保证金 ¥12,000 已托管 · 延期预警与替补机制生效中(REQ-046);任务支持模板/依赖/暂停/转派(REQ-034)。</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 蜂群式交付(§1.5 步骤④) -->
|
||||
<div class="section">
|
||||
<h2>蜂群式交付 <span class="req">§1.5 ④ · SOP 标准体系 · 单兵可替 · 产能可扩</span></h2>
|
||||
<div class="card">
|
||||
<p style="margin-bottom:12px">基于 <code>SOP_电商视觉_V3.2</code> 标准体系,多个 OPC 按统一标准并行交付同一项目;每个交付单元独立可替换,单个 OPC 退出不影响整体产能。</p>
|
||||
<table id="swarm-tbl"></table>
|
||||
<p class="muted" style="margin-top:10px">蜂群交付核心:① 统一 SOP 标准保证质量一致性 ② 任务粒度可拆可替 ③ 产能随 OPC 数量线性扩展 ④ 项目负责人复检 + 运营商终检兜底</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- REQ-036 进度甘特图 -->
|
||||
<div class="section">
|
||||
<div class="card">
|
||||
<h3>进度甘特图 <span class="req">REQ-036 · 红线为今日 09-11</span></h3>
|
||||
<div class="gantt" id="gantt"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- REQ-049 三级质检 -->
|
||||
<div class="section">
|
||||
<div class="two-col">
|
||||
<div class="card">
|
||||
<h3>三级质检 <span class="req">REQ-049/039/054/055</span></h3>
|
||||
<table id="qc-tbl"></table>
|
||||
<p class="muted" style="margin-top:8px">版权与合规审查为内容类订单强制终检项(REQ-054);AI 生成内容须经事实/肖像/商标/有害信息审核(REQ-055)。</p>
|
||||
<p class="muted">返工归因(REQ-057):详情页批次 A → 需求变更(客户新增合规文案要求),不计入 OPC 返工率。</p>
|
||||
</div>
|
||||
<div class="card">
|
||||
<h3>质量指标 · 跨境电商视觉 <span class="req">REQ-051/056/058/059</span>
|
||||
<span style="margin-left:auto"><button class="btn sm ghost" onclick="qcRules()">抽检规则</button></span>
|
||||
</h3>
|
||||
<ul class="list" id="qm-list"></ul>
|
||||
<p class="muted" style="margin-top:8px">REQ-052:按时交付率接近阈值,已触发预警观察;质量数据脱敏同步政府驾驶舱与 OPC 能力档案(REQ-058),指标集版本 QI_0002/V3 可扩展(REQ-059)。</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- REQ-035/038 协作与安全 -->
|
||||
<div class="section">
|
||||
<div class="two-col">
|
||||
<div class="card">
|
||||
<h3>文件与沟通 <span class="req">REQ-035</span></h3>
|
||||
<ul class="list" id="file-list"></ul>
|
||||
</div>
|
||||
<div class="card">
|
||||
<h3>数据安全 <span class="req">REQ-038 · L3 敏感</span></h3>
|
||||
<ul class="list" id="sec-list"></ul>
|
||||
</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 D = DB.orderDetail;
|
||||
const role = currentRole();
|
||||
const subMap = {
|
||||
opc: 'OPC 交付方视角 · 提交交付物、三级质检、替补协作',
|
||||
enterprise: '企业发单方视角 · 跟踪进度、验收与争议',
|
||||
personal: '个人发单方视角 · 跟踪进度、验收与争议',
|
||||
operator: '运营商管理视角 · 全链路协同与质检监管',
|
||||
};
|
||||
document.getElementById('od-title').textContent = '订单协同 · ' + D.id;
|
||||
document.getElementById('od-sub').textContent = D.title + (subMap[role] ? ' · ' + subMap[role] : '');
|
||||
document.getElementById('od-steps').innerHTML = STEPS(D.steps);
|
||||
renderTasks();
|
||||
renderSwarm();
|
||||
renderQc();
|
||||
|
||||
document.getElementById('qm-list').innerHTML = D.qualityMetrics.map(q => LI(q[0], B(q[1]))).join('');
|
||||
renderGantt();
|
||||
document.getElementById('file-list').innerHTML = D.files.map(f =>
|
||||
`<li><span>${f[0]}</span><span class="muted">${f[1]}</span></li>`).join('');
|
||||
document.getElementById('sec-list').innerHTML =
|
||||
D.security.map(s => LI(s[0], B(s[1]))).join('') +
|
||||
`<li><span>下载审计日志</span><span><span class="muted">近 7 天 14 次</span> <button class="btn sm ghost" onclick="auditLog()">查看</button></span></li>`;
|
||||
}
|
||||
|
||||
const DAYS = 20, TODAY = 11;
|
||||
function renderGantt() {
|
||||
const D = DB.orderDetail;
|
||||
const ticks = [1, 5, 10, 15, 20].map(d =>
|
||||
`<span style="left:${(d - 0.5) / DAYS * 100}%">09-${String(d).padStart(2, '0')}</span>`).join('');
|
||||
document.getElementById('gantt').innerHTML =
|
||||
`<div class="gantt-row"><span class="gantt-name"></span><div class="gantt-axis">${ticks}</div></div>` +
|
||||
D.tasks.map(t => `
|
||||
<div class="gantt-row">
|
||||
<span class="gantt-name">${t.name}</span>
|
||||
<div class="gantt-track">
|
||||
<div class="gantt-bar ${t.risk ? 'err' : (t.cls || '')}" style="left:${(t.s - 1) / DAYS * 100}%;width:${(t.e - t.s + 1) / DAYS * 100}%">${t.ddl} 止 · ${t.pct}%</div>
|
||||
<div class="gantt-today" style="left:${(TODAY - 0.5) / DAYS * 100}%"></div>
|
||||
</div>
|
||||
</div>`).join('');
|
||||
}
|
||||
|
||||
function qcRules() {
|
||||
openModal({
|
||||
title: '抽检规则配置(REQ-056)',
|
||||
body: `
|
||||
<div class="field-row">
|
||||
<div class="field"><label>抽检比例</label><select><option>10%</option><option selected>30%</option><option>100%(高敏项目默认)</option></select></div>
|
||||
<div class="field"><label>合格阈值</label><select><option>≥95%</option><option selected>≥98%</option><option>≥99%</option></select></div>
|
||||
</div>
|
||||
<div class="field"><label>抽检人</label><select><option>运营商质检组</option><option>交叉质检(其他 L3+ OPC)</option></select></div>
|
||||
<p class="muted">本项目数据等级 L3 敏感,建议全检;规则变更留痕并影响后续批次。</p>`,
|
||||
actions: [
|
||||
{ label: '取消', cls: 'ghost' },
|
||||
{ label: '保存规则', onClick: m => { m.remove(); toast('抽检规则已更新:30% → 全检(L3 高敏默认),新批次生效'); } },
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
function renderSwarm() {
|
||||
const S = DB.orderDetail.swarm || [];
|
||||
document.getElementById('swarm-tbl').innerHTML =
|
||||
`<tr><th>交付单元</th><th>承接 OPC</th><th>等级</th><th>SOP 标准</th><th>状态</th><th>可替换</th></tr>` +
|
||||
S.map(s => `<tr>
|
||||
<td>${s.unit}</td>
|
||||
<td>${s.opc}</td>
|
||||
<td><span class="badge pri">${s.level}</span></td>
|
||||
<td><code>${s.sop}</code></td>
|
||||
<td>${B(s.status)}</td>
|
||||
<td>${s.replaceable ? '<span class="badge ok">可替</span>' : '<span class="badge gray">—</span>'}</td>
|
||||
</tr>`).join('');
|
||||
}
|
||||
|
||||
function renderTasks() {
|
||||
const D = DB.orderDetail;
|
||||
document.getElementById('task-tbl').innerHTML =
|
||||
`<tr><th>任务</th><th>负责人</th><th>前置依赖</th><th>截止</th><th>状态</th><th>进度</th></tr>` +
|
||||
D.tasks.map((t, i) => `<tr${t.risk ? ' id="task-risk"' : ''}><td>${t.name}</td><td>${t.owner}</td><td>${t.dep}</td><td>${t.ddl}</td><td>${B(t.status)}</td><td>${BAR(t.pct, t.cls)}</td></tr>`).join('');
|
||||
renderRiskNotice();
|
||||
}
|
||||
|
||||
function renderRiskNotice() {
|
||||
const t = DB.orderDetail.tasks.find(x => x.risk);
|
||||
const n = document.getElementById('risk-notice');
|
||||
if (!t) { n.style.display = 'none'; return; }
|
||||
n.style.display = '';
|
||||
n.innerHTML = t.taken
|
||||
? `替补已接管:OPC_00061 刘工 接手商品场景图任务,新交期 09-21,已同步客户与项目负责人。`
|
||||
: `REQ-037 预警:${t.name}任务预计逾期 2 天,已通知项目负责人与运营商,替补 OPC_00061 刘工 可接管。
|
||||
<button class="btn sm" style="margin-left:8px" onclick="takeover()">启用替补接管</button>
|
||||
<button class="btn sm ghost" onclick="reassign()">转派</button>`;
|
||||
}
|
||||
|
||||
function renderQc() {
|
||||
const D = DB.orderDetail;
|
||||
document.getElementById('qc-tbl').innerHTML =
|
||||
`<tr><th>交付批次</th><th>① OPC 自检</th><th>② 项目复检</th><th>③ 交付终检</th><th>操作</th></tr>` +
|
||||
D.qc.map((q, i) => `<tr${q.id ? ` id="${q.id}"` : ''}><td>${q.batch}</td><td>${B(q.s1)}</td><td>${B(q.s2)}</td><td>${q.s3 ? B(q.s3) : '—'}</td><td>${qcAction(q, i)}</td></tr>`).join('');
|
||||
}
|
||||
function qcAction(q, i) {
|
||||
if (q.action === 'rework') return `<button class="btn sm ghost" onclick="reworkDetail()">归因</button>`;
|
||||
if (q.action === 'review') return `<button class="btn sm" onclick="reviewPass(${i})">复检通过</button> <button class="btn sm ghost" onclick="reviewFail(${i})">退回</button>`;
|
||||
if (q.action === 'final') return `<button class="btn sm" onclick="finalPass(${i})">终检通过</button>`;
|
||||
return '—';
|
||||
}
|
||||
|
||||
function submitDeliver() {
|
||||
openModal({
|
||||
title: '提交交付物 · SOP 提交清单校验(REQ-039)',
|
||||
body: `
|
||||
<div class="field"><label>所属任务</label><select><option>首页+详情页改版 ×8</option><option>活动 Banner ×12</option></select></div>
|
||||
<div class="checks">
|
||||
<label><input type="checkbox" id="d1" checked> 交付文件齐全(源文件+导出图)</label>
|
||||
<label><input type="checkbox" id="d2" checked> 命名规范符合 SOP_电商视觉_V3.2</label>
|
||||
<label><input type="checkbox" id="d3"> 素材来源记录已填写(版权审查必备)</label>
|
||||
<label><input type="checkbox" id="d4" checked> 自检问题清单已附</label>
|
||||
</div>
|
||||
<div class="field"><label>文件</label><input type="file" multiple></div>`,
|
||||
actions: [
|
||||
{ label: '取消', cls: 'ghost' },
|
||||
{ label: '提交质检', onClick: m => {
|
||||
if (!document.getElementById('d3').checked) { toast('清单不完整:素材来源记录为强制项,无法进入质检', 'err'); return; }
|
||||
m.remove();
|
||||
DB.orderDetail.qc.push({ batch: 'DLV_2026091101 · 详情页批次 B(新提交)', s1: ['自检通过', 'ok'], s2: ['待复检', 'info'], s3: null, action: null });
|
||||
renderQc();
|
||||
toast('清单校验通过,交付物进入①自检→②复检队列');
|
||||
} },
|
||||
],
|
||||
});
|
||||
}
|
||||
function takeover() {
|
||||
confirmDlg('启用替补接管', '将「商品场景图 ×40」移交替补 OPC_00061 刘工?已交付部分与文件版本一并移交,逾期责任按 REQ-057 归因。', '确认接管', () => {
|
||||
const t = DB.orderDetail.tasks.find(x => x.risk);
|
||||
t.owner = 'OPC_00061 刘工(替补)'; t.status = ['已接管 · 排产中', 'info']; t.taken = true;
|
||||
renderTasks();
|
||||
toast('替补接管完成,任务与权限已转移');
|
||||
});
|
||||
}
|
||||
function reassign() {
|
||||
openModal({
|
||||
title: '任务转派',
|
||||
body: `<div class="field"><label>转派给</label><select><option>OPC_00061 刘工(替补 · L2 · 匹配 88%)</option><option>OPC_00045 陈视觉(L2 · 当前负载 80%)</option></select></div>
|
||||
<div class="field"><label>转派原因</label><textarea placeholder="将记录于任务流转留痕"></textarea></div>`,
|
||||
actions: [
|
||||
{ label: '取消', cls: 'ghost' },
|
||||
{ label: '确认转派', onClick: m => { m.remove(); toast('转派申请已提交项目负责人审批'); } },
|
||||
],
|
||||
});
|
||||
}
|
||||
function reviewPass(i) {
|
||||
const q = DB.orderDetail.qc[i];
|
||||
q.s2 = ['通过', 'ok']; q.s3 = ['待终检', 'info']; q.action = 'final';
|
||||
renderQc();
|
||||
toast('②复检通过,进入③交付终检');
|
||||
}
|
||||
function reviewFail(i) {
|
||||
const q = DB.orderDetail.qc[i];
|
||||
q.s2 = ['返工', 'err']; q.action = 'rework';
|
||||
renderQc();
|
||||
toast('已退回返工,请填写责任归因(REQ-057)', 'warn');
|
||||
}
|
||||
function finalPass(i) {
|
||||
const q = DB.orderDetail.qc[i];
|
||||
q.s3 = ['通过', 'ok']; q.action = null;
|
||||
renderQc();
|
||||
toast('③终检通过,批次可提交客户验收');
|
||||
}
|
||||
function reworkDetail() {
|
||||
openModal({
|
||||
title: '返工归因 · 详情页批次 A(REQ-057)',
|
||||
body: `<div class="checks">
|
||||
<label><input type="radio" name="rw" checked> 需求变更(客户新增合规文案)</label>
|
||||
<label><input type="radio" name="rw"> OPC 执行问题</label>
|
||||
<label><input type="radio" name="rw"> 质检遗漏</label>
|
||||
<label><input type="radio" name="rw"> 客户其他原因</label>
|
||||
</div><p class="muted">归因结果用于费用与信用结算:本次不计入 OPC 返工率。</p>`,
|
||||
actions: [{ label: '确认归因', onClick: m => { m.remove(); toast('归因已记录:需求变更 · 客户承担返工费用'); } }],
|
||||
});
|
||||
}
|
||||
function auditLog() {
|
||||
openModal({
|
||||
title: '下载审计日志(近 7 天)',
|
||||
body: `<table>
|
||||
<tr><th>时间</th><th>操作人</th><th>动作</th></tr>
|
||||
<tr><td>09-11 14:02</td><td>OPC_00017 张设计</td><td>下载 首页改版_v2.psd</td></tr>
|
||||
<tr><td>09-10 09:31</td><td>项目负责人</td><td>导出 交付清单</td></tr>
|
||||
<tr><td>09-09 16:47</td><td>运营商质检员</td><td>下载 DLV_2026090901 源文件</td></tr>
|
||||
</table>`,
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user