1229 lines
33 KiB
HTML
1229 lines
33 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="description" content="柏悦物流客户端栏目架构交互展示">
|
|||
|
|
<link rel="icon" href="data:,">
|
|||
|
|
<title>柏悦物流客户端栏目架构图</title>
|
|||
|
|
<!--
|
|||
|
|
THESIS: 把复杂栏目关系变成可逐层展开的业务地图,拒绝静态鱼骨图和拥挤流程图。
|
|||
|
|
OWN-WORLD: 明亮办公场景;纸白表面、深海蓝骨架、青绿节点、琥珀与珊瑚辅助分类,线条克制,节点紧凑。
|
|||
|
|
STORY: 读者先掌握八个一级栏目,再展开业务入口、页面模块、详情下钻和全局工具。
|
|||
|
|
FIRST VIEWPORT: 紧凑标题区接根节点与四列栏目地图;展开控制位于根节点右侧,不遮挡架构内容。
|
|||
|
|
FORM: 已批准方案第一位“总览图 + 交互式栏目卡片”;根节点驱动多列分支,方向由用户确认,无随机种子。
|
|||
|
|
-->
|
|||
|
|
<style>
|
|||
|
|
:root {
|
|||
|
|
color-scheme: light;
|
|||
|
|
--page: #eef3f3;
|
|||
|
|
--surface: #ffffff;
|
|||
|
|
--surface-soft: #f7f9f9;
|
|||
|
|
--ink: #18252d;
|
|||
|
|
--ink-soft: #50626c;
|
|||
|
|
--ink-faint: #6d7d84;
|
|||
|
|
--line: #d6e0e2;
|
|||
|
|
--line-strong: #b7c7cb;
|
|||
|
|
--deep: #143748;
|
|||
|
|
--deep-2: #0e2b38;
|
|||
|
|
--blue: #12658f;
|
|||
|
|
--blue-soft: #e8f3f8;
|
|||
|
|
--teal: #087d73;
|
|||
|
|
--teal-soft: #e7f4f1;
|
|||
|
|
--gold: #986513;
|
|||
|
|
--gold-soft: #fbf2df;
|
|||
|
|
--coral: #ad5746;
|
|||
|
|
--coral-soft: #f9ece8;
|
|||
|
|
--focus: #1f78b4;
|
|||
|
|
--shadow: 0 14px 34px rgba(17, 49, 62, 0.13);
|
|||
|
|
--radius: 8px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
* {
|
|||
|
|
box-sizing: border-box;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
html {
|
|||
|
|
scroll-behavior: smooth;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
body {
|
|||
|
|
margin: 0;
|
|||
|
|
min-width: 320px;
|
|||
|
|
background: var(--page);
|
|||
|
|
color: var(--ink);
|
|||
|
|
font-family: "Microsoft YaHei", "PingFang SC", "Noto Sans CJK SC", Arial, sans-serif;
|
|||
|
|
font-size: 15px;
|
|||
|
|
line-height: 1.6;
|
|||
|
|
letter-spacing: 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
button {
|
|||
|
|
font: inherit;
|
|||
|
|
letter-spacing: 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
button:focus-visible,
|
|||
|
|
summary:focus-visible {
|
|||
|
|
outline: 3px solid rgba(31, 120, 180, 0.35);
|
|||
|
|
outline-offset: 3px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.page-shell {
|
|||
|
|
width: min(1480px, 100%);
|
|||
|
|
margin: 0 auto;
|
|||
|
|
padding: 28px clamp(16px, 3vw, 44px) 56px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.masthead {
|
|||
|
|
position: relative;
|
|||
|
|
overflow: hidden;
|
|||
|
|
background: var(--deep);
|
|||
|
|
color: #ffffff;
|
|||
|
|
padding: clamp(24px, 4vw, 46px);
|
|||
|
|
border-radius: var(--radius);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.masthead::after {
|
|||
|
|
content: "";
|
|||
|
|
position: absolute;
|
|||
|
|
inset: auto 0 0;
|
|||
|
|
height: 5px;
|
|||
|
|
background: linear-gradient(90deg, var(--teal) 0 46%, #e2a83b 46% 68%, var(--coral) 68% 100%);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.brand-line {
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
gap: 12px;
|
|||
|
|
margin-bottom: 24px;
|
|||
|
|
color: #d6e7ec;
|
|||
|
|
font-weight: 600;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.brand-mark {
|
|||
|
|
display: inline-grid;
|
|||
|
|
place-items: center;
|
|||
|
|
width: 38px;
|
|||
|
|
height: 38px;
|
|||
|
|
background: #ffffff;
|
|||
|
|
color: var(--deep);
|
|||
|
|
border-radius: 6px;
|
|||
|
|
font-size: 14px;
|
|||
|
|
font-weight: 800;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.brand-divider {
|
|||
|
|
width: 1px;
|
|||
|
|
height: 18px;
|
|||
|
|
background: rgba(255, 255, 255, 0.35);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.masthead-layout {
|
|||
|
|
display: grid;
|
|||
|
|
grid-template-columns: minmax(0, 1fr) auto;
|
|||
|
|
gap: 32px;
|
|||
|
|
align-items: end;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
h1,
|
|||
|
|
h2,
|
|||
|
|
h3,
|
|||
|
|
p {
|
|||
|
|
margin-top: 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
h1 {
|
|||
|
|
max-width: 15ch;
|
|||
|
|
margin-bottom: 12px;
|
|||
|
|
font-size: clamp(32px, 5vw, 58px);
|
|||
|
|
line-height: 1.12;
|
|||
|
|
font-weight: 750;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.masthead-copy {
|
|||
|
|
max-width: 64ch;
|
|||
|
|
margin-bottom: 0;
|
|||
|
|
color: #d7e6ea;
|
|||
|
|
font-size: 16px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.summary-line {
|
|||
|
|
display: flex;
|
|||
|
|
flex-wrap: wrap;
|
|||
|
|
justify-content: flex-end;
|
|||
|
|
gap: 24px;
|
|||
|
|
margin: 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.summary-item {
|
|||
|
|
min-width: 92px;
|
|||
|
|
text-align: right;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.summary-item dt {
|
|||
|
|
color: #b9d0d7;
|
|||
|
|
font-size: 12px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.summary-item dd {
|
|||
|
|
margin: 2px 0 0;
|
|||
|
|
font-size: 28px;
|
|||
|
|
line-height: 1.2;
|
|||
|
|
font-weight: 750;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.architecture-section {
|
|||
|
|
margin-top: 22px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.root-node {
|
|||
|
|
position: relative;
|
|||
|
|
z-index: 2;
|
|||
|
|
display: grid;
|
|||
|
|
grid-template-columns: minmax(0, 1fr) auto;
|
|||
|
|
align-items: center;
|
|||
|
|
gap: 24px;
|
|||
|
|
padding: 20px 22px;
|
|||
|
|
background: var(--surface);
|
|||
|
|
box-shadow: var(--shadow);
|
|||
|
|
border-radius: var(--radius);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.root-title-row {
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
gap: 14px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.root-symbol {
|
|||
|
|
display: grid;
|
|||
|
|
place-items: center;
|
|||
|
|
flex: 0 0 auto;
|
|||
|
|
width: 44px;
|
|||
|
|
height: 44px;
|
|||
|
|
border-radius: 50%;
|
|||
|
|
background: var(--deep);
|
|||
|
|
color: #ffffff;
|
|||
|
|
font-weight: 750;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.root-node h2 {
|
|||
|
|
margin: 0;
|
|||
|
|
font-size: 20px;
|
|||
|
|
line-height: 1.3;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.root-node p {
|
|||
|
|
margin: 3px 0 0;
|
|||
|
|
color: var(--ink-soft);
|
|||
|
|
font-size: 13px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.toolbar {
|
|||
|
|
display: flex;
|
|||
|
|
flex-wrap: wrap;
|
|||
|
|
justify-content: flex-end;
|
|||
|
|
gap: 8px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.toolbar-button {
|
|||
|
|
display: inline-flex;
|
|||
|
|
align-items: center;
|
|||
|
|
justify-content: center;
|
|||
|
|
min-height: 40px;
|
|||
|
|
padding: 8px 14px;
|
|||
|
|
border: 1px solid var(--line-strong);
|
|||
|
|
border-radius: 6px;
|
|||
|
|
background: var(--surface);
|
|||
|
|
color: var(--ink);
|
|||
|
|
cursor: pointer;
|
|||
|
|
transition: background-color 160ms ease-out, border-color 160ms ease-out;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.toolbar-button:hover {
|
|||
|
|
border-color: var(--blue);
|
|||
|
|
background: var(--blue-soft);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.toolbar-button.primary {
|
|||
|
|
border-color: var(--deep);
|
|||
|
|
background: var(--deep);
|
|||
|
|
color: #ffffff;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.toolbar-button.primary:hover {
|
|||
|
|
border-color: var(--blue);
|
|||
|
|
background: var(--blue);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.architecture-map {
|
|||
|
|
position: relative;
|
|||
|
|
padding-top: 34px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.architecture-map::before {
|
|||
|
|
content: "";
|
|||
|
|
position: absolute;
|
|||
|
|
top: 0;
|
|||
|
|
left: 50%;
|
|||
|
|
width: 1px;
|
|||
|
|
height: 34px;
|
|||
|
|
background: var(--line-strong);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.map-guide {
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
gap: 12px;
|
|||
|
|
margin-bottom: 14px;
|
|||
|
|
color: var(--ink-faint);
|
|||
|
|
font-size: 12px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.map-guide::before,
|
|||
|
|
.map-guide::after {
|
|||
|
|
content: "";
|
|||
|
|
height: 1px;
|
|||
|
|
background: var(--line-strong);
|
|||
|
|
flex: 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.architecture-grid {
|
|||
|
|
display: grid;
|
|||
|
|
grid-template-columns: repeat(4, minmax(0, 1fr));
|
|||
|
|
gap: 18px;
|
|||
|
|
align-items: start;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.group-card {
|
|||
|
|
--accent: var(--blue);
|
|||
|
|
--accent-soft: var(--blue-soft);
|
|||
|
|
min-width: 0;
|
|||
|
|
overflow: hidden;
|
|||
|
|
background: var(--surface);
|
|||
|
|
border: 1px solid var(--line);
|
|||
|
|
border-radius: var(--radius);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.group-card[data-tone="teal"] {
|
|||
|
|
--accent: var(--teal);
|
|||
|
|
--accent-soft: var(--teal-soft);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.group-card[data-tone="gold"] {
|
|||
|
|
--accent: var(--gold);
|
|||
|
|
--accent-soft: var(--gold-soft);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.group-card[data-tone="coral"] {
|
|||
|
|
--accent: var(--coral);
|
|||
|
|
--accent-soft: var(--coral-soft);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.group-toggle {
|
|||
|
|
width: 100%;
|
|||
|
|
display: grid;
|
|||
|
|
grid-template-columns: auto minmax(0, 1fr) auto;
|
|||
|
|
gap: 12px;
|
|||
|
|
align-items: center;
|
|||
|
|
padding: 16px;
|
|||
|
|
border: 0;
|
|||
|
|
box-shadow: inset 0 3px 0 var(--accent);
|
|||
|
|
background: var(--surface);
|
|||
|
|
color: var(--ink);
|
|||
|
|
text-align: left;
|
|||
|
|
cursor: pointer;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.group-toggle:hover {
|
|||
|
|
background: var(--accent-soft);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.group-index {
|
|||
|
|
display: grid;
|
|||
|
|
place-items: center;
|
|||
|
|
width: 34px;
|
|||
|
|
height: 34px;
|
|||
|
|
border-radius: 50%;
|
|||
|
|
background: var(--accent-soft);
|
|||
|
|
color: var(--accent);
|
|||
|
|
font-size: 12px;
|
|||
|
|
font-weight: 750;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.group-title-wrap {
|
|||
|
|
min-width: 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.group-category {
|
|||
|
|
display: block;
|
|||
|
|
color: var(--accent);
|
|||
|
|
font-size: 11px;
|
|||
|
|
font-weight: 700;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.group-title {
|
|||
|
|
display: block;
|
|||
|
|
margin-top: 2px;
|
|||
|
|
font-size: 17px;
|
|||
|
|
font-weight: 750;
|
|||
|
|
overflow-wrap: anywhere;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.chevron {
|
|||
|
|
color: var(--accent);
|
|||
|
|
font-size: 18px;
|
|||
|
|
transform: rotate(180deg);
|
|||
|
|
transition: transform 180ms ease-out;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.group-toggle[aria-expanded="false"] .chevron {
|
|||
|
|
transform: rotate(0deg);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.group-intro {
|
|||
|
|
margin: 0;
|
|||
|
|
padding: 0 16px 14px;
|
|||
|
|
color: var(--ink-soft);
|
|||
|
|
font-size: 13px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.group-details {
|
|||
|
|
padding: 0 16px 16px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.group-details[hidden] {
|
|||
|
|
display: none;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.branch-list,
|
|||
|
|
.branch-children,
|
|||
|
|
.utility-list,
|
|||
|
|
.legend-list,
|
|||
|
|
.conclusion-list {
|
|||
|
|
margin: 0;
|
|||
|
|
padding: 0;
|
|||
|
|
list-style: none;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.branch-list {
|
|||
|
|
border-top: 1px solid var(--line);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.branch-item {
|
|||
|
|
position: relative;
|
|||
|
|
padding: 10px 0 10px 18px;
|
|||
|
|
border-bottom: 1px solid var(--line);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.branch-item:last-child {
|
|||
|
|
border-bottom: 0;
|
|||
|
|
padding-bottom: 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.branch-item::before {
|
|||
|
|
content: "";
|
|||
|
|
position: absolute;
|
|||
|
|
top: 19px;
|
|||
|
|
left: 2px;
|
|||
|
|
width: 7px;
|
|||
|
|
height: 7px;
|
|||
|
|
border-radius: 50%;
|
|||
|
|
background: var(--accent);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.branch-line {
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
justify-content: space-between;
|
|||
|
|
gap: 8px;
|
|||
|
|
min-width: 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.branch-title {
|
|||
|
|
min-width: 0;
|
|||
|
|
font-size: 13px;
|
|||
|
|
font-weight: 650;
|
|||
|
|
overflow-wrap: anywhere;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.node-badge {
|
|||
|
|
flex: 0 0 auto;
|
|||
|
|
padding: 2px 6px;
|
|||
|
|
border-radius: 4px;
|
|||
|
|
background: var(--accent-soft);
|
|||
|
|
color: var(--accent);
|
|||
|
|
font-size: 10px;
|
|||
|
|
font-weight: 700;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
details.branch > summary {
|
|||
|
|
list-style: none;
|
|||
|
|
cursor: pointer;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
details.branch > summary::-webkit-details-marker {
|
|||
|
|
display: none;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.branch-summary::after {
|
|||
|
|
content: "+";
|
|||
|
|
flex: 0 0 auto;
|
|||
|
|
color: var(--accent);
|
|||
|
|
font-weight: 700;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
details[open] > .branch-summary::after {
|
|||
|
|
content: "−";
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.branch-children {
|
|||
|
|
display: grid;
|
|||
|
|
gap: 6px;
|
|||
|
|
margin-top: 9px;
|
|||
|
|
padding-left: 10px;
|
|||
|
|
border-left: 1px solid var(--line-strong);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.branch-children .branch-item {
|
|||
|
|
padding: 5px 0 5px 14px;
|
|||
|
|
border-bottom: 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.branch-children .branch-item::before {
|
|||
|
|
top: 13px;
|
|||
|
|
left: 0;
|
|||
|
|
width: 5px;
|
|||
|
|
height: 5px;
|
|||
|
|
background: var(--line-strong);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.branch-children .branch-title {
|
|||
|
|
color: var(--ink-soft);
|
|||
|
|
font-size: 12px;
|
|||
|
|
font-weight: 550;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.support-strip {
|
|||
|
|
display: grid;
|
|||
|
|
grid-template-columns: minmax(220px, 0.75fr) minmax(0, 2fr);
|
|||
|
|
gap: 24px;
|
|||
|
|
margin-top: 18px;
|
|||
|
|
padding: 20px 22px;
|
|||
|
|
background: var(--deep-2);
|
|||
|
|
color: #ffffff;
|
|||
|
|
border-radius: var(--radius);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.support-strip h2 {
|
|||
|
|
margin-bottom: 5px;
|
|||
|
|
font-size: 18px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.support-strip p {
|
|||
|
|
margin-bottom: 0;
|
|||
|
|
color: #c5d8df;
|
|||
|
|
font-size: 13px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.utility-list {
|
|||
|
|
display: grid;
|
|||
|
|
grid-template-columns: repeat(4, minmax(0, 1fr));
|
|||
|
|
gap: 8px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.utility-item {
|
|||
|
|
display: flex;
|
|||
|
|
align-items: center;
|
|||
|
|
gap: 9px;
|
|||
|
|
min-width: 0;
|
|||
|
|
padding: 10px 12px;
|
|||
|
|
background: rgba(255, 255, 255, 0.08);
|
|||
|
|
border-radius: 6px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.utility-marker {
|
|||
|
|
width: 8px;
|
|||
|
|
height: 8px;
|
|||
|
|
flex: 0 0 auto;
|
|||
|
|
border-radius: 50%;
|
|||
|
|
background: #e3ad45;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.utility-title {
|
|||
|
|
overflow-wrap: anywhere;
|
|||
|
|
font-size: 13px;
|
|||
|
|
font-weight: 650;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.reading-section {
|
|||
|
|
display: grid;
|
|||
|
|
grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr);
|
|||
|
|
gap: 18px;
|
|||
|
|
margin-top: 28px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.reading-block {
|
|||
|
|
padding-top: 20px;
|
|||
|
|
border-top: 1px solid var(--line-strong);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.section-heading {
|
|||
|
|
margin-bottom: 14px;
|
|||
|
|
font-size: 20px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.legend-list {
|
|||
|
|
display: grid;
|
|||
|
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|||
|
|
gap: 14px 22px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.legend-item {
|
|||
|
|
display: grid;
|
|||
|
|
grid-template-columns: auto minmax(0, 1fr);
|
|||
|
|
gap: 10px;
|
|||
|
|
align-items: start;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.legend-marker {
|
|||
|
|
display: grid;
|
|||
|
|
place-items: center;
|
|||
|
|
min-width: 32px;
|
|||
|
|
height: 24px;
|
|||
|
|
padding: 0 7px;
|
|||
|
|
border-radius: 4px;
|
|||
|
|
background: var(--blue-soft);
|
|||
|
|
color: var(--blue);
|
|||
|
|
font-size: 10px;
|
|||
|
|
font-weight: 750;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.legend-item h3 {
|
|||
|
|
margin: 0 0 2px;
|
|||
|
|
font-size: 13px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.legend-item p {
|
|||
|
|
margin: 0;
|
|||
|
|
color: var(--ink-soft);
|
|||
|
|
font-size: 12px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.conclusion-list {
|
|||
|
|
display: grid;
|
|||
|
|
gap: 10px;
|
|||
|
|
counter-reset: conclusion;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.conclusion-list li {
|
|||
|
|
position: relative;
|
|||
|
|
padding-left: 32px;
|
|||
|
|
color: var(--ink-soft);
|
|||
|
|
font-size: 13px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.conclusion-list li::before {
|
|||
|
|
counter-increment: conclusion;
|
|||
|
|
content: counter(conclusion);
|
|||
|
|
position: absolute;
|
|||
|
|
left: 0;
|
|||
|
|
top: 0;
|
|||
|
|
display: grid;
|
|||
|
|
place-items: center;
|
|||
|
|
width: 22px;
|
|||
|
|
height: 22px;
|
|||
|
|
border-radius: 50%;
|
|||
|
|
background: var(--teal-soft);
|
|||
|
|
color: var(--teal);
|
|||
|
|
font-size: 11px;
|
|||
|
|
font-weight: 750;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.page-footer {
|
|||
|
|
display: flex;
|
|||
|
|
justify-content: space-between;
|
|||
|
|
gap: 18px;
|
|||
|
|
margin-top: 34px;
|
|||
|
|
padding-top: 18px;
|
|||
|
|
border-top: 1px solid var(--line-strong);
|
|||
|
|
color: var(--ink-faint);
|
|||
|
|
font-size: 12px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.sr-only {
|
|||
|
|
position: absolute;
|
|||
|
|
width: 1px;
|
|||
|
|
height: 1px;
|
|||
|
|
padding: 0;
|
|||
|
|
margin: -1px;
|
|||
|
|
overflow: hidden;
|
|||
|
|
clip: rect(0, 0, 0, 0);
|
|||
|
|
white-space: nowrap;
|
|||
|
|
border: 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
@media (max-width: 1120px) {
|
|||
|
|
.architecture-grid {
|
|||
|
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.utility-list {
|
|||
|
|
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
@media (max-width: 720px) {
|
|||
|
|
.page-shell {
|
|||
|
|
padding: 12px 12px 36px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.masthead {
|
|||
|
|
padding: 22px 18px 26px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.brand-line {
|
|||
|
|
margin-bottom: 18px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.masthead-layout,
|
|||
|
|
.root-node,
|
|||
|
|
.support-strip,
|
|||
|
|
.reading-section {
|
|||
|
|
grid-template-columns: 1fr;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
h1 {
|
|||
|
|
max-width: none;
|
|||
|
|
font-size: 34px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.summary-line {
|
|||
|
|
justify-content: flex-start;
|
|||
|
|
gap: 18px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.summary-item {
|
|||
|
|
min-width: 76px;
|
|||
|
|
text-align: left;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.summary-item dd {
|
|||
|
|
font-size: 23px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.root-node {
|
|||
|
|
gap: 16px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.toolbar {
|
|||
|
|
justify-content: stretch;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.toolbar-button {
|
|||
|
|
flex: 1 1 140px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.architecture-map {
|
|||
|
|
padding-top: 20px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.architecture-map::before,
|
|||
|
|
.map-guide {
|
|||
|
|
display: none;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.architecture-grid,
|
|||
|
|
.utility-list,
|
|||
|
|
.legend-list {
|
|||
|
|
grid-template-columns: 1fr;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.support-strip {
|
|||
|
|
gap: 16px;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.page-footer {
|
|||
|
|
flex-direction: column;
|
|||
|
|
gap: 5px;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
@media (prefers-reduced-motion: reduce) {
|
|||
|
|
html {
|
|||
|
|
scroll-behavior: auto;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
*,
|
|||
|
|
*::before,
|
|||
|
|
*::after {
|
|||
|
|
transition-duration: 0.01ms !important;
|
|||
|
|
animation-duration: 0.01ms !important;
|
|||
|
|
animation-iteration-count: 1 !important;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
@media print {
|
|||
|
|
body {
|
|||
|
|
background: #ffffff;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.page-shell {
|
|||
|
|
width: 100%;
|
|||
|
|
padding: 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.masthead {
|
|||
|
|
background: var(--deep);
|
|||
|
|
-webkit-print-color-adjust: exact;
|
|||
|
|
print-color-adjust: exact;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
.toolbar {
|
|||
|
|
display: none;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
</style>
|
|||
|
|
</head>
|
|||
|
|
<body>
|
|||
|
|
<div class="page-shell">
|
|||
|
|
<header class="masthead">
|
|||
|
|
<div class="brand-line">
|
|||
|
|
<span class="brand-mark" aria-hidden="true">BY</span>
|
|||
|
|
<span>柏悦物流</span>
|
|||
|
|
<span class="brand-divider" aria-hidden="true"></span>
|
|||
|
|
<span>信息架构</span>
|
|||
|
|
</div>
|
|||
|
|
<div class="masthead-layout">
|
|||
|
|
<div>
|
|||
|
|
<h1>客户端栏目架构图</h1>
|
|||
|
|
<p class="masthead-copy">从业务入口到页面模块,统一呈现下单、海外仓、订单、财务与账户体系。</p>
|
|||
|
|
</div>
|
|||
|
|
<dl class="summary-line" aria-label="架构摘要">
|
|||
|
|
<div class="summary-item">
|
|||
|
|
<dt>一级栏目</dt>
|
|||
|
|
<dd>8</dd>
|
|||
|
|
</div>
|
|||
|
|
<div class="summary-item">
|
|||
|
|
<dt>业务入口</dt>
|
|||
|
|
<dd>14</dd>
|
|||
|
|
</div>
|
|||
|
|
<div class="summary-item">
|
|||
|
|
<dt>业务分组</dt>
|
|||
|
|
<dd>5</dd>
|
|||
|
|
</div>
|
|||
|
|
</dl>
|
|||
|
|
</div>
|
|||
|
|
</header>
|
|||
|
|
|
|||
|
|
<main>
|
|||
|
|
<section class="architecture-section" aria-labelledby="architecture-title">
|
|||
|
|
<div class="root-node">
|
|||
|
|
<div class="root-title-row">
|
|||
|
|
<span class="root-symbol" aria-hidden="true">根</span>
|
|||
|
|
<div>
|
|||
|
|
<h2 id="architecture-title">柏悦物流客户端</h2>
|
|||
|
|
<p>一级栏目按现有侧边栏顺序排列;点击栏目或页面节点查看完整层级。</p>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
<div class="toolbar" aria-label="架构图控制">
|
|||
|
|
<button class="toolbar-button primary" id="expand-all" type="button">+ 全部展开</button>
|
|||
|
|
<button class="toolbar-button" id="collapse-all" type="button">− 全部收起</button>
|
|||
|
|
</div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="architecture-map">
|
|||
|
|
<div class="map-guide" aria-hidden="true">八个一级栏目</div>
|
|||
|
|
<div class="architecture-grid" id="architecture-grid"></div>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="support-strip" aria-labelledby="utilities-title">
|
|||
|
|
<div>
|
|||
|
|
<h2 id="utilities-title">全局工具</h2>
|
|||
|
|
<p>跨栏目使用的系统级操作,不计入主业务栏目。</p>
|
|||
|
|
</div>
|
|||
|
|
<ul class="utility-list" id="utility-list"></ul>
|
|||
|
|
</div>
|
|||
|
|
</section>
|
|||
|
|
|
|||
|
|
<section class="reading-section" aria-label="架构图说明">
|
|||
|
|
<div class="reading-block">
|
|||
|
|
<h2 class="section-heading" id="legend-title">层级说明</h2>
|
|||
|
|
<ul class="legend-list" aria-labelledby="legend-title">
|
|||
|
|
<li class="legend-item">
|
|||
|
|
<span class="legend-marker">一级</span>
|
|||
|
|
<div><h3>栏目或分组</h3><p>侧边栏直接入口或可展开的业务分组。</p></div>
|
|||
|
|
</li>
|
|||
|
|
<li class="legend-item">
|
|||
|
|
<span class="legend-marker">二级</span>
|
|||
|
|
<div><h3>业务入口</h3><p>从业务分组进入的独立页面。</p></div>
|
|||
|
|
</li>
|
|||
|
|
<li class="legend-item">
|
|||
|
|
<span class="legend-marker">模块</span>
|
|||
|
|
<div><h3>页面模块</h3><p>页面内标签或业务区块,不占用侧边栏。</p></div>
|
|||
|
|
</li>
|
|||
|
|
<li class="legend-item">
|
|||
|
|
<span class="legend-marker">详情</span>
|
|||
|
|
<div><h3>下钻页面</h3><p>从列表或账户模块进入的详细内容。</p></div>
|
|||
|
|
</li>
|
|||
|
|
</ul>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<div class="reading-block">
|
|||
|
|
<h2 class="section-heading">统计口径</h2>
|
|||
|
|
<ol class="conclusion-list">
|
|||
|
|
<li>业务总览的三个快捷入口复用“出海下单”页面,不重复计算。</li>
|
|||
|
|
<li>公司信息和我的信息为一级直达页,内部标签归为页面模块。</li>
|
|||
|
|
<li>账单明细、余额明细属于详情下钻,全局工具不计入主栏目。</li>
|
|||
|
|
</ol>
|
|||
|
|
</div>
|
|||
|
|
</section>
|
|||
|
|
</main>
|
|||
|
|
|
|||
|
|
<footer class="page-footer">
|
|||
|
|
<span>整理日期:2026-08-10</span>
|
|||
|
|
<span>依据:柏悦物流客户端栏目架构及现有工作台原型</span>
|
|||
|
|
</footer>
|
|||
|
|
<p class="sr-only" id="interaction-status" aria-live="polite"></p>
|
|||
|
|
</div>
|
|||
|
|
|
|||
|
|
<script id="architecture-data" type="application/json">
|
|||
|
|
{
|
|||
|
|
"title": "柏悦物流客户端",
|
|||
|
|
"groups": [
|
|||
|
|
{
|
|||
|
|
"id": "overview",
|
|||
|
|
"title": "业务总览",
|
|||
|
|
"category": "首页入口",
|
|||
|
|
"description": "核心业务捷径、账户状态与服务支持的统一起点。",
|
|||
|
|
"tone": "blue",
|
|||
|
|
"children": [
|
|||
|
|
{
|
|||
|
|
"title": "快捷下单",
|
|||
|
|
"kind": "入口组",
|
|||
|
|
"children": [
|
|||
|
|
{ "title": "海外采购", "kind": "复用", "reuse": true },
|
|||
|
|
{ "title": "美国本土卡", "kind": "复用", "reuse": true },
|
|||
|
|
{ "title": "美本土散板", "kind": "复用", "reuse": true }
|
|||
|
|
]
|
|||
|
|
},
|
|||
|
|
{ "title": "账户信息", "kind": "模块" },
|
|||
|
|
{
|
|||
|
|
"title": "数据概览",
|
|||
|
|
"kind": "模块",
|
|||
|
|
"children": [
|
|||
|
|
{ "title": "进行中订单", "kind": "指标" },
|
|||
|
|
{ "title": "已完成订单", "kind": "指标" },
|
|||
|
|
{ "title": "本月下单", "kind": "指标" }
|
|||
|
|
]
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"title": "帮助与支持",
|
|||
|
|
"kind": "模块",
|
|||
|
|
"children": [
|
|||
|
|
{ "title": "联系客服", "kind": "操作" },
|
|||
|
|
{ "title": "常见问题", "kind": "操作" },
|
|||
|
|
{ "title": "获取报价", "kind": "操作" }
|
|||
|
|
]
|
|||
|
|
}
|
|||
|
|
]
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"id": "first-mile",
|
|||
|
|
"title": "头程物流",
|
|||
|
|
"category": "业务分组",
|
|||
|
|
"description": "覆盖标准下单、批量导入与简化信息快速下单。",
|
|||
|
|
"tone": "teal",
|
|||
|
|
"children": [
|
|||
|
|
{
|
|||
|
|
"title": "头程下单",
|
|||
|
|
"kind": "二级入口",
|
|||
|
|
"businessEntry": true,
|
|||
|
|
"children": [
|
|||
|
|
{
|
|||
|
|
"title": "取货方式",
|
|||
|
|
"kind": "模块",
|
|||
|
|
"children": [
|
|||
|
|
{ "title": "自送货-快递", "kind": "选项" },
|
|||
|
|
{ "title": "我司提货", "kind": "选项" },
|
|||
|
|
{ "title": "自送货-卡车", "kind": "选项" }
|
|||
|
|
]
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"title": "目的地信息",
|
|||
|
|
"kind": "模块",
|
|||
|
|
"children": [
|
|||
|
|
{ "title": "FBA仓", "kind": "选项" },
|
|||
|
|
{ "title": "海外仓", "kind": "选项" },
|
|||
|
|
{ "title": "私人仓", "kind": "选项" }
|
|||
|
|
]
|
|||
|
|
},
|
|||
|
|
{ "title": "货物明细", "kind": "模块" },
|
|||
|
|
{ "title": "费用预估", "kind": "模块" }
|
|||
|
|
]
|
|||
|
|
},
|
|||
|
|
{ "title": "一键导入", "kind": "二级入口", "businessEntry": true },
|
|||
|
|
{ "title": "快速下单", "kind": "二级入口", "businessEntry": true }
|
|||
|
|
]
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"id": "overseas-order",
|
|||
|
|
"title": "出海下单",
|
|||
|
|
"category": "业务分组",
|
|||
|
|
"description": "海外采购与美国本土运输服务的下单入口。",
|
|||
|
|
"tone": "gold",
|
|||
|
|
"children": [
|
|||
|
|
{ "title": "海外采购", "kind": "二级入口", "businessEntry": true },
|
|||
|
|
{ "title": "美国本土卡", "kind": "二级入口", "businessEntry": true },
|
|||
|
|
{ "title": "美本土散板", "kind": "二级入口", "businessEntry": true }
|
|||
|
|
]
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"id": "warehouse",
|
|||
|
|
"title": "海外仓",
|
|||
|
|
"category": "业务分组",
|
|||
|
|
"description": "覆盖贴标、仓储转运、货物废弃以及退货换标业务。",
|
|||
|
|
"tone": "coral",
|
|||
|
|
"children": [
|
|||
|
|
{ "title": "贴标申请", "kind": "二级入口", "businessEntry": true },
|
|||
|
|
{
|
|||
|
|
"title": "仓储转运单",
|
|||
|
|
"kind": "二级入口",
|
|||
|
|
"businessEntry": true,
|
|||
|
|
"children": [
|
|||
|
|
{ "title": "新增订单", "kind": "模块" },
|
|||
|
|
{ "title": "查询订单", "kind": "模块" },
|
|||
|
|
{ "title": "订单列表", "kind": "模块" },
|
|||
|
|
{ "title": "后台海外仓-尾程订单", "kind": "联动", "integration": true, "relation": "提交后联动" },
|
|||
|
|
{ "title": "后台海外仓-换标单", "kind": "联动", "integration": true, "relation": "选择换标时联动" }
|
|||
|
|
]
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"title": "货物废弃",
|
|||
|
|
"kind": "二级入口",
|
|||
|
|
"businessEntry": true,
|
|||
|
|
"children": [
|
|||
|
|
{ "title": "新增订单", "kind": "模块" },
|
|||
|
|
{ "title": "查询订单", "kind": "模块" },
|
|||
|
|
{ "title": "订单列表", "kind": "模块" },
|
|||
|
|
{ "title": "相关入库单", "kind": "关联", "integration": true, "relation": "选择一张入库单" },
|
|||
|
|
{ "title": "后台尾程单", "kind": "联动", "integration": true, "relation": "提交后联动" },
|
|||
|
|
{ "title": "后台出库单-废弃", "kind": "联动", "integration": true, "relation": "提交后联动" },
|
|||
|
|
{ "title": "后台计费-弃货费", "kind": "联动", "integration": true, "relation": "5 USD/箱" }
|
|||
|
|
]
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"title": "退货换标",
|
|||
|
|
"kind": "二级入口",
|
|||
|
|
"businessEntry": true,
|
|||
|
|
"children": [
|
|||
|
|
{ "title": "新增订单", "kind": "模块" },
|
|||
|
|
{ "title": "查询订单", "kind": "模块" },
|
|||
|
|
{ "title": "订单列表", "kind": "模块" },
|
|||
|
|
{ "title": "后台海外仓-尾程订单", "kind": "联动", "integration": true, "relation": "提交后联动" },
|
|||
|
|
{ "title": "后台海外仓-换标单", "kind": "联动", "integration": true, "relation": "选择换标时联动" }
|
|||
|
|
]
|
|||
|
|
}
|
|||
|
|
]
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"id": "orders",
|
|||
|
|
"title": "订单管理",
|
|||
|
|
"category": "管理分组",
|
|||
|
|
"description": "集中查询入库与派送订单,承接下单后的业务跟踪。",
|
|||
|
|
"tone": "blue",
|
|||
|
|
"children": [
|
|||
|
|
{ "title": "入库订单列表", "kind": "二级入口", "businessEntry": true },
|
|||
|
|
{ "title": "派送订单列表", "kind": "二级入口", "businessEntry": true }
|
|||
|
|
]
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"id": "finance",
|
|||
|
|
"title": "财务结算",
|
|||
|
|
"category": "管理分组",
|
|||
|
|
"description": "查看应付账单,并从列表进入单笔账单明细。",
|
|||
|
|
"tone": "teal",
|
|||
|
|
"children": [
|
|||
|
|
{
|
|||
|
|
"title": "应付账单",
|
|||
|
|
"kind": "二级入口",
|
|||
|
|
"businessEntry": true,
|
|||
|
|
"children": [
|
|||
|
|
{ "title": "账单明细", "kind": "详情", "detail": true }
|
|||
|
|
]
|
|||
|
|
}
|
|||
|
|
]
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"id": "company",
|
|||
|
|
"title": "公司信息",
|
|||
|
|
"category": "一级直达页",
|
|||
|
|
"description": "维护企业主体、联系信息与业务资质文件。",
|
|||
|
|
"tone": "gold",
|
|||
|
|
"children": [
|
|||
|
|
{ "title": "企业基本信息", "kind": "页面标签" },
|
|||
|
|
{ "title": "联系信息", "kind": "页面标签" },
|
|||
|
|
{ "title": "资质文件", "kind": "页面标签" }
|
|||
|
|
]
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"id": "profile",
|
|||
|
|
"title": "我的信息",
|
|||
|
|
"category": "一级直达页",
|
|||
|
|
"description": "管理账户余额、个人资料和登录密码。",
|
|||
|
|
"tone": "coral",
|
|||
|
|
"children": [
|
|||
|
|
{
|
|||
|
|
"title": "账户余额",
|
|||
|
|
"kind": "模块",
|
|||
|
|
"children": [
|
|||
|
|
{ "title": "充值", "kind": "操作", "operation": true },
|
|||
|
|
{ "title": "余额明细", "kind": "详情", "detail": true }
|
|||
|
|
]
|
|||
|
|
},
|
|||
|
|
{ "title": "基本信息", "kind": "页面标签" },
|
|||
|
|
{ "title": "修改密码", "kind": "页面标签" }
|
|||
|
|
]
|
|||
|
|
}
|
|||
|
|
],
|
|||
|
|
"utilities": [
|
|||
|
|
{ "title": "多语言", "description": "中 / EN / ES" },
|
|||
|
|
{ "title": "充值", "description": "账户资金操作" },
|
|||
|
|
{ "title": "返回官网", "description": "跨站导航" },
|
|||
|
|
{ "title": "退出登录", "description": "会话操作" }
|
|||
|
|
]
|
|||
|
|
}
|
|||
|
|
</script>
|
|||
|
|
|
|||
|
|
<script>
|
|||
|
|
(() => {
|
|||
|
|
'use strict';
|
|||
|
|
|
|||
|
|
const dataElement = document.getElementById('architecture-data');
|
|||
|
|
const architectureData = JSON.parse(dataElement.textContent);
|
|||
|
|
const grid = document.getElementById('architecture-grid');
|
|||
|
|
const utilityList = document.getElementById('utility-list');
|
|||
|
|
const interactionStatus = document.getElementById('interaction-status');
|
|||
|
|
|
|||
|
|
const businessEntryCount = architectureData.groups
|
|||
|
|
.flatMap((group) => group.children)
|
|||
|
|
.filter((child) => child.businessEntry).length;
|
|||
|
|
|
|||
|
|
if (architectureData.groups.length !== 8) {
|
|||
|
|
throw new Error('栏目数据错误:一级栏目必须为 8 个。');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (businessEntryCount !== 13) {
|
|||
|
|
throw new Error('栏目数据错误:二级业务入口必须为 13 个。');
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function createElement(tagName, className, text) {
|
|||
|
|
const element = document.createElement(tagName);
|
|||
|
|
if (className) element.className = className;
|
|||
|
|
if (text !== undefined) element.textContent = text;
|
|||
|
|
return element;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function badgeText(item) {
|
|||
|
|
if (item.reuse) return '复用';
|
|||
|
|
if (item.detail) return '详情';
|
|||
|
|
if (item.operation) return '操作';
|
|||
|
|
if (item.integration) return item.relation || '联动';
|
|||
|
|
return item.kind || '';
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function createBranchItem(item) {
|
|||
|
|
const listItem = createElement('li', 'branch-item');
|
|||
|
|
const hasChildren = Array.isArray(item.children) && item.children.length > 0;
|
|||
|
|
const line = createElement(hasChildren ? 'summary' : 'div', hasChildren ? 'branch-line branch-summary' : 'branch-line');
|
|||
|
|
line.append(createElement('span', 'branch-title', item.title));
|
|||
|
|
|
|||
|
|
const label = badgeText(item);
|
|||
|
|
if (label) line.append(createElement('span', 'node-badge', label));
|
|||
|
|
|
|||
|
|
if (!hasChildren) {
|
|||
|
|
listItem.append(line);
|
|||
|
|
return listItem;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const details = createElement('details', 'branch');
|
|||
|
|
details.append(line);
|
|||
|
|
const childList = createElement('ul', 'branch-children');
|
|||
|
|
item.children.forEach((child) => childList.append(createBranchItem(child)));
|
|||
|
|
details.append(childList);
|
|||
|
|
listItem.append(details);
|
|||
|
|
return listItem;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function createGroupCard(group, index) {
|
|||
|
|
const card = createElement('article', 'group-card');
|
|||
|
|
card.dataset.group = group.id;
|
|||
|
|
card.dataset.tone = group.tone;
|
|||
|
|
|
|||
|
|
const detailId = `group-details-${group.id}`;
|
|||
|
|
const toggle = createElement('button', 'group-toggle');
|
|||
|
|
toggle.type = 'button';
|
|||
|
|
toggle.setAttribute('aria-expanded', 'true');
|
|||
|
|
toggle.setAttribute('aria-controls', detailId);
|
|||
|
|
toggle.setAttribute('aria-label', `收起${group.title}`);
|
|||
|
|
|
|||
|
|
toggle.append(createElement('span', 'group-index', String(index + 1).padStart(2, '0')));
|
|||
|
|
const titleWrap = createElement('span', 'group-title-wrap');
|
|||
|
|
titleWrap.append(createElement('span', 'group-category', group.category));
|
|||
|
|
titleWrap.append(createElement('span', 'group-title', group.title));
|
|||
|
|
toggle.append(titleWrap);
|
|||
|
|
toggle.append(createElement('span', 'chevron', '⌃'));
|
|||
|
|
|
|||
|
|
const intro = createElement('p', 'group-intro', group.description);
|
|||
|
|
const details = createElement('div', 'group-details');
|
|||
|
|
details.id = detailId;
|
|||
|
|
const list = createElement('ul', 'branch-list');
|
|||
|
|
group.children.forEach((child) => list.append(createBranchItem(child)));
|
|||
|
|
details.append(list);
|
|||
|
|
|
|||
|
|
toggle.addEventListener('click', () => {
|
|||
|
|
const expanded = toggle.getAttribute('aria-expanded') === 'true';
|
|||
|
|
setGroupExpanded(card, !expanded);
|
|||
|
|
interactionStatus.textContent = `${group.title}已${expanded ? '收起' : '展开'}`;
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
card.append(toggle, intro, details);
|
|||
|
|
return card;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function setGroupExpanded(card, expanded) {
|
|||
|
|
const toggle = card.querySelector('.group-toggle');
|
|||
|
|
const details = card.querySelector('.group-details');
|
|||
|
|
toggle.setAttribute('aria-expanded', String(expanded));
|
|||
|
|
toggle.setAttribute('aria-label', `${expanded ? '收起' : '展开'}${card.querySelector('.group-title').textContent}`);
|
|||
|
|
details.hidden = !expanded;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function setAllExpanded(expanded) {
|
|||
|
|
document.querySelectorAll('.group-card').forEach((card) => setGroupExpanded(card, expanded));
|
|||
|
|
document.querySelectorAll('details.branch').forEach((details) => {
|
|||
|
|
details.open = expanded;
|
|||
|
|
});
|
|||
|
|
interactionStatus.textContent = expanded ? '已展开全部栏目层级' : '已收起全部栏目层级';
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
architectureData.groups.forEach((group, index) => grid.append(createGroupCard(group, index)));
|
|||
|
|
|
|||
|
|
architectureData.utilities.forEach((utility) => {
|
|||
|
|
const item = createElement('li', 'utility-item');
|
|||
|
|
item.append(createElement('span', 'utility-marker'));
|
|||
|
|
const text = createElement('span');
|
|||
|
|
text.append(createElement('span', 'utility-title', utility.title));
|
|||
|
|
text.append(document.createTextNode(` · ${utility.description}`));
|
|||
|
|
item.append(text);
|
|||
|
|
utilityList.append(item);
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
document.getElementById('expand-all').addEventListener('click', () => setAllExpanded(true));
|
|||
|
|
document.getElementById('collapse-all').addEventListener('click', () => setAllExpanded(false));
|
|||
|
|
})();
|
|||
|
|
</script>
|
|||
|
|
</body>
|
|||
|
|
</html>
|