---
name: baoyu-workbench-theming
description: 宝锐工作台HTML页面统一品牌化 — 批量为工具/仪表盘页面注入白色顶栏（Logo加BIORI BIOTECH）、统一配色（白蓝科技风）、统一的导航交互。
category: productivity
---

# 宝锐工作台HTML页面统一品牌化

## 架构
所有工具页面通过 `http://localhost:8765` 本地HTTP服务器访问。
Logo文件：`~/Desktop/Hermes输出-工作类/logo.png`（复制自 `~/work/公司资料/logo_transparent.png`）

## 白色顶栏（标准格式，所有页面统一）

```html
<div style="position:fixed;top:0;left:0;right:0;height:48px;background:#fff;border-bottom:1px solid #e0e0e0;display:flex;align-items:center;padding:0 20px;z-index:9999;box-shadow:0 1px 4px rgba(0,0,0,.06);">
<a href="/工具/宝锐统一工作平台.html" style="display:flex;align-items:center;gap:10px;text-decoration:none;">
<img src="/logo.png" style="height:30px;width:auto;" alt="BIORI">
<span style="font-size:14px;font-weight:700;color:#1852B6;letter-spacing:0.5px;">BIORI BIOTECH</span>
</a>
<span style="margin-left:auto;font-size:11px;color:#9aa0a6;font-weight:400;">统一工作平台</span>
</div>
```

顶栏规范：48px高，Logo 30px，公司名 14px 粗体蓝色，右侧灰色"统一工作平台"。

## 交付件工业蓝页眉标准（2026-09-05 新增）

用户明确要求"输出的 HTML 做标准化"：**带公司logo + 工业蓝页眉 + 浅色背景**。适用于**交付件**（自包含 HTML，经微信 MEDIA 发送、单文件打开）。

与本地工作台"白色顶栏"的区别：
- 本地工作台页面：白色顶栏 + `/logo.png`（localhost:8765 服务）
- **交付件**：工业蓝页眉 + **内嵌 base64 logo**（单文件自包含，跨设备打开不裂图）

### 页眉 CSS
```css
.bior-header{background:linear-gradient(135deg,#0d47a1 0%,#1565c0 50%,#1a73e8 100%);color:#fff;box-shadow:0 2px 8px rgba(13,71,161,.18)}
.bior-header-inner{max-width:1080px;margin:0 auto;display:flex;align-items:center;gap:12px;padding:11px 20px}
.bior-logo-chip{background:#fff;border-radius:8px;padding:3px 9px;display:flex;align-items:center;box-shadow:0 1px 3px rgba(0,0,0,.16)}
.bior-logo-chip img{height:34px;width:auto;display:block}
.bior-brand{line-height:1.25}
.bior-name{font-size:15px;font-weight:700;letter-spacing:.5px;display:block}
.bior-cn{font-size:11px;opacity:.85;display:block}
.bior-tag{margin-left:auto;font-size:11px;opacity:.9;text-align:right;line-height:1.35}
```

### 页眉 HTML
```html
<div class="bior-header">
  <div class="bior-header-inner">
    <div class="bior-logo-chip"><img src="data:image/png;base64,{LOGO_B64}" alt="BIORI"></div>
    <div class="bior-brand"><span class="bior-name">BIORI BIOTECH</span><span class="bior-cn">宝锐生物</span></div>
    <span class="bior-tag">营销中心</span>
  </div>
</div>
```

### logo 内嵌（关键）
logo 源文件 `~/work/公司资料/logo_transparent.png`（透明 PNG，蓝+绿，1170×396）。内嵌前先缩到高度 72px（显示 36px 的 2x 保证清晰），base64 约 21KB：
```python
from PIL import Image
import base64, io
im = Image.open('/Users/liuxinyuan/work/公司资料/logo_transparent.png').convert('RGBA')
w,h = im.size; nh=72; nw=int(w*nh/h)
im2 = im.resize((nw,nh), Image.LANCZOS)
buf = io.BytesIO(); im2.save(buf, format='PNG', optimize=True)
LOGO_B64 = base64.b64encode(buf.getvalue()).decode()
```

### 浅色背景
body 用 `--bg:#f5f7fa`（或 #f0f2f5），卡片白底 `#fff`，正文 #202124，辅助 #5f6368。

### 已验证示例
`市场/2026上半年IVD业绩榜_58家.html` — 首个按此标准生成的交付件（2026-09-05）。

## 注入方法

### 步骤1：注入顶栏

```python
import re, os

TOPBAR = '<div style="...topbar HTML..."></div>'

for root, dirs, files in os.walk(BASE):
    for f in files:
        if not f.endswith('.html'): continue
        path = os.path.join(root, f)
        with open(path) as fh: html = fh.read()
        # 清除旧浮动Logo
        html = re.sub(r'<a href="/工具/宝锐统一工作平台\.html"[^>]*>.*?</a>', '', html, flags=re.DOTALL)
        # 注入顶栏
        body_m = re.search(r'(<body[^>]*>)', html)
        if body_m:
            html = html.replace(body_m.group(1), body_m.group(1) + '\n' + TOPBAR)
        # 补偿padding-top（处理CSS规则中的padding）
        def fix_padding(m):
            val = int(m.group(2))
            return f'{m.group(1)}{val+30}px' if val < 60 else m.group(0)
        html = re.sub(r'(body\s*\{[^}]*padding:\s*)(\d+)px', fix_padding, html)
        with open(path, 'w') as fh: fh.write(html)
```

### 步骤2：全量白底转换（排除仪表盘）

对所有非仪表盘页面，执行两轮颜色替换：

第一轮：CSS变量 + 硬编码颜色
```python
FIXES_V1 = [
    ('--bg:#0a0e14', '--bg:#ffffff'), ('--bg:#0d1117', '--bg:#ffffff'),
    ('--card:#161b22', '--card:#f5f5f5'), ('--border:#21262d', '--border:#dadce0'),
    ('--pri:#58a6ff', '--pri:#1a73e8'), ('--ok:#3fb950', '--ok:#0d904f'),
    ('--warn:#d2991d', '--warn:#e37400'), ('--bad:#f85149', '--bad:#d93025'),
    ('--sub:#8b949e', '--sub:#5f6368'), ('--text:#c9d1d9', '--text:#202124'),
    ('var(--bg)', '#ffffff'), ('var(--card)', '#f5f5f5'),
    ('var(--text)', '#202124'), ('var(--border)', '#dadce0'),
    ('#0a0e14', '#ffffff'), ('#0d1117', '#ffffff'), ('#161b22', '#f5f5f5'),
    ('#c9d1d9', '#202124'), ('#e6edf3', '#202124'),
    ('rgba(88,166,255,*)', 'rgba(26,115,232,*)'),  # * = 0.12/0.1/0.08/0.06/0.05/0.03/0.2
]
```

第二轮：对比度修正（白底后浅色文字不可读）
```python
FIXES_V2 = [
    ('#9aa0a6', '#5f6368'), ('#8b949e', '#5f6368'), ('#6e7681', '#4a4d52'),
    ('color:var(--sub)', 'color:#5f6368'), ('var(--text-light)', '#5f6368'),
    ('var(--muted)', '#5f6368'), ('var(--warn)', '#e37400'),
]
```

检测残留暗色：
```python
def is_dark(html):
    return any(p in html for p in ['var(--bg)','var(--card)','var(--text)',
        '#0a0e14','#0d1117','#161b22','#c9d1d9','var(--border)'])
```

## 配色体系

### 暗色→白蓝转换（工具页面CSS变量替换）

| 暗色变量 | 白蓝变量 |
|---------|---------|
| --bg:#0a0e14 / #0d1117 | --bg:#f8f9fa |
| --card:#161b22 | --card:#ffffff |
| --border:#21262d / #30363d | --border:#dadce0 |
| --pri:#58a6ff | --pri:#1a73e8 |
| --ok:#3fb950 | --ok:#0d904f |
| --warn:#d2991d | --warn:#e37400 |
| --bad:#f85149 | --bad:#d93025 |
| --sub:#8b949e | --sub:#5f6368 |
| --text:#c9d1d9 | --text:#202124 |

RGB色值替换：`rgba(88,166,255,*)` → `rgba(26,115,232,*)`
背景渐变：`linear-gradient(135deg,#e8f0fe 0%,#f8f9fa 30%,#fff 100%)`

### 仪表盘页面保留暗色（默认）
数据可视化仪表盘默认保留暗色（图表对比度更好），仅注入白色顶栏。

### 仪表盘白底转换（PPT截图需求）
当用户明确要求将仪表盘改为白底（如截图到PPT），执行全量配色转换。以诊断原料作战室为例：

**CSS变量映射（暗→白）**：

| 变量 | 暗色 | 白底 |
|------|------|------|
| --pri | #4fc3f7 | #1a73e8 |
| --pri2 | #0288d1 | #0059b3 |
| --ok | #69f0ae | #0d904f |
| --warn | #ffab40 | #f4a236 / #e37400 |
| --bad | #ff5252 | #d93025 |
| --bg0 | #0a1628 | #f0f2f5 |
| --bg1 | #0f1f38 | #ffffff |
| --bg2 | #162844 | #e8eaed |
| --text | #e0e8f0 | #202124 |
| --sub | #8899b4 | #5f6368 |
| --border | rgba(79,195,247,.15) | #e0e0e0 |
| --glass | rgba(15,31,56,.85) | #ffffff |

**转换清单**（Python一次性替换，不要逐个patch）：
1. CSS :root 块完全重写
2. body 背景：渐变→纯色 `#f0f2f5`
3. Topbar：暗色毛玻璃→白色 48px + Logo + BIORI BIOTECH
4. KPI卡/panel-card：毛玻璃→白底+微阴影（`box-shadow:0 1px 3px rgba(0,0,0,.08)`）
5. HermesTable：暗色覆写→白底蓝表头（th: `#f1f3f4`, td: `#e8eaed` 边框）
6. 所有Chart.js图表颜色同步替换（见下方）
7. 所有inline KPI颜色、表格颜色同步替换
8. 修复后必须 `node --check` 验证JS语法

**Chart.js图表颜色映射**：

| 元素 | 暗色 | 白底 |
|------|------|------|
| 2024年 | #69f0ae | #9e9e9e（灰，历史参考） |
| 2025年 | #ffab40 | #f4a236（金橙） |
| 2026年 | #4fc3f7 | #1a73e8（宝锐蓝） |
| 大客户部 | #00e5ff系 | #0059b3系 |
| 拓展部 | #4fc3f7系 | #1a73e8系 |
| 饼图 | 荧光色系 | #0d904f/#f4a236/#d93025 |
| 网格线 | rgba(79,195,247,.08) | rgba(0,0,0,.06) |
| 图例文字 | #8899b4 | #5f6368 |
| 销售趋势柱 | rgba(79,195,247,.4) | rgba(26,115,232,.5) |

**⚠️ 陷阱**：不要用patch逐段改配色——涉及50+处改动，patch极易引入字符串转义错误（`\n`→`\\n`）。用Python一次性读取、批量替换、验证、写回。

**⚠️ JS字符串引号损毁陷阱**：批量替换Chart.js颜色字符串时，如果替换目标跨越了引号边界（如 `color:'#8899b4'` → `color:#5f6368` 丢失开引号），产出 `color:#5f6368'` 不会被 `node --check` 检测（语法仍然合法），但Chart.js初始化时 `labels.color` 为 `undefined`，图例不显示。预防：搜索 `color:#` 检查是否有悬挂的单引号；写回前 `node --check` + 浏览器验证图例可见。

## 适用范围

**所有** `~/Desktop/Hermes输出-工作类/` 下的HTML页面均使用此标准，**全部白底**。唯一例外是仪表盘保留暗色（数据可视化需要）。

| 类型 | 数量 | 主题 |
|------|------|------|
| 工具页面 | 4 | 白底 ✅ |
| 客户调研/拜访卡 | 11+ | 白底 ✅ |
| 竞争分析 | 1 | 白底 ✅ |
| 知识沉淀 | 7 | 白底 ✅ |
| 市场调研/商务/销售分析 | 5+ | 白底 ✅ |
| 市场/其他 | 1 | 白底 ✅ |
| **仪表盘** | **5** | **4暗色 + 1白底**（诊断原料作战室已转白底） |

总计约37个页面，统一：白底 + 顶栏(48px Logo 30px) + 正文色#202124 + 辅助色#5f6368。

## 注入脚本

对 `~/Desktop/Hermes输出-工作类/` 下所有HTML文件批量处理：
```python
import re, os

TOPBAR = '''<div style="...Logo+BIORI BIOTECH...统一工作平台...</div>'''

for root, dirs, files in os.walk(BASE):
    for f in files:
        if not f.endswith('.html'): continue
        path = os.path.join(root, f)
        with open(path) as fh: html = fh.read()
        # 跳过已有顶栏的页面
        if 'logo.png' in html and 'BIORI BIOTECH' in html: continue
        # 清除旧浮动Logo
        html = re.sub(r'<a href="/工具/宝锐统一工作平台\.html"[^>]*>.*?</a>', '', html, flags=re.DOTALL)
        # 注入顶栏
        html = re.sub(r'(<body[^>]*>)', r'\1\n' + TOPBAR, html, count=1)
        # 补偿padding-top
        html = re.sub(r'(padding:\s*)(\d+)px', lambda m: m.group(1)+str(int(m.group(2))+30)+'px', html, count=1)
        with open(path, 'w') as fh: fh.write(html)
```

## 核心页面清单（完整白蓝转换的页面）

| 页面 | 顶栏 | 配色 |
|------|------|------|
| 工具/宝锐统一工作平台.html | ✅ | 白蓝科技风（入口页） |
| 工具/宝锐访前准备中心.html | ✅ | 白蓝科技风 |
| 工具/宝锐客户综合管理工作台.html | ✅ | 白蓝科技风（CSS变量替换） |
| 工具/宝锐组织架构与权限管理.html | ✅ | 白蓝科技风 |
| 仪表盘/宝锐综合管理仪表盘.html | ✅ | 暗色保留 |
| 仪表盘/客户分析仪表盘_2024-2026.html | ✅ | 暗色保留 |
| 其余全部页面 | ✅ | 仅顶栏 |

## 共享样式表（V2 升级）

`工具/baoyu-style-v2.css` — 拜访卡、访前报告等页面的统一白蓝科技风样式。包含：

| 组件 | 类名 | 说明 |
|------|------|------|
| 顶栏 | `.bior-topbar` | 固定48px白底，Logo + 返回链接 |
| 页面容器 | `.bior-page` | 标准padding，max-width 980px |
| KPI卡片 | `.kpi-row` / `.kpi-card` | 四格响应式，微阴影，`.accent`变体 |
| 内容卡片 | `.bior-card` | 白底圆角，h3带蓝色左侧竖线 |
| 表格 | `.bior-table` | 蓝表头 + `.label-cell` 浅蓝标签列 |
| 图表容器 | `.chart-wrap` | 固定高度，Chart.js就位 |
| 竞争条 | `.comp-bar-wrap` / `.comp-bar` | 供应商份额进度条 |
| 标签 | `.tag-ok/warn/bad/pri` | 统一彩色标签 |
| 报告区段 | `.report-section` | 蓝色h2标题条 |
| 产品线卡片 | `.pl-card` / `.pl-head` | launched/filing/rd三态色块 |

引入方式：`<link rel="stylesheet" href="/工具/baoyu-style-v2.css">`（页面CSS中覆盖专项样式）。

## 宝锐销售工作台-IMA 参考设计（2026-07-10）

用户提供的 `宝锐销售工作台-ima.html` 展示了偏好设计风格：

### 顶栏 — 深蓝渐变版
```css
.header{background:linear-gradient(135deg,#1a1a2e 0%,#16213e 50%,#0f3460 100%);color:#fff;height:60px}
```
右侧带角色切换按钮组。可替代白色顶栏用于作战室类页面。

### 统计卡片 — 彩色左边框
```css
.stat-card{border-left:4px solid #e94560}
.stat-card.blue{border-left-color:#3b82f6}
```
28px大字 + 左侧4px彩色边框区分类型。

### 维度面板
6个面板2列网格：日常/测试/订单/售后/案例/待办。每面板底部引用管理规程编号。

### 渲染策略优先级
1. 裸 innerHTML（首选，秒开）
2. HermesTable（需排序/筛选/导出时用）
3. Smart.Table（不推荐）

### 待办事项CSS（客户档案/生命科学通用）
```css
.todo-item{display:flex;align-items:center;gap:5px;padding:3px 0;font-size:10px;border-bottom:1px solid #f5f5f5}
.todo-item input[type=checkbox]{width:13px;height:13px;cursor:pointer;accent-color:var(--pri)}
.todo-item.done{opacity:.4;text-decoration:line-through}
.todo-item .del{margin-left:auto;color:var(--bad);cursor:pointer;font-size:12px;padding:0 4px}
```
localStorage key: `todo_客户名`（诊断原料）或 `todo_ls_大学名_课题组名`（生命科学）。

### 页面隔离规则
诊断原料（客户档案）与生命科学（商机）**不做跳转链接**。# 若返回000或Empty reply → 进程僵尸，重启：
# lsof -ti:8765 | xargs kill; cd ~/Desktop/Hermes输出-工作类 && python3 -m http.server 8765 &
curl -s -o /dev/null -w "%{http_code}" http://localhost:8765/logo.png  # 必须200
# 抽查任意页面
curl -s http://localhost:8765/竞争分析/xxx.html | grep -c "BIORI BIOTECH"  # ≥2
```

## 常见陷阱
- 先复制Logo：`cp ~/work/公司资料/logo_transparent.png ~/Desktop/Hermes输出-工作类/logo.png`
- 顶栏注入后必须补偿 padding-top（+30px），用 `re.sub(r'body\\{([^}]+padding:\\s*)(\\d+)px', ...)` 处理CSS中的body padding
- 仪表盘页面只加顶栏不改配色（数据可视化需要暗色）
- **⚠️ file:// 协议不可用**：页面含 fetch()、绝对路径脚本（`/工具/xxx.js`）、CDN外链时，file:// 无法加载。必须通过 `http://127.0.0.1:8765` 访问。HTTP服务器需持续运行。
- **子页面链接改造**：统一工作台的所有子页面链接需从相对路径改为HTTP绝对路径（`http://127.0.0.1:8765/工具/xxx.html`），动态链接用 `fixPath()` 函数替换 `../` 前缀。
- 旧浮动Logo需先清除再注入新顶栏
- Hermes新生成页面时也默认带此顶栏
- **暗色→白底转换后，必须检查文字对比度**：残留的浅色文字（#9aa0a6, #8b949e, var(--sub), var(--text-light)等）在白底上不可读，需替换为#5f6368或#4a4d52
- `body` CSS规则中的 `background:var(--bg)` 需要显式替换为 `background:#ffffff`，不能仅靠CSS变量转换

### 拜访卡/报告 批量CSS修复模式（白底后对比度修正）

**适用场景**：批量升级现有拜访卡和访前报告的CSS，修正暗色变量遗留 + 白底对比度问题。

**🧨 高频陷阱（拜访卡/报告批改必查）**：

| 陷阱 | 症状 | 修复 |
|------|------|------|
| `h1{color:#fff}` 或 `color:var(--text)` 且var(--text)仍为暗色 | 标题白字在白底上完全不可见 | `color:#202124` |
| `.kpi .v{color:#fff}` | KPI数字白字在灰/白卡片上不可见 | `color:#1a73e8`（宝锐蓝） |
| `.kpi{background:#f5f5f5}` + 白色字体 | 灰色背景上白字读不清 | 卡底改`background:#ffffff` |
| `textarea:focus{background:#1a1f3a}` | 聚焦后文字区变暗色 | `background:#ffffff;box-shadow:0 0 0 3px rgba(26,115,232,.12)` |
| `input{border:1px dashed #3a4a6c}` | 暗色虚线边框不协调 | `border:2px solid #e0e0e0` |
| `--border:#1e3a5f` / 旧暗色CSS变量残留 | 边框颜色太深 | `--border:#e0e0e0` |
| `--sub:#8899aa` 残留 | 副文字太淡 | `--sub:#5f6368` |
| `--pri:#2e86de` 非标准蓝 | 主色调不一致 | `--pri:#1a73e8` |
| `.card{background:#f5f5f5;border:1px solid #dadce0}` | 卡片偏灰 | `background:#ffffff;border:1px solid #e0e0e0` |

**批量修复脚本模板**：

```python
import os, glob, re

base = os.path.expanduser("~/Desktop/Hermes输出-工作类/客户管理")
visit_cards = glob.glob(os.path.join(base, "拜访卡/*.html"))
reports = glob.glob(os.path.join(base, "访前背调/**/*.html"), recursive=True)

FIXES = [
    # KPI 白字→蓝字
    (".kpi .v{font-size:20px;font-weight:bold;color:#fff}", ".kpi .v{font-size:20px;font-weight:bold;color:#202124}"),
    # 卡底灰→白
    (".kpi{background:#f5f5f5;", ".kpi{background:#ffffff;"),
    (".card{background:#f5f5f5;", ".card{background:#ffffff;"),
    # 聚焦暗→亮
    ("background:#1a1f3a}", "background:#ffffff;box-shadow:0 0 0 3px rgba(26,115,232,.12)}"),
    # 虚线边框
    ("1px dashed #3a4a6c", "2px solid #e0e0e0"),
    # 链接→HTTP绝对路径
    ('href="/工具/宝锐统一工作平台.html"', 'href="http://127.0.0.1:8765/工具/宝锐统一工作平台.html"'),
    # 旧主题色→宝锐蓝
    ("#1a5c8a", "#1a73e8"),  # 蕾灵百奥等旧报告主题色
    # 表格边框
    ("1px solid #d5d5d0", "1px solid #e0e0e0"),
    ("border-bottom:2px solid #dadce0", "border-bottom:2px solid #1a73e8"),
]

for path in visit_cards + reports:
    with open(path) as f: html = f.read()
    orig = html
    for old, new in FIXES:
        html = html.replace(old, new)
    if html != orig:
        with open(path, 'w') as f: f.write(html)
        print(f"  ✅ {os.path.basename(path)}")
```

### 统一工作台链接改造模式

当工作台入口页的子页面链接从相对路径改为HTTP绝对路径：

```python
BASE = "http://127.0.0.1:8765"
# 静态链接：直接替换href
for old, new in [
    ('href="../诊断原料作战室.html"', f'href="{BASE}/诊断原料作战室.html"'),
    ('href="宝锐访前准备中心.html"', f'href="{BASE}/工具/宝锐访前准备中心.html"'),
]:
    html = html.replace(old, new)

# 动态链接：JS中加转换函数
html = html.replace(
    'function scanCustomerFiles(){',
    'function scanCustomerFiles(){\n  function fixPath(p){return p.replace(/^\\.\\.\\//,"'+BASE+'/");}'
)
# 然后将 href="'+f.path+'" 改为 href="'+fixPath(f.path)+'"
```
