@pioneer_zmc/dsh-workbench 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +98 -0
- package/README.zh.md +100 -0
- package/client.js +122 -0
- package/cordis.patch.yml +8 -0
- package/dist/check-building.js +1669 -0
- package/dist/check-room.js +980 -0
- package/dist/index.js +2873 -0
- package/package.json +60 -0
- package/skills/specdev-building/SKILL.md +85 -0
- package/skills/specdev-building/assets/layouts/court.json +53 -0
- package/skills/specdev-building/assets/layouts/row.json +48 -0
- package/skills/specdev-building/assets/layouts/single.json +27 -0
- package/skills/specdev-building/assets/layouts/tower-9.json +71 -0
- package/skills/specdev-building/assets/layouts/tower.json +59 -0
- package/skills/specdev-building/references/blueprint-contract.md +126 -0
- package/skills/specdev-building/references/diagnostics.md +101 -0
- package/skills/specdev-building/references/layouts.md +112 -0
- package/skills/specdev-business/SKILL.md +91 -0
- package/skills/specdev-business/assets/plan-template.md +66 -0
- package/skills/specdev-business/assets/spec-template.md +111 -0
- package/skills/specdev-business/assets/tasks-template.md +36 -0
- package/skills/specdev-business/references/change.md +117 -0
- package/skills/specdev-business/references/evidence-review.md +125 -0
- package/skills/specdev-business/references/implementation.md +67 -0
- package/skills/specdev-business/references/project-contract.md +211 -0
- package/skills/specdev-business/references/source-map.md +110 -0
- package/skills/specdev-business/references/specification.md +93 -0
- package/skills/specdev-business/references/workflow.md +126 -0
- package/skills/specdev-room/SKILL.md +77 -0
- package/skills/specdev-room/assets/intro-room.json +14 -0
- package/skills/specdev-room/references/diagnostics.md +21 -0
- package/skills/specdev-room/references/room-contract.md +59 -0
- package/vendor/archify-renderer/VERSION.md +52 -0
- package/vendor/archify-renderer/archify/LICENSE +22 -0
- package/vendor/archify-renderer/archify/THIRD_PARTY_NOTICES.md +56 -0
- package/vendor/archify-renderer/archify/assets/template.html +14787 -0
- package/vendor/archify-renderer/archify/bin/archify.mjs +1990 -0
- package/vendor/archify-renderer/archify/renderers/shared/brand-marks.mjs +563 -0
- package/vendor/archify-renderer/archify/renderers/shared/cli.mjs +218 -0
- package/vendor/archify-renderer/archify/renderers/shared/desktop-readability.mjs +26 -0
- package/vendor/archify-renderer/archify/renderers/shared/diagnostics.mjs +127 -0
- package/vendor/archify-renderer/archify/renderers/shared/engineering-profiles.mjs +157 -0
- package/vendor/archify-renderer/archify/renderers/shared/generated-brand-marks.mjs +2003 -0
- package/vendor/archify-renderer/archify/renderers/shared/generated-validators.mjs +13 -0
- package/vendor/archify-renderer/archify/renderers/shared/geometry.mjs +1423 -0
- package/vendor/archify-renderer/archify/renderers/shared/i18n.mjs +594 -0
- package/vendor/archify-renderer/archify/renderers/shared/legend.mjs +217 -0
- package/vendor/archify-renderer/archify/renderers/shared/output-path.mjs +321 -0
- package/vendor/archify-renderer/archify/renderers/shared/repository-evidence.mjs +235 -0
- package/vendor/archify-renderer/archify/renderers/shared/text-fit.mjs +49 -0
- package/vendor/archify-renderer/archify/renderers/shared/utils.mjs +232 -0
- package/vendor/archify-renderer/archify/renderers/shared/validator.mjs +86 -0
- package/vendor/archify-renderer/archify/renderers/workflow/render-workflow.mjs +35 -0
- package/vendor/archify-renderer/archify/renderers/workflow/workflow-compiler.mjs +4400 -0
- package/vendor/archify-renderer/archify/renderers/workflow/workflow-migration-geometry.mjs +144 -0
- package/vendor/archify-renderer/archify/schemas/common.schema.json +115 -0
- package/vendor/archify-renderer/archify/schemas/workflow.schema.json +428 -0
- package/vendor/archify-renderer/archify/scripts/check-render-output.mjs +835 -0
- package/vendor/archify-renderer/shims/process.mjs +18 -0
- package/vendor/archify-renderer/stubs/child_process.mjs +2 -0
- package/vendor/archify-renderer/stubs/crypto.mjs +3 -0
- package/vendor/archify-renderer/stubs/dns-promises.mjs +2 -0
- package/vendor/archify-renderer/stubs/fs.mjs +3 -0
- package/vendor/archify-renderer/stubs/http.mjs +3 -0
- package/vendor/archify-renderer/stubs/https.mjs +3 -0
- package/vendor/archify-renderer/stubs/net.mjs +3 -0
- package/vendor/archify-renderer/stubs/path.mjs +3 -0
- package/vendor/archify-renderer/stubs/url.mjs +3 -0
- package/web/assets/building-kit.js +1157 -0
- package/web/assets/building-look.js +185 -0
- package/web/assets/building-plan.js +495 -0
- package/web/assets/building-scene.js +529 -0
- package/web/assets/building-walk.js +248 -0
- package/web/assets/building.js +859 -0
- package/web/assets/business.js +124 -0
- package/web/assets/chart-link.js +165 -0
- package/web/assets/common.js +302 -0
- package/web/assets/details.js +197 -0
- package/web/assets/evidence.js +30 -0
- package/web/assets/furniture/SOURCES.md +24 -0
- package/web/assets/furniture/assets/ceramic-display-stand-01/asset.json +25 -0
- package/web/assets/furniture/assets/ceramic-display-stand-01/model.js +116 -0
- package/web/assets/furniture/assets/ceramic-display-stand-01/preview.webp +0 -0
- package/web/assets/furniture/assets/ceramic-floor-lamp-01/asset.json +61 -0
- package/web/assets/furniture/assets/ceramic-floor-lamp-01/model.js +56 -0
- package/web/assets/furniture/assets/ceramic-floor-lamp-01/preview.webp +0 -0
- package/web/assets/furniture/assets/ceramic-low-cabinet-01/asset.json +81 -0
- package/web/assets/furniture/assets/ceramic-low-cabinet-01/model.js +67 -0
- package/web/assets/furniture/assets/ceramic-low-cabinet-01/preview.webp +0 -0
- package/web/assets/furniture/assets/ceramic-vase-01/asset.json +21 -0
- package/web/assets/furniture/assets/ceramic-vase-01/model.js +119 -0
- package/web/assets/furniture/assets/ceramic-vase-01/preview.webp +0 -0
- package/web/assets/furniture/assets/fairy-bed-01/asset.json +61 -0
- package/web/assets/furniture/assets/fairy-bed-01/model.js +63 -0
- package/web/assets/furniture/assets/fairy-bed-01/preview.webp +0 -0
- package/web/assets/furniture/assets/fairy-book-stack-01/asset.json +21 -0
- package/web/assets/furniture/assets/fairy-book-stack-01/model.js +71 -0
- package/web/assets/furniture/assets/fairy-book-stack-01/preview.webp +0 -0
- package/web/assets/furniture/assets/fairy-bookshelf-01/asset.json +32 -0
- package/web/assets/furniture/assets/fairy-bookshelf-01/model.js +168 -0
- package/web/assets/furniture/assets/fairy-bookshelf-01/preview.webp +0 -0
- package/web/assets/furniture/assets/fairy-desk-01/asset.json +25 -0
- package/web/assets/furniture/assets/fairy-desk-01/model.js +132 -0
- package/web/assets/furniture/assets/fairy-desk-01/preview.webp +0 -0
- package/web/assets/furniture/assets/fairy-notice-board-01/asset.json +23 -0
- package/web/assets/furniture/assets/fairy-notice-board-01/model.js +125 -0
- package/web/assets/furniture/assets/fairy-notice-board-01/preview.webp +0 -0
- package/web/assets/furniture/assets/fairy-potted-plant-01/asset.json +21 -0
- package/web/assets/furniture/assets/fairy-potted-plant-01/model.js +128 -0
- package/web/assets/furniture/assets/fairy-potted-plant-01/preview.webp +0 -0
- package/web/assets/furniture/assets/fairy-reading-chair-01/asset.json +61 -0
- package/web/assets/furniture/assets/fairy-reading-chair-01/model.js +66 -0
- package/web/assets/furniture/assets/fairy-reading-chair-01/preview.webp +0 -0
- package/web/assets/furniture/assets/fairy-table-lamp-01/asset.json +21 -0
- package/web/assets/furniture/assets/fairy-table-lamp-01/model.js +182 -0
- package/web/assets/furniture/assets/fairy-table-lamp-01/preview.webp +0 -0
- package/web/assets/furniture/catalog.js +137 -0
- package/web/assets/furniture/index.json +110 -0
- package/web/assets/furniture/registry.js +72 -0
- package/web/assets/furniture-page.css +68 -0
- package/web/assets/furniture-page.js +302 -0
- package/web/assets/home.js +65 -0
- package/web/assets/node-detail.js +148 -0
- package/web/assets/panel-link.js +47 -0
- package/web/assets/read.js +746 -0
- package/web/assets/room-scene.js +386 -0
- package/web/assets/room.css +287 -0
- package/web/assets/room.js +437 -0
- package/web/assets/rooms/bindings.js +449 -0
- package/web/assets/rooms/ceramic-reflection.js +193 -0
- package/web/assets/rooms/ceramic-room.js +302 -0
- package/web/assets/rooms/door.js +35 -0
- package/web/assets/rooms/fairy-room.js +492 -0
- package/web/assets/rooms/furniture-assembly.js +113 -0
- package/web/assets/rooms/navigation.js +262 -0
- package/web/assets/rooms/placeholder-catalog.json +71 -0
- package/web/assets/rooms/placeholder-furniture.js +76 -0
- package/web/assets/rooms/placement.js +588 -0
- package/web/assets/rooms/reader.js +441 -0
- package/web/assets/rooms/reading-gate.js +157 -0
- package/web/assets/rooms/room-lighting.js +50 -0
- package/web/assets/rooms/templates.json +50 -0
- package/web/assets/rooms/walk-frame.js +64 -0
- package/web/assets/rooms/walk-session.js +138 -0
- package/web/assets/save-result.js +89 -0
- package/web/assets/screenshots/business.png +0 -0
- package/web/assets/screenshots/node-detail.png +0 -0
- package/web/assets/screenshots/project-home.png +0 -0
- package/web/assets/screenshots/workflow.png +0 -0
- package/web/assets/showcase.js +232 -0
- package/web/assets/style.css +836 -0
- package/web/assets/template.js +7 -0
- package/web/assets/theme.js +29 -0
- package/web/assets/three/OrbitControls.js +1972 -0
- package/web/assets/three/VERSION.md +12 -0
- package/web/assets/three/three.core.js +60586 -0
- package/web/assets/three/three.module.js +19719 -0
- package/web/assets/workspaces.css +21 -0
- package/web/assets/workspaces.js +81 -0
- package/web/building.html +131 -0
- package/web/business.html +43 -0
- package/web/furniture.html +47 -0
- package/web/index.html +57 -0
- package/web/read.html +107 -0
- package/web/room.html +146 -0
- package/web/showcase.html +50 -0
- package/web/workspaces.html +32 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/* 独立项目选择页:共用主题色,样式仅限本页;内容自然换行和滚动。 */
|
|
2
|
+
.workspaces-page { background: var(--page); }
|
|
3
|
+
.workspaces-page .workspaces-main { max-width: 860px; margin: 40px auto; padding: 0 24px 40px; }
|
|
4
|
+
.workspaces-page h1 { margin: 0 0 8px; font-size: 28px; }
|
|
5
|
+
.workspaces-page .workspaces-intro { color: var(--secondary); margin: 0 0 24px; }
|
|
6
|
+
.workspaces-page .workspace-list { list-style: none; margin: 20px 0; padding: 0; display: grid; gap: 12px; }
|
|
7
|
+
.workspaces-page .workspace-project {
|
|
8
|
+
display: block; min-width: 0; padding: 16px 20px;
|
|
9
|
+
color: var(--text); background: var(--surface); border: 1px solid var(--border); border-radius: 12px;
|
|
10
|
+
white-space: normal; overflow-wrap: anywhere;
|
|
11
|
+
}
|
|
12
|
+
.workspaces-page .workspace-project:hover { background: var(--hover); border-color: var(--accent); text-decoration: none; }
|
|
13
|
+
.workspaces-page .workspace-project:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
|
|
14
|
+
.workspaces-page .workspace-title { display: block; font-size: 17px; font-weight: 600; }
|
|
15
|
+
.workspaces-page .workspace-path { display: block; margin-top: 6px; color: var(--secondary); overflow-wrap: anywhere; white-space: pre-wrap; }
|
|
16
|
+
.workspaces-page #workspaceStatus { color: var(--muted); }
|
|
17
|
+
.workspaces-page #workspaceFallback { margin-top: 20px; font-size: 13px; }
|
|
18
|
+
@media (max-width: 480px) {
|
|
19
|
+
.workspaces-page .workspaces-main { margin-top: 24px; padding: 0 16px 24px; }
|
|
20
|
+
.workspaces-page .workspace-project { padding: 14px; }
|
|
21
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
// 只读宿主工作区;选择由作者完成,不猜当前项目或默认第一项。
|
|
2
|
+
;(() => {
|
|
3
|
+
const list = document.getElementById('workspaceList')
|
|
4
|
+
const status = document.getElementById('workspaceStatus')
|
|
5
|
+
const error = document.getElementById('workspaceError')
|
|
6
|
+
const empty = document.getElementById('workspaceEmpty')
|
|
7
|
+
const retry = document.getElementById('workspaceRetry')
|
|
8
|
+
const fallback = document.getElementById('workspaceFallback')
|
|
9
|
+
let pending = false
|
|
10
|
+
let gone = false
|
|
11
|
+
let serial = 0
|
|
12
|
+
let controller = null
|
|
13
|
+
|
|
14
|
+
function entries(body) {
|
|
15
|
+
if (!body || !Array.isArray(body.workspaces)) throw new Error('项目清单格式不正确,请重试。')
|
|
16
|
+
const ids = new Set()
|
|
17
|
+
for (const item of body.workspaces) {
|
|
18
|
+
if (!item || typeof item.id !== 'string' || !item.id.trim()
|
|
19
|
+
|| typeof item.title !== 'string' || !item.title.trim() || typeof item.path !== 'string'
|
|
20
|
+
|| ids.has(item.id)) throw new Error('项目条目格式不正确,请重试。')
|
|
21
|
+
ids.add(item.id)
|
|
22
|
+
}
|
|
23
|
+
return body.workspaces
|
|
24
|
+
}
|
|
25
|
+
async function load() {
|
|
26
|
+
if (pending || gone) return
|
|
27
|
+
pending = true
|
|
28
|
+
const current = ++serial
|
|
29
|
+
controller = new AbortController()
|
|
30
|
+
const late = () => gone || current !== serial
|
|
31
|
+
list.replaceChildren()
|
|
32
|
+
list.setAttribute('aria-busy', 'true')
|
|
33
|
+
error.hidden = empty.hidden = retry.hidden = fallback.hidden = true
|
|
34
|
+
retry.disabled = true
|
|
35
|
+
status.textContent = '正在读取项目清单…'
|
|
36
|
+
try {
|
|
37
|
+
const response = await fetch('/specdev-workbench/api/workspaces', { signal: controller.signal })
|
|
38
|
+
if (late()) return
|
|
39
|
+
if (!response.ok) throw new Error(`项目清单读取失败(HTTP ${response.status}),请重试。`)
|
|
40
|
+
const body = await response.json()
|
|
41
|
+
if (late()) return
|
|
42
|
+
const projects = entries(body)
|
|
43
|
+
const fragment = document.createDocumentFragment()
|
|
44
|
+
for (const project of projects) {
|
|
45
|
+
const item = document.createElement('li')
|
|
46
|
+
const link = document.createElement('a')
|
|
47
|
+
link.className = 'workspace-project'
|
|
48
|
+
link.href = '/specdev-workbench/?workspace=' + encodeURIComponent(project.id)
|
|
49
|
+
const name = document.createElement('span')
|
|
50
|
+
name.className = 'workspace-title'; name.textContent = project.title
|
|
51
|
+
const location = document.createElement('span')
|
|
52
|
+
location.className = 'workspace-path'; location.textContent = project.path
|
|
53
|
+
link.append(name, location); item.append(link); fragment.append(item)
|
|
54
|
+
}
|
|
55
|
+
list.replaceChildren(fragment)
|
|
56
|
+
status.textContent = projects.length ? `共 ${projects.length} 个项目,请选择。` : '暂无项目'
|
|
57
|
+
empty.hidden = fallback.hidden = projects.length !== 0
|
|
58
|
+
} catch (reason) {
|
|
59
|
+
if (late()) return
|
|
60
|
+
list.replaceChildren()
|
|
61
|
+
status.textContent = '项目清单读取失败'
|
|
62
|
+
error.textContent = reason instanceof SyntaxError ? '项目清单不是有效 JSON,请重试。' : String(reason?.message ?? reason)
|
|
63
|
+
error.hidden = retry.hidden = fallback.hidden = false
|
|
64
|
+
} finally {
|
|
65
|
+
if (!late()) {
|
|
66
|
+
pending = false; controller = null
|
|
67
|
+
list.setAttribute('aria-busy', 'false')
|
|
68
|
+
retry.disabled = false
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
retry.addEventListener('click', load)
|
|
73
|
+
window.addEventListener('pagehide', () => {
|
|
74
|
+
gone = true; serial += 1; pending = false
|
|
75
|
+
controller?.abort(); controller = null
|
|
76
|
+
})
|
|
77
|
+
window.addEventListener('pageshow', (event) => {
|
|
78
|
+
if (event.persisted) { gone = false; void load() }
|
|
79
|
+
})
|
|
80
|
+
void load()
|
|
81
|
+
})()
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="zh-CN" data-theme="dark">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
|
+
<title>建筑总览 · SpecDev 工作台</title>
|
|
7
|
+
<script src="/specdev-workbench/assets/theme.js"></script>
|
|
8
|
+
<link rel="stylesheet" href="/specdev-workbench/assets/style.css">
|
|
9
|
+
<!-- Three.js 副本随包发布(web/assets/three/,来源与版本见其 VERSION.md):
|
|
10
|
+
裸名 'three' 与官方 addon 路径都在这里映射,页面脚本与场景模块共用。 -->
|
|
11
|
+
<script type="importmap">
|
|
12
|
+
{
|
|
13
|
+
"imports": {
|
|
14
|
+
"three": "/specdev-workbench/assets/three/three.module.js",
|
|
15
|
+
"three/addons/controls/OrbitControls.js": "/specdev-workbench/assets/three/OrbitControls.js"
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
</script>
|
|
19
|
+
</head>
|
|
20
|
+
<body class="building-page">
|
|
21
|
+
<a class="skip-link" href="#main">跳到主要内容</a>
|
|
22
|
+
<header class="app-bar">
|
|
23
|
+
<a class="brand" data-home-link href="/specdev-workbench/" aria-label="SpecDev 项目首页"><span class="brand-mark" aria-hidden="true">S<span></span></span><span>SpecDev<span class="brand-caption">工作台</span></span></a>
|
|
24
|
+
<div class="theme-switch" role="group" aria-label="页面主题"><button type="button" data-theme-choice="light" aria-pressed="false"><span aria-hidden="true">☼</span> 浅色</button><button type="button" data-theme-choice="dark" aria-pressed="true"><span aria-hidden="true">☾</span> 深色</button></div>
|
|
25
|
+
</header>
|
|
26
|
+
<div class="page-content">
|
|
27
|
+
<header class="top">
|
|
28
|
+
<div>
|
|
29
|
+
<p class="crumbs"><a href="/specdev-workbench/">项目首页</a> / <span>建筑总览</span></p>
|
|
30
|
+
<h1 id="title">建筑总览</h1>
|
|
31
|
+
<p class="sub" id="intro">按建筑蓝图把项目看成一栋房子:楼层、业务房间与资料入口。</p>
|
|
32
|
+
<!-- 工作区行与三页同款:默认收起,展开见全路径(common.js renderRepoLine 填充)。 -->
|
|
33
|
+
<details class="workspace-details" id="workspaceDetails" hidden><summary id="workspaceLabel">工作区</summary><p id="repoLine"></p></details>
|
|
34
|
+
</div>
|
|
35
|
+
<p id="status" class="status" data-kind="info">正在读取建筑蓝图…</p>
|
|
36
|
+
</header>
|
|
37
|
+
<p id="errorBox" class="error" role="alert" hidden></p>
|
|
38
|
+
<section id="guideBox" class="guide" hidden></section>
|
|
39
|
+
<!-- 核对或几何有问题:列出诊断(error 阻止生成,warning 只是提示),不建三维场景。 -->
|
|
40
|
+
<section id="diagnosticsPanel" class="diagnostics-panel" hidden aria-labelledby="diagnosticsHeading">
|
|
41
|
+
<h2 id="diagnosticsHeading">蓝图需要调整,暂不能生成建筑</h2>
|
|
42
|
+
<p class="diagnostics-note">修好下面的问题后刷新本页即可;管理页只读,不会自动改蓝图或清单。</p>
|
|
43
|
+
<ol id="problemList" class="problem-list"></ol>
|
|
44
|
+
</section>
|
|
45
|
+
<!-- 三维视图+房间目录:几何全部由服务端算好(model/present),页面只负责呈现。
|
|
46
|
+
建筑生成成功后整页切到"全窗口"形态(body.building-live,由 building.js 加上):
|
|
47
|
+
三维视图占满窗口,右侧目录改成浮在视口上的抽屉,可随手收起让视图全宽。 -->
|
|
48
|
+
<section id="buildingStage" class="building-layout" hidden>
|
|
49
|
+
<div id="viewport" class="building-viewport" aria-label="三维建筑视图,拖动环绕,滚轮缩放">
|
|
50
|
+
<div class="view-toolbar" role="group" aria-label="浏览方式">
|
|
51
|
+
<div class="toolbar-group">
|
|
52
|
+
<label class="toolbar-field" for="floor">楼层剖看</label>
|
|
53
|
+
<select id="floor" class="floor-select"><option value="all">全部楼层</option></select>
|
|
54
|
+
<label class="preview-toggle" for="preview"><input id="preview" type="checkbox"><span>完整外观预览<small>仅预览造型,不代表实现</small></span></label>
|
|
55
|
+
<button id="walkToggle" class="walk-button" type="button" aria-pressed="false">进入探索</button>
|
|
56
|
+
<button id="resetView" class="reset-button" type="button">回到总览</button>
|
|
57
|
+
<!-- 操作提示跟控制放在同一行:这样它永远不与底部横幅、方向按钮区争地方,
|
|
58
|
+
窄屏换行时也只是把操作行抬高一点(抽屉与卡片按同一行高让位)。 -->
|
|
59
|
+
<p id="sceneHint" class="scene-hint">拖动环绕 · 滚轮缩放 · 点目录定位房间</p>
|
|
60
|
+
</div>
|
|
61
|
+
<!-- 资料目录的开关:目录浮在视口右侧,收起后三维视图占满整页;状态由 building.js 管
|
|
62
|
+
(作者的选择记在本机,进探索时临时收起、退出后收回他的选择)。 -->
|
|
63
|
+
<button id="directoryToggle" class="panel-toggle" type="button" aria-expanded="true" aria-controls="directory">收起目录</button>
|
|
64
|
+
</div>
|
|
65
|
+
<p id="previewBanner" class="preview-banner" hidden>完整外观预览 · 不代表代码已实现或已验收</p>
|
|
66
|
+
<!-- 进不去探索时的说明(入口站不住、没有行走面):留在视口里,不被状态行的换版口径冲掉。 -->
|
|
67
|
+
<p id="walkNotice" class="walk-notice" role="status" hidden></p>
|
|
68
|
+
<!-- 探索模式:所在位置+方向按钮(键盘 WASD/方向键、Shift 加速同样可用;按钮按住即走)。 -->
|
|
69
|
+
<div id="walkHud" class="walk-hud" hidden>
|
|
70
|
+
<p id="walkLocation" class="walk-location"></p>
|
|
71
|
+
<div class="walk-pad" role="group" aria-label="漫游方向按钮">
|
|
72
|
+
<button type="button" data-walk-key="ArrowUp" aria-label="前进">↑</button>
|
|
73
|
+
<button type="button" data-walk-key="ArrowLeft" aria-label="向左">←</button>
|
|
74
|
+
<button type="button" data-walk-key="ArrowDown" aria-label="后退">↓</button>
|
|
75
|
+
<button type="button" data-walk-key="ArrowRight" aria-label="向右">→</button>
|
|
76
|
+
</div>
|
|
77
|
+
</div>
|
|
78
|
+
<div id="sceneFallback" class="scene-fallback" hidden>
|
|
79
|
+
<strong>三维视图不可用</strong>
|
|
80
|
+
<p id="sceneFallbackReason"></p>
|
|
81
|
+
<p>房间目录与资料入口不受影响,仍可使用。</p>
|
|
82
|
+
</div>
|
|
83
|
+
<!-- 房内打开资料:业务门牌/房间目录给该业务的介绍与资料清单,项目牌给项目介绍。
|
|
84
|
+
文档正文在面板里读;流程图用现有阅读页(iframe,带同一个工作区参数)。
|
|
85
|
+
打开时暂停漫游输入,关闭后位置与视角原样——读完留在原地接着逛。 -->
|
|
86
|
+
<section id="materialPanel" class="material-panel" role="dialog" aria-modal="false" aria-labelledby="materialTitle" hidden>
|
|
87
|
+
<div class="material-head">
|
|
88
|
+
<div class="material-heading">
|
|
89
|
+
<p class="material-kind" id="materialKind">业务资料</p>
|
|
90
|
+
<h2 id="materialTitle">…</h2>
|
|
91
|
+
</div>
|
|
92
|
+
<button id="materialClose" class="material-close" type="button" aria-label="关闭资料面板">×</button>
|
|
93
|
+
</div>
|
|
94
|
+
<div class="material-body">
|
|
95
|
+
<div class="material-side">
|
|
96
|
+
<p id="materialIntro" class="material-intro" hidden></p>
|
|
97
|
+
<p id="materialListLabel" class="material-list-label" hidden>资料清单 <span id="materialCount"></span></p>
|
|
98
|
+
<ul id="materialList" class="material-list" hidden></ul>
|
|
99
|
+
<p id="materialEmpty" class="material-empty" hidden></p>
|
|
100
|
+
</div>
|
|
101
|
+
<div class="material-reader">
|
|
102
|
+
<p id="materialReaderHint" class="material-reader-hint">在左边挑一份资料,正文与流程图都在这里读。</p>
|
|
103
|
+
<p id="materialReaderTitle" class="material-reader-title" hidden></p>
|
|
104
|
+
<p id="materialReaderStatus" class="material-reader-status" role="alert" hidden></p>
|
|
105
|
+
<div id="materialReaderBody" class="material-reader-body" hidden></div>
|
|
106
|
+
<iframe id="materialReaderFrame" class="material-reader-frame" title="流程图阅读" hidden></iframe>
|
|
107
|
+
</div>
|
|
108
|
+
</div>
|
|
109
|
+
</section>
|
|
110
|
+
</div>
|
|
111
|
+
<aside id="directory" class="building-directory" aria-label="项目与房间目录">
|
|
112
|
+
<div class="project-block">
|
|
113
|
+
<p class="eyebrow"><span class="eyebrow-line"></span> 当前项目</p>
|
|
114
|
+
<h2 id="projectName">…</h2>
|
|
115
|
+
<p id="projectDesc" class="project-description"></p>
|
|
116
|
+
<p id="metrics" class="metrics" aria-label="建筑信息"></p>
|
|
117
|
+
</div>
|
|
118
|
+
<div id="phaseCard" class="phase-card"><span class="status-dot" aria-hidden="true"></span><div><strong id="phaseLabel">…</strong><p id="phaseNote"></p></div></div>
|
|
119
|
+
<section id="notices" class="notices" hidden aria-label="生成提示">
|
|
120
|
+
<details><summary>生成提示 <span id="noticeCount"></span></summary><ul id="noticeList"></ul></details>
|
|
121
|
+
</section>
|
|
122
|
+
<div class="section-label">房间目录 <span>点击定位 · 资料链接到阅读入口</span></div>
|
|
123
|
+
<!-- tabindex="-1":关掉资料面板时若原来的触发按钮已经不在了(换蓝图会重建目录),
|
|
124
|
+
焦点落到这块目录容器上,不丢在没有落点的地方。 -->
|
|
125
|
+
<div id="rooms" class="rooms" tabindex="-1"></div>
|
|
126
|
+
</aside>
|
|
127
|
+
</section>
|
|
128
|
+
</div>
|
|
129
|
+
<script type="module" src="/specdev-workbench/assets/building.js"></script>
|
|
130
|
+
</body>
|
|
131
|
+
</html>
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="zh-CN">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
|
+
<title>业务 · SpecDev 工作台</title>
|
|
7
|
+
<script src="/specdev-workbench/assets/theme.js"></script>
|
|
8
|
+
<link rel="stylesheet" href="/specdev-workbench/assets/style.css">
|
|
9
|
+
</head>
|
|
10
|
+
<body class="business-page">
|
|
11
|
+
<header class="app-bar">
|
|
12
|
+
<a class="brand" data-home-link href="/specdev-workbench/" aria-label="SpecDev 项目首页"><span class="brand-mark" aria-hidden="true">S<span></span></span><span>SpecDev<span class="brand-caption">工作台</span></span></a>
|
|
13
|
+
<div class="theme-switch" role="group" aria-label="页面主题"><button type="button" data-theme-choice="light" aria-pressed="false"><span aria-hidden="true">☼</span> 浅色</button><button type="button" data-theme-choice="dark" aria-pressed="true"><span aria-hidden="true">☾</span> 深色</button></div>
|
|
14
|
+
</header>
|
|
15
|
+
<div class="page-content">
|
|
16
|
+
<header class="top">
|
|
17
|
+
<div>
|
|
18
|
+
<p class="crumbs"><a href="/specdev-workbench/">项目首页</a> / <span id="bizName">…</span></p>
|
|
19
|
+
<h1 id="title">业务</h1>
|
|
20
|
+
<p class="sub" id="intro"></p>
|
|
21
|
+
<!-- P1b-2:独立业务房间入口。初始隐藏;business.js 读到当前业务且说明文件有效后才显示。
|
|
22
|
+
不为它预读房间接口:没有 room.json 时由房间页给出明确空态。
|
|
23
|
+
E9b:同一行增加「家具图鉴」入口(随业务有效显示,同样不预读房间接口);
|
|
24
|
+
新标签打开并保留本页,workspace 由 common.js 经 data-ws-link 补全。 -->
|
|
25
|
+
<p class="room-entry-line" id="roomEntryLine" hidden><a id="roomEntry" class="room-entry-link" href="/specdev-workbench/room">进入房间 ↗</a> <a id="furnitureEntry" class="room-entry-link" data-ws-link="/specdev-workbench/furniture" href="/specdev-workbench/furniture" target="_blank" rel="noopener">家具图鉴 ↗</a></p>
|
|
26
|
+
<!-- 第二期第 2 步:工作区模式显示"工作区:名称(路径)",手动配置模式注明(由 business.js 填充)。
|
|
27
|
+
长路径不再直接铺开行内断词,与首页一样折进可展开块(common.js renderRepoLine 填充)。 -->
|
|
28
|
+
<details class="workspace-details" id="workspaceDetails" hidden><summary id="workspaceLabel">工作区</summary><p id="repoLine"></p></details>
|
|
29
|
+
</div>
|
|
30
|
+
<p id="status" class="status" data-kind="info">正在读取业务…</p>
|
|
31
|
+
</header>
|
|
32
|
+
<p id="errorBox" class="error" hidden></p>
|
|
33
|
+
<div id="chartSummary" class="chart-summary chip-row" hidden></div>
|
|
34
|
+
<section id="guideBox" class="guide" hidden></section>
|
|
35
|
+
<section id="docs" class="panel" hidden>
|
|
36
|
+
<h2>业务文档</h2>
|
|
37
|
+
<ul id="docList" class="doc-list"></ul>
|
|
38
|
+
</section>
|
|
39
|
+
<main id="root" class="cards"></main>
|
|
40
|
+
</div>
|
|
41
|
+
<script type="module" src="/specdev-workbench/assets/business.js"></script>
|
|
42
|
+
</body>
|
|
43
|
+
</html>
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="zh-CN">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
|
+
<title>家具图鉴 · SpecDev 工作台</title>
|
|
7
|
+
<script src="/specdev-workbench/assets/theme.js"></script>
|
|
8
|
+
<link rel="stylesheet" href="/specdev-workbench/assets/style.css">
|
|
9
|
+
<!-- 图鉴页独立样式:只作用于 .furniture-page,复用全局主题变量,不改业务/房间页。 -->
|
|
10
|
+
<link rel="stylesheet" href="/specdev-workbench/assets/furniture-page.css">
|
|
11
|
+
</head>
|
|
12
|
+
<body class="furniture-page">
|
|
13
|
+
<header class="app-bar">
|
|
14
|
+
<a class="brand" data-home-link href="/specdev-workbench/" aria-label="SpecDev 项目首页"><span class="brand-mark" aria-hidden="true">S<span></span></span><span>SpecDev<span class="brand-caption">工作台</span></span></a>
|
|
15
|
+
<div class="theme-switch" role="group" aria-label="页面主题"><button type="button" data-theme-choice="light" aria-pressed="false"><span aria-hidden="true">☼</span> 浅色</button><button type="button" data-theme-choice="dark" aria-pressed="true"><span aria-hidden="true">☾</span> 深色</button></div>
|
|
16
|
+
</header>
|
|
17
|
+
<div class="page-content">
|
|
18
|
+
<header class="top">
|
|
19
|
+
<div>
|
|
20
|
+
<p class="crumbs"><a href="/specdev-workbench/">项目首页</a> / <span>家具图鉴</span></p>
|
|
21
|
+
<h1 id="title">家具图鉴</h1>
|
|
22
|
+
<!-- E9b:随包共用家具库的看图挑选页。不按业务过滤,也从这里推断不出任何业务。 -->
|
|
23
|
+
<p class="sub">本插件随包的全部家具都在这里:看图挑选喜欢的款式,复制清单回聊天,AI 按你的选择布置房间。各款风格只是搭配建议,可以混搭。</p>
|
|
24
|
+
<details class="workspace-details" id="workspaceDetails" hidden><summary id="workspaceLabel">工作区</summary><p id="repoLine"></p></details>
|
|
25
|
+
</div>
|
|
26
|
+
<p id="status" class="status" data-kind="info">正在加载家具目录…</p>
|
|
27
|
+
</header>
|
|
28
|
+
<p id="errorBox" class="error" role="alert" hidden></p>
|
|
29
|
+
<section id="guideBox" class="guide" hidden></section>
|
|
30
|
+
<!-- 选择工具条:勾选卡片上的复选框后来这里复制清单;未选择时按钮禁用。 -->
|
|
31
|
+
<section id="picker" class="picker-bar" hidden aria-label="选择与复制">
|
|
32
|
+
<p id="pickCount">已选 0 款</p>
|
|
33
|
+
<button id="copyButton" type="button" disabled>复制给 AI</button>
|
|
34
|
+
<button id="clearButton" type="button" disabled>清空选择</button>
|
|
35
|
+
</section>
|
|
36
|
+
<div id="pickListBox" class="pick-list-box" hidden>
|
|
37
|
+
<label class="pick-list-label" for="pickList">复制后粘贴到聊天发给 AI:</label>
|
|
38
|
+
<!-- 只读文本框:始终可手动全选复制,内容随勾选即时同步;未勾选时以占位文字提示(不虚构默认选择)。 -->
|
|
39
|
+
<textarea id="pickList" readonly rows="4" spellcheck="false" placeholder="勾选上方家具后,这里会出现可复制的挑选清单。"></textarea>
|
|
40
|
+
<p id="copyNote" class="copy-note" role="status" aria-live="polite" hidden></p>
|
|
41
|
+
</div>
|
|
42
|
+
<!-- 目录卡片按 index.json 分类动态填充(furniture-page.js);空态与错误态也渲染在这里。 -->
|
|
43
|
+
<main id="catalog" class="furniture-cards"></main>
|
|
44
|
+
</div>
|
|
45
|
+
<script type="module" src="/specdev-workbench/assets/furniture-page.js"></script>
|
|
46
|
+
</body>
|
|
47
|
+
</html>
|
package/web/index.html
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="zh-CN" data-theme="dark">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
|
+
<title>项目首页 · SpecDev 工作台</title>
|
|
7
|
+
<script src="/specdev-workbench/assets/theme.js"></script>
|
|
8
|
+
<link rel="stylesheet" href="/specdev-workbench/assets/style.css">
|
|
9
|
+
</head>
|
|
10
|
+
<body class="home-page">
|
|
11
|
+
<a class="skip-link" href="#main">跳到主要内容</a>
|
|
12
|
+
<header class="app-bar">
|
|
13
|
+
<a class="brand" data-home-link href="/specdev-workbench/" aria-label="SpecDev 项目首页"><span class="brand-mark" aria-hidden="true">S<span></span></span><span>SpecDev<span class="brand-caption">工作台</span></span></a>
|
|
14
|
+
<div class="theme-switch" role="group" aria-label="页面主题">
|
|
15
|
+
<button type="button" data-theme-choice="light" aria-pressed="false"><span aria-hidden="true">☼</span> 浅色</button>
|
|
16
|
+
<button type="button" data-theme-choice="dark" aria-pressed="true"><span aria-hidden="true">☾</span> 深色</button>
|
|
17
|
+
</div>
|
|
18
|
+
</header>
|
|
19
|
+
<main id="main" class="home-main">
|
|
20
|
+
<section class="project-hero" aria-labelledby="projectName">
|
|
21
|
+
<div class="hero-copy">
|
|
22
|
+
<p class="eyebrow"><span class="eyebrow-line"></span> 项目总览</p>
|
|
23
|
+
<h1 id="projectName">你的业务,<br>在这里清晰展开。</h1>
|
|
24
|
+
<p id="projectDesc" class="hero-description">从业务出发,阅读流程、理解实现,回看每一个版本。</p>
|
|
25
|
+
<div class="hero-actions" id="heroActions" hidden><a id="buildingLink" class="primary-link primary-link-lead" data-ws-link="/specdev-workbench/building" hidden>走进建筑 <span aria-hidden="true">↗</span></a><a href="#businesses" class="secondary-link">浏览业务</a><span class="hero-hint">从一张图,进入项目</span></div>
|
|
26
|
+
<details class="workspace-details" id="workspaceDetails" hidden><summary id="workspaceLabel">当前工作区</summary><p id="repoLine"></p></details>
|
|
27
|
+
</div>
|
|
28
|
+
<div class="hero-art" aria-hidden="true">
|
|
29
|
+
<div class="art-grid"></div>
|
|
30
|
+
<svg viewBox="0 0 480 340" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
31
|
+
<defs><linearGradient id="flowLine" x1="40" y1="0" x2="440" y2="340" gradientUnits="userSpaceOnUse"><stop stop-color="currentColor" stop-opacity=".15"/><stop offset=".5" stop-color="currentColor"/><stop offset="1" stop-color="currentColor" stop-opacity=".2"/></linearGradient></defs>
|
|
32
|
+
<g class="art-path" stroke="url(#flowLine)" stroke-width="1.5"><path d="M56 168H126Q144 168 144 150V98Q144 80 162 80H234"/><path d="M56 168H218"/><path d="M56 168H126Q144 168 144 186V252Q144 270 162 270H296"/><path d="M280 168H332Q350 168 350 150V98Q350 80 368 80H426"/><path d="M280 168H332Q350 168 350 186V252Q350 270 368 270H426"/><path d="M276 80H426"/></g>
|
|
33
|
+
<g class="art-ghost"><rect x="8" y="140" width="80" height="56" rx="14"/><rect x="234" y="57" width="58" height="46" rx="12"/><rect x="272" y="247" width="58" height="46" rx="12"/><rect x="408" y="65" width="30" height="30" rx="9"/><rect x="408" y="255" width="30" height="30" rx="9"/></g>
|
|
34
|
+
<rect class="art-node-halo" x="204" y="120" width="96" height="96" rx="27" transform="rotate(-8 252 168)"/>
|
|
35
|
+
<rect class="art-node" x="211" y="127" width="82" height="82" rx="22"/>
|
|
36
|
+
<g class="art-symbol" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="234" y="150" width="11" height="11" rx="3"/><rect x="259" y="175" width="11" height="11" rx="3"/><path d="M245 155H260Q264 155 264 159V175M239 161V177Q239 181 243 181H259"/></g>
|
|
37
|
+
<g class="art-dot" fill="currentColor"><circle cx="144" cy="168" r="4"/><circle cx="350" cy="168" r="4"/><circle cx="263" cy="80" r="3"/><circle cx="48" cy="168" r="3"/><circle cx="301" cy="270" r="3"/></g>
|
|
38
|
+
</svg>
|
|
39
|
+
<span class="art-caption">连接业务与实现</span>
|
|
40
|
+
</div>
|
|
41
|
+
</section>
|
|
42
|
+
<section id="projectMetrics" class="project-metrics" aria-label="项目概况" hidden>
|
|
43
|
+
<div><span class="metric-label">业务领域</span><strong id="businessCount">—</strong><span class="metric-unit">个业务入口</span></div>
|
|
44
|
+
<div><span class="metric-label">流程图</span><strong id="chartCount">—</strong><span class="metric-unit" id="chartCountNote">张登记的图</span></div>
|
|
45
|
+
<div class="metric-note"><span class="metric-label">阅读路径</span><p>业务 <span>→</span> 流程 <span>→</span> 实现</p><span class="metric-unit">让项目上下文有迹可循</span></div>
|
|
46
|
+
</section>
|
|
47
|
+
<section id="businesses" class="business-section" aria-labelledby="businessHeading">
|
|
48
|
+
<div class="section-heading"><div><p class="eyebrow">探索项目</p><h2 id="businessHeading">业务入口</h2></div><div class="heading-side"><a id="showcaseLink" class="showcase-link" href="/specdev-workbench/showcase" data-ws-link="/specdev-workbench/showcase" hidden>业务展示 ↗</a><p id="status" class="status" data-kind="info" role="status">正在读取项目清单…</p></div></div>
|
|
49
|
+
<p id="errorBox" class="error" role="alert" hidden></p>
|
|
50
|
+
<section id="guideBox" class="guide" hidden></section>
|
|
51
|
+
<div id="root" class="cards home-cards" aria-busy="true"><p class="loading-copy">正在整理业务入口…</p></div>
|
|
52
|
+
</section>
|
|
53
|
+
<footer class="home-footer"><span>SpecDev · 让业务逻辑清晰可读</span><span>业务 / 流程 / 版本</span></footer>
|
|
54
|
+
</main>
|
|
55
|
+
<script type="module" src="/specdev-workbench/assets/home.js"></script>
|
|
56
|
+
</body>
|
|
57
|
+
</html>
|
package/web/read.html
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="zh-CN">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
|
+
<title>图阅读 · SpecDev 工作台</title>
|
|
7
|
+
<script src="/specdev-workbench/assets/theme.js"></script>
|
|
8
|
+
<link rel="stylesheet" href="/specdev-workbench/assets/style.css">
|
|
9
|
+
<!-- 把渲染器用到的 node: 内置模块映射到随包替身(vendor/archify-renderer/stubs/)。
|
|
10
|
+
编译路径不该真调用它们;一旦被调用,替身抛错暴露。 -->
|
|
11
|
+
<script type="importmap">
|
|
12
|
+
{
|
|
13
|
+
"imports": {
|
|
14
|
+
"node:fs": "/specdev-workbench/vendor/stubs/fs.mjs",
|
|
15
|
+
"node:path": "/specdev-workbench/vendor/stubs/path.mjs",
|
|
16
|
+
"node:url": "/specdev-workbench/vendor/stubs/url.mjs",
|
|
17
|
+
"node:crypto": "/specdev-workbench/vendor/stubs/crypto.mjs",
|
|
18
|
+
"node:http": "/specdev-workbench/vendor/stubs/http.mjs",
|
|
19
|
+
"node:https": "/specdev-workbench/vendor/stubs/https.mjs",
|
|
20
|
+
"node:net": "/specdev-workbench/vendor/stubs/net.mjs",
|
|
21
|
+
"node:dns/promises": "/specdev-workbench/vendor/stubs/dns-promises.mjs",
|
|
22
|
+
"node:child_process": "/specdev-workbench/vendor/stubs/child_process.mjs"
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
</script>
|
|
26
|
+
</head>
|
|
27
|
+
<body class="read-page">
|
|
28
|
+
<header class="app-bar">
|
|
29
|
+
<a class="brand" data-home-link href="/specdev-workbench/" aria-label="SpecDev 项目首页"><span class="brand-mark" aria-hidden="true">S<span></span></span><span>SpecDev<span class="brand-caption">工作台</span></span></a>
|
|
30
|
+
<div class="theme-switch" role="group" aria-label="页面主题"><button type="button" data-theme-choice="light" aria-pressed="false"><span aria-hidden="true">☼</span> 浅色</button><button type="button" data-theme-choice="dark" aria-pressed="true"><span aria-hidden="true">☾</span> 深色</button></div>
|
|
31
|
+
</header>
|
|
32
|
+
<div class="page-content">
|
|
33
|
+
<header class="top">
|
|
34
|
+
<div>
|
|
35
|
+
<p class="crumbs"><a href="/specdev-workbench/">项目首页</a> / <a id="bizLink" href="/specdev-workbench/">业务</a> / <span id="chartName">…</span></p>
|
|
36
|
+
<h1 id="title">图阅读</h1>
|
|
37
|
+
<p class="sub" id="summary"></p>
|
|
38
|
+
<!-- 第二期第 2 步:工作区模式显示"工作区:名称(路径)",手动配置模式注明(由 read.js 填充)。
|
|
39
|
+
长路径不再直接铺开行内断词,与首页一样折进可展开块(common.js renderRepoLine 填充)。 -->
|
|
40
|
+
<details class="workspace-details" id="workspaceDetails" hidden><summary id="workspaceLabel">工作区</summary><p id="repoLine"></p></details>
|
|
41
|
+
</div>
|
|
42
|
+
<p id="status" class="status" data-kind="info">正在读取图…</p>
|
|
43
|
+
</header>
|
|
44
|
+
<p id="errorBox" class="error" hidden></p>
|
|
45
|
+
<section id="guideBox" class="guide" hidden></section>
|
|
46
|
+
<nav id="versions" class="versions"></nav>
|
|
47
|
+
<!-- 正看"当前(工作区)"时的登记信息行:看历史快照时这里说明图名与摘要的来处;由 read.js 填充。 -->
|
|
48
|
+
<p id="snapshotMeta" class="muted" hidden></p>
|
|
49
|
+
<!-- 「已选」状态条(E·选中同步+F·节点详情阅读):显示图里当前被原生选中的步骤,
|
|
50
|
+
并给一个「查看详情」入口;没有选中时整条隐藏,接不上增强阅读时在这里说明一句。 -->
|
|
51
|
+
<p id="selectionBar" class="selection-bar" hidden>
|
|
52
|
+
<span id="selectionText"></span>
|
|
53
|
+
<button id="detailOpen" class="detail-open" type="button" hidden>查看详情</button>
|
|
54
|
+
</p>
|
|
55
|
+
<div class="reader-tools"><span class="muted">双击节点查看详情,也可选中后点击“查看详情”</span><button id="materialsOpen" type="button" disabled>全部阅读资料</button></div>
|
|
56
|
+
<!-- 现场渲染挂载点:原生装配出的整页装在 iframe(独立小房间)里,样式自带。 -->
|
|
57
|
+
<main id="stage" class="chart-stage"></main>
|
|
58
|
+
</div>
|
|
59
|
+
<!-- 节点详情弹层(F):读某个步骤在当前所选版本里的说明正文。
|
|
60
|
+
关闭三方式:右上按钮 / ESC / 点框外空白;弹层不碰图,关闭后图的缩放与位置原样。 -->
|
|
61
|
+
<dialog id="detailDialog" class="detail-dialog" aria-label="节点详情与源码对照">
|
|
62
|
+
<div class="detail-dialog-head">
|
|
63
|
+
<span>节点详情</span>
|
|
64
|
+
<button autofocus id="detailClose" class="detail-close" type="button" aria-label="关闭详情">×</button>
|
|
65
|
+
</div>
|
|
66
|
+
<div id="detailContent" class="detail-dialog-body"></div>
|
|
67
|
+
<p id="detailSource" class="detail-source"></p>
|
|
68
|
+
</dialog>
|
|
69
|
+
<!-- 原底部资料移入按需打开的弹层,保留未配对资料与图渲染失败时的阅读入口。 -->
|
|
70
|
+
<dialog id="materialsDialog" class="detail-dialog materials-dialog" aria-label="全部阅读资料">
|
|
71
|
+
<div class="detail-dialog-head"><span>全部阅读资料 · 当前所选版本</span><button autofocus id="materialsClose" class="detail-close" type="button" aria-label="关闭阅读资料">×</button></div>
|
|
72
|
+
<div class="detail-dialog-body"><section id="detailsPanel" class="details-panel"></section><section id="evidencePanel" class="evidence-panel"><p>正在读取源码证据…</p></section></div>
|
|
73
|
+
</dialog>
|
|
74
|
+
<script type="module" src="/specdev-workbench/assets/read.js"></script>
|
|
75
|
+
<!-- 保存版本弹层(G):给"当前(工作区)"这一份内容登记一个带名称/阶段/说明的版本。
|
|
76
|
+
关闭三方式与节点详情弹层一致:右上按钮 / ESC / 点框外空白。
|
|
77
|
+
打开时先问一次"现在能不能存",并把服务端的内容摘要与页面正看的那一份对一下——
|
|
78
|
+
页面旧了就提示刷新并禁用保存,绝不把没确认过的内容存下来。 -->
|
|
79
|
+
<dialog id="saveDialog" class="save-dialog">
|
|
80
|
+
<div class="detail-dialog-head">
|
|
81
|
+
<span>保存版本</span>
|
|
82
|
+
<button id="saveClose" class="detail-close" type="button" aria-label="关闭保存">×</button>
|
|
83
|
+
</div>
|
|
84
|
+
<div class="save-dialog-body">
|
|
85
|
+
<p id="saveCheck" class="save-check"></p>
|
|
86
|
+
<label class="save-field">
|
|
87
|
+
<span class="save-label">版本名称</span>
|
|
88
|
+
<input id="saveName" type="text" maxlength="200" autocomplete="off" placeholder="例如:首版设计">
|
|
89
|
+
</label>
|
|
90
|
+
<fieldset class="save-field save-stages">
|
|
91
|
+
<legend class="save-label">阶段</legend>
|
|
92
|
+
<label><input type="radio" name="saveStage" value="design" checked> 设计版</label>
|
|
93
|
+
<label><input type="radio" name="saveStage" value="implemented"> 实现版</label>
|
|
94
|
+
</fieldset>
|
|
95
|
+
<label class="save-field">
|
|
96
|
+
<span class="save-label">保存说明(可以不填)</span>
|
|
97
|
+
<textarea id="saveNote" rows="3" maxlength="1000" placeholder="这一版存下来是为了什么,或者和别人约定了什么"></textarea>
|
|
98
|
+
</label>
|
|
99
|
+
<p id="saveError" class="save-error" hidden></p>
|
|
100
|
+
<div class="save-actions">
|
|
101
|
+
<button id="saveSubmit" class="save-submit" type="button" disabled>保存</button>
|
|
102
|
+
<button id="saveCancel" class="save-cancel" type="button">取消</button>
|
|
103
|
+
</div>
|
|
104
|
+
</div>
|
|
105
|
+
</dialog>
|
|
106
|
+
</body>
|
|
107
|
+
</html>
|