Files
OPC/Demo/service.html
freedakandDevin 13cad398dc feat: OPC 平台功能增强 v1.4 · 8 项需求变更实施
CHG-006 抢单订单池:OPC 工作台加抢单池(REQ-128/129)
CHG-004 政策落地:OPC 加算力券申领/核销+贷款+租金,运营商加政策跟踪(REQ-124/125/126)
CHG-001 组队模块:新增 team.html 组队协同页(REQ-119/120/121)
CHG-003 活动管理:运营工作台加活动创建/发布/报名管理(REQ-122/123)
CHG-005 OPC 财务分析:OPC 工作台加财务看板(REQ-127)
CHG-008 平台撮合归集:运营工作台加录入入口(REQ-130)
CHG-002 入口跳转:确认已正确(OPC→opc.html)
CHG-007 服务中心定位:明确为运营商服务资源管理

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

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-09-14 08:47:29 +08:00

204 lines
10 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!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="service">
<header class="topnav" id="topnav"></header>
<div class="container">
<div class="page-title">企业服务中心</div>
<div class="page-sub" id="svc-sub"></div>
<!-- REQ-061/062 外包服务目录 -->
<div class="section">
<h2>外包服务目录 <span class="req">REQ-061/062 · 标准化服务包</span></h2>
<div class="grid grid-3" id="svc-catalog"></div>
</div>
<!-- REQ-063 服务工单 -->
<div class="section">
<h2>我的服务工单 <span class="req">REQ-063</span></h2>
<div class="card">
<table id="svc-tbl"></table>
<p class="muted" style="margin-top:8px">工单状态:受理 → 办理中 → 待补充材料 → 已完成 / 异常(REQ-063);凭证电子化归档(REQ-069);外包服务质量计入经营档案(REQ-064);服务费可与订单收入联动抵扣/代扣(REQ-068)</p>
</div>
</div>
<!-- REQ-065/066 机构超市 -->
<div class="section">
<h2>服务机构超市 <span class="req">REQ-065/066 · 资质审核入驻</span></h2>
<div class="card">
<table id="org-tbl"></table>
<p class="muted" style="margin-top:8px">机构经资质审核后方可上架,平台实施评价与退出管理,不做未经审查的广告展示(REQ-066)。
<button class="btn sm" style="float:right" onclick="newSvc()">+ 上架新服务(机构角色)</button></p>
</div>
</div>
<!-- 服务机构工作台(service/operator 角色) -->
<div class="section" id="vendor-section" style="display:none">
<h2>机构工单处理 <span class="req">REQ-063/064 · 服务机构侧</span></h2>
<div class="grid grid-4" id="vendor-stats" style="margin-bottom:16px"></div>
<div class="card"><table id="vendor-tbl"></table></div>
</div>
<!-- REQ-067 数据安全提示 -->
<div class="section">
<div class="notice">REQ-067:涉及财务、人事等敏感经营数据的外包服务,须签署数据处理协议并按 L3/L4 级数据管控。</div>
</div>
</div>
<div class="footer">OPC 公共服务平台 Demo · 企业服务中心</div>
<script src="assets/app.js"></script>
<script src="assets/store.js"></script>
<script>
let svcSeq = 13;
function renderPage(DB) {
const S = DB.service;
const role = currentRole();
document.getElementById('svc-sub').textContent =
role === 'service' ? '服务机构视图 · 资质上架、工单办理、评价与退出管理'
: role === 'operator' ? '运营商服务资源管理 · 自营服务包 + 入驻服务商管理 + 工单分发(REQ-061~070)'
: role === 'opc' ? '自营外包服务 + 第三方服务机构超市 · 为 OPC 提供经营支撑'
: '自营外包服务 + 第三方服务机构超市 · 标准化服务包';
document.getElementById('svc-catalog').innerHTML = S.catalog.map(c => `
<div class="card"><h3>${c.name} ${B(c.badge)}</h3><p class="muted">${c.desc}</p>
${c.action === 'insPlan'
? `<button class="btn sm" onclick="insPlan()">查看方案</button>`
: `<button class="btn sm" onclick="buy('${c.svcName || c.name}','${c.vendor}','${c.price}')">购买服务包</button>`}
</div>`).join('');
renderWorkorders();
renderVendor(role);
document.getElementById('org-tbl').innerHTML =
`<tr><th>机构</th><th>类目</th><th>资质状态</th><th>服务评价</th><th>在架服务</th><th>操作</th></tr>` +
S.orgs.map(o => `<tr><td>${o.name}</td><td>${o.cat}</td><td>${B(o.qual)}</td><td>${o.rating}</td><td>${o.svcs}</td><td>${orgAction(o)}</td></tr>`).join('');
}
function orgAction(o) {
if (o.action === 'detail') return `<button class="btn sm ghost" onclick="orgDetail('${o.name}','${o.license}','${o.score}','${o.complaint}')">资质详情</button>`;
if (o.action === 'coupon') return `<button class="btn sm ghost" onclick="toast('支持算力券/模型券核销,接口对接已完成(REQ-076)')">券核销</button>`;
if (o.action === 'urge') return `<button class="btn sm ghost" onclick="toast('已向机构发送年审提醒,逾期将自动下架服务','warn')">催审</button>`;
return '—';
}
function renderVendor(role) {
const show = ['service', 'operator'].includes(role);
document.getElementById('vendor-section').style.display = show ? '' : 'none';
if (!show) return;
const V = DB.service.myVendor;
document.getElementById('vendor-stats').innerHTML = V.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('vendor-tbl').innerHTML =
`<tr><th>工单号</th><th>事项</th><th>客户/需求</th><th>状态</th><th>操作</th></tr>` +
V.tickets.map((t, i) => `<tr><td>${t.code}</td><td>${t.item}</td><td>${t.need}</td><td>${B(t.status)}</td><td>${vendorAction(t, i)}</td></tr>`).join('');
}
function vendorAction(t, i) {
if (t.action === 'accept') return `<button class="btn sm" onclick="ticketAct(${i},'accept')">受理</button> <button class="btn sm ghost" onclick="ticketAct(${i},'reject')">转派</button>`;
if (t.action === 'finish') return `<button class="btn sm" onclick="ticketAct(${i},'finish')">办结</button>`;
if (t.action === 'urge') return `<button class="btn sm ghost" onclick="toast('已向客户发送补料提醒')">催补料</button>`;
return '—';
}
function ticketAct(i, act) {
const t = DB.service.myVendor.tickets[i];
if (act === 'reject') { confirmDlg('工单转派', `将 ${t.code} 转派给其他机构/自营?将通知客户并留痕。`, '确认转派', () => { t.status = ['已转派', 'gray']; t.action = null; renderVendor(currentRole()); toast('工单已转派'); }); return; }
const label = act === 'accept' ? '受理' : '办结';
confirmDlg(`工单${label}`, `确认${label} ${t.code}(${t.item})?`, '确认', () => {
t.status = act === 'accept' ? ['办理中', 'warn'] : ['已完成', 'ok'];
t.action = act === 'accept' ? 'finish' : null;
renderVendor(currentRole());
toast(`工单已${label},服务记录计入经营档案(REQ-064)`);
});
}
function renderWorkorders() {
document.getElementById('svc-tbl').innerHTML =
`<tr><th>工单号</th><th>服务</th><th>服务商</th><th>状态</th><th>凭证归档</th><th>评价</th></tr>` +
DB.service.workorders.map(w => `<tr><td>${w.id}</td><td>${w.svc}</td><td>${w.vendor}</td><td>${B(w.status)}</td><td>${
w.doc === 'policy' ? `<button class="btn sm ghost" onclick="toast('保单 INS_2026080101.pdf 已下载(演示)')">保单已归档</button>` : w.doc
}</td><td>${
w.rate === 'supply' ? `<button class="btn sm" onclick="supply(this)">补材料</button>` : w.rate
}</td></tr>`).join('');
}
function buy(name, provider, price) {
openModal({
title: '购买服务包 · ' + name,
body: `<table>
<tr><th>服务商</th><td>${provider}</td></tr>
<tr><th>价格</th><td>${price}</td></tr>
<tr><th>SLA</th><td>申报/办理及时率 100%;差错率 ≤0.5%;投诉率 ≤1%</td></tr>
<tr><th>交付物</th><td>服务结果 + 电子化凭证归档(REQ-069)</td></tr>
</table>
<div class="checks"><label><input type="checkbox" id="dpa"> 同意签署数据处理协议(涉及敏感经营数据时必选 REQ-067)</label></div>`,
actions: [
{ label: '取消', cls: 'ghost' },
{ label: '确认下单', onClick: m => {
m.remove();
const id = 'SVC_202609' + String(svcSeq++).padStart(2, '0') + '01';
DB.service.workorders.push({ id, svc: name, vendor: provider, status: ['受理', 'info'], doc: '—', rate: '—' });
renderWorkorders();
toast(`服务工单已创建:${id},状态可在工单列表跟踪`);
} },
],
});
}
function insPlan() {
const rows = DB.service.insPlans.map(p =>
`<tr><td>${p.plan}</td><td>${p.for}</td><td>${p.cover}</td><td>${p.price}</td></tr>`).join('');
openModal({
title: '商保方案推荐 · 按 OPC 等级差异化(REQ-070)',
body: `<table><tr><th>方案</th><th>适用</th><th>保障</th><th>保费</th></tr>${rows}</table>`,
actions: [
{ label: '关闭', cls: 'ghost' },
{ label: '投保进阶版', onClick: m => { m.remove(); toast('投保申请已提交,承保进度可在工单跟踪'); } },
],
});
}
function orgDetail(name, license, score, complaint) {
openModal({
title: '机构资质 · ' + name,
body: `<table>
<tr><th>资质证照</th><td>${license}(已核验)</td></tr>
<tr><th>服务评价</th><td>${score} / 5.0 · 投诉率 ${complaint}</td></tr>
<tr><th>入驻审核</th><td>2026-03 通过 · 年审周期 12 个月</td></tr>
<tr><th>退出条款</th><td>投诉率连续超标或资质失效即下架(REQ-066)</td></tr>
</table>`,
});
}
function supply(btn) {
openModal({
title: '补充材料 · SVC_2026071201',
body: `<p class="muted">代理机构要求补充:商标图样高清版(JPG ≥2000px)</p>
<div class="field"><label>上传材料</label><input type="file"></div>`,
actions: [
{ label: '取消', cls: 'ghost' },
{ label: '提交', onClick: m => { m.remove(); btn.outerHTML = '<span class="badge warn">办理中</span>'; toast('材料已提交,工单恢复办理中'); } },
],
});
}
function newSvc() {
openModal({
title: '上架新服务(服务机构角色)',
body: `
<div class="field"><label>服务名称</label><input placeholder="如:高新认定辅导"></div>
<div class="field-row">
<div class="field"><label>类目</label><select><option>财税</option><option>法务</option><option>知识产权</option><option>人力</option><option>融资</option></select></div>
<div class="field"><label>价格</label><input placeholder="¥ / 计价方式"></div>
</div>
<div class="field"><label>SLA 与交付物</label><textarea placeholder="服务时效、交付标准、投诉通道"></textarea></div>`,
actions: [
{ label: '取消', cls: 'ghost' },
{ label: '提交审核', onClick: m => { m.remove(); toast('服务已提交,运营商资质+内容审核通过后上架'); } },
],
});
}
</script>
</body>
</html>