diff --git a/docker/.env.example b/docker/.env.example index 9ff6f87..7d1c145 100644 --- a/docker/.env.example +++ b/docker/.env.example @@ -115,6 +115,10 @@ KEYSTONE_AXON_RECORDER_RESPONSE_TIMEOUT=300 KEYSTONE_JWT_SECRET=your-strong-secret-here KEYSTONE_JWT_EXPIRY_HOURS=24 KEYSTONE_JWT_ISSUER=keystone-edge +# Optional long-lived read-only token for /admin/dashboard TV display mode. +# Generate with: openssl rand -hex 48 +# Leave empty to disable display-token access. +KEYSTONE_DASHBOARD_DISPLAY_TOKEN= # Admin user credentials (for full API access) KEYSTONE_ADMIN_USERNAME=admin KEYSTONE_ADMIN_PASSWORD=admin123 diff --git a/docs/designs/synapse-admin-brand-palette.md b/docs/designs/synapse-admin-brand-palette.md new file mode 100644 index 0000000..6da91a6 --- /dev/null +++ b/docs/designs/synapse-admin-brand-palette.md @@ -0,0 +1,94 @@ + + +# Synapse 管理后台品牌色系调整 + +**Scope:** Synapse 非沉浸式管理后台页面,即 `/admin/*` 中除 `/admin/dashboard` 生产大屏外的普通管理页。 + +## 1. 背景 + +生产大屏已经采用“工业暗屏基底 + ArcheBase 品牌强调色”的视觉方向。普通管理后台也应与该方向保持品牌一致,但它的主要用途是高频操作、筛选、录入和表格扫描,因此不应直接套用生产大屏的暗色大屏布局。 + +本调整的目标是统一色系,不重做全站设计系统、不改变信息架构、不修改 API。 + +## 2. 设计方向 + +普通管理后台采用“深色品牌导航 + 浅色操作台”的结构: + +- 左侧导航使用 ArcheBase 深蓝/青色暗屏基底,建立与生产大屏一致的品牌识别。 +- 主内容区保持浅色、低噪声、适合长时间操作和表格阅读。 +- 卡片、表格、筛选区使用冷灰蓝边界和轻量青色选中态。 +- 主要按钮、当前导航、排序/链接/进度等焦点元素使用 ArcheBase 品牌蓝/青色。 +- 状态色继续保持生产语义:成功/在线为绿色,进行中/当前焦点为品牌青,警告为琥珀色,失败为红色,离线/取消/不可用为灰色。 + +## 3. Token 约束 + +Synapse 已有品牌基础变量: + +- `--brand-blue: #07338c` +- `--brand-cyan: #079dd9` +- `--brand-yellow: #f1d86b` + +普通管理后台不应在各页面硬编码新色值,而应在 `AdminLayout.vue` 的非沉浸式 `.admin-layout` 范围内派生后台 token,并让子组件继承: + +- `--page-bg`:冷灰蓝页面基底。 +- `--surface-bg` / `--surface-subtle` / `--surface-muted` / `--surface-selected`:浅色操作台表面。 +- `--border-color` / `--border-subtle` / `--border-strong`:冷灰蓝边界。 +- `--admin-sidebar-bg` / `--admin-sidebar-text` / `--admin-sidebar-active-bg`:深色品牌导航。 +- `--admin-accent-line` / `--admin-accent-soft`:表格 hover、筛选区、卡片边界和焦点弱背景。 + +生产大屏继续使用局部 `--screen-brand-*` token;普通后台不复用大屏的 `100dvh`、全屏 grid、视频舞台动效或大屏字号。 + +## 4. 实现范围 + +建议优先修改: + +- `src/components/layout/AdminLayout.vue` +- `src/components/layout/AdminSidebar.vue` +- `src/styles/admin-crud.css` +- `src/components/crud/ListPageLayout.vue` +- `src/components/crud/CrudFormLayout.vue` +- `src/components/common/DataTable.vue` + +避免逐个重写所有管理页面。已有页面内使用 `var(--primary-*)`、`var(--secondary-*)`、`var(--surface-*)`、`var(--border-*)` 的样式应自然继承新色系。 + +## 5. 默认入口 + +生产大屏是沉浸式展示入口,不是管理员日常操作首页。Admin 登录成功后应进入普通管理后台的工厂管理页面: + +- admin 登录成功默认跳转 `/admin/factories`。 +- 直接访问 `/admin` 默认重定向到 `/admin/factories`。 +- `/admin/dashboard` 仍作为显式生产大屏入口保留,可以从侧边栏“生产大屏”进入。 +- 旧 `/dashboard` legacy redirect 可以继续指向 `/admin/dashboard`,用于兼容已经配置好的电视或书签。 + +这样可以避免管理员每次登录后误入全屏展示页面,同时不破坏生产大屏的独立访问路径。 + +## 6. 验收标准 + +- `/admin/dashboard` 生产大屏视觉不回退,仍保持沉浸式一屏布局。 +- `/admin/*` 普通管理页拥有一致的 ArcheBase 深蓝/青色品牌识别,但主内容区仍适合表格阅读和表单操作。 +- 管理后台不出现紫色霓虹、满屏发光卡片、营销页 hero 或大屏化排版。 +- 离线、取消、不可用仍为灰色;失败和错误仍为红色。 +- 侧边栏、表格、筛选区、表单页和通用按钮均能看到统一色系。 +- admin 登录成功和访问 `/admin` 都进入 `/admin/factories`,不会自动进入 `/admin/dashboard`。 +- `/admin/dashboard` 仍可直接访问,且侧边栏保留生产大屏入口。 +- 桌面与移动宽度下导航和内容不重叠、不出现由色系调整引入的横向溢出。 + +## 7. 验证 + +前端至少运行: + +```bash +npm run build +``` + +建议浏览检查: + +- `/admin/factories` +- `/admin/workstations` +- `/admin/tasks` +- `/admin/statistics/data-production` +- `/admin/dashboard` diff --git a/docs/designs/synapse-production-big-screen-tasks.md b/docs/designs/synapse-production-big-screen-tasks.md new file mode 100644 index 0000000..7d360a4 --- /dev/null +++ b/docs/designs/synapse-production-big-screen-tasks.md @@ -0,0 +1,518 @@ + + +# Synapse 生产大屏任务拆解 + +**Scope:** Keystone `worktree2` 与 Synapse `worktree2` 后续开发任务 + +## 1. 目的 + +本文档把 `synapse-production-big-screen.md` 中的设计和技术方案拆成可执行开发任务。它不重复设计愿景,只定义开发顺序、依赖关系、修改范围、验收标准和推荐 PR 切分。 + +后续开发应同时参考: + +- `docs/designs/synapse-production-big-screen.md` +- 本任务拆解文档 + +## 2. 拆分原则 + +- 先数据契约,再前端数据层,再页面布局,最后动画和验收。 +- 每个任务尽量能独立验证,避免一个 PR 同时大改后端、数据层、布局和动画。 +- 第一版以 MVP 为目标,不新增告警表,不做独立告警栏,不做视频转码服务,不引入 WebSocket 和重型动画库。 +- 前端优先消费聚合 API;只有 API 不可用或字段暂缺时使用集中 fallback。 +- 改动优先复用现有文件和模式,避免新建过多平行体系。 + +## 3. 推荐 PR 切分 + +| PR | 任务 | 仓库 | 是否阻塞后续 | 目标 | +|---|---|---|---|---| +| PR-1 | 后端 overview 聚合 API | `keystone-worktree2` | 是 | 建立大屏数据契约 | +| PR-2 | 前端 overview 数据层 | `synapse-worktree2` | 是 | 建立 API client、adapter、fallback | +| PR-3 | 大屏响应式基础布局 | `synapse-worktree2` | 是 | 页面能展示完整数据区域 | +| PR-4 | Video Flight Stage MVP | `synapse-worktree2` | 否 | 实现预览轮播状态机和 fallback | +| PR-5 | 图表、设备、任务流打磨 | `synapse-worktree2` | 否 | 补齐生产指挥中心信息密度 | +| PR-6 | 电视视口和稳定性验收 | `synapse-worktree2`,必要时 `keystone-worktree2` | 否 | 修正响应式、性能和边界问题 | + +如果需要更快出第一版展示,PR-3 可以先接 mock/fallback 数据并与 PR-2 并行,但最终必须回到 overview API 契约。 + +## 4. 任务清单 + +### T1. 后端 overview API 契约与基础响应 + +**仓库:** `keystone-worktree2` + +**目标:** 在现有 `ProductionDashboardHandler` 中新增面向大屏的 `GET /api/v1/production/dashboard/overview`。 + +**依赖:** 无。 + +**建议修改范围:** + +- `internal/api/handlers/production_dashboard.go` +- `internal/api/handlers/production_dashboard_test.go` +- `docs/docs.go`、`docs/swagger.*`,如果项目要求同步 Swagger + +**实现要点:** + +- 复用现有 `resolveProductionDashboardScope()`、查询参数解析、只读事务和 scope 过滤。 +- 新增 overview response structs。 +- 第一版返回完整结构,即使部分数组为空。 +- `summary`、`trend`、`task_status_distribution`、`devices`、`stations`、`recent_tasks` 优先实现。 +- 第一版不返回独立 `alerts` 字段,不建设告警栏;设备不在线、工位离线、任务失败、接口降级等异常内联展示在顶部状态、设备/工位状态和任务流中。 +- `previews.video_url` 可以为空,但如果非空必须是真实可播放视频 URL;为空时返回 episode/task 元信息(SOP、场景、设备类型、设备 ID 等)和可解析的 `preview_url`,保证前端可复用数据预览页播放 MCAP 图像帧。原 `task_name` 字段改为 `scene_name`,大屏不再需要独立标题字段;原舞台上的“机器人”元信息改为 `device_type`。 + +**验收标准:** + +- `GET /api/v1/production/dashboard/overview` 默认需要 JWT,允许 `admin` 和 `data_collector`;常驻电视模式按 T8 支持专用 display token。 +- `data_collector` 自动限定到绑定工位。 +- 空数据返回 200,数值为 0,数组为空。 +- 参数错误返回 400,未认证返回 401。 +- 响应包含 `generated_at`、`scope`、`summary`、`trend`、`task_status_distribution`、`quality`、`devices`、`stations`、`recent_tasks`、`previews`。 +- `previews.video_url` 为空时仍有 `scene_name`、`sop_label`、`device_type`、`device_id`、`status`、`created_at`;有 MCAP 时返回 `preview_url`;`video_url` 非空时必须是真实可播放视频。 + +**验证命令:** + +```bash +go test ./internal/api/handlers/... -run ProductionDashboard -v +gofmt -w internal/api/handlers/production_dashboard.go internal/api/handlers/production_dashboard_test.go +``` + +**风险:** + +- 今日任务和全量任务口径容易混淆;接口字段名必须明确。 +- 设备在线率需要确认规则,第一版可以沿用 workstation status。 + +### T2. 后端 overview 查询补齐 + +**仓库:** `keystone-worktree2` + +**目标:** 在 T1 基础上补齐更有展示价值的字段,不引入新表。 + +**依赖:** T1。 + +**建议修改范围:** + +- `internal/api/handlers/production_dashboard.go` +- `internal/api/handlers/production_dashboard_test.go` + +**实现要点:** + +- overview `trend` 改为数据生产数量趋势,按 `episodes` 数据生产记录聚合,不再使用任务状态桶作为趋势口径。 +- `devices` 只返回在线/不在线汇总,不返回 `items`;设备在线以 recorder hub 与 transfer hub 均联通为准。 +- `stations.summary` 返回工位管理状态汇总:`active` 执行中、`inactive` 待命中、`break` 休息中、`offline` 离线。 +- `recent_tasks` 覆盖最近发生变化的任务,并由后端按最近更新时间排序后再截取:`updated_at` 倒序,再按任务主键倒序;`updated_at` 可继续使用 `COALESCE(t.updated_at, t.completed_at, t.started_at, t.assigned_at, t.created_at)` 兜底。 +- `recent_tasks` 不再按状态优先级置顶 `failed` 或 `cancelled`;失败和取消只作为最近变化的一种状态展示,避免旧异常占满任务流。 +- `quality.recent_failures` 如果查询成本可控则实现,否则保留空数组。 + +**验收标准:** + +- overview 中 `trend` 每个点包含 `date`、`total`,`total` 表示当天数据生产记录数量。 +- `recent_tasks` 按最近更新时间排序,受 `recent_limit` 限制;前端不得在已截断的小集合上重新定义业务排序。 +- 所有 limit 参数有上限,避免大屏接口返回过大。 + +**验证命令:** + +```bash +go test ./internal/api/handlers/... -run ProductionDashboard -v +go test ./... ./cmd/keystone-edge/... +``` + +**风险:** + +- `sync_logs` 或 episode join 较复杂时,异常状态可以先只通过任务流和设备状态表达,避免阻塞前端。 + +### T3. 前端 overview API client 与数据 adapter + +**仓库:** `synapse-worktree2` + +**目标:** 增加前端大屏数据入口,优先消费 overview API。 + +**依赖:** T1,或临时使用 mock 契约并在 T1 合入后对齐。 + +**建议修改范围:** + +- `src/api/productionDashboard.js` +- `src/features/production/useProductionBigScreenData.js` +- 可选:`src/features/production/productionBigScreenMock.js` + +**实现要点:** + +- `useProductionDashboardApi()` 增加 `overview(params)`。 +- 新增 composable 管理 `loading`、`error`、`lastUpdatedAt`、`usingFallback`、`overview`。 +- adapter 统一补默认值,避免模板写大量空值判断。 +- API 失败时保留上一份成功数据;无历史数据时使用集中 mock fallback。 +- 定时刷新默认 15s 或 30s,后续可配置。 + +**验收标准:** + +- API 成功、失败、空数据均返回稳定的数据结构。 +- fallback 数据集中定义,不散落在 Vue 模板。 +- composable `onUnmounted` 时清理 polling timer。 +- 不打断 Video Flight Stage 当前播放状态,数据层只更新队列数据。 + +**验证命令:** + +```bash +npm run build +``` + +**风险:** + +- 真实 API 字段和 mock 字段不一致会造成返工;adapter 必须成为唯一入口。 + +### T4. 大屏响应式基础布局 + +**仓库:** `synapse-worktree2` + +**目标:** 改造 `/admin/dashboard` 对应页面,建立生产指挥中心基础布局。此阶段先不追求复杂视频动画。 + +**依赖:** T3。 + +**建议修改范围:** + +- `src/views/FullscreenDashboard.vue` +- 可选:`src/components/production/BigScreenKpiStrip.vue` +- 可选:`src/components/production/BigScreenStatusRail.vue` +- 可选:`src/components/production/BigScreenTaskFeed.vue` +- 可选:`src/components/production/BigScreenTrendPanel.vue` +- `src/styles/dashboard-light.css` 或新建大屏专用 CSS 文件 + +**实现要点:** + +- 保留 `/admin/dashboard` 路由。 +- 建立顶部状态栏、KPI、中央舞台占位、趋势、设备状态和任务流;不设置独立告警栏。 +- 使用 CSS Grid、Flexbox、`clamp()`、`minmax()`、`aspect-ratio`。 +- 核心 KPI 和视频舞台在所有断点优先展示。 +- `1366x768` 下可减少列表条数,但不能横向滚动或文字重叠。 + +**验收标准:** + +- `1920x1080` 下首屏能看到 KPI、中央舞台、设备健康和异常状态。 +- `3840x2160` 下内容不显得过小或过空。 +- `1366x768` 下不横向滚动,不出现明显文字重叠。 +- 没有视频数据时中央舞台显示稳定占位。 + +**验证命令:** + +```bash +npm run build +``` + +**手动检查视口:** + +- `3840x2160` +- `2560x1440` +- `1920x1080` +- `1600x900` +- `1366x768` + +**风险:** + +- 如果一次拆太多组件,会增加 PR 审查成本;优先按职责拆少量组件。 + +### T5. Video Flight Stage MVP + +**仓库:** `synapse-worktree2` + +**目标:** 实现视频/预览轮播舞台状态机和克制飞行动效。 + +**依赖:** T3、T4。 + +**建议修改范围:** + +- `src/components/production/VideoFlightStage.vue` +- `src/views/FullscreenDashboard.vue` +- 大屏相关 CSS + +**实现要点:** + +- 状态机:`loading`、`entering`、`playing`、`leaving`、`error`。 +- 只播放当前条目;带真实 `video_url` 时使用 `