@@ -266,57 +272,6 @@ export function GovShell({ surface }: { surface: Surface }) {
);
}
-/**
- * 台账段 —— 左轨里唯一的**动态位**:一域一枚,随数据域发布而生长。
- *
- * 这是「设计产生运营的形状」最直观的一处:导航本身就是被设计出来的。
- */
-function LedgerRail({
- domains,
- active,
- onPick,
-}: {
- domains: readonly string[];
- active: string | undefined;
- onPick: (domain: string) => void;
-}) {
- return (
- <>
-
- 台账
-
- {domains.length === 0 ? (
-
- 随数据域
-
- 发布生长
-
- ) : (
- domains.map((d) => (
-
- ))
- )}
- >
- );
-}
-
function ZoneHome({ zone, tab, nav }: { zone: GovZone; tab: string; nav: Nav }) {
const P = {
// 设计中心
diff --git a/apps/web/src/app/styles/console.css b/apps/web/src/app/styles/console.css
index 8a3764d..f0cc6fa 100644
--- a/apps/web/src/app/styles/console.css
+++ b/apps/web/src/app/styles/console.css
@@ -458,3 +458,35 @@
.g-dbpage button:hover:not(:disabled) { border-color: var(--brand); color: var(--brand); }
.g-dbpage button:disabled { opacity: .35; cursor: default; }
.g-dbpage b { min-width: 36px; text-align: center; font-size: 11px; color: var(--ink-2); }
+
+/* ═══════════ 三面补充(非原型)—— 蓝图因果链 / 终态堆叠条 / 数据域紧凑轨钮 ═══════════ */
+
+/* 蓝图因果链:四库节点卡以真箭头相连 —— 箭头编码真实依赖(流程包→活动→工具→数据),节点即入口 */
+.g-chain { display: flex; align-items: stretch; gap: 0; margin-bottom: 14px; }
+.g-chain-node { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 8px; padding: 14px 16px; background: var(--card); border: 1px solid var(--cline); border-radius: 13px; box-shadow: var(--cshadow); text-align: left; font: inherit; color: var(--ink); cursor: pointer; transition: border-color var(--t-fast), transform var(--t-fast), box-shadow var(--t-fast); }
+.g-chain-node:hover { border-color: var(--brand); transform: translateY(-1px); box-shadow: 0 4px 14px -6px rgba(51, 112, 255, .35); }
+.g-chain-node:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
+.g-chain-k { display: flex; align-items: center; gap: 7px; font-size: 11px; font-weight: 600; color: var(--ink-3); }
+.g-chain-k .ic { width: 22px; height: 22px; border-radius: 7px; display: grid; place-items: center; flex: none; background: var(--fill-2, #eef1f5); color: var(--ink-3); }
+.g-chain-node.t-brand .ic { background: var(--brand-soft); color: var(--brand-deep); }
+.g-chain-node.t-auto .ic { background: #e6f7f4; color: #0a6a64; }
+.g-chain-node.t-collab .ic { background: #f0e9ff; color: #5b21cf; }
+.g-chain-node.t-ok .ic { background: var(--ok-soft); color: var(--ok); }
+.g-chain-v { font-size: 24px; font-weight: 800; font-family: var(--mono); letter-spacing: -.03em; line-height: 1; }
+.g-chain-node.t-brand .g-chain-v { color: var(--brand-deep); }
+.g-chain-node.t-auto .g-chain-v { color: #0a6a64; }
+.g-chain-node.t-collab .g-chain-v { color: #5b21cf; }
+.g-chain-node.t-ok .g-chain-v { color: var(--ok); }
+.g-chain-h { font-size: 11px; line-height: 1.5; color: var(--ink-4); }
+.g-chain-arr { flex: none; width: 26px; display: grid; place-items: center; color: var(--ink-4); }
+@media (max-width: 1100px) {
+ .g-chain { flex-direction: column; }
+ .g-chain-arr { transform: rotate(90deg); width: auto; padding: 2px 0; }
+}
+
+/* 终态堆叠条:五终态五色一条,比例即信息 —— 装在 .g-kpi 卡里 */
+.g-mixbar { display: flex; height: 8px; border-radius: 4px; overflow: hidden; background: var(--fill-2, #eef1f5); }
+.g-mixbar i { display: block; min-width: 2px; }
+.g-mixbar-legend { display: flex; flex-wrap: wrap; gap: 3px 10px; font-size: 10px; color: var(--ink-3); }
+.g-mixbar-legend b { font-family: var(--mono); font-weight: 700; color: var(--ink-2); }
+.g-mixbar-legend i { display: inline-block; width: 7px; height: 7px; border-radius: 2px; margin-right: 4px; }
diff --git a/apps/web/src/features/gov-blueprint/internal/panel.tsx b/apps/web/src/features/gov-blueprint/internal/panel.tsx
index 6430afa..8725660 100644
--- a/apps/web/src/features/gov-blueprint/internal/panel.tsx
+++ b/apps/web/src/features/gov-blueprint/internal/panel.tsx
@@ -9,7 +9,8 @@
* 这里**不出现任何运行态数字**(在跑几单、30 天起单数、死信数)。
* 设计者看的是定义完不完整,不是今天忙不忙 —— 混进运行数字,这页就退化成第二个驾驶舱。
*/
-import { Clear, Entry, Kpi, Sec, Todo } from '@web-shared/gov/primitives.tsx';
+import { Ico } from '@web-shared/Ico.tsx';
+import { Clear, Sec, Todo } from '@web-shared/gov/primitives.tsx';
import type { Nav } from '@web-shared/gov/gov-route.ts';
import {
useGovActivities,
@@ -58,38 +59,67 @@ export function BlueprintHome({ nav }: HomeProps) {
const gaps = draftBad.length + missingActivities.length + uncalled.length;
- // 因果链那句话写在区说明里(ZM.blueprint.desc),此处不重复 —— 直接上四库读数
+ // 因果链是这一屏的主角:四库以真箭头相连 —— 箭头编码的是真实依赖
+ // (流程包引用活动、活动调工具、活动物化数据),节点卡即入口,点卡即入库。
return (
<>
-
-
-
-
t.effect === 'read').length} · 写类 ${toolRows.filter((t) => t.effect === 'write').length}`}
- />
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -144,34 +174,6 @@ export function BlueprintHome({ nav }: HomeProps) {
)}
-
-
- nav.jump('workflows', 'pkgs')}
- />
- nav.jump('library', 'shelf')}
- />
- nav.jump('tools', 'catalog')}
- />
- nav.jump('data', 'domains')}
- />
-
-
>
);
}
diff --git a/apps/web/src/features/gov-data/index.ts b/apps/web/src/features/gov-data/index.ts
index e0aa4dc..a274856 100644
--- a/apps/web/src/features/gov-data/index.ts
+++ b/apps/web/src/features/gov-data/index.ts
@@ -1,5 +1,5 @@
/**
* feature `gov-data` 唯一出口(编码规范 §9.1)。
- * 数据的两副面孔:结构定义在设计中心(数据域),行数据在运营中心(台账 · 某域)。
+ * 数据的两副面孔:结构定义在设计中心(数据域),行数据在运营中心(台账 · 某域页签)。
*/
export { DataHome, LedgersHome, ObjPage } from './internal/panel.tsx';
diff --git a/apps/web/src/features/gov-data/internal/panel.tsx b/apps/web/src/features/gov-data/internal/panel.tsx
index 087f684..09019f4 100644
--- a/apps/web/src/features/gov-data/internal/panel.tsx
+++ b/apps/web/src/features/gov-data/internal/panel.tsx
@@ -2,7 +2,7 @@
* feature `gov-data` —— 数据的两副面孔,各归其台:
*
* `DataHome`(设计中心 · 数据域):**定义面** —— 域 × 对象的结构:有哪些列、主键是什么、谁声明了它。
- * `LedgersHome`(运营中心 · 台账 · 某域):**运营面** —— 这张表现在有多少行、里面是什么。
+ * `LedgersHome`(运营中心 · 台账 · 某域页签):**运营面** —— 这张表现在有多少行、里面是什么。
*
* 分开的理由:改 schema 和查行数据是两种心智。
* 设计者问「这个对象定义全不全」,运营者问「今天这张表有几条」——
@@ -15,6 +15,7 @@ import { Ico } from '@web-shared/Ico.tsx';
import { Card, Chip, Clear, NList, NRow, Note, PageHead, QueryGate, Sec } from '@web-shared/gov/primitives.tsx';
import type { Nav } from '@web-shared/gov/gov-route.ts';
import { useGovLedger, useGovObjects } from '@web-shared/gov/gov-api.ts';
+import { domainShort, sortDomains } from '@web-shared/gov/domains.ts';
export type HomeProps = { tab: string; nav: Nav };
@@ -27,7 +28,7 @@ export type HomeProps = { tab: string; nav: Nav };
export function DataHome({ nav }: HomeProps) {
const q = useGovObjects();
const objects = q.data?.objects ?? [];
- const domains = [...new Set(objects.map((o) => o.domain))].sort();
+ const domains = sortDomains([...new Set(objects.map((o) => o.domain))]);
return (
@@ -40,8 +41,11 @@ export function DataHome({ nav }: HomeProps) {
- {d}
- {objects.filter((o) => o.domain === d).length} 个对象 · 发布即在运营中心长出一位
+ {domainShort(d)}
+
+ {d}
+
+ {objects.filter((o) => o.domain === d).length} 个对象 · 发布即入运营台账
{objects
@@ -80,10 +84,10 @@ function ObjectSchemaRow({ domain, object, nav }: { domain: string; object: stri
);
}
-/* ==================== 运营侧:台账(某一个域) ==================== */
+/* ==================== 运营侧:台账(某一个域页签) ==================== */
/**
- * 台账的一个域 —— 壳层把左轨选中的域名当页签传进来。
+ * 台账的一个域 —— 壳层把选中的域页签(键)传进来;没带域时壳层已落到首域。
* 这里看的是运营事实:这张表现在多少行,点进去逐行看。
*/
export function LedgersHome({ tab, nav }: HomeProps) {
@@ -95,8 +99,8 @@ export function LedgersHome({ tab, nav }: HomeProps) {
<>
- {domain} 域的台账:行数据、主键与列结构。结构要改去设计中心 · 数据域;
- 这里做的是运营动作 —— 查行、看版本、追引用。
+ {domainShort(domain)}域({domain})的行数据、主键与列结构。
+ 结构要改去设计中心 · 数据域;这里做的是运营动作 —— 查行、看版本、追引用。
{inDomain.length === 0 ? (
这个域还没有对象 —— 对象随活动首次写入而物化,建好就出现在这里。
@@ -112,7 +116,7 @@ export function LedgersHome({ tab, nav }: HomeProps) {
);
}
-/** 一个台账对象一行:行数是运营侧最想先看到的那个数 */
+/** 一个数据对象一行:行数是运营侧最想先看到的那个数 */
function LedgerObjectRow({ domain, object, nav }: { domain: string; object: string; nav: Nav }) {
const page = useGovLedger(domain, object);
const total = page.data?.total;
diff --git a/apps/web/src/features/gov-memory/internal/panel.tsx b/apps/web/src/features/gov-memory/internal/panel.tsx
index b43e03b..3800172 100644
--- a/apps/web/src/features/gov-memory/internal/panel.tsx
+++ b/apps/web/src/features/gov-memory/internal/panel.tsx
@@ -10,6 +10,7 @@
import { useState } from 'react';
import { TERMINAL_STATE_LABEL } from '@contracts';
import type { TerminalState } from '@contracts';
+import { Ico } from '@web-shared/Ico.tsx';
import { Chip, Clear, Kpi, NList, NRow, Note, PageHead, QueryGate, Todo } from '@web-shared/gov/primitives.tsx';
import type { Nav } from '@web-shared/gov/gov-route.ts';
import {
@@ -25,6 +26,15 @@ export type HomeProps = { tab: string; nav: Nav };
const pct = (v: number | undefined) => Math.round((v ?? 0) * 100);
+/** 终态五名的呈现色 —— 放行绿、驳回琥珀、停滞灰、耗尽红、终止墨,与状态章同族 */
+const TERMINAL_TONE: Readonly> = {
+ released: 'var(--ok-accent)',
+ blocked: 'var(--warn-accent)',
+ stalled: '#8f959e',
+ exhausted: 'var(--danger-accent)',
+ terminated: '#41464e',
+};
+
/* ---------------- 经营驾驶舱(运营首页) ---------------- */
/**
@@ -119,18 +129,35 @@ export function CockpitHome({ nav }: HomeProps) {
unit="tok"
sub={`每放行一单:${(m?.unitCost.minutes ?? 0).toFixed(1)} 分钟 · 调人 ${(m?.unitCost.humanCalls ?? 0).toFixed(1)} 次`}
/>
- `${TERMINAL_STATE_LABEL[k as TerminalState] ?? k} ${pct(v)}%`)
- .join(' · ')
- }
- />
+ {/* 终态分布:比例即信息 —— 五终态五色一条,不把五个百分比塞进一行小字 */}
+
+
+
+ 终态分布
+
+ {mixTop.length === 0 ? (
+ <>
+ —
+ 还没有任务落终态
+ >
+ ) : (
+ <>
+
+ {mixTop.map(([k, v]) => (
+
+ ))}
+
+
+ {mixTop.map(([k, v]) => (
+
+
+ {TERMINAL_STATE_LABEL[k as TerminalState] ?? k} {pct(v)}%
+
+ ))}
+
+ >
+ )}
+
自主率与纠正率成对读,复合为有效自主率——单看自主率会奖励「猛冲后返工」。度量只是仪表,不载权力。
diff --git a/apps/web/src/features/gov-trigger/internal/panel.tsx b/apps/web/src/features/gov-trigger/internal/panel.tsx
index 2f68f6b..1921960 100644
--- a/apps/web/src/features/gov-trigger/internal/panel.tsx
+++ b/apps/web/src/features/gov-trigger/internal/panel.tsx
@@ -282,7 +282,7 @@ function TriggerForm({
)}
{draft.spec.kind === 'periodic-data' && (
<>
-
+