CareerNexus 职联:岗位能力图谱构建与动态演化分析平台(挑战杯 XH-202621)
- 全链路:多源JD接入/清洗交叉验证/结构化抽取(星火+离线双通道)/时序知识图谱/新岗位发现/演化分析/人岗匹配/学习路径 - WebUI 五视图:驾驶舱/图谱工作台/岗位演化/匹配(单人+批量)/学习路径 - 设置中心(config.json)/Token鉴权/SQLite状态库/语义向量通道(BGE-M3本地或联网API) - 71 个 pytest 用例;数据目录仅保留结构(.gitkeep),数据由 scripts/generate_dataset.py 复现
This commit is contained in:
@@ -0,0 +1,511 @@
|
||||
<!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=20260803">
|
||||
</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="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="metric-grid" id="metric-cards"></div>
|
||||
<div class="grid-2">
|
||||
<div class="card">
|
||||
<div class="card-head">
|
||||
<h3>近 12 个季度演化事件趋势</h3>
|
||||
<span class="text-weak text-aux">按事件窗口统计</span>
|
||||
</div>
|
||||
<div class="card-body"><canvas id="trend-canvas" height="220"></canvas></div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="card-head">
|
||||
<h3>任务与审核状态</h3>
|
||||
<button class="btn btn-secondary btn-sm" id="btn-import-jd">导入 JD 数据</button>
|
||||
</div>
|
||||
<div class="card-body" 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>
|
||||
</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="badge badge-warning" id="pending-count">0 待办</span></div>
|
||||
<div class="card-body" id="pending-list"></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="graph-actions">
|
||||
<button class="btn btn-secondary" 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="btn btn-secondary" 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="btn btn-primary" 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>
|
||||
导出图谱</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="graph-body">
|
||||
<div class="graph-canvas-wrap card" id="graph-canvas-wrap">
|
||||
<canvas id="graph-canvas"></canvas>
|
||||
|
||||
<!-- 左上浮动工具条 -->
|
||||
<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 active" 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" checked><i class="lg-dot industry"></i>行业</label>
|
||||
<label class="check"><input type="checkbox" data-ftype="Scenario" checked><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-suggest card" id="graph-suggest">
|
||||
<div class="gs-head">
|
||||
<svg viewBox="0 0 24 24"><path d="M12 2a7 7 0 00-4 12.7V17a1 1 0 001 1h6a1 1 0 001-1v-2.3A7 7 0 0012 2z"/><path d="M9 21h6"/></svg>
|
||||
智能建议
|
||||
<button class="icon-btn sm" id="gs-toggle" title="收起/展开"><svg viewBox="0 0 24 24"><path d="M6 9l6 6 6-6"/></svg></button>
|
||||
</div>
|
||||
<div class="gs-list" id="gs-list"></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>
|
||||
</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">
|
||||
<!-- 全部岗位演化热力图 -->
|
||||
<div class="evo-chart-title text-aux text-secondary">全部岗位演化热力图(每格 = 该季度演化事件数,点击行切换岗位)</div>
|
||||
<div class="evo-heatmap" id="evo-heatmap"><div class="empty small">加载中…</div></div>
|
||||
|
||||
<!-- 统计条 -->
|
||||
<div class="evo-stats" id="evo-stats"></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-diff" id="evo-diff"></div>
|
||||
</div>
|
||||
|
||||
<!-- 变更类型构成(堆叠柱状) -->
|
||||
<div class="evo-chart-title text-aux text-secondary">变更类型构成(每季度 新增/增强/减弱/退出)</div>
|
||||
<div class="evo-heat-wrap"><canvas id="evo-stack-canvas"></canvas></div>
|
||||
<div class="stack-legend" id="stack-legend"></div>
|
||||
|
||||
<!-- 技能生命周期甘特图 -->
|
||||
<div class="evo-chart-title text-aux text-secondary">技能生命周期(横条 = 技能在画像中的生效区间,圆点 = 变更事件)</div>
|
||||
<div class="evo-gantt" id="evo-gantt"></div>
|
||||
|
||||
<!-- 热度走势(限高) -->
|
||||
<div class="evo-chart-title text-aux text-secondary">技能热度走势(活跃技能关系数)</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="timeline" id="evo-timeline"></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 步 -->
|
||||
<div class="match-pane" id="match-pane-1">
|
||||
<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>
|
||||
|
||||
<!-- 第 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>
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<footer class="app-footer">如遇问题,请联系 support@rrrosmontis.icu</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>
|
||||
|
||||
<script src="/static/app.js?v=20260803"></script>
|
||||
<script src="/static/graph.js?v=20260803"></script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user