638 lines
38 KiB
HTML
638 lines
38 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>CareerNexus 职联 · 岗位与能力图谱平台</title>
|
||
<link rel="stylesheet" href="/static/style.css?v=20260819">
|
||
</head>
|
||
<body>
|
||
<!-- ============ 顶部栏 56px ============ -->
|
||
<header class="topbar">
|
||
<div class="brand">
|
||
<span class="brand-logo">
|
||
<svg viewBox="0 0 24 24" fill="none"><circle cx="6" cy="6" r="3"/><circle cx="18" cy="7" r="3"/><circle cx="12" cy="18" r="3"/><path d="M8.5 7.5l7-1M7.5 8.8l3 6.4M16.5 9.6l-3 5.6"/></svg>
|
||
</span>
|
||
<span class="brand-name">CareerNexus <b>职联</b></span>
|
||
</div>
|
||
<div class="topbar-left-actions">
|
||
<button class="btn btn-primary btn-sm" id="btn-demo-tour">
|
||
<svg viewBox="0 0 24 24"><polygon points="6 3 20 12 6 21 6 3"/></svg>
|
||
开始演示</button>
|
||
<span class="demo-badge" id="demo-badge" title="运行状态(点击查看设置)"><i class="dot"></i><span id="demo-badge-text">演示模式</span></span>
|
||
</div>
|
||
<div class="page-title" id="page-title">数据驾驶舱</div>
|
||
<div class="topbar-right">
|
||
<div class="global-search">
|
||
<svg viewBox="0 0 24 24"><circle cx="11" cy="11" r="7"/><path d="M21 21l-4.35-4.35"/></svg>
|
||
<input id="global-search-input" type="text" placeholder="搜索岗位 / 技能 / 场景…" autocomplete="off">
|
||
<div id="global-search-drop" class="search-drop hidden"></div>
|
||
</div>
|
||
<span class="badge badge-version" id="data-version" title="图谱数据版本">数据版本 —</span>
|
||
<button class="icon-btn" id="btn-config" title="系统设置" aria-label="系统设置">
|
||
<svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 00.33 1.82l.06.06a2 2 0 11-2.83 2.83l-.06-.06a1.65 1.65 0 00-1.82-.33 1.65 1.65 0 00-1 1.51V21a2 2 0 11-4 0v-.09a1.65 1.65 0 00-1-1.51 1.65 1.65 0 00-1.82.33l-.06.06a2 2 0 11-2.83-2.83l.06-.06a1.65 1.65 0 00.33-1.82 1.65 1.65 0 00-1.51-1H3a2 2 0 110-4h.09a1.65 1.65 0 001.51-1 1.65 1.65 0 00-.33-1.82l-.06-.06a2 2 0 112.83-2.83l.06.06a1.65 1.65 0 001.82.33h.01a1.65 1.65 0 001-1.51V3a2 2 0 114 0v.09a1.65 1.65 0 001 1.51h.01a1.65 1.65 0 001.82-.33l.06-.06a2 2 0 112.83 2.83l-.06.06a1.65 1.65 0 00-.33 1.82v.01a1.65 1.65 0 001.51 1H21a2 2 0 110 4h-.09a1.65 1.65 0 00-1.51 1z"/></svg>
|
||
</button>
|
||
<span class="avatar" title="演示账号">演</span>
|
||
</div>
|
||
</header>
|
||
|
||
<!-- ============ 横向导航(顶栏下方) ============ -->
|
||
<nav class="topnav" id="topnav">
|
||
<button class="nav-item active" data-view="dashboard">
|
||
<svg viewBox="0 0 24 24"><rect x="3" y="3" width="7" height="9" rx="1.5"/><rect x="14" y="3" width="7" height="5" rx="1.5"/><rect x="14" y="12" width="7" height="9" rx="1.5"/><rect x="3" y="16" width="7" height="5" rx="1.5"/></svg>
|
||
<span>数据驾驶舱</span>
|
||
</button>
|
||
<button class="nav-item" data-view="graph">
|
||
<svg viewBox="0 0 24 24"><circle cx="5" cy="6" r="2.5"/><circle cx="19" cy="6" r="2.5"/><circle cx="12" cy="18" r="2.5"/><path d="M7.3 7.2l9.4-1M6.2 8.3l4.2 7.4M17.8 8.3l-4.2 7.4"/></svg>
|
||
<span>全景图谱</span>
|
||
</button>
|
||
<button class="nav-item" data-view="evolution">
|
||
<svg viewBox="0 0 24 24"><path d="M3 17l5.5-5.5 3.5 3.5L20 7"/><path d="M15 7h5v5"/></svg>
|
||
<span>岗位演化</span>
|
||
</button>
|
||
<button class="nav-item" data-view="match">
|
||
<svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="8"/><circle cx="12" cy="12" r="4"/><circle cx="12" cy="12" r="1" fill="currentColor"/></svg>
|
||
<span>人岗匹配</span>
|
||
</button>
|
||
<button class="nav-item" data-view="path">
|
||
<svg viewBox="0 0 24 24"><circle cx="6" cy="19" r="2.5"/><circle cx="18" cy="5" r="2.5"/><path d="M8 17.5C12 14 8 10 12 7.5c1.5-1 3-1.2 4-1.3"/></svg>
|
||
<span>学习路径</span>
|
||
</button>
|
||
</nav>
|
||
|
||
<!-- 离线回退模式横幅 -->
|
||
<div class="offline-banner hidden" id="offline-banner">
|
||
<svg viewBox="0 0 24 24"><path d="M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z"/><path d="M12 9v4M12 17h.01"/></svg>
|
||
<span>当前为<b>离线回退模式</b>:未配置 LLM 密钥,抽取与生成使用离线确定性方案。配置星火大模型密钥可启用联网能力。</span>
|
||
<button class="banner-btn" id="banner-config">去配置</button>
|
||
<button class="banner-close" id="banner-close" title="关闭">×</button>
|
||
</div>
|
||
<!-- 语义向量模型横幅 -->
|
||
<div class="offline-banner hidden" id="embed-banner">
|
||
<svg viewBox="0 0 24 24"><path d="M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z"/><path d="M12 9v4M12 17h.01"/></svg>
|
||
<span>语义向量模型<b>未就绪</b>:当前使用词表归一化匹配。下载 BGE-M3 权重并在设置中配置,可启用语义相似匹配增强。</span>
|
||
<button class="banner-btn" id="embed-banner-config">去配置</button>
|
||
<button class="banner-close" id="embed-banner-close" title="关闭">×</button>
|
||
</div>
|
||
|
||
<div class="shell">
|
||
<!-- ============ 主内容区 ============ -->
|
||
<main class="content">
|
||
|
||
<!-- ======== 人才能力变化指挥台(数据驾驶舱) ======== -->
|
||
<section id="view-dashboard" class="view active">
|
||
<div class="card cmd-hero">
|
||
<div class="cmd-hero-main">
|
||
<h2 id="cmd-title">人才能力变化概览</h2>
|
||
<div class="cmd-sub" id="cmd-sub">正在汇总本期变化…</div>
|
||
<div class="cmd-scale text-weak" id="cmd-scale"></div>
|
||
</div>
|
||
<div class="cmd-hero-actions">
|
||
<button class="btn btn-primary btn-sm" id="btn-cmd-report">查看本期报告</button>
|
||
<button class="btn btn-secondary btn-sm" id="btn-open-review-desk">候选审核台</button>
|
||
<button class="btn btn-secondary btn-sm" id="btn-import-jd">导入 JD 数据</button>
|
||
</div>
|
||
</div>
|
||
<div class="metric-grid cmd-kpis" id="metric-cards"></div>
|
||
<div class="grid-2">
|
||
<div class="card">
|
||
<div class="card-head">
|
||
<h3>近 8 季度变化事件流(全岗位)</h3>
|
||
<span class="text-weak text-aux">点击柱段进入该季度演化详情</span>
|
||
</div>
|
||
<div class="card-body">
|
||
<canvas id="trend-canvas" height="220"></canvas>
|
||
<div class="stack-legend" id="cmd-stack-legend"></div>
|
||
</div>
|
||
</div>
|
||
<div class="card">
|
||
<div class="card-head">
|
||
<h3>数据可信度</h3>
|
||
<span class="text-weak text-aux">多源交叉验证口径</span>
|
||
</div>
|
||
<div class="card-body" id="trust-card"><div class="empty small">统计中…</div></div>
|
||
</div>
|
||
</div>
|
||
<div class="grid-2">
|
||
<div class="card">
|
||
<div class="card-head"><h3>变化播报</h3><span class="text-weak text-aux">点击跳转演化详情</span></div>
|
||
<div class="card-body feed" id="activity-feed"></div>
|
||
</div>
|
||
<div class="card">
|
||
<div class="card-head">
|
||
<h3>待办行动</h3>
|
||
<span class="cmd-head-right">
|
||
<span class="badge badge-warning" id="pending-count">0 待办</span>
|
||
<button class="btn btn-text btn-sm" id="btn-open-review-desk-2">进入审核台</button>
|
||
</span>
|
||
</div>
|
||
<div class="card-body" id="pending-list"></div>
|
||
</div>
|
||
</div>
|
||
<div class="card cmd-ledger">
|
||
<div class="card-head">
|
||
<h3>任务与审核台账</h3>
|
||
<button class="btn btn-text btn-sm" id="btn-audit-toggle">展开台账</button>
|
||
</div>
|
||
<div class="card-body hidden" id="task-table-wrap">
|
||
<table class="table" id="task-table">
|
||
<thead><tr><th>类型</th><th>对象</th><th>操作人</th><th>时间</th><th>结果</th></tr></thead>
|
||
<tbody></tbody>
|
||
</table>
|
||
<div class="empty small hidden" id="task-empty">暂无任务记录</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- ======== 全景图谱工作台 ======== -->
|
||
<section id="view-graph" class="view">
|
||
<div class="graph-header card">
|
||
<div class="graph-title">
|
||
<h2>岗位能力证据地图</h2>
|
||
<span class="tag tag-blue">演示模式</span>
|
||
<span class="tag tag-cyan">技能点级</span>
|
||
<span class="tag tag-green">审核已开启</span>
|
||
</div>
|
||
<div class="seg graph-view-tabs" id="graph-view-tabs">
|
||
<button data-gview="overview" class="active">全景总览</button>
|
||
<button data-gview="tech">技术栈</button>
|
||
<button data-gview="level">职级演进</button>
|
||
<button data-gview="timeline">动态时序</button>
|
||
</div>
|
||
<div class="graph-actions">
|
||
<button class="btn btn-secondary" id="btn-goto-evo">
|
||
<svg viewBox="0 0 24 24"><path d="M3 17l5.5-5.5 3.5 3.5L20 7"/><path d="M15 7h5v5"/></svg>
|
||
查看演化</button>
|
||
<button class="btn btn-secondary" id="btn-goto-evidence">
|
||
<svg viewBox="0 0 24 24"><path d="M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8z"/><path d="M14 2v6h6"/></svg>
|
||
查看证据</button>
|
||
<button class="btn btn-primary" id="btn-goto-match">
|
||
<svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="8"/><circle cx="12" cy="12" r="4"/><circle cx="12" cy="12" r="1" fill="currentColor"/></svg>
|
||
开始匹配</button>
|
||
<div class="more-wrap">
|
||
<button class="btn btn-secondary" id="btn-more-menu">更多 ▾</button>
|
||
<div class="more-menu hidden" id="more-menu">
|
||
<button class="more-item" id="btn-save-view">
|
||
<svg viewBox="0 0 24 24"><path d="M19 21H5a2 2 0 01-2-2V5a2 2 0 012-2h11l5 5v11a2 2 0 01-2 2z"/><path d="M17 21v-8H7v8M7 3v5h8"/></svg>
|
||
保存视图</button>
|
||
<button class="more-item" id="btn-share-graph">
|
||
<svg viewBox="0 0 24 24"><circle cx="18" cy="5" r="3"/><circle cx="6" cy="12" r="3"/><circle cx="18" cy="19" r="3"/><path d="M8.6 13.5l6.8 4M15.4 6.5l-6.8 4"/></svg>
|
||
分享链接</button>
|
||
<button class="more-item" id="btn-export-graph">
|
||
<svg viewBox="0 0 24 24"><path d="M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4M7 10l5 5 5-5M12 15V3"/></svg>
|
||
导出图谱 PNG</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="graph-body">
|
||
<div class="graph-canvas-wrap card" id="graph-canvas-wrap">
|
||
<canvas id="graph-canvas"></canvas>
|
||
|
||
<!-- 岗位子图状态徽标 -->
|
||
<div class="solo-badge hidden" id="solo-badge">
|
||
<span id="solo-badge-text">岗位子图</span>
|
||
<button id="solo-exit" title="退出岗位子图">×</button>
|
||
</div>
|
||
|
||
<!-- 动态时序视图:季度时间轴(仅该视图显示) -->
|
||
<div class="graph-timeline hidden" id="graph-timeline">
|
||
<button class="btn btn-secondary btn-sm" id="gt-play">播放</button>
|
||
<input type="range" id="gt-slider" min="0" max="0" step="1" value="0">
|
||
<span class="gt-window" id="gt-label">—</span>
|
||
</div>
|
||
|
||
<!-- 左上浮动工具条 -->
|
||
<div class="graph-toolbar">
|
||
<button class="tool-btn" id="tool-zoom-in" title="放大"><svg viewBox="0 0 24 24"><circle cx="11" cy="11" r="7"/><path d="M21 21l-4.35-4.35M11 8v6M8 11h6"/></svg></button>
|
||
<button class="tool-btn" id="tool-zoom-out" title="缩小"><svg viewBox="0 0 24 24"><circle cx="11" cy="11" r="7"/><path d="M21 21l-4.35-4.35M8 11h6"/></svg></button>
|
||
<button class="tool-btn" id="tool-fit" title="适应画布"><svg viewBox="0 0 24 24"><path d="M8 3H5a2 2 0 00-2 2v3M16 3h3a2 2 0 012 2v3M8 21H5a2 2 0 01-2-2v-3M16 21h3a2 2 0 002-2v-3"/></svg></button>
|
||
<span class="tool-sep"></span>
|
||
<button class="tool-btn" id="tool-filter" title="筛选"><svg viewBox="0 0 24 24"><path d="M22 3H2l8 9.46V19l4 2v-8.54L22 3z"/></svg></button>
|
||
<button class="tool-btn" id="tool-labels" title="关系标签开关"><svg viewBox="0 0 24 24"><path d="M20.59 13.41L11 3H4v7l9.59 9.59a2 2 0 002.82 0l4.18-4.18a2 2 0 000-2.82z"/><circle cx="7.5" cy="7.5" r="1" fill="currentColor"/></svg></button>
|
||
<button class="tool-btn" id="tool-relayout" title="一键整理布局"><svg viewBox="0 0 24 24"><path d="M12 3v3M12 18v3M3 12h3M18 12h3M5.6 5.6l2.2 2.2M16.2 16.2l2.2 2.2M5.6 18.4l2.2-2.2M16.2 7.8l2.2-2.2"/></svg></button>
|
||
</div>
|
||
|
||
<!-- 筛选面板 -->
|
||
<div class="graph-filter-panel hidden" id="graph-filter-panel">
|
||
<div class="fp-head">图谱筛选 <button class="link-btn" id="fp-reset">重置</button></div>
|
||
<div class="fp-block">
|
||
<div class="fp-label">节点类型</div>
|
||
<label class="check"><input type="checkbox" data-ftype="Job" checked><i class="lg-dot job"></i>岗位</label>
|
||
<label class="check"><input type="checkbox" data-ftype="Skill" checked><i class="lg-dot skill"></i>技能</label>
|
||
<label class="check"><input type="checkbox" data-ftype="Industry"><i class="lg-dot industry"></i>行业</label>
|
||
<label class="check"><input type="checkbox" data-ftype="Scenario"><i class="lg-dot scenario"></i>场景</label>
|
||
</div>
|
||
<div class="fp-block">
|
||
<div class="fp-label">连线类型</div>
|
||
<label class="check"><input type="checkbox" data-etype="required" checked><i class="lg-line solid"></i>必备技能(116)</label>
|
||
<label class="check"><input type="checkbox" data-etype="preferred" checked><i class="lg-line dashed"></i>加分技能(78)</label>
|
||
<label class="check"><input type="checkbox" data-etype="applies" checked><i class="lg-line purple"></i>应用场景(45)</label>
|
||
<label class="check"><input type="checkbox" data-etype="belongs" checked><i class="lg-line cyan"></i>所属行业(22)</label>
|
||
</div>
|
||
<div class="fp-block">
|
||
<div class="fp-label">岗位类别(技术栈)</div>
|
||
<select id="fp-category"><option value="">全部类别</option></select>
|
||
</div>
|
||
<div class="fp-block">
|
||
<div class="fp-label">岗位级别</div>
|
||
<select id="fp-level">
|
||
<option value="">全部级别</option>
|
||
<option value="初级">初级(≤2 年)</option>
|
||
<option value="中级">中级(3-5 年)</option>
|
||
<option value="高级">高级(>5 年)</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 左下:小地图 + 图例 -->
|
||
<div class="graph-minimap">
|
||
<canvas id="minimap-canvas" width="180" height="120"></canvas>
|
||
<div class="graph-legend">
|
||
<span><i class="lg-dot job"></i>岗位</span>
|
||
<span><i class="lg-sq skill"></i>技能</span>
|
||
<span><i class="lg-dot scenario"></i>场景</span>
|
||
<span><i class="lg-dot pending"></i>待审核</span>
|
||
<span><i class="lg-line solid"></i>必备</span>
|
||
<span><i class="lg-line dashed"></i>加分</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 右下:智能建议已移至右侧详情面板「系统发现」 -->
|
||
|
||
<!-- 底部:演化逻辑链 -->
|
||
<div class="graph-chain" id="graph-chain">
|
||
<div class="gc-head">演化逻辑链 <span class="text-weak text-aux" id="gc-job-name">选择岗位节点后展示能力演化路径</span></div>
|
||
<div class="gc-chips" id="gc-chips"><span class="text-weak text-aux">—</span></div>
|
||
</div>
|
||
|
||
<div class="graph-loading" id="graph-loading">
|
||
<div class="skeleton-graph"></div>
|
||
<div class="text-weak">图谱布局计算中…</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 右侧详情面板 320px -->
|
||
<aside class="graph-detail card" id="graph-detail">
|
||
<div class="detail-empty" id="detail-empty">
|
||
<svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="9"/><path d="M12 8v5M12 16h.01"/></svg>
|
||
<p>点击画布中的节点<br>查看详情、证据与操作</p>
|
||
<p class="text-aux text-weak">支持拖拽平移 / 滚轮缩放 / 点击选中</p>
|
||
</div>
|
||
<div class="detail-body hidden" id="detail-body"></div>
|
||
<!-- 系统发现(原画布浮层「智能建议」移入此处,含采纳/忽略) -->
|
||
<details class="sys-findings" id="sys-findings" open>
|
||
<summary>系统发现(智能建议)</summary>
|
||
<div class="gs-list" id="gs-list"></div>
|
||
</details>
|
||
</aside>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- ======== 岗位演化 ======== -->
|
||
<section id="view-evolution" class="view">
|
||
<div class="card">
|
||
<div class="card-head">
|
||
<h3>岗位能力演化分析</h3>
|
||
<div class="evo-controls">
|
||
<select id="evo-job-select" class="select"></select>
|
||
<div class="seg" id="evo-gran">
|
||
<button data-gran="month">月</button>
|
||
<button data-gran="quarter" class="active">季</button>
|
||
<button data-gran="year">年</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="card-body">
|
||
<!-- 二级 Tab:岗位报告(默认) / 全岗位扫描(热力图) -->
|
||
<div class="match-tabs" id="evo-tabs">
|
||
<button class="match-tab active" data-evotab="report">岗位报告</button>
|
||
<button class="match-tab" data-evotab="scan">全岗位扫描</button>
|
||
</div>
|
||
|
||
<div id="evo-tab-scan" class="hidden">
|
||
<!-- 全岗位扫描:近 12 季度各岗位变化量横条排行(比热力图直观) -->
|
||
<div class="evo-chart-title text-aux text-secondary">全岗位扫描 · 近 12 季度变化量排行(点击行进入该岗位报告)</div>
|
||
<div class="evo-chart-desc">怎么看:每行一个岗位,横条长度=近 12 个季度的能力变化总量;绿色段=新增的技能,红色段=退出的技能。条越长说明这个岗位的能力要求变化越剧烈。</div>
|
||
<div class="evo-scan" id="evo-scan"><div class="empty small">加载中…</div></div>
|
||
</div>
|
||
|
||
<div id="evo-tab-report">
|
||
<!-- 统计条 -->
|
||
<div class="evo-stats" id="evo-stats"></div>
|
||
|
||
<!-- 本期结论(最近两个季度的新增/增强/减弱/退出) -->
|
||
<div class="evo-chart-title text-aux text-secondary">本期结论(最近两个季度)</div>
|
||
<div class="evo-chart-desc">是什么:系统根据近两个季度的招聘 JD 自动归纳出的能力变化结论。新增=以前不要求、现在要求;增强=要求变重;减弱=要求变少;退出=不再要求。每条结论都可追溯到原始 JD 证据。</div>
|
||
<div class="evo-summary" id="evo-summary"><div class="empty small">加载中…</div></div>
|
||
|
||
<!-- 能力更替流:旧核心 → 持续能力 → 新核心 -->
|
||
<div class="evo-chart-title text-aux text-secondary">能力更替流(旧核心 → 持续能力 → 新核心)</div>
|
||
<div class="evo-chart-desc">是什么:把岗位技能按演化结果分三列——左边是已退出的旧要求,中间是一直有效的持续能力,右边是新进入的要求。用于回答"这个岗位正在从什么技术栈转向什么技术栈"。</div>
|
||
<div class="evo-replace" id="evo-replace"></div>
|
||
|
||
<!-- 时点对比器 -->
|
||
<div class="evo-compare">
|
||
<div class="evo-compare-head">
|
||
<span class="evo-chart-title">能力画像时点对比</span>
|
||
<div class="evo-dates">
|
||
<input type="date" id="evo-date-a" class="input">
|
||
<span class="text-weak">→</span>
|
||
<input type="date" id="evo-date-b" class="input">
|
||
<button class="btn btn-secondary btn-sm" id="evo-compare-btn">对比</button>
|
||
</div>
|
||
</div>
|
||
<div class="evo-chart-desc">怎么用:选择两个日期,系统回放该岗位在两个时点的完整能力画像并按行求差(Git 风格)——绿色 + 行=右边时点新增;红色 - 行(删除线)=左边时点有、后来退出;灰色行=一直保留(带↑表示从加分升级为必备)。点击任意行查看该技能的证据 JD 原文(技能名在原文中高亮)。</div>
|
||
<div class="evo-diff" id="evo-diff"></div>
|
||
</div>
|
||
|
||
<!-- 变更类型构成(堆叠柱状) -->
|
||
<div class="evo-chart-title text-aux text-secondary">变更类型构成(每季度 新增/增强/减弱/退出)</div>
|
||
<div class="evo-chart-desc">怎么看:每根柱子是一个季度,四种颜色堆叠表示该季度四类变化的数量。柱子变高=该岗位在加速变化;绿色段厚=能力在扩张;橙红段厚=能力在收缩。用于判断岗位所处阶段(扩张期/调整期/稳定期)。</div>
|
||
<div class="evo-heat-wrap"><canvas id="evo-stack-canvas"></canvas></div>
|
||
<div class="stack-legend" id="stack-legend"></div>
|
||
|
||
<!-- 热度走势(限高,默认近 8 个季度,纵轴为活跃技能关系数) -->
|
||
<div class="evo-chart-title text-aux text-secondary evo-heat-head">
|
||
<span>技能热度走势(纵轴:活跃技能关系数)</span>
|
||
<span class="seg seg-sm" id="evo-heat-range">
|
||
<button data-range="8" class="active">近 8 季</button>
|
||
<button data-range="all">全部</button>
|
||
</span>
|
||
</div>
|
||
<div class="evo-chart-desc">是什么:该岗位每个季度实际生效的技能总数(按岗位-技能关系的生效区间统计)。曲线上升=岗位要求在扩充,下降=在精简,平直=稳定。可切换近 8 季 / 全部历史。</div>
|
||
<div class="evo-heat-wrap"><canvas id="evo-heat-canvas"></canvas></div>
|
||
|
||
<!-- 本期变化卡:事件时间轴,每条含变化前后/支撑证据入口 -->
|
||
<div class="evo-chart-title text-aux text-secondary">本期变化卡(变化前 → 变化后 / 支撑 JD 数 / 点击查看证据原文)</div>
|
||
<div class="evo-chart-desc">怎么用:每一次能力变化的明细卡片,含变化说明、前后需求指数、支撑 JD 数量。点击任意卡片可查看支撑该结论的原始 JD 证据(来源平台、企业、发布时间、原文片段)。</div>
|
||
<div class="timeline" id="evo-timeline"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- ======== 人岗匹配(三步向导 + 批量匹配) ======== -->
|
||
<section id="view-match" class="view">
|
||
<div class="card">
|
||
<div class="card-body">
|
||
<div class="match-tabs">
|
||
<button class="match-tab active" data-mtab="single">单人诊断</button>
|
||
<button class="match-tab" data-mtab="batch">批量匹配</button>
|
||
</div>
|
||
<div id="match-single">
|
||
<div class="steps" id="match-steps">
|
||
<div class="step active" data-step="1"><i>1</i><span>简历录入</span></div>
|
||
<div class="step" data-step="2"><i>2</i><span>解析确认</span></div>
|
||
<div class="step" data-step="3"><i>3</i><span>诊断结果</span></div>
|
||
</div>
|
||
|
||
<!-- 第 1 步:60/40 布局(左:简历输入;右:目标岗位信息卡) -->
|
||
<div class="match-pane" id="match-pane-1">
|
||
<div class="match-input-grid">
|
||
<div class="match-input-left">
|
||
<div class="form-row">
|
||
<label class="form-label">目标岗位</label>
|
||
<select id="match-job-select" class="select w-320"></select>
|
||
</div>
|
||
<div class="form-row">
|
||
<label class="form-label">简历文本</label>
|
||
<textarea id="resume-text" class="textarea" rows="10" placeholder="粘贴简历全文(将自动脱敏与技能抽取),或点击下方按钮上传 / 载入示例简历"></textarea>
|
||
</div>
|
||
<div class="form-actions">
|
||
<button class="btn btn-secondary" id="btn-load-sample">载入示例简历</button>
|
||
<label class="btn btn-secondary" for="resume-file">上传简历文件</label>
|
||
<input type="file" id="resume-file" accept=".txt,.md,.docx,.pdf" class="hidden">
|
||
<span class="text-aux text-weak">支持 .txt / .docx / .pdf,≤5MB</span>
|
||
<button class="btn btn-primary" id="btn-parse-resume">开始解析</button>
|
||
</div>
|
||
</div>
|
||
<div class="match-input-right">
|
||
<div class="job-info-card" id="match-job-info">
|
||
<div class="text-weak text-aux">岗位信息加载中…</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 第 2 步 -->
|
||
<div class="match-pane hidden" id="match-pane-2">
|
||
<div class="parse-summary" id="parse-summary"></div>
|
||
<div class="form-row">
|
||
<label class="form-label">识别技能(可增删)</label>
|
||
<div class="chip-editor" id="skill-chip-editor"></div>
|
||
<div class="chip-add">
|
||
<input id="skill-add-input" class="input" placeholder="输入技能后回车添加,支持逗号分隔,如 Kubernetes, Docker">
|
||
<button class="btn btn-secondary btn-sm" id="btn-skill-add">添加</button>
|
||
</div>
|
||
</div>
|
||
<div class="form-row">
|
||
<label class="form-label">工作年限</label>
|
||
<input id="parse-years" type="number" min="0" max="40" step="0.5" class="input w-120">
|
||
</div>
|
||
<div class="form-actions">
|
||
<button class="btn btn-secondary" id="btn-back-1">上一步</button>
|
||
<button class="btn btn-primary" id="btn-run-match">开始诊断</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 第 3 步 -->
|
||
<div class="match-pane hidden" id="match-pane-3">
|
||
<div class="match-step3-grid">
|
||
<!-- 左:简历原文 + 技能高亮 -->
|
||
<div class="resume-viewer">
|
||
<div class="rv-head">
|
||
<span class="rv-title">结构化简历(已脱敏)</span>
|
||
<span class="rv-legend">
|
||
<span class="hl hl-req">必备</span>
|
||
<span class="hl hl-pref">加分</span>
|
||
<span class="hl hl-other">其他技能</span>
|
||
<button class="btn btn-secondary btn-sm" id="btn-export-resume">
|
||
<svg viewBox="0 0 24 24"><path d="M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4M7 10l5 5 5-5M12 15V3"/></svg>
|
||
导出 DOCX</button>
|
||
</span>
|
||
</div>
|
||
<div class="rv-body" id="resume-highlight">
|
||
<div class="empty"><p>解析简历后此处显示规范简历模板</p></div>
|
||
</div>
|
||
</div>
|
||
<!-- 右:诊断结果 -->
|
||
<div class="match-step3-right">
|
||
<div class="match-result-grid">
|
||
<div class="mrg-left">
|
||
<div class="gauge-wrap"><canvas id="gauge-canvas" width="220" height="150"></canvas>
|
||
<div class="gauge-text"><b id="gauge-score">0</b><span>综合匹配分</span></div>
|
||
</div>
|
||
<div class="match-verdict" id="match-verdict"></div>
|
||
<div class="match-advice" id="match-advice"></div>
|
||
<canvas id="radar-canvas" width="340" height="280"></canvas>
|
||
</div>
|
||
<div class="mrg-right">
|
||
<div class="hit-miss">
|
||
<div class="hm-col">
|
||
<div class="hm-title ok"><svg viewBox="0 0 24 24"><path d="M20 6L9 17l-5-5"/></svg>已命中技能</div>
|
||
<div class="hm-chips" id="matched-chips"></div>
|
||
</div>
|
||
<div class="hm-col">
|
||
<div class="hm-title bad"><svg viewBox="0 0 24 24"><path d="M18 6L6 18M6 6l12 12"/></svg>缺失技能</div>
|
||
<div class="hm-chips" id="missing-chips"></div>
|
||
</div>
|
||
</div>
|
||
<div class="transfer-block">
|
||
<div class="hm-title info"><svg viewBox="0 0 24 24"><path d="M17 3l4 4-4 4M21 7H9a4 4 0 00-4 4v1M7 21l-4-4 4-4M3 17h12a4 4 0 004-4v-1"/></svg>可迁移技能</div>
|
||
<div class="hm-chips" id="transfer-chips"></div>
|
||
</div>
|
||
<div class="transfer-block hidden" id="irrelevant-block">
|
||
<div class="hm-title weak">与目标岗位无关的技能(不计入评分)</div>
|
||
<div class="hm-chips" id="irrelevant-chips"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="rec-jobs">
|
||
<div class="hm-title info">推荐岗位(按匹配分排序)</div>
|
||
<div class="rec-job-cards" id="rec-job-cards"></div>
|
||
</div>
|
||
<div class="form-actions">
|
||
<button class="btn btn-secondary" id="btn-back-2">重新录入</button>
|
||
<button class="btn btn-primary" id="btn-goto-path">生成学习路径</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div><!-- /match-single -->
|
||
|
||
<!-- ======== 批量匹配 ======== -->
|
||
<div id="match-batch" class="hidden">
|
||
<div class="form-row">
|
||
<label class="form-label">目标岗位</label>
|
||
<select id="batch-job-select" class="select w-320"></select>
|
||
</div>
|
||
<div class="dropzone" id="batch-drop">
|
||
<svg viewBox="0 0 24 24"><path d="M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4M17 8l-5-5-5 5M12 3v12"/></svg>
|
||
<p><b>拖拽简历文件或文件夹到此处</b>,或:</p>
|
||
<div class="dropzone-btns">
|
||
<label class="btn btn-secondary" for="batch-files">选择文件(可多选)</label>
|
||
<label class="btn btn-secondary" for="batch-dir">选择文件夹</label>
|
||
</div>
|
||
<input type="file" id="batch-files" accept=".txt,.md,.docx,.pdf" multiple class="hidden">
|
||
<input type="file" id="batch-dir" webkitdirectory class="hidden">
|
||
<p class="text-aux text-weak">支持 .txt/.docx/.pdf · 单批 ≤50 份 · 单份 ≤5MB · 解析自动脱敏</p>
|
||
</div>
|
||
<div class="batch-filelist" id="batch-filelist"></div>
|
||
<div class="form-actions">
|
||
<button class="btn btn-primary" id="btn-batch-run">
|
||
<svg viewBox="0 0 24 24"><circle cx="12" cy="12" r="8"/><circle cx="12" cy="12" r="4"/><circle cx="12" cy="12" r="1" fill="currentColor"/></svg>
|
||
开始批量匹配</button>
|
||
<button class="btn btn-secondary hidden" id="btn-batch-export">
|
||
<svg viewBox="0 0 24 24"><path d="M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4M7 10l5 5 5-5M12 15V3"/></svg>
|
||
导出结果 CSV</button>
|
||
</div>
|
||
<div id="batch-result"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<!-- ======== 学习路径 ======== -->
|
||
<section id="view-path" class="view">
|
||
<div class="path-layout">
|
||
<!-- 左栏:路径配置 -->
|
||
<div class="card path-side">
|
||
<div class="card-head"><h3>路径配置</h3></div>
|
||
<div class="card-body">
|
||
<div class="form-item">
|
||
<label class="form-label">目标岗位</label>
|
||
<select id="path-job-select" class="select w-full"></select>
|
||
</div>
|
||
<div class="form-item">
|
||
<label class="form-label">岗位能力清单<span class="form-label-tip">点击标记为「已掌握」</span></label>
|
||
<div class="skill-pool" id="path-skill-pool">
|
||
<div class="pool-loading">选择岗位后加载技能清单…</div>
|
||
</div>
|
||
</div>
|
||
<div class="form-item">
|
||
<label class="form-label">学习周期</label>
|
||
<div class="seg" id="path-weeks">
|
||
<button class="seg-item" data-weeks="4">4 周</button>
|
||
<button class="seg-item active" data-weeks="8">8 周</button>
|
||
<button class="seg-item" data-weeks="12">12 周</button>
|
||
</div>
|
||
</div>
|
||
<div class="path-summary" id="path-summary">
|
||
<div class="path-summary-row"><span>已掌握</span><b id="ps-known">0 项</b></div>
|
||
<div class="path-summary-row"><span>待补齐</span><b id="ps-gap">—</b></div>
|
||
<div class="progress"><div class="progress-bar" id="ps-bar" style="width:0%"></div></div>
|
||
<div class="path-summary-tip" id="ps-tip">覆盖率 0%</div>
|
||
</div>
|
||
<button class="btn btn-primary btn-block" id="btn-path">
|
||
<svg viewBox="0 0 24 24"><circle cx="6" cy="19" r="2.5"/><circle cx="18" cy="5" r="2.5"/><path d="M8 17.5C12 14 8 10 12 7.5c1.5-1 3-1.2 4-1.3"/></svg>
|
||
生成学习路径</button>
|
||
</div>
|
||
</div>
|
||
<!-- 右栏:路径结果 -->
|
||
<div class="card path-main">
|
||
<div class="card-head">
|
||
<h3>分阶段学习路线</h3>
|
||
<button class="btn btn-secondary btn-sm hidden" id="btn-export-path">
|
||
<svg viewBox="0 0 24 24"><path d="M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4M7 10l5 5 5-5M12 15V3"/></svg>
|
||
导出文本</button>
|
||
</div>
|
||
<div class="card-body">
|
||
<div class="path-overview hidden" id="path-overview"></div>
|
||
<div class="path-flow" id="path-result">
|
||
<div class="empty">
|
||
<svg viewBox="0 0 24 24"><circle cx="6" cy="19" r="2.5"/><circle cx="18" cy="5" r="2.5"/><path d="M8 17.5C12 14 8 10 12 7.5c1.5-1 3-1.2 4-1.3"/></svg>
|
||
<p>尚未生成学习路径<br>先完成一次人岗诊断,再生成个性化路径(将自动带入岗位与技能缺口)</p>
|
||
<button class="btn btn-primary btn-sm" id="path-goto-match">去完成人岗诊断</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
<footer class="app-footer" id="app-footer">CareerNexus 职联 · 演示模式</footer>
|
||
</main>
|
||
</div>
|
||
|
||
<!-- 通用弹窗容器 -->
|
||
<div class="modal-mask hidden" id="modal-mask">
|
||
<div class="modal" id="modal-box" role="dialog" aria-modal="true">
|
||
<div class="modal-head"><h3 id="modal-title"></h3>
|
||
<button class="icon-btn" id="modal-close" title="关闭"><svg viewBox="0 0 24 24"><path d="M18 6L6 18M6 6l12 12"/></svg></button>
|
||
</div>
|
||
<div class="modal-body" id="modal-body"></div>
|
||
<div class="modal-foot hidden" id="modal-foot"></div>
|
||
</div>
|
||
</div>
|
||
<div class="toast-wrap" id="toast-wrap"></div>
|
||
|
||
<!-- 候选岗位审核台(右侧抽屉式二级界面) -->
|
||
<div class="drawer-mask hidden" id="review-desk-mask">
|
||
<aside class="drawer" id="review-desk" role="dialog" aria-modal="true">
|
||
<div class="drawer-head">
|
||
<h3>候选岗位审核台</h3>
|
||
<span class="text-weak text-aux">发现 → 证据 → 人工决策 → 自动入图</span>
|
||
<button class="icon-btn" id="review-desk-close" title="关闭"><svg viewBox="0 0 24 24"><path d="M18 6L6 18M6 6l12 12"/></svg></button>
|
||
</div>
|
||
<div class="drawer-body" id="review-desk-body"></div>
|
||
</aside>
|
||
</div>
|
||
|
||
<!-- 评委演示导览浮动条(右上角固定) -->
|
||
<div class="tour-bar hidden" id="tour-bar">
|
||
<span class="tour-prog" id="tour-prog">演示 1/6</span>
|
||
<span class="tour-text">
|
||
<b id="tour-title"></b>
|
||
<span class="tour-desc" id="tour-desc"></span>
|
||
</span>
|
||
<button class="btn btn-secondary btn-sm" id="tour-prev">上一步</button>
|
||
<button class="btn btn-primary btn-sm" id="tour-next">下一步</button>
|
||
<button class="btn btn-text btn-sm" id="tour-exit">退出</button>
|
||
</div>
|
||
|
||
<script src="/static/app.js?v=20260819"></script>
|
||
<script src="/static/graph.js?v=20260819"></script>
|
||
</body>
|
||
</html>
|