REA模型实战:用事件驱动重构订单与账务系统

1. "REA" 这个词,我前后摸索了好几天才真正接上话

我在某次内部架构评审会上第一次听到"REA"这个词,当时差点没接住话头。同事说"下单模块要继续加状态的话,后面退款和风控都很难做,不如按 REA 重建",我下意识以为是某个工具的名字,搜了一下发现搜索结果五花八门,有房产资讯、有环境评价机构,甚至还有语言学相关内容,唯独没有我要找的那个解释。如果你也是因为类似场景来搜"rea",这篇就是把这块拼图帮你补上。

先说三个最常撞车的含义,方便你判断自己找的是哪个:

场景"REA" 通常指什么
房产/地产房产中介、代理机构或相关服务品牌的缩写
环境与监管区域环境评估、可再生能源评估类职能机构的缩写
会计信息系统/架构设计Resource-Events-Agents 模型,即"资源—事件—参与者"业务建模方法

这篇要聊的是第三种,也是在我看来最值得花时间搞懂的一种。它不解决"怎么把代码写得漂亮"的问题,而是解决"业务事实该怎么记录才经得起对账、审计和纠纷追溯"的问题。适合后端开发、架构师、正在改造订单/账务系统的团队,以及任何一个被"应付款怎么调"、"历史数据被 update 覆盖了"这种问题折磨过的人。

2. REA 骨架拆解:Resource、Event、Agent 谁才是真正的主角

很多人第一眼看到 REA 模型都会被名字骗了,以为三样东西平起平坐。实际上,Event(事件)才是整个模型的灵魂,Resource 和 Agent 更像是事件的两个维度,一个说明"什么东西发生变化",一个说明"谁对谁发生这个变化"。

2.1 Resource:它可以是一杯咖啡,也可以是一笔积分余额

Resource 对应的是"经济资源",定义上很宽泛:现金、商品、积分、虚拟币、服务产能、甚至一段可以被授权使用的数据,只要它满足两个条件——能被某一方持有或支配,并且持有或支配会产生经济后果。

我在设计时习惯把 Resource 继续分两类:一类是"存量型资源",比如账户余额、库存数量,它在任何时候都有明确的数量;另一类是"记录型资源",比如一笔订单、一次服务记录,它没有严格意义上的"余额",但有"是否发生过"和"归属谁是"的判断。分类不是必须的,但能让你在想"正负号怎么算"的时候少挠头。

2.2 Event:事实入库,状态靠计算

Event 记录的是"已经发生的经济事实",比如支付、发货、收货、退款。REA 的核心纪律是:事实一旦入库,原则上不允许修改或删除。后续任何变化都通过追加新事件来表达。

这个纪律和普通 CRUD 的思维差异非常大。常规订单表里一个status字段,从pending改成paid再改成refunded,过程全被覆盖,只能靠操作日志猜。而事件流方式下,每次状态变更都是一条新记录,账户余额、库存数量都可以直接从事件重新计算出来,谁也别想"偷改账"。

2.3 Agent:决定"谁对谁负责"

Agent 就是"参与者",分为内部参与者和外部参与者。内部参与者是你的员工、部门、平台自身;外部参与者是客户、供应商、银行渠道等等。两方和一个资源往往构成一个最小经济交换单元。

比如你在咖啡店买一杯咖啡,REA 视角下至少包含两组经济交换:一组是现金交换——你的现金资源减少,店家现金资源增加;一组是商品交换——店家咖啡库存减少,你获得咖啡。所以别急着把"下单付款"当一条操作,它其实是两条事件链的组合。

明确 Agent 有什么好处?对账时你能精确回答"这笔钱到底从谁账户到了谁账户",而不是笼统地 "订单支付成功"。到了退款和差错处理环节,这个答案就是决策依据。

2.4 Policy:REA 中容易被忽视的"第四位成员"

原始 REA 模型严格说只有 R、E、A,但落地时基本都要补一个 Policy,用来定义"何时允许发生哪个事件"。比如"必须先付款后发货""单笔退款不得超过原金额""同一订单只允许一次全额退款"。Policy 本身不产生事件,但它是事件入账的校验规则。

我自己的经验是:先有 Policy,再写recordEvent的执行逻辑。把业务规则从代码的 if-else 里抽出来,变成配置化或至少标注化的规则清单,后面审计和合规沟通会顺畅很多。

3. 为什么我决定用 REA 重写订单模块:三个传统模型的硬伤

有人会问,市面上大部分系统就是"订单表 + 状态机 + 流水表",不也跑得好好的吗?我在决定重构之前也这么想,直到一次真实的财务纠纷让我看到问题:用户退款了,订单状态改成了"已退款",但财务流水里有一笔原始支付记录没有配套冲正记录,对账时两边对不上,最后只能人工翻日志手工补单。

这类问题的根源,可以归结为传统模型的三点硬伤:

硬伤传统订单+状态机REA 事件模型
历史被覆盖update 状态,覆水难收追加事件,事实永久保留
余额与流水脱节余额是独立字段,错了难定位余额由事件重算,可追溯
退款造"负订单"逆向逻辑各不相同,口径混乱反向事件天然对称

3.1 状态枚举的"三宗罪"

订单状态枚举会越来越复杂:待支付、已支付、待发货、已发货、已收货、退款中、已退款、部分退款……每次新增业务都要在状态机里加节点,还免不了"非法迁移"的坑。更麻烦的是,状态字段本质上是"结论",而不是"原因"。当你看到一条订单处于"已退款",你并不知道它经历了怎样的事件序列,这对风控和客诉处理都不够友好。

REA 不是彻底消灭状态,而是把状态降级为"由事件推导出来的展示层字段"。展示层想看到一个订单流转历史?直接按时间拉事件即可,不需要在订单表里维护数组字段。

3.2 从"改字段"到"算字段":余额问题的本质解法

传统账户表里的balance字段,最大的问题是它和流水可能不一致。扣款时先改余额,再插流水,如果第二步失败,余额和流水就过掉了。REA 的思路反过来:先管好事件,余额是事件计算出的投影。

实际操作时,我不会真的每次都全表聚合算余额,而是维护一份"余额投影表",每当新事件落库,就在同一事务里更新投影。这相当于做了物化视图,既保留事件溯源的可重算性,又保住查询性能。

3.3 它和借贷记账法不是一回事,而是更上游

不少财务背景的朋友一看到 REA 就说"这不就是借贷记账吗",我起初也有这个错觉,后来才理清关系。借贷记账法(借方/贷方)属于记账层,规定的是"分录怎么写、借贷怎么平衡";REA 属于业务本体层,回答的是"经济事实的语义是什么"。

用 REA 事件可以投影出任何你需要的会计口径:凡是"资源从 A 流到 B",你总能拆成 A 的贷方和 B 的借方。换句话说,REA 是更上游的事实层,借贷分录只是下游的报表投影方式。这个理解一旦打通,你就不会被"REA 会不会和现有财务系统冲突"吓到——它不冲突,它只是把源头理顺了。

4. 落地实战:用 REA 思想重做一个二手交易结算模块

光讲概念容易飘,我直接用一个真实做过的"模拟项目X"来说明。某二手交易社区原先把"抢单、托管、确认收货、退款"全放在一张order表里,字段越加越多,团队决定重写结算模块,我们按 REA 思路做了完整的落地。

4.1 领域建模:先画资源,再画事件

动手写代码前,先别急着建表,按两步做领域建模:

  1. 列出所有 Resource:用户平台余额(积分)、商品、平台托管资金池、提现用的现金池。
  2. 列出所有 Agent:买家、卖家、平台自身、外部支付渠道。

然后画出事件链。这里我建议用一张简单的流程表来理清每个业务动作对应哪些事件:

业务动作涉及资源事件方向
充值现金池,平台余额渠道→平台入现金;平台→用户增余额
下单托管平台余额买家余额减,平台托管池增
确认收货商品,托管池卖家交付商品给买家;平台托管池给卖家增余额
退款平台余额平台托管池→买家余额回补

关键原则是"一增一减成对出现"。托管时买家余额减,托管池就要增;收货时托管池减,卖家余额就要增。每一对事件都保证守恒,这就是后续对账能自动平衡的原因。

4.2 四张核心表和建表 SQL

我们最终落地了四张核心表:resource、agent、economic_event、commitment。前两张是基础主数据,后两张是业务事实。

-- 资源:平台内可被交易和追踪的价值载体 CREATE TABLE resource ( id BIGSERIAL PRIMARY KEY, resource_type VARCHAR(20) NOT NULL, -- PLATFORM_CREDIT / ITEM / CASH_POOL code VARCHAR(64) NOT NULL UNIQUE, name VARCHAR(128) NOT NULL, unit VARCHAR(20) NOT NULL DEFAULT '个' ); -- 参与者:内部与外部 CREATE TABLE agent ( id BIGSERIAL PRIMARY KEY, agent_type VARCHAR(20) NOT NULL, -- USER / PLATFORM / CHANNEL external_uid VARCHAR(64), name VARCHAR(128) NOT NULL ); -- 经济事件:事实流水 CREATE TABLE economic_event ( id BIGSERIAL PRIMARY KEY, event_time TIMESTAMPTZ NOT NULL DEFAULT NOW(), event_type VARCHAR(20) NOT NULL, -- RECEIVE / PROVIDE resource_id BIGINT NOT NULL REFERENCES resource(id), quantity NUMERIC(18, 4) NOT NULL, -- 正数表示数量,方向由 from/to 表达 from_agent_id BIGINT REFERENCES agent(id), to_agent_id BIGINT REFERENCES agent(id), ref_no VARCHAR(64) NOT NULL ); CREATE UNIQUE INDEX uk_economic_event_ref_no ON economic_event(ref_no); -- 承诺:预排但尚未发生 CREATE TABLE commitment ( id BIGSERIAL PRIMARY KEY, planned_time TIMESTAMPTZ, resource_id BIGINT NOT NULL REFERENCES resource(id), quantity NUMERIC(18, 4) NOT NULL, from_agent_id BIGINT REFERENCES agent(id), to_agent_id BIGINT REFERENCES agent(id), status VARCHAR(20) NOT NULL DEFAULT 'OPEN' );

commitment表一开始很容易被忽略。它记录的是"承诺但尚未发生"的业务,比如买家下单后商家还没发货,此刻商品和钱都没真正流动。承诺不该影响余额计算,但它是业务状态的重要组成部分。没有这张表,你就只能靠脑补或者状态字段。

4.3 业务代码里如何落一个事件

领域层我通常只暴露一个recordEvent方法,所有业务动作最后都收敛到这里。它要保证两件事:幂等、事务一致。

type EconomicEvent = { eventType: "RECEIVE" | "PROVIDE"; resourceId: string; quantity: number; // 恒为正数 fromAgentId?: string; toAgentId?: string; refNo: string; // 业务关联号,用于幂等 }; async function recordEvent(event: EconomicEvent, tx: Transaction): Promise<void> { // 1. 校验 Policy:比如 fromAgent 余额是否足够 await assertPolicy(event, tx); // 2. 幂等检查:ref_no 重复则直接返回,防止网络重试造成双花 const existing = await tx.query( "SELECT id FROM economic_event WHERE ref_no = $1", [event.refNo] ); if (existing.rows.length > 0) return; // 3. 落事件,同一事务里更新余额投影 await tx.query( `INSERT INTO economic_event (event_type, resource_id, quantity, from_agent_id, to_agent_id, ref_no) VALUES ($1, $2, $3, $4, $5, $6)`, [event.eventType, event.resourceId, event.quantity, event.fromAgentId, event.toAgentId, event.refNo] ); await updateBalanceProjection(event, tx); }

ref_no是防重试的命脉。我们遇到过支付渠道重复回调、前端双击下单、队列重投三种情况,靠它全部挡下了。给它的建议是:全局唯一,且每个业务场景有自己的前缀规则,比如PAY_订单号_时间戳、REFUND_订单号_序号,排查问题的时候一眼就能定位链路。

4.4 托管、收货、退款:三条路径的完整事件推演

我用一个具体数字走一遍。买家 A 下单购买了卖家 B 的 100 元商品,场景如下:

步骤事件资源变动
1. 下单托管A → 平台托管池,PROVIDE 100A 余额 -100,托管池 +100
2. 卖家发货B → A,商品 PROVIDE 1商品从 B 转移到 A
3. 确认收货平台托管池 → B,PROVIDE 100托管池 -100,B 余额 +100
4. 部分退款平台托管池 → A,PROVIDE 20托管池 -20,A 余额 +20

每一步都可以独立审计。最后对账时只要执行同样的余额推算 SQL,任何一环出错都会被立刻揪出来。

-- 计算某用户当前某资源的余额 SELECT e.resource_id, SUM(CASE WHEN e.to_agent_id = :agentId THEN e.quantity WHEN e.from_agent_id = :agentId THEN -e.quantity ELSE 0 END) AS balance FROM economic_event e WHERE e.from_agent_id = :agentId OR e.to_agent_id = :agentId GROUP BY e.resource_id;

这段 SQL 的重点是"方向由 from/to 决定"而不是由正负号决定。quantity永远是正数,表达语义时更不容易出错。如果你在传统系统里习惯"正数入、负数出",这套模型初期可能需要适应一下,但适应之后你会发现代码里几乎没有"负数到底代表扣还是退"的判断谜题了。

5. 这五个坑我全都踩过,写出来帮你绕开

落地 REA 的过程远没有 UML 图那么美好。下面五个问题,是我在不同项目里真实遇到的,每一条都让团队付出过加班代价。

5.1 误区一:把 REA 当成 Event Sourcing 来宣传

Event Sourcing 是技术层面的持久化策略,REA 是业务语义模型,两者能配合,但不能画等号。如果团队没理解 REA 的"资源—事件—参与者"语义,只看见"追加事件"这个表象,很容易搞出一堆技术上叫事件、业务上说不清来源的流水。

我们的教训是:引入 REA 时,先给团队讲清楚"哪些动作算经济事件、哪些是承诺、哪些只是展示层状态",而不是上来就讨论数据库架构。

5.2 误区二:所有资源都用同一套正负号逻辑

资源和资源之间差异很大。现金、余额这类资源适合做"存量余额推算";但商品资源如果只做数量推算,就无法回答"是哪个批次、哪个 SKU、什么成色"这种明细问题。所以我在实现时给resource_type分了类,不同类型用不同的查询器。

建议提前定义好资源细粒度。比如把"商品"建模到 SKU 级别,而不是笼统的"货品"级别,否则事件流越滚越大,后来再想拆分成本极高。

5.3 误区三:余额投影和事件流不在同一事务里更新

这是掉过最多坑的地方。如果先插事件成功、更新投影失败,余额和事实立刻不一致;反过来先改投影再插事件,查流水时会发现缺了凭证。必须在同一个数据库事务里完成两步。

分布式场景下,如果多个服务都写事件,需要引入独立的事件服务或至少统一的事件表入口,别让业务服务各自往表里乱插。

5.4 误区四:给前端直接查事件表

事件表适合写入和审计,但不适合直接给前端列表、报表做展示。买家看到的是"订单号、金额、状态、时间",不是一堆 fromAgent/toAgent 的技术流水。因此必须做查询投影,把事件流聚合出订单视图、交易视图、余额视图等。

我的建议是让每个查询投影对应一个明确的业务问题,比如"我的订单列表""我的余额""我的结算明细"。投影数据可以由事件流重建,也可以定期校正。

5.5 误区五:小项目也套全套 REA

REA 的完整模型,对大部分小工具来说有点过度设计。如果你只需要一个简单的记账本、一个原型 Demo、或者一个状态不会反复横跳的内部小系统,状态机反而更直接。

我个人的判断标准很简单:当"冲正"、"对账"、"多方交易"、"审计追溯"出现两个以上,才值得引入 REA。它在项目早期看起来像绕远路,但一旦业务规模上来,你会发现它是唯一能让多方信任同一套事实基础的模型。

所以如果你现在还在犹豫要不要用,我建议从小模块试点开始——比如把"余额变动"单独抽成事件流,其余部分继续沿用状态机。等团队真正理解了 Resource、Event、Agent 这套语义,再逐步扩大范围。最后再分享一个我坚持了很久的习惯:每次事件落库时,把当时的业务上下文(订单号、操作人、操作终端、IP)作为事件元数据一并存下来,这些看似冗余的信息,在日后客诉和合规审计时,比任何一张表都更有说服力。

相关新闻

技能学习的底层逻辑:从收藏到实战,打造个人能力系统

技能学习的底层逻辑:从收藏到实战,打造个人能力系统

"skills"这个词这几年在热搜里的出现频率越来越高。今天网络热词是AI、提示词、搞钱、上岸&#xff0c;明天是内卷、复盘、长期主义、个人IP&#xff0c;但你把每一轮热度拆开看&#xff0c;背后其实都是同一个问题&#xff1a;怎么让自己变得更有价值。技能学习说穿…

2026/10/20 13:35:45 阅读更多 →
SVN服务器IP变更实战:relocate命令原理与批量迁移避坑指南

SVN服务器IP变更实战:relocate命令原理与批量迁移避坑指南

能在一天之内把整个开发部的SVN地址从旧IP迁到新IP&#xff0c;其实不是个复杂活&#xff0c;但你如果没搞清楚SVN地址到底存在哪里、用什么命令改、改了之后哪些人还要跟着动&#xff0c;那这件事可能从五分钟变成一下午。最近我又处理了一轮SVN服务迁移&#xff0c;把所有要改…

2026/10/20 13:35:45 阅读更多 →
基于Win32 API与GDI+的捕鱼达人游戏开发实战:C++课程设计完整方案

基于Win32 API与GDI+的捕鱼达人游戏开发实战:C++课程设计完整方案

简介&#xff1a;这是一份面向高校C课程设计与Windows游戏开发初学者的实践项目源码&#xff0c;主题为经典小游戏“捕鱼达人”。项目以C语言为基础&#xff0c;结合Windows API完成窗口创建、消息循环与事件响应&#xff0c;并借助GDI绘制游戏背景、鱼群、炮台与子弹等元素&am…

2026/10/20 13:34:41 阅读更多 →

最新新闻

科研场景下大模型技能包配置指南:论文写作、数据可视化与汇报材料三大核心技能包

科研场景下大模型技能包配置指南:论文写作、数据可视化与汇报材料三大核心技能包

1. 科研场景下大模型技能包的真实需求拆解科研工作流和普通的内容创作、代码开发有本质区别。一篇论文从选题到最终发表&#xff0c;中间要经历文献调研、实验设计、数据处理、图表绘制、论文撰写、同行评审回复、会议汇报等多个环节&#xff0c;每个环节对AI辅助的需求都不一样…

2026/10/20 14:19:19 阅读更多 →
多智能体协作翻车实录:32倍耗时13倍Token换来准确率下降

多智能体协作翻车实录:32倍耗时13倍Token换来准确率下降

1. 从一次翻车的多智能体协作实验说起去年下半年&#xff0c;我接手了一个内部知识库问答系统的重构任务。需求本身不算复杂&#xff1a;把散落在多个文档仓库里的技术资料整合起来&#xff0c;做一个能回答"某个接口怎么调用""某个配置项默认值是多少"这类…

2026/10/20 14:19:19 阅读更多 →
2026年9月GitHub十大热门项目盘点:本地推理、数据管道与终端效率工具

2026年9月GitHub十大热门项目盘点:本地推理、数据管道与终端效率工具

1. 榜单背后的筛选逻辑&#xff1a;为什么这十个项目能上榜每个月月初我都会花两三个小时翻一遍 GitHub Trending 和几个技术社区的月度汇总&#xff0c;时间久了慢慢摸出一些门道。2026 年 9 月这一期的十大热门项目&#xff0c;乍看之下题材跨度很大——有做本地推理的、有做…

2026/10/20 14:19:19 阅读更多 →
多播与广播编程实战:从原理到代码排障

多播与广播编程实战:从原理到代码排障

我最早接触多播和广播&#xff0c;是在调一个局域网内多台设备的同步程序时被逼出来的。当时用单播一条条发指令&#xff0c;设备一多&#xff0c;数据包就像早高峰的地铁&#xff0c;挤在一条链路上&#xff0c;延迟和丢包全都来了。后来换成广播&#xff0c;一台发、全网收&a…

2026/10/20 14:19:19 阅读更多 →
AI芯片选型指南:从TOPS参数到功耗生态的实用过滤方法

AI芯片选型指南:从TOPS参数到功耗生态的实用过滤方法

年初有位朋友做边缘计算设备选型&#xff0c;一开始列了个 AI 芯片候选清单&#xff0c;拢共 57 款&#xff0c;觉得已经覆盖得很全面了。结果调研越做越深&#xff0c;发现同一个厂家在不同产品线、不同代际、甚至不同封装下都会分出好几款&#xff0c;最后这份清单硬生生整理…

2026/10/20 14:19:18 阅读更多 →
多模态数据扩散模型做预测:原理、实操与工程落地全解析

多模态数据扩散模型做预测:原理、实操与工程落地全解析

打开扩散模型相关论文的时候&#xff0c;我第一反应也是“又一个做图像生成的”。直到我自己把扩散模型接到一个多模态预测项目上&#xff0c;才发现这条路的价值被严重低估了。传统的预测模型&#xff0c;不管是LSTM、Transformer还是各种树模型&#xff0c;本质上都在学“给定…

2026/10/20 14:18:12 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

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

2026/10/20 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

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

2026/10/20 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

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

2026/10/20 1:01:30 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型&#xff08;GMM&#xff09;的语音识别系统&#xff0c;很多人第一反应就是一堆数学公式&#xff0c;觉得门槛很高。但如果你真的在MATLAB里把它落地跑通&#xff0c;会发现核心其实就是三件事&#xff1a;把声音变成特征向量&#xff0c;用GMM给每个类别…

2026/10/20 10:02:13 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人&#xff0c;但落到具体操作上&#xff0c;无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程&#xff1a;对图像做反白、改调色板、彩色转灰度&#xff0c;最后把像素数据导出成txt文件。单看每一…

2026/10/19 17:32:41 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词&#xff0c;你会发现一个很有意思的现象&#xff1a;每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型&#xff0c;有人指的是运动控制系统&#xff0c;还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

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

2026/10/20 10:02:08 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

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

2026/10/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

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

2026/10/20 9:50:45 阅读更多 →