公寓管理系统租务闭环:合同、账单与退租清算的状态机设计

整套公寓管理系统做到第三个阶段,我明显感觉画风变了。前两个阶段还在跟公寓、房间、租客档案这些基础数据打交道,写起来就是标准的增删改查;到了第三阶段,突然要面对的是租赁合同、账单、退款、逾期这些带着钱和时间的业务,稍不留神就会把自己绕进去。这个阶段的目标很明确:把一套房子从签约到退租的完整业务链路跑通,让合同状态、账单状态、款项记录在系统里能对上账。

这篇就记录我在这个阶段做功能拆分、数据模型设计、费用计算和联调时踩过的坑,以及最后采用的方案。如果你也正在做一个类似的公寓管理系统,或者手头有带钱、带状态流转的业务系统要开发,这部分经验可以直接照抄。

1. 第三阶段不是在写CRUD,是在搭一条能跑通的租务闭环

1.1 我理解的第三阶段业务边界

前面两个阶段如果把公寓、楼栋、房间、租客档案这些静态数据都维护完了,第三阶段要做的就是动态业务:运营人员选中一间房,给某个租客发起签约;签约成功后系统根据租期和付款方式自动生成账单;租客支付后系统登记收款;租期临近时系统提醒续租或退租;租客申请退租后走退租清算,处理水电费差额、押金退还和剩余租金结算。

这一整条链路里,核心实体从原来的“房间”“租客”变成了“合同”“账单”“退款单”。换句话说,第三阶段的本质不是给某个表多写几个接口,而是给公寓运营建立一套可审计的台账。

为什么不能只靠原来的房间表加几个字段硬撑?原因很简单:一份合同的寿命可能长达一年甚至两年,期间房间调价、租客换房、水电单价变化都可能发生。如果没有独立的合同和账单记录,等合同结束再去追溯当时签多少钱、收过多少钱、退了多少押金,基本无从查起。

1.2 功能不是越多越好,先把主链路跑通

我一开始上手时列了一堆需求:自动生成账单、短信提醒、逾期违约金、退租清算、财务报表、经营统计……全部铺开之后发现根本做不完。后来重新排序,才把功能收敛到一条最小可用链路上。

功能模块依赖的前序功能如果延期会怎样
签约生成合同房态管理、租客档案系统无法进入租务流程
账单自动生成合同生效无法正常收租
账单支付与状态流转账单生成收款记录对不上
退租清算与退款账单、款项记录合同无法正常关闭
临期提醒与逾期处理账单状态、合同状态运营全靠人工盯

优先级原则很简单:先把“签约 -> 收租 -> 退租”这一条主线跑通,再来处理提醒、统计、报表这些辅助能力。如果一开始就把所有功能堆上来,联调的时候会非常痛苦,因为你根本分不清报错是主流程的问题还是辅助功能的问题。

2. 从合同到账单:表结构里的快照思维

2.1 合同主表:价格与租期必须冻结在现场

合同表是这个阶段最重要的表,没有之一。设计的时候我反复强调一个词:快照。合同一旦签约成功,租金单价、押金金额、租期起止这些关键信息就应当原原本本存进合同表,而不是去关联房间表实时读取当前价格。

为什么?举个实际场景:房间月租从3000元调到3500元,如果合同里没有存租金快照,那么历史合同查询时会跟着房间价格变成3500元,账面全乱了。租房合同签完字,合同上写了多少就是多少,不会因为房价上涨而改变。这就是快照思维。

我当时建的合同主表大概长这样:

CREATE TABLE lease_contract ( id BIGINT PRIMARY KEY AUTO_INCREMENT, contract_no VARCHAR(32) NOT NULL COMMENT '合同编号', room_id BIGINT NOT NULL COMMENT '房间ID', tenant_id BIGINT NOT NULL COMMENT '租客ID', rent_amount DECIMAL(10,2) NOT NULL COMMENT '租金快照', deposit_amount DECIMAL(10,2) NOT NULL COMMENT '押金快照', lease_start_date DATE NOT NULL COMMENT '租期开始日', lease_end_date DATE NOT NULL COMMENT '租期结束日', status TINYINT NOT NULL COMMENT '1草稿 2生效中 3已到期 4已退租 5已作废', created_time DATETIME NOT NULL, updated_time DATETIME NOT NULL ) COMMENT '租赁合同表';

合同状态我一开始只留了“生效中”和“已退租”,后来发现根本不够用。运营人员新建合同还没确认时要能保存;合同到期后不一定是退租,可能直接转续租;退租流程走到一半也不能算完全结束。所以最终定成了五个状态:草稿、生效中、已到期、已退租、已作废。

每个状态能做的操作是完全不同的:草稿可以改、可以作废;生效中可以发起退租申请;已退租后只允许查看和退款登记,不能再执行签约相关操作。状态机不设计清楚,后面接口校验会写得怀疑人生。

2.2 账单表:把“该收的钱”拆成可追踪的明细

合同签约后要收钱,这里我踩了第一个大坑:一开始计划只用一张“收费记录表”记录所有收款,后来发现问题很大——什么时候该收、哪笔钱对应哪个周期的租金、哪笔钱已经逾期,根本表达不出来。最终老老实实拆了一张账单表。

CREATE TABLE bill ( id BIGINT PRIMARY KEY AUTO_INCREMENT, bill_no VARCHAR(32) NOT NULL COMMENT '账单编号', contract_id BIGINT NOT NULL, tenant_id BIGINT NOT NULL, bill_type TINYINT NOT NULL COMMENT '1租金 2押金 3水费 4电费 5杂费', period_start DATE COMMENT '费用周期开始日', period_end DATE COMMENT '费用周期结束日', amount DECIMAL(10,2) NOT NULL COMMENT '账单金额', status TINYINT NOT NULL COMMENT '0待支付 1已支付 2已逾期 3已作废 4已退款', due_date DATE NOT NULL COMMENT '应缴日期', pay_time DATETIME COMMENT '实缴时间', payment_no VARCHAR(64) COMMENT '支付流水号', created_time DATETIME NOT NULL, updated_time DATETIME NOT NULL, UNIQUE KEY uk_bill_no (bill_no), KEY idx_contract (contract_id), KEY idx_tenant_due (tenant_id, due_date) ) COMMENT '账单表';

账单表的核心价值在于,每个合同会衍生出多期账单,每期账单有独立的周期、金额和状态。租金月付的就按月生成,押金单独生成一笔押金账单,水电费则在实际抄表后生成。这样每一笔钱都能追溯到具体合同、具体时间段、具体费用类型。

租客付了租金之后,账单状态从“待支付”变成“已支付”,同时记录实缴时间和支付流水号。如果又退租退款,原账单状态变成“已退款”,但这条记录不能被删掉。财务上的每一笔账都应当在历史里留痕。

2.3 为什么我坚持不在查询时实时计算账单金额

其实账单金额是可以算出来的,比如“月租3000,住了5个月,就是15000”。我为什么不这么干,而是每期账单都落库?

因为业务一旦跑起来,对账场景会非常复杂。租客可能中途换房、可能水电费单价调整、可能某个账单只收了一半钱、可能因为投诉减免了一部分租金。这些情况如果都靠查询时实时计算,逻辑会膨胀到没法维护。

账单落库之后,它就成为一笔独立存在的财务凭据。运营人员查看历史账单,看到的就是当时生成时记录的金额,不会因为后来房租涨价或水电单价调整而变化。这就是快照思维在账单表上的延伸。

3. 租金、押金、退款分摊:费用计算的边界条件

3.1 月付账单与跨月拆分的计算规则

费用计算是这个阶段最容易出bug的地方,尤其是跨月账单。我当时的业务约定是:租金按月支付,签约日就是每期账单的起算日。比如租期从1月15日开始,月租3000元,第一笔账单按整月收,也就是1月15日到2月14日这一期,到期日是2月14日。

听起来很简单,但退租时的费用结算是另一个故事。租客3月10日退租,3月10日到4月14日这一整期租金已经收了,该怎么退?我采用的方案是:按照实际剩余天数折算。一个月按30天计算,剩余天数从3月10日到4月14日一共35天,应退金额 = 月租 / 30 × 35 = 3500元。

水电费也是类似逻辑。每次抄表后保存“上期表底数、本期表底数、单价”三个关键字段,生成费用时用差值乘以单价。这个操作同样要落快照,因为一旦下次单价变了,历史账单不应该跟着变。

我当时把所有费用计算逻辑收敛到了一个独立的FeeCalculator服务里,不散落在各个Controller中。这样后续调整计算规则时,只需要改一个类,测试也能集中覆盖。

3.2 退租清算里的退款顺序与状态机

退租是整个阶段里业务节点最多、最容易乱的操作。我梳理出来的完整流程是:租客发起退租申请 -> 运营确认房屋交接 -> 读取最后一次水电表底数生成水电账单 -> 生成退租清算单 -> 财务审核退款 -> 合同状态变为已退租。

其中退租清算单要分三块展示:待结账单列表、押金退还金额、剩余租金退还金额。退款顺序也有硬性约定:先抵扣租客尚未支付的账单,再退押金,最后退剩余租金。举个例子,押金2000元,退租时发现还有一笔500元电费没付,那么清算单上会显示“抵扣欠费500元,实际退还押金1500元”。

合同状态流转我设计成了:生效中 -> 退租申请中 -> 清算中 -> 已退租。状态不能跳变,比如租客还在退租申请中,运营不能直接把它改成已退租,必须走完清算流程。如果退款单填写错误被作废,合同状态要回到清算中,不允许直接在已退租状态下修改数据。

3.3 金额类型先统一成最小单位

这是最基础也是最重要的一个决定:Java代码里所有金额都用BigDecimal,数据库字段用DECIMAL(10,2),绝对不用float和double。

浮点数的坑我就不详细展开了,简单说就是0.1 + 0.2在二进制里不是0.3,算出来是0.30000000000000004。账单金额一旦出现这种精度问题,财务对账根本没法做。

我在项目里额外加了一个MoneyUtils工具类,统一处理金额的加法、减法、乘法以及向上取整到分的逻辑。每个涉及金额的入参和出参都用BigDecimal接收,避免某处不小心写了个double导致金额异常。

4. 深夜定时任务:逾期账单、临期提醒与自动归档的取舍

4.1 每天凌晨扫描账单,把“待支付”变成“已逾期”

账单生成了不代表钱一定会按时到账。我的系统里每天凌晨两点跑一个定时任务,扫描所有状态为“待支付”、应缴日期小于今天日期的账单,把它们统一更新为“已逾期”。

定时任务的逻辑非常简单:

@Service public class BillOverdueTask { @Scheduled(cron = "0 0 2 * * ?") public void processOverdue() { // 1. 分页查询状态为待支付、应缴日期小于今天的账单 // 2. 逐条更新状态为已逾期,写入账单状态变更日志 // 3. 组装站内信和短信提醒消息,批量发送 } }

为什么非要用定时任务,而不是在支付回调的时候顺便判断?因为租客可能一直不付钱,没有任何回调会发生,只有定时任务才会主动发现“这笔账已经拖了两周了”。这也是这类业务流程里很典型的思维转换:不是每个业务动作都由用户操作触发,系统自己也要有主动检查的能力。

4.2 合同到期预警与自动归档的取舍

合同到期前30天、前7天,系统要分别生成临期提醒。提醒不能做成实时查询,否则每次查看都重复提醒,我单独建了一张remind_log表,记录合同ID和提醒类型,避免同一条提醒被发送多次。

合同到期之后的状态,我一开始想直接自动变成“已退租”,后来发现不行。到期和退租是两件事:到期只是租期结束,但如果租客还有未结清的账单,或者押金还没退,合同就不能关闭。我的方案是:合同到期后状态自动变为“已到期”,此时如果没有任何未支付账单且押金退款已经结清,再由系统自动转成“已退租”并归档;否则就进入“清退待办”,等运营人工处理。

自动归档看起来省事,实际上把太多假设塞进了系统里。账没结清、押金没退,合同就自动关了,后续财务报表会非常难看。这里我宁可保守一点,让机器做扫描和提醒,让运营做最终决策。

4.3 定时任务的幂等与防堆叠

定时任务跑多了有一个隐藏问题:重入和堆叠。如果任务执行时间超过了任务间隔,下一个任务进来后可能会重复处理同一条数据,造成重复扣款或重复提醒。我的做法是加分布式锁,或者用数据库唯一约束挡住重复执行。

我给每个任务都设计了一张task_execution表,任务名加执行日期做唯一索引。每次任务开始先插入一条执行记录,如果插入失败说明当天已经跑过了,直接跳过。处理账单明细数据时也采用分页扫描,不在一次查询里加载全表数据,防止内存溢出和锁表。

5. 支付回调、跨表事务与对账兜底:联调阶段的三场硬仗

5.1 支付回调与本地状态更新的一致性处理

接入支付渠道是让我最头疼的部分。租客扫码付钱后,支付平台会异步回调我们的后端接口。回调可能因为网络超时被重发,也可能在我们更新状态到一半的时候系统重启,导致支付流水已经扣了钱,本地账单还是“待支付”。

我的处理方案是:“先记录回调,再更新账单”。在数据库里建一张payment_callback_log表,用支付流水号做唯一索引。回调到达后先把原始报文写入这张表,写入成功后更新对应账单状态为“已支付”。如果同一条流水号再次回调,唯一索引会阻止重复写入,后续更新直接被幂等跳过。

这样即使更新账单状态失败,至少回调报文已经落库。我可以写一个定时对账任务,每隔半小时扫描payment_callback_log中未处理的记录,把对应账单补成“已支付”,避免用户付了钱但系统一直显示未支付。

5.2 一个业务动作跨多张表的事务边界

退租清算这个动作会同时修改多项数据:更新合同状态为“清算中”、生成水电账单、生成退款单、更新押金账单状态。这些操作必须放在同一个数据库事务里,否则就会出现合同状态改成了“已退租”,但水电账单还没生成的脏数据。

用Spring的@Transactional把事务边界划好,同时要注意锁顺序。我的经验是:涉及同一个合同的多张表操作时,所有事务都先更新合同表,再更新账单表,最后更新款项表。如果不同事务按不同顺序去锁这些行,很容易出现死锁。统一锁顺序之后,这类问题基本没有再出现。

还要坚持一条原则:事务内部不要调用远程接口,比如短信服务或支付查询接口。远程调用可能超时,一旦超时整个事务回滚,会造成非常诡异的现象。远程操作放到事务提交之后异步处理。

5.3 人工对账兜底:系统不可能永远正确

定时任务和状态机再怎么设计,也挡不住运营数据录入错误、接口异常、脏数据这些问题。我在后台留了一个对账页面,运营可以按账单号或支付流水号批量核对,系统给出“账单状态”和“支付流水状态”的对比结果。

如果发现两边对不上,提供了一个“记账修正”操作,只允许管理员使用,并且每次操作都会记录完整的操作日志。这个功能我一开始觉得没必要,后来线上跑了一阵才知道,对账兜底比整个支付流程本身还重要。没有兜底功能,运营发现问题只能去找开发改数据库,那才真的会出大事。

6. 第三阶段最容易翻车的几个细节

6.1 时间精度和时区问题

账单的应缴日期如果不存对,逾期判断会全面错乱。我遇到过连接数据库的时区参数没有配置,服务器默认时区跟数据库时区不一致,导致“今天”的判断少了一天,租金明明没有逾期却被标成了已逾期。

最终的约定是:服务器时区统一为Asia/Shanghai,数据库连接串上显式加上serverTimezone=Asia/Shanghai,接口传输时间格式统一用字符串,所有涉及日期的字段明确使用DATE类型而不是DATETIME,避免精度和时区带来的冤枉问题。

6.2 BigDecimal与数据库映射问题

MyBatis映射金额字段时,如果数据库字段没有显式设置精度,很容易出现四舍五入或精度丢失。建表时所有金额字段我都强制写成DECIMAL(10,2),Java实体类型统一用BigDecimal。查询统计时尽量用数据库的SUM聚合,返回结果直接映射成BigDecimal,避免中途经过Double类型。

6.3 删除按钮应该变成“作废”

涉及合同、账单、退款记录的表,我全部取消了物理删除。逻辑上只允许做“作废”操作,而且作废必须填写原因。账单如果需要作废,还要走状态机:已经支付的账单不能直接作废,得先生成一张负数冲正账单,把原金额冲掉,再进行退款登记。

这一条听起来像是给自己找麻烦,但实际操作下来非常值得。好几个人在初期都问过“为什么不能直接删掉这条测试数据”,我的回答是:如果哪天真有财务审计,或者需要追溯一笔异常交易,这些历史记录就是唯一线索。宁可操作上麻烦一点,也不能让数据凭空消失。

整个第三阶段做完,我最大的体会是:真正考验人的不是某个单独的功能怎么写,而是这些功能放在一起时,状态能不能永远保持一致。每次我忍不住想加一个绕过状态机的快捷入口,都会先问自己一句:这个操作会把数据带到哪个状态,会不会让后面的人对不上账?想清楚这个问题,很多设计上的纠结其实就不存在了。

相关新闻

从零构建skills能力封装系统:注册、发现与调度实战

从零构建skills能力封装系统:注册、发现与调度实战

1. 当“skills”成为一个项目标题:我看到的不是技能清单,而是一套能力封装系统第一次看到“skills”这个项目标题时,我下意识以为又是一个技能树展示页面或者简历生成器。但仔细琢磨这个命名方式——全小写、单数形式、没有任何修饰词——反而…

2026/10/20 21:13:37 阅读更多 →
Hive高频面试题全解析:内部表、分区分桶与排序四兄弟

Hive高频面试题全解析:内部表、分区分桶与排序四兄弟

1. 面试官为什么总爱从Hive开始问:三个真实原因很多同学准备大数据面试时,最容易低估的就是Hive。总觉得它不过是一层SQL壳子,把HQL翻译成MapReduce或者Spark任务而已,真到现场被追问,才发现“知道”和“说得清楚”完全…

2026/10/20 21:13:37 阅读更多 →
REA建模实战:用资源-事件-代理理清业务流程与数据模型

REA建模实战:用资源-事件-代理理清业务流程与数据模型

1. 先别急着画数据表,REA解决的是你的业务建模惯性问题第一次看到REA这个缩写,我以为是某个数据库中间件的名字。后来在一次梳理某制造公司业务模型时被它帮了大忙,才真正意识到REA是“资源-事件-代理”本体,不是工具,…

2026/10/20 21:13:37 阅读更多 →

最新新闻

戴森球计划工厂蓝图仓库:3步装好,产线开箱即用

戴森球计划工厂蓝图仓库:3步装好,产线开箱即用

戴森球计划工厂蓝图仓库:3步装好,产线开箱即用 【免费下载链接】FactoryBluePrints 游戏戴森球计划的**工厂**蓝图仓库 项目地址: https://gitcode.com/GitHub_Trending/fa/FactoryBluePrints 凌晨两点还在对着传送带发呆,数着分拣器该…

2026/10/21 1:35:24 阅读更多 →
Jasna 马赛克检测模型选型指南:按素材挑对模型,少漏检、不白等

Jasna 马赛克检测模型选型指南:按素材挑对模型,少漏检、不白等

Jasna 马赛克检测模型选型指南:按素材挑对模型,少漏检、不白等 【免费下载链接】jasna Video restoration tool 项目地址: https://gitcode.com/GitHub_Trending/ja/jasna Jasna 是一款视频修复工具,第一步就是靠检测模型在每帧里找出…

2026/10/21 1:35:24 阅读更多 →
ESP32 无感 BLDC 免霍尔换相:比较器过零检测 3 步跑通闭环

ESP32 无感 BLDC 免霍尔换相:比较器过零检测 3 步跑通闭环

ESP32 无感 BLDC 免霍尔换相:比较器过零检测 3 步跑通闭环 【免费下载链接】esp-iot-solution Espressif IoT Library. IoT Device Drivers, Documentations and Solutions. 项目地址: https://gitcode.com/GitHub_Trending/es/esp-iot-solution 无感 BLDC 控…

2026/10/21 1:35:24 阅读更多 →
Front End Interview Handbook:101 道前端面试题,配前 FAANG 工程师解答

Front End Interview Handbook:101 道前端面试题,配前 FAANG 工程师解答

Front End Interview Handbook:101 道前端面试题,配前 FAANG 工程师解答 【免费下载链接】front-end-interview-handbook Front End interview preparation materials for busy engineers (updated for 2026) 项目地址: https://gitcode.com/GitHub_Tr…

2026/10/21 1:35:24 阅读更多 →
从零实现旋转电压矢量:SVPWM与SPWM的工程实践指南

从零实现旋转电压矢量:SVPWM与SPWM的工程实践指南

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

2026/10/21 1:35:24 阅读更多 →
无名杀网页版:浏览器三国杀,一条命令启动

无名杀网页版:浏览器三国杀,一条命令启动

无名杀网页版:浏览器三国杀,一条命令启动 【免费下载链接】noname 项目地址: https://gitcode.com/GitHub_Trending/no/noname 无名杀(noname)网页版是一个完全开源的三国杀实现,跑在浏览器里。最大卖点&#…

2026/10/21 1:34:24 阅读更多 →

日新闻

统一内存+量化:锐龙AI Max PRO 400如何本地跑320B大模型

统一内存+量化:锐龙AI Max PRO 400如何本地跑320B大模型

这段时间硬件圈和AI圈都在传一个事:AMD锐龙AI Max PRO 400系列把最高192GB统一内存搬进了PC形态的产品里,按宣传口径,本地跑320B参数的大家伙不再是纸面概念。我第一反应倒不是“内存真大”,而是这话背后的含金量——它把过去只能…

2026/10/21 0:00:11 阅读更多 →
AI助手深度使用体验:对话质量、长文本处理与指令遵循如何留住用户

AI助手深度使用体验:对话质量、长文本处理与指令遵循如何留住用户

1. 从“封号重开”这个行为说起:用户到底在追求什么“封号重开”这四个字,放在任何产品语境里都带着一股决绝的味道。一个账号从零开始积累使用记录、调教偏好、沉淀工作流,背后是大量的时间和精力成本。正常情况下,没有人愿意主动…

2026/10/21 0:00:11 阅读更多 →
ROS中YOLOv3工程落地:通信同步、坐标变换与性能调优

ROS中YOLOv3工程落地:通信同步、坐标变换与性能调优

1. 为什么在ROS里硬刚YOLOv3不是“炫技”,而是工程落地的必经之路我第一次在某高校机器人实验室看到那台搭载Jetson TX2的移动底盘原地打转、反复识别错垃圾桶时,就意识到:单纯跑通darknet_ros demo和真正让YOLOv3在ROS里“干活”&#xff0c…

2026/10/21 0:00:11 阅读更多 →

周新闻

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

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

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

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

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

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

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

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

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在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 阅读更多 →