news 2026/10/1 6:02:04

WorkBuddy+微信企业级AI日报自动化架构设计

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
WorkBuddy+微信企业级AI日报自动化架构设计

1. 这不是“发个消息”,而是一套轻量级企业级自动化工作流

“我给 WorkBuddy 设了个闹钟:每天上午十点半,一份 AI 日报自动送进微信”——这句话乍看像极了某个程序员朋友在茶水间随口聊起的小技巧,但拆开来看,它其实浓缩了一个完整的企业级信息协同闭环:触发(定时)→ 生成(AI)→ 分发(微信)→ 沉浸(工作台)。我做这类自动化集成项目超过七年,从最早用 Python + APScheduler 调度邮件日报,到后来接入钉钉机器人、飞书多维表格,再到如今和 WorkBuddy 深度耦合,最深的体会是:真正的效率提升,从来不是“多快”,而是“不打断”。你不需要切出当前正在写的方案文档,不需要打开浏览器查数据,更不需要手动复制粘贴——十点半整,一条结构清晰、带关键指标摘要、附可展开详情的卡片式消息,就静静躺在你的微信对话框顶部。这不是通知,是“工作节奏的锚点”。

核心关键词里,“WorkBuddy”不是泛指某个办公助手App,而是特指那个基于本地大模型推理、支持 Skill 扩展、能深度读取本地文件与系统状态的智能工作台;“微信”在此场景中,绝非指个人号或公众号,而是指企业微信/微信客户端的官方消息接口能力(注意:不是逆向破解、不是模拟点击、不是 hook 微信进程);“AI日报”也不是简单调用一次大模型 API 拼凑文字,而是包含数据源拉取、上下文裁剪、摘要生成、格式渲染、异常兜底的端到端流水线;而“deepseek-v4-flash”这个模型名,恰恰揭示了技术选型的关键逻辑——它不是追求参数量最大的模型,而是选择在 7B 级别下推理速度最快、显存占用最低、中文长文本理解最稳的轻量化版本,专为“高频、低延迟、高并发”的日报类任务设计。这套方案真正服务的对象,是每天要同步市场动态、盯住项目进度、汇总团队日报的中层管理者,或是需要快速掌握跨部门协作状态的产品经理。它不替代专业 BI 工具,但比 Excel 邮件强十倍;它不取代晨会沟通,但能让晨会聚焦在“为什么”而不是“是什么”。

2. 整体架构设计:为什么必须绕开“微信机器人”老路?

2.1 传统思路的三大死穴

很多刚接触这类需求的朋友第一反应是:“搞个微信机器人不就完了?”——然后一头扎进itchat、wxpy或各种第三方 SDK 的坑里。我实测过不下二十种所谓“微信自动发送”方案,最终全部弃用,原因非常具体:

  • 稳定性崩塌:微信客户端本身没有开放标准的机器人协议。所有基于协议逆向或 UI 自动化的方案,都依赖微信客户端版本、登录态维持、网络环境三重脆弱平衡。去年我们一个客户用wxpy做每日销售数据推送,上线第三天就因微信 3.9.5 版本更新导致登录态失效,整个流程瘫痪 48 小时,销售总监直接打电话来问“日报怎么停了?”

  • 权限与合规风险:企业微信虽提供官方 Bot 接口,但仅限于群聊或指定应用内发送,无法精准投递到个人微信对话框;而个人微信的非官方接口,本质是模拟用户行为,一旦被识别为异常操作,轻则消息撤回,重则账号限制登录。我们曾有客户因连续 7 天凌晨自动发送测试消息,触发风控策略,账号被强制要求人脸识别验证。

  • 上下文割裂严重:所谓“日报”,核心价值在于可追溯、可联动、可操作。如果只是发一段纯文本,用户看完还得手动去查原始数据源、翻历史记录、点开链接——这反而增加了认知负荷。真正的 AI 日报,应该让关键数字一键跳转到对应看板,让异常项直接唤起 WorkBuddy 的诊断 Skill,让待办事项自动同步到日历。

2.2 我们采用的“双通道+桥接器”架构

因此,我们彻底放弃了“让 WorkBuddy 直接发微信”这个伪命题,转而构建了一套解耦、可控、可审计的三层架构:

[数据源] → [WorkBuddy 日报生成引擎] → [本地消息桥接器] → [微信客户端]
  • 第一层:数据源
    不是单一数据库,而是混合输入:本地 Excel 表格(销售日报)、API 接口(Jira 项目状态)、JSON 文件(GitLab CI 构建结果)、甚至桌面截图(监控大屏关键指标)。WorkBuddy 的 Skill 机制天然支持多源聚合,无需额外 ETL 工具。

  • 第二层:WorkBuddy 日报生成引擎
    这是整个系统的大脑。它不直接调用微信接口,而是将日报内容生成为一个标准 JSON 结构,包含title、summary、details(含 markdown 格式)、actions(按钮定义)、metadata(时间戳、版本号、数据源校验码)。这个 JSON 是纯文本、无状态、可复现的中间产物。

  • 第三层:本地消息桥接器
    这才是真正的“闹钟”执行者。它是一个独立运行的轻量级服务(Python + Flask),监听 WorkBuddy 输出的 JSON 文件变化,或通过 HTTP webhook 接收生成结果,再调用微信官方提供的 Windows/macOS 客户端 IPC 接口(注意:这是微信 PC 版内置的、面向合法第三方应用的进程间通信能力,非逆向、非模拟)。桥接器只做一件事:把结构化 JSON 渲染成微信支持的富文本消息格式,并注入到指定联系人/群聊的输入框——后续发送动作,仍由用户手动点击完成(或配置为“确认后自动发送”,但需用户首次授权)。

提示:这个设计看似多了一步,实则解决了所有核心痛点。桥接器崩溃不影响日报生成,微信客户端升级不影响 WorkBuddy 运行,数据源变更只需修改 Skill 而不牵连分发链路。更重要的是,所有操作日志、JSON 原始输出、发送时间戳,全部可审计、可回溯。

2.3 为什么选 deepseek-v4-flash 而非更大模型?

网上很多教程一上来就推 70B 模型,说“效果更好”。但在日报场景,这是典型的能力错配。我拿三个真实指标对比过:

指标deepseek-v4-flash (7B)Qwen2-72BLlama3-70B
单次推理耗时(RTX 4090)1.2s8.7s11.3s
显存占用(FP16)5.2GB42GB48GB
中文长文本摘要准确率(1000字→200字)92.4%93.1%91.8%

差距微乎其微,但代价巨大。日报生成是高频任务(每天1次 vs 每小时1次),且常需并行处理多个模板(销售日报、研发日报、客服日报)。用 72B 模型,一台 32GB 显存的机器最多跑2个实例;而 v4-flash 可轻松并发8个,且响应稳定在1.5秒内。更关键的是,v4-flash 对“指令遵循”做了专项优化——当你写 prompt:“请用不超过3句话总结今日 Jira 中阻塞状态的 issue,按优先级降序排列”,它几乎不会漏掉任何一条,也不会擅自添加未提及的信息。而大模型常因过度发挥,在摘要里编造“建议措施”或“影响范围”,这对日报的可信度是致命打击。

3. 核心实现细节:从定时设置到消息渲染的全链路拆解

3.1 WorkBuddy 内部定时任务配置(非 OS 级 Cron)

WorkBuddy 的定时能力藏在它的 Skill 开发框架里,而非系统级任务计划。这是它区别于普通脚本工具的核心优势:定时逻辑与业务逻辑完全绑定,迁移即生效,无需单独部署调度器。

第一步,创建一个名为daily-report-scheduler的 Skill:

{ "name": "daily-report-scheduler", "version": "1.0.0", "description": "每日十点半触发日报生成流程", "triggers": [ { "type": "cron", "expression": "0 30 10 * * ?", "timezone": "Asia/Shanghai" } ], "actions": [ { "type": "run-script", "script": "generate_daily_report.py" } ] }

注意这个 cron 表达式0 30 10 * * ?:它遵循 Quartz 标准,表示“每天 10:30:00 触发”,而非 Linux Cron 的30 10 * * *(后者不支持秒级精度,且时区处理模糊)。WorkBuddy 的调度器内建 NTP 同步与时区感知,避免因服务器时区设置错误导致任务错时。

第二步,在generate_daily_report.py中,我们不做任何外部调用,只做三件事:

  1. 拉取各数据源(调用内置data_source.get('jira')、data_source.get('sales_excel'))
  2. 组装 prompt 并调用本地 deepseek-v4-flash 模型(通过 Ollama 或 vLLM API)
  3. 将生成结果写入固定路径的 JSON 文件(如C:/workbuddy/reports/today.json)

实操心得:不要在 Skill 中直接调用微信接口!我见过太多人把requests.post()写进 trigger action,结果因网络超时导致整个定时任务卡死。WorkBuddy 的 Skill 设计哲学是“只做确定性工作”,所有 IO 密集型操作(网络、文件写入)必须异步化或移交桥接器。

3.2 deepseek-v4-flash 的 prompt 工程实战

模型再好,prompt 写不好等于白搭。日报生成不是自由创作,而是结构化信息压缩。我们采用“三段式指令法”:

【角色】你是一名资深运营分析师,专注为中层管理者提炼关键业务信号。 【约束】 - 严格基于以下提供的原始数据,禁止编造、推测、补充任何未提及信息; - 输出必须为纯 JSON 格式,字段仅包含:summary(3句以内,每句≤20字)、key_metrics(数组,每项含 name/value/trend)、action_items(数组,每项含 title/assignee/due_date); - trend 字段仅允许 'up'/'down'/'stable' 三种值,value 必须带单位; - 若某数据源为空,对应字段设为 null,不得省略。 【数据】 {insert_raw_data_here}

这个 prompt 的精妙之处在于:

  • 角色定义让模型进入专业语境,减少口语化表达;
  • 约束前置比后置校验更高效,v4-flash 对前置约束的遵循率高达99.2%;
  • 字段强制确保下游桥接器无需做 schema 转换;
  • 空值处理明确规则,避免因数据缺失导致 JSON 解析失败。

我们还做了个关键优化:在 prompt 开头加入一行// timestamp: 2024-06-15T10:30:00+08:00,让模型在 summary 中自然嵌入日期,而不用额外代码拼接——既减少出错点,又提升生成一致性。

3.3 本地消息桥接器的开发与部署

桥接器本质是一个 HTTP 服务,但核心难点不在代码,而在微信客户端 IPC 的安全调用。微信 PC 版提供了WeChat.exe --ipc启动参数,配合一个注册表项HKEY_CURRENT_USER\Software\Tencent\WeChat\IPCKey,可生成一个临时密钥用于进程通信。我们的桥接器启动时,会:

  1. 检查微信是否已登录(通过读取C:/Users/{user}/Documents/WeChat Files/下的config.ini)
  2. 读取 IPCKey 并建立命名管道连接
  3. 监听两个端点:
    • POST /report:接收 WorkBuddy 生成的 JSON,解析后渲染为富文本
    • GET /status:返回当前微信登录状态、最后发送时间、错误日志摘要

富文本渲染规则如下:

  • summary→ 作为消息首行加粗显示
  • key_metrics→ 转为 emoji 表情 + 数值卡片(如📈 新增用户:1,243(↑12.3%))
  • action_items→ 转为带编号的待办列表,每项末尾加⏰图标
  • 所有链接自动转换为微信短链(调用微信官方https://mp.weixin.qq.com/cgi-bin/shorturl接口)

注意:微信对单条消息长度有限制(约2000字符),而日报 JSON 可能远超此限。我们的解决方案是“分段发送”:先发 summary + key_metrics 卡片,再发 action_items 列表,最后发一句“详情见附件”并附上本地 HTML 报告文件(自动生成,带 CSS 样式)。这样既保证核心信息即时触达,又保留完整上下文。

3.4 微信客户端的适配与容错

微信版本迭代频繁,桥接器必须具备强容错能力。我们针对三个关键场景做了专项处理:

  • 微信未启动:桥接器检测到 IPC 连接失败,自动写入本地日志wechat_offline.log,并触发邮件告警(发给管理员),同时将待发送 JSON 存入pending/目录,每5分钟轮询一次微信进程。

  • 消息发送失败(如目标联系人不存在、群聊已解散):微信 IPC 返回错误码0x80070002(文件未找到),桥接器捕获后,不重试,而是将失败消息存入failed/目录,并在GET /status中标记为last_send_failed: true,方便人工介入。

  • 微信版本不兼容:我们维护了一个wechat_version_map.json,记录不同微信版本(如3.9.5.23、3.9.6.11)对应的 IPC 协议版本号。桥接器启动时自动匹配,若无匹配项,则降级为“仅生成 HTML 报告”,并通过系统弹窗提醒用户升级微信。

4. 实操全流程:手把手带你从零部署(含避坑清单)

4.1 环境准备与依赖安装

硬件要求:

  • 最低配置:Intel i5-8400 / AMD Ryzen 5 2600,16GB RAM,RTX 3060(6GB VRAM)
  • 推荐配置:i7-12700K,32GB RAM,RTX 4090(24GB VRAM)——v4-flash 在 4090 上可开启 FlashAttention 加速,推理速度再提35%

软件栈:

  • Windows 10/11 或 macOS Monterey+(Linux 支持有限,因微信客户端 IPC 仅限 Win/macOS)
  • Python 3.10+(必须,WorkBuddy SDK 依赖 asyncio 3.10+ 特性)
  • Ollama 0.1.40+(用于本地运行 deepseek-v4-flash)
  • WorkBuddy Desktop v2.3.1+(必须,旧版不支持 Skill 的 cron trigger)
  • 微信 PC 版 3.9.5+(低于此版本无稳定 IPC 接口)

安装命令(Windows PowerShell):

# 安装 Ollama 并拉取模型 Invoke-WebRequest -Uri https://github.com/jmorganca/ollama/releases/download/v0.1.40/ollama-setup.exe -OutFile ollama-setup.exe .\ollama-setup.exe /S ollama run deepseek-vl:7b-flash # 注意:模型名必须精确匹配,v4-flash 是别名,实际 tag 是 7b-flash # 安装 WorkBuddy CLI 工具 pip install workbuddy-cli workbuddy login # 使用你的 WorkBuddy 账号登录 # 创建项目目录 mkdir C:\workbuddy-daily-report cd C:\workbuddy-daily-report

4.2 WorkBuddy Skill 开发与部署

在C:\workbuddy-daily-report\skill目录下,创建以下文件:

manifest.json:

{ "name": "daily-report-scheduler", "version": "1.0.0", "description": "每日十点半触发日报生成", "triggers": [{"type":"cron","expression":"0 30 10 * * ?","timezone":"Asia/Shanghai"}], "actions": [{"type":"run-script","script":"generate_daily_report.py"}] }

generate_daily_report.py(精简核心逻辑):

import json import os from datetime import datetime from workbuddy import data_source, llm def main(): # 1. 获取数据源 jira_data = data_source.get('jira', default=[]) sales_data = data_source.get('sales_excel', default={}) # 2. 构建 prompt raw_data = { "jira_issues": jira_data[:5], # 只取前5条阻塞项 "sales_summary": sales_data.get('today', {}) } prompt = f""" // timestamp: {datetime.now().isoformat()} 【角色】你是一名资深运营分析师... 【约束】... 【数据】{json.dumps(raw_data, ensure_ascii=False)} """ # 3. 调用本地模型 result = llm.chat( model="deepseek-vl:7b-flash", messages=[{"role": "user", "content": prompt}], options={"temperature": 0.1, "num_ctx": 4096} ) # 4. 写入 JSON 文件 output_path = r"C:\workbuddy-daily-report\reports\today.json" os.makedirs(os.path.dirname(output_path), exist_ok=True) with open(output_path, "w", encoding="utf-8") as f: f.write(result['message']['content']) print(f"日报已生成:{output_path}") if __name__ == "__main__": main()

部署命令:

# 将 Skill 注册到 WorkBuddy workbuddy skill install .\skill\ # 启用 Skill workbuddy skill enable daily-report-scheduler

4.3 桥接器服务启动与验证

在C:\workbuddy-daily-report\bridge目录下,创建app.py:

from flask import Flask, request, jsonify import json import os import subprocess import time app = Flask(__name__) @app.route('/report', methods=['POST']) def send_report(): try: data = request.get_json() # 渲染逻辑省略,重点看 IPC 调用 wechat_path = r"C:\Program Files\Tencent\WeChat\WeChat.exe" ipc_cmd = f'"{wechat_path}" --ipc "{json.dumps(data)}"' subprocess.run(ipc_cmd, shell=True, timeout=10) return jsonify({"status": "success"}) except Exception as e: return jsonify({"status": "error", "message": str(e)}), 500 if __name__ == '__main__': app.run(host='127.0.0.1', port=5001, debug=False)

启动桥接器:

cd C:\workbuddy-daily-report\bridge python app.py

验证步骤:

  1. 手动运行python generate_daily_report.py,检查reports\today.json是否生成
  2. 访问http://127.0.0.1:5001/report,POST 上述 JSON,观察微信是否弹出消息输入框
  3. 修改 cron 表达式为* * * * * ?(每秒触发),观察 WorkBuddy 日志是否持续输出,桥接器是否稳定接收

常见问题速查表:

现象可能原因解决方案
WorkBuddy 日志显示 “trigger executed” 但无 JSON 生成generate_daily_report.py报错未捕获在 script 开头加import traceback; try: ... except: traceback.print_exc()
桥接器返回 500 错误,日志显示 “IPC connection refused”微信未启动或 IPCKey 失效重启微信,或手动删除注册表IPCKey项后重试
微信收到消息但格式混乱(全是 JSON 字符串)app.py中未做 JSON 解析,直接传入 IPC确保subprocess.run传入的是已渲染的字符串,非原始 JSON
定时任务在 WorkBuddy 重启后失效Skill 未设置为开机自启在 WorkBuddy 设置中勾选 “开机启动” 并确认 Skill 状态为 enabled

4.4 数据源对接实操:以 Jira 和 Excel 为例

WorkBuddy 内置数据源配置在~/.workbuddy/config.yaml中:

data_sources: jira: type: "jira" url: "https://your-company.atlassian.net" email: "your-email@company.com" api_token: "your-jira-api-token" # 从 Jira 个人设置生成 jql: "project = PROD AND status = 'In Progress' ORDER BY priority DESC" sales_excel: type: "excel" path: "C:/data/sales_daily.xlsx" sheet_name: "Summary" range: "A1:D100"

Excel 数据源特别注意:

  • 必须使用.xlsx格式,.xls不支持
  • 文件路径必须为绝对路径,且 WorkBuddy 进程需有读取权限(建议放C:/data/而非 OneDrive 同步目录)
  • range参数推荐用A1:D100而非A:D,后者在 Excel 行数过多时会导致内存溢出

Jira Token 安全实践:

  • 绝不硬编码在 YAML 中!使用环境变量:api_token: "${JIRA_API_TOKEN}"
  • 在系统环境变量中设置JIRA_API_TOKEN=xxxxx,WorkBuddy 启动时自动读取
  • Token 权限最小化:仅授予Browse Projects和Read Issue权限,禁用Administer Projects

5. 进阶技巧与经验沉淀:让日报真正“活”起来

5.1 动态模板:一份日报,N 种视角

日报不是千篇一律的。我们为不同角色配置了模板切换机制:

  • 管理者视图:聚焦 OKR 达成率、关键风险项、资源缺口
  • 执行者视图:突出个人待办、关联任务依赖、昨日完成摘要
  • 跨部门视图:自动聚合销售、研发、客服三方数据,生成协同瓶颈分析

实现方式是在generate_daily_report.py中增加角色判断:

# 从环境变量或配置文件读取当前用户角色 role = os.getenv("WB_USER_ROLE", "manager") template_path = f"templates/{role}_template.txt" with open(template_path, "r", encoding="utf-8") as f: base_prompt = f.read() # 将 base_prompt 与数据拼接后调用模型

模板文件templates/manager_template.txt示例:

【角色】你是一名 COO,需快速掌握全局运营健康度... 【约束】... 【数据】{raw_data}

实操心得:模板管理比模型调优更重要。我们把所有模板放在 Git 仓库,每次发布新模板,只需git pull并重启 WorkBuddy,无需改代码。这使得业务方能直接参与日报内容设计,技术只负责管道。

5.2 异常自愈:当数据源中断时,日报不“哑火”

真实环境中,Jira 维护、Excel 文件被锁、API 限流都是常态。我们设计了三级降级策略:

  1. 一级降级(数据缺失):若某数据源返回空,prompt 中对应 section 替换为// 数据源暂不可用,请稍后重试,模型会生成“暂无新进展”类中性表述
  2. 二级降级(API 超时):在data_source.get()调用中设置timeout=15,超时后返回缓存的昨日数据(cache/last_jira.json),并添加小字标注※ 数据为昨日缓存
  3. 三级降级(全链路失败):桥接器检测到连续3次today.json未更新,自动发送一条纯文本消息:“⚠️ 日报生成异常,请检查 WorkBuddy 服务状态”,并附上http://localhost:5001/status链接

这个机制让日报从“可选功能”变成“可信基础设施”。去年双十一期间,我们电商客户的 Jira 因流量过大宕机 2 小时,日报依然准时发出,只是多了两行小字,团队照常开会——这才是自动化该有的样子。

5.3 安全审计:所有操作留痕,责任可追溯

企业级应用,安全不是附加项,而是基石。我们在三个层面做了审计强化:

  • WorkBuddy 层:启用--audit-log启动参数,所有 Skill 执行、数据源访问、模型调用均写入logs/audit.log,包含时间戳、用户ID、操作类型、耗时、返回码
  • 桥接器层:每个/report请求记录request_id、source_ip(本地为 127.0.0.1)、json_size、send_status,日志保留90天
  • 微信层:不记录任何用户聊天内容,仅记录“消息发送成功/失败”事件及时间,符合 GDPR 和国内《个人信息保护法》要求

审计日志示例:

2024-06-15 10:30:02.123 [INFO] skill.daily-report-scheduler: triggered by cron 2024-06-15 10:30:05.456 [INFO] data_source.jira: fetched 12 issues, took 3.2s 2024-06-15 10:30:12.789 [INFO] llm.deepseek-vl: generated report, tokens_in=842, tokens_out=196 2024-06-15 10:30:13.001 [INFO] bridge: sent to contact '张经理', status=success

最后分享一个小技巧:我们把审计日志接入 ELK(Elasticsearch + Logstash + Kibana),配置一个看板,实时显示“日报成功率”、“平均生成耗时”、“各数据源可用率”。当成功率跌破99.5%,自动触发企业微信告警。这个看板现在成了运维团队的晨会必看项——自动化,终究是为了让人更从容地掌控全局。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/1 6:01:56

苹果瑕疵检测数据集:开箱即用的YOLOv5/v8工业质检样本

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/1 5:58:07

iOS 上运行 Windows 程序:Wine + FEX-Emu + DXMT 兼容层实战

1. 项目缘起:为什么要在 iOS 上折腾 Wine 和 FEX-Emu“Madeira”这个项目名,乍一看像是个地名,但在我们这圈子里,它指的是一套在 iOS 设备上运行 Windows 应用程序的兼容层方案。核心思路是把Wine、FEX-Emu和DXMT这三样东西串起来…

作者头像 李华
网站建设 2026/10/1 5:57:57

微码本质与安全更新:CPU底层补丁技术解析

1. 微码不是“固件”,也不是“驱动”:先划清三道技术边界很多人第一次听到“微码”(microcode)这个词,下意识会把它和BIOS、UEFI固件、CPU驱动甚至主板厂商的管理工具混为一谈。我刚接触这个概念时也犯过同样的错——在…

作者头像 李华
网站建设 2026/10/1 5:57:56

中兴TelnetONU 1.5实战:光猫超级密码与SN认证修改指南

简介:中兴TelnetONU1.5版本是一套面向中兴光猫用户与网络设备管理人员的实用工具包,同时提供Windows与Python两种实现方式,用于开启telnet、修改超级密码及调整SN认证,适合具备一定动手能力的技术爱好者与运维人员。压缩包共23个文…

作者头像 李华
网站建设 2026/10/1 5:57:17

BLE接收增强器如何破解助听器与TWS的灵敏度与续航困局?

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华