208 lines
9.1 KiB
HTML
208 lines
9.1 KiB
HTML
<!doctype html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||
<meta name="color-scheme" content="dark">
|
||
<title>魔力工坊 · 配方树工作台</title>
|
||
<link rel="stylesheet" href="./styles.css?v=20260812-2">
|
||
</head>
|
||
<body>
|
||
<div class="app" id="app" aria-busy="true">
|
||
<header class="topbar">
|
||
<div class="brand">
|
||
<span class="brand-mark" aria-hidden="true">◇</span>
|
||
<div>
|
||
<strong>配方树工作台</strong>
|
||
<span>魔力工坊 / 策划数据</span>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="top-stats" aria-label="数据统计">
|
||
<span><b id="statRecipes">—</b> 配方</span>
|
||
<span><b id="statItems">—</b> 物品</span>
|
||
<span><b id="statMachines">—</b> 设施</span>
|
||
</div>
|
||
|
||
<div class="toolbar" role="toolbar" aria-label="文件和编辑操作">
|
||
<span class="save-state loading" id="saveState"><i></i><span>读取中</span></span>
|
||
<button class="button ghost" id="undoButton" type="button" title="撤销(Ctrl+Z)" disabled>撤销</button>
|
||
<button class="button ghost" id="redoButton" type="button" title="重做(Ctrl+Y)" disabled>重做</button>
|
||
<button class="button ghost" id="importButton" type="button">导入</button>
|
||
<button class="button ghost" id="exportButton" type="button">导出</button>
|
||
<button class="button issue-button" id="issuesButton" type="button"><span id="issueCount">校验</span></button>
|
||
<button class="button primary" id="saveButton" type="button" title="保存到 data/recipe-book.json(Ctrl+S)">保存数据</button>
|
||
</div>
|
||
</header>
|
||
|
||
<main class="workspace">
|
||
<aside class="catalog panel" aria-label="数据目录">
|
||
<div class="panel-heading">
|
||
<div>
|
||
<span class="eyebrow">数据目录</span>
|
||
<h1>配方与物料</h1>
|
||
</div>
|
||
<button class="icon-button" id="addEntityButton" type="button" aria-label="新增当前类型" title="新增当前类型">+</button>
|
||
</div>
|
||
|
||
<div class="type-tabs" id="typeTabs" role="tablist" aria-label="数据类型">
|
||
<button type="button" role="tab" data-type="recipes" class="active">配方 <span id="tabRecipes">0</span></button>
|
||
<button type="button" role="tab" data-type="items">物品 <span id="tabItems">0</span></button>
|
||
<button type="button" role="tab" data-type="machines">设施 <span id="tabMachines">0</span></button>
|
||
</div>
|
||
|
||
<label class="search-box">
|
||
<span aria-hidden="true">⌕</span>
|
||
<input id="catalogSearch" type="search" placeholder="搜索名称、ID 或标签" autocomplete="off">
|
||
<kbd>/</kbd>
|
||
</label>
|
||
|
||
<div class="catalog-filters">
|
||
<label>
|
||
<span>阶段</span>
|
||
<select id="stageFilter"><option value="all">全部阶段</option></select>
|
||
</label>
|
||
<label>
|
||
<span>生态区</span>
|
||
<select id="biomeFilter"><option value="all">全部生态区</option></select>
|
||
</label>
|
||
</div>
|
||
|
||
<div class="catalog-summary" id="catalogSummary">正在整理数据…</div>
|
||
<nav class="entity-list" id="entityList" aria-label="实体列表"></nav>
|
||
</aside>
|
||
|
||
<section class="graph-panel panel" aria-label="配方依赖图">
|
||
<div class="graph-header">
|
||
<div class="graph-title">
|
||
<span class="eyebrow">依赖视图</span>
|
||
<h2 id="graphTitle">配方树</h2>
|
||
<p id="graphSubtitle">选择左侧条目以查看上下游。</p>
|
||
</div>
|
||
<div class="graph-controls">
|
||
<div class="segmented" id="graphMode" aria-label="图谱范围">
|
||
<button type="button" data-mode="focus" class="active">聚焦</button>
|
||
<button type="button" data-mode="full">全局</button>
|
||
</div>
|
||
<label class="depth-control" id="depthControl">层级
|
||
<select id="graphDepth">
|
||
<option value="1" selected>1</option>
|
||
<option value="2">2</option>
|
||
<option value="3">3</option>
|
||
<option value="4">4</option>
|
||
<option value="5">5</option>
|
||
</select>
|
||
</label>
|
||
<button class="button ghost compact" id="fitGraphButton" type="button">适应画布</button>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="graph-stage" id="graphStage">
|
||
<svg id="recipeGraph" role="img" aria-label="物品与配方依赖关系图">
|
||
<defs>
|
||
<marker id="arrowOutput" markerWidth="8" markerHeight="8" refX="7" refY="4" orient="auto" markerUnits="strokeWidth">
|
||
<path d="M0,0 L8,4 L0,8 Z" fill="#67d8b2"></path>
|
||
</marker>
|
||
<marker id="arrowInput" markerWidth="8" markerHeight="8" refX="7" refY="4" orient="auto" markerUnits="strokeWidth">
|
||
<path d="M0,0 L8,4 L0,8 Z" fill="#8795b5"></path>
|
||
</marker>
|
||
</defs>
|
||
<g id="graphViewport">
|
||
<g id="graphBackdrop"></g>
|
||
<g id="graphEdges"></g>
|
||
<g id="graphNodes"></g>
|
||
</g>
|
||
</svg>
|
||
<div class="graph-empty" id="graphEmpty" hidden>
|
||
<span>◇</span>
|
||
<strong>没有可显示的节点</strong>
|
||
<p>调整筛选条件,或选择其他条目。</p>
|
||
</div>
|
||
<div class="zoom-tools" aria-label="画布缩放">
|
||
<button type="button" id="zoomOutButton" aria-label="缩小">−</button>
|
||
<output id="zoomOutput">100%</output>
|
||
<button type="button" id="zoomInButton" aria-label="放大">+</button>
|
||
</div>
|
||
<div class="graph-legend">
|
||
<span><i class="legend-item"></i>物品</span>
|
||
<span><i class="legend-recipe"></i>配方</span>
|
||
<span><i class="legend-catalyst"></i>催化/状态</span>
|
||
</div>
|
||
</div>
|
||
|
||
<footer class="graph-footer">
|
||
<div id="routeSummary">—</div>
|
||
<div class="graph-hint">滚轮缩放 · 拖拽平移 · 单击节点编辑</div>
|
||
</footer>
|
||
</section>
|
||
|
||
<aside class="inspector panel" aria-label="属性编辑器">
|
||
<div class="panel-heading inspector-heading">
|
||
<div>
|
||
<span class="eyebrow">属性编辑器</span>
|
||
<h2 id="inspectorTitle">选择一个条目</h2>
|
||
</div>
|
||
<span class="entity-kind" id="inspectorKind">—</span>
|
||
</div>
|
||
<div id="inspectorContent" class="inspector-content">
|
||
<div class="empty-inspector">
|
||
<span>✦</span>
|
||
<p>从左侧目录或中央配方树选择一个条目。</p>
|
||
</div>
|
||
</div>
|
||
</aside>
|
||
</main>
|
||
</div>
|
||
|
||
<dialog id="issuesDialog" class="issues-dialog">
|
||
<form method="dialog" class="dialog-shell">
|
||
<header>
|
||
<div>
|
||
<span class="eyebrow">实时校验</span>
|
||
<h2>数据健康检查</h2>
|
||
<p id="issuesSummary">—</p>
|
||
</div>
|
||
<button class="icon-button" value="cancel" aria-label="关闭">×</button>
|
||
</header>
|
||
<div class="issue-filter" id="issueFilter">
|
||
<button type="button" data-severity="all" class="active">全部</button>
|
||
<button type="button" data-severity="error">错误</button>
|
||
<button type="button" data-severity="warning">警告</button>
|
||
<button type="button" data-severity="info">提示</button>
|
||
</div>
|
||
<div class="issue-list" id="issueList"></div>
|
||
<footer>
|
||
<span>点击问题可定位到对应条目。</span>
|
||
<button class="button primary" value="cancel">完成</button>
|
||
</footer>
|
||
</form>
|
||
</dialog>
|
||
|
||
<dialog id="helpDialog" class="help-dialog">
|
||
<form method="dialog" class="dialog-shell">
|
||
<header>
|
||
<div><span class="eyebrow">字段速查</span><h2>魔法配方怎么填</h2></div>
|
||
<button class="icon-button" value="cancel" aria-label="关闭">×</button>
|
||
</header>
|
||
<div class="help-content">
|
||
<dl>
|
||
<dt>消耗</dt><dd>每次制作永久扣除,例如木材、供物。</dd>
|
||
<dt>催化</dt><dd>参与法则但不扣除,例如生命锚核、边界石。</dd>
|
||
<dt>流体</dt><dd>按配方批次统计的管网输入。</dd>
|
||
<dt>状态</dt><dd>物品必须带入某种状态,完成后可由产出表达状态变化。</dd>
|
||
<dt>权重</dt><dd>用于传送门结果袋;同一配方所有权重应合计 100。</dd>
|
||
<dt>概率</dt><dd>用于独立概率结果;全部产出都是概率项时应合计 1。</dd>
|
||
<dt>熵</dt><dd>一次制作给传送门或仪式网络增加的复杂度压力。</dd>
|
||
</dl>
|
||
</div>
|
||
<footer><span>修改会先进入浏览器草稿;“保存数据”才写回项目。</span><button class="button primary" value="cancel">知道了</button></footer>
|
||
</form>
|
||
</dialog>
|
||
|
||
<input id="importFile" type="file" accept="application/json,.json" hidden>
|
||
<div class="toast-stack" id="toastStack" aria-live="polite"></div>
|
||
|
||
<script type="module" src="./app.mjs?v=20260812-5"></script>
|
||
</body>
|
||
</html>
|