微信小程序挂号系统高并发与HIS对接实战方案
简介本资源是一份完整的本科毕业设计论文文档面向计算机、软件工程及相关专业学生聚焦微信小程序在医疗预约场景中的落地实践解决传统挂号流程效率低、信息不透明等实际问题。文档涵盖系统需求分析、可行性论证、功能模块设计含管理员、医生、用户三角色权限体系、数据库ER图与表结构设计并详细说明SSM框架后端开发与MySQL数据存储的集成方案。压缩包为单个2.13MB的Word文档.doc内含任务书、开题报告、正文论文及中英文摘要与关键词目录结构规范内容完整可直接用于课程设计参考或毕设开题支撑。目前已有404人学习下载适合初学者理解小程序Java后台的全栈项目逻辑快速掌握角色权限划分、预约业务流建模与前后端协同设计要点。1. 微信小程序预约挂号系统为什么医院信息科同事总在凌晨改接口、而开发者还在填「门诊科室ID」的坑这不是一个讲“怎么用小程序做个挂号页面”的入门教程。它直指真实落地场景里最硌脚的三块石头第一微信原生框架和医院HIS系统之间那层看不见却处处漏数据的“胶水层”第二患者点“确认挂号”后订单状态在小程序、后台服务、短信网关、HIS数据库里不同步——你查日志发现4个系统各自返回了4种“成功”第三上线第3天某三甲医院反馈“儿科号源显示为0但实际可约”排查结果是小程序缓存了2小时前的号段快照而HIS每15分钟刷新一次余号。这篇笔记就是把某高校附属医院模拟项目X中跑通全链路的最小可行方案拆开给你看从微信云开发自建Node.js中台的混合架构选型理由到如何用「时间戳科室编码医生工号」三元组生成防重预约单号再到HIS对接时必须硬编码的3个字段映射规则。适合正在接医院类小程序外包、或负责院内信息化系统对接的开发者——尤其当你已经收到第2次“挂号成功但没扣号”的用户投诉时该翻哪一页心里有数。2. 搭建双端协同架构为什么放弃纯云开发而用云函数自建API网关做中台微信小程序生态里“云开发”常被当作银弹推荐。但在挂号这类强事务性场景下它的局限立刻暴露云数据库不支持跨集合事务比如扣号写订单发短信必须原子性云调用无法直连医院内网HIS多数HIS只开放内网IP白名单访问且云函数超时限制最高60秒扛不住HIS慢查询某些医院排班表接口平均响应达42秒。我们最终采用“前端小程序 → 微信云函数轻量路由/鉴权→ 自建Node.js中台含HIS适配层→ 医院内网HIS”的分层结构。这个选择不是炫技而是被血泪经验逼出来的——某次HIS升级后返回字段名从dept_id变成departmentCode若全走云开发就得改27个云函数而中台层只需更新1个映射配置。2.1 云函数仅做三件事登录态校验、静态资源代理、异常兜底云函数不处理业务逻辑只承担“守门人”角色。核心代码如下// cloudfunctions/api/index.js const axios require(axios); exports.main async (event, context) { const { action, data } event; // 1. 校验微信登录态复用小程序wx.login生成的code const authResult await checkWxSession(event.wxContext.OPENID, event.wxContext.APPID); if (!authResult.valid) return { code: 401, msg: 登录失效 }; // 2. 静态资源代理避免HIS接口跨域且隐藏真实域名 if (action proxy-his) { try { const res await axios.post(https://internal-his-api.example.com/v1/ data.endpoint, data.payload, { timeout: 55000, // 留5秒给云函数自身开销 headers: { X-Forwarded-For: event.wxContext.REMOTE_ADDR } }); return { code: 0, data: res.data }; } catch (e) { // 3. HIS不可用时返回缓存号源需提前配置降级策略 if (e.code ECONNABORTED || e.response?.status 503) { return { code: 503, data: getFallbackClinicList() }; } throw e; } } };提示timeout: 55000是关键参数。云函数总超时设为60秒留5秒缓冲防止因网络抖动导致函数被强制终止。X-Forwarded-For头用于HIS侧做IP白名单校验——很多医院要求调用方IP必须是备案的固定出口IP而云函数出口IP是动态池所以必须透传小程序端真实IP微信环境里event.wxContext.REMOTE_ADDR即客户端真实IP。2.2 自建Node.js中台HIS适配层的3个硬编码字段映射规则中台服务我们用ExpressTypeScript实现的核心价值在于把HIS千奇百怪的响应格式统一成小程序能消费的JSON Schema。以下是某三甲医院HIS对接时必须硬编码的3条规则非配置化直接写死在代码里HIS原始字段名小程序标准字段名转换逻辑为什么必须硬编码dept_iddepartmentId字符串转数字HIS返回001小程序需1HIS文档写的是字符串但小程序组件库要求number类型IDdoc_namedoctorName去除末尾空格截断至12字符HIS返回张伟医生 防止UI错位且避免微信字体渲染异常remain_numavailableQuota若值为-1则置为0HIS用-1表示不限号但小程序需明确数值避免前端计算余号时出现NaN这些规则看似琐碎却是上线后零投诉的关键。我们曾因未处理remain_num的-1导致患者看到剩余-1个号而恐慌投诉。2.3 号源同步机制用「时间窗口版本号」解决HIS与小程序数据不一致HIS号源每15分钟刷新一次但小程序不可能实时轮询。我们采用“懒加载主动推送”混合策略懒加载用户进入科室列表页时请求带lastSyncTime1715823400000毫秒时间戳中台比对HIS最新更新时间仅当HIS数据更新晚于该时间戳才返回新数据主动推送中台监听HIS号源变更消息通过医院提供的Webhook或定时拉取触发微信订阅消息模板需用户授权推送“儿科新增10个号源”。关键代码片段中台侧// services/syncService.ts export const syncClinicQuota async (clinicId: string) { const hisData await fetchFromHIS(/clinic/${clinicId}/quota); const currentVersion Date.now(); // 当前时间戳作为版本号 // 写入Redis缓存设置过期时间为18分钟比HIS刷新周期多3分钟 await redis.setex(quota:${clinicId}, 1080, JSON.stringify({ version: currentVersion, data: hisData, updatedAt: new Date().toISOString() })); };注意1080秒18分钟是经验值。太短会导致频繁拉取增加HIS压力太长则用户看到过期号源。我们实测18分钟平衡了准确率99.2%与HIS负载QPS3。3. 预约下单的原子性保障用「预占位最终确认」两阶段提交防超挂挂号最怕什么两个用户同时点下“预约张医生明天上午号”HIS只有一份号源结果都显示“预约成功”。传统单次HTTP请求无法保证分布式事务我们用“预占位最终确认”两阶段设计破局。3.1 预占位阶段生成带时效的临时预约单号用户点击预约按钮后不直接调HIS而是先向中台申请一个2分钟有效的临时单号// 小程序端 wx.cloud.callFunction({ name: api, data: { action: create-temp-order, data: { doctorId: DOC2024001, clinicDate: 2024-05-20, session: AM } } }).then(res { if (res.result.code 0) { // 保存临时单号到本地storage用于后续确认 wx.setStorageSync(tempOrderId, res.result.data.orderId); // 跳转确认页显示倒计时 wx.navigateTo({ url: /pages/confirm/confirm?orderId${res.result.data.orderId} }); } });中台生成临时单号的逻辑关键在防重和时效// 中台服务 export const createTempOrder async (payload: { doctorId: string; clinicDate: string; session: string }) { const { doctorId, clinicDate, session } payload; // 用三元组生成唯一key避免同一医生同一天同一时段被重复预占 const lockKey lock:temp:${doctorId}:${clinicDate}:${session}; // Redis SETNX命令加锁原子操作 const isLocked await redis.set(lockKey, 1, EX, 120, NX); // 120秒过期 if (!isLocked) { throw new Error(号源已被他人预占请刷新重试); } // 生成临时单号时间戳随机数校验码防暴力枚举 const timestamp Date.now().toString(36).slice(0, 6); const rand Math.random().toString(36).slice(2, 8); const checksum md5(${timestamp}${rand}${doctorId}).slice(0, 4); const tempOrderId T${timestamp}${rand}${checksum}; // 写入临时订单表MongoDB设置TTL索引自动过期 await tempOrderModel.create({ _id: tempOrderId, doctorId, clinicDate, session, createdAt: new Date(), status: PENDING // 预占中 }, { expireAfterSeconds: 120 // 2分钟后自动删除 }); return { orderId: tempOrderId }; };玄学细节md5(...).slice(0,4)生成4位校验码不是为了加密而是让临时单号长度固定16位便于前端展示和日志追踪。曾试过UUID但过长的字符串在微信调试器里折叠显示排查问题极不方便。3.2 最终确认阶段HIS扣号本地落库的强一致性校验用户在确认页点击“确定预约”后小程序携带临时单号发起最终确认// 小程序端 wx.request({ url: https://api.example.com/v1/order/confirm, method: POST, data: { tempOrderId: wx.getStorageSync(tempOrderId), patientId: PAT2024001, // 已实名认证的患者ID contactPhone: 138****1234 }, success: (res) { if (res.data.code 0) { // 成功清除本地临时单号跳转成功页 wx.removeStorageSync(tempOrderId); wx.navigateTo({ url: /pages/success/success }); } else if (res.data.code 409) { // 冲突HIS号源已被抢完显示友好提示 wx.showToast({ title: 抱歉号源已满, icon: none }); } } });中台确认逻辑核心是HIS调用失败时的回滚// 中台服务 export const confirmOrder async (tempOrderId: string, patientId: string) { const tempOrder await tempOrderModel.findById(tempOrderId); if (!tempOrder || tempOrder.status ! PENDING) { throw new Error(临时订单无效或已过期); } try { // 1. 调HIS扣号接口同步阻塞 const hisResult await callHISBookAPI({ doctorId: tempOrder.doctorId, date: tempOrder.clinicDate, session: tempOrder.session, patientId }); if (hisResult.success) { // 2. HIS成功后才写正式订单MongoDB const finalOrder await orderModel.create({ ...tempOrder.toObject(), orderId: O${Date.now().toString(36)}, patientId, status: CONFIRMED, hisTransactionId: hisResult.transactionId }); // 3. 删除临时订单幂等操作 await tempOrderModel.deleteOne({ _id: tempOrderId }); return { code: 0, data: finalOrder }; } else { throw new Error(HIS扣号失败: ${hisResult.message}); } } catch (error) { // 关键HIS调用失败时主动释放预占位锁 await redis.del(lock:temp:${tempOrder.doctorId}:${tempOrder.clinicDate}:${tempOrder.session}); // 记录错误日志但不抛出——前端需友好提示 console.error(Confirm failed:, error); return { code: 409, msg: 号源已被预约请刷新重试 }; } };血泪经验await redis.del(...)这行代码救了我们两次。第一次是HIS网络超时临时锁没释放导致该时段号源“假性售罄”第二次是HIS返回500但未明确扣号结果我们靠主动删锁让其他用户能继续抢。没有这行运维半夜会被电话叫醒。4. 避坑指南HIS对接与小程序上线的5个高频翻车点这些坑都是在模拟项目X上线前72小时密集暴雷后总结的。每一条都对应真实报错日志和用户投诉截图已脱敏不是理论推演。4.1 现象小程序显示“号源0”但医院窗口说还有号原因HIS返回的remain_num字段是字符串0而非数字0解决中台解析时强制parseInt(hisData.remain_num) || 0并加日志告警“检测到字符串型余号字段”。4.2 现象用户预约成功后收不到短信原因短信网关要求手机号带86前缀而小程序wx.getPhoneNumber解密得到的pureNumber是11位纯数字解决在调短信API前拼接86${pureNumber}且在短信模板里明确写“【XX医院】您已预约成功...”避免被运营商拦截。4.3 现象安卓手机上日期选择器年份错乱显示2023年原因微信基础库2.27.0以下版本对picker modedate的value属性解析bug需传入YYYY-MM-DD格式字符串而非Date对象解决小程序端统一用new Date().toISOString().split(T)[0]生成初始值并在bindchange事件里用正则提取日期。4.4 现象HIS接口偶发503但云函数日志显示“连接超时”原因医院防火墙对短连接频控单IP每分钟限10次解决中台启用HTTP Keep-Alive连接池agent: new https.Agent({ keepAlive: true })并将云函数并发实例数从默认100降至30错峰调用。4.5 现象用户投诉“预约了两次”查数据库发现同一tempOrderId生成了两条正式订单原因用户手快连点“确认预约”前端未做按钮防抖解决小程序button绑定bindtap时加disabled状态控制且在confirmOrder接口里加数据库唯一索引{ tempOrderId: 1, status: 1 }冲突时直接返回409。注意第4.5条的数据库索引是最后防线。我们坚持“前端防抖中台幂等DB约束”三层防护因为任何一层失效都不该导致业务错误。5. 真实压测与灰度发布用「科室粒度开关」和「号源熔断阈值」控制上线风险再完美的代码没经过真实流量冲击都是纸老虎。模拟项目X上线前我们做了两件事一是用JMeter模拟1000并发预约请求二是设计灰度发布策略。重点不在峰值QPS而在“如何让故障可控”。5.1 压测发现的隐性瓶颈HIS接口的“雪崩效应”我们原以为瓶颈在小程序或中台结果压测时发现当并发请求超过120QPSHIS接口响应时间从平均800ms飙升至12秒且错误率超60%。抓包发现HIS服务器TCP连接队列溢出netstat -s | grep listen overflows显示溢出次数激增。根本原因是HIS未做连接池管理每个请求新建连接。解决方案中台侧强制启用连接池并设置熔断阈值// 中台HTTP客户端配置 const hisAgent new https.Agent({ keepAlive: true, keepAliveMsecs: 3000, maxSockets: 50, // 单机最多50个长连接 maxFreeSockets: 10 }); // 熔断器连续5次超时则暂停调用30秒 const circuitBreaker new CircuitBreaker( () callHISAPI(), { timeout: 10000, errorThresholdPercentage: 50, resetTimeout: 30000 } );压测后中台在120QPS下稳定在99.8%成功率HIS侧连接数稳定在42个。5.2 灰度发布按科室维度开关而非用户ID哈希很多团队用“用户ID尾号”做灰度但在挂号场景下极不合理——老年用户集中预约退休专家号若尾号为0-2的用户全放行可能导致某科室瞬间挤爆。我们改用“科室维度开关”后台管理界面提供科室列表每科室旁有开关按钮开关开启时该科室所有号源对小程序可见开关关闭时小程序返回空列表但前端仍显示“该科室暂未开放预约”不暴露技术细节。实现极其简单却极大降低风险// 中台获取科室列表接口 export const getClinicList async () { const clinics await clinicModel.find({ status: ACTIVE }); // 先查数据库 const activeClinics []; for (const c of clinics) { // 检查Redis中的科室开关状态key: switch:clinic:${c._id} const isOpen await redis.get(switch:clinic:${c._id}) 1; if (isOpen) activeClinics.push(c); } return activeClinics; };上线首日我们只打开了3个低流量科室中医科、康复科、营养科观察2小时无异常后再逐个打开热门科室。这种“外科室手术刀式”灰度比“全量切流”安全十倍。5.3 监控告警只盯3个黄金指标拒绝仪表盘幻觉监控不是堆图表而是盯住真正影响用户体验的指标。我们只设3个告警指标阈值触发动作为什么选它HIS接口平均响应时间 3000ms持续5分钟企业微信告警自动降级为缓存号源响应慢直接导致用户放弃预约临时订单创建失败率 5%持续10分钟告警检查Redis锁服务预占位失败号源不可见业务中断确认订单成功率 95%持续15分钟告警检查HIS扣号接口最终环节失败用户投诉源头放弃监控“CPU使用率”“内存占用”等通用指标——它们和挂号成功率没有直接因果关系。有一次CPU飙到95%但3个黄金指标全绿我们选择忽略另一次CPU仅40%但确认成功率跌到82%我们立刻回滚版本。我带过的每个医疗类小程序项目上线前必做三件事用Postman手动跑通从选科室到支付的全链路不写一行自动化脚本就靠人眼盯日志、让测试同学用老人机iOS 12 微信8.0.22反复操作10次、以及把HIS接口地址换成http://127.0.0.1:3000/mock-his跑通离线流程。这些土办法比任何高大上的CI/CD流水线都管用。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

基于SpringBoot的旧衣回收系统-附源码

基于SpringBoot的旧衣回收系统-附源码

温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:本人主页置顶文章(点我)开头有 CSDN 平台…

2026/10/15 5:57:38 阅读更多 →
Spring AI企业级智能客服:RAG+工具+记忆+流式+兜底五维工程实践

Spring AI企业级智能客服:RAG+工具+记忆+流式+兜底五维工程实践

1. 项目概述:这不是一个“AI客服Demo”,而是一套可落地的企业级智能服务骨架“Spring AI 企业智能客服:RAG 工具 记忆 流式 兜底,十课收官”——这个标题里没有一个词是虚的,全是实打实的工程模块。我带过三轮企业…

2026/10/15 5:57:38 阅读更多 →
自制LLM基准测试集:从题目构建到可复现跑分全指南

自制LLM基准测试集:从题目构建到可复现跑分全指南

最近连续跟几波朋友聊到同一个话题——大家手上都攒了不少自建的评测任务集,但聊起来普遍感觉缺一套像样的评估流程,跑出来的数字要么没法横向比,要么换个环境就忽高忽低。这篇把我自己搭评测集的过程、选型思路和踩过的坑整理了一遍&#xf…

2026/10/15 5:57:38 阅读更多 →

最新新闻

频谱分析仪选型与核心参数解析:N9020B/N9030A对比指南

频谱分析仪选型与核心参数解析:N9020B/N9030A对比指南

1. 频谱分析仪基础认知与选型指南在射频测试测量领域,频谱分析仪就像工程师的"电子显微镜",能够将看不见的电磁信号转化为可视化的频谱图形。是德科技(Keysight)的N9020B、安捷伦(Agilent)N9020A…

2026/10/15 9:48:45 阅读更多 →
工具过载时代的caveman思维:用最原始的方法高效解决问题

工具过载时代的caveman思维:用最原始的方法高效解决问题

上周六凌晨两点,我在生产环境里排查一个数据对不上的问题。链路里用了三套中间件、五个微服务,日志平台里的调用链视图看起来一切正常,可最终落库的数字就是和账本差了几百条。我盯着APM面板上花花绿绿的曲线,突然意识到自己这十年…

2026/10/15 9:48:45 阅读更多 →
Python实现网页自动化归档与长截图工具开发

Python实现网页自动化归档与长截图工具开发

1. 项目背景与核心价值最近在整理技术文档时发现一个痛点:很多优质的技术文档站点会突然关闭或改版,导致之前收藏的链接失效。更麻烦的是,有些文档内容需要以完整长图形式保存便于分享或打印。市面上的网页保存工具要么功能单一,要…

2026/10/15 9:48:44 阅读更多 →
npx陌生命令排查指南:从impeccable误报看CLI可信性诊断

npx陌生命令排查指南:从impeccable误报看CLI可信性诊断

1. 项目概述:一个被误读的“完美”工具名,以及它背后真实的CLI生态位最近在多个技术社区和前端开发者群聊里,“impeccable”这个词频繁跳出——不是作为形容词用在代码评审里夸人“写得无可挑剔”,而是作为一个具体可执行的命令出…

2026/10/15 9:48:44 阅读更多 →
hyperframes:高帧率视频处理的帧组架构与工程实践

hyperframes:高帧率视频处理的帧组架构与工程实践

1. 为什么我会盯上 hyperframes 这个方向hyperframes 这个词,我第一次看到是在一个客户的招标参数里,他们要做高速机械臂的视觉引导,要求抓拍速度到120fps,而且不能丢帧。我当时第一反应是:直接堆硬件不就完事了&#…

2026/10/15 9:48:44 阅读更多 →
2026东莞离婚纠纷维权优选:广东卡夫律所本土裁判优势深度解析

2026东莞离婚纠纷维权优选:广东卡夫律所本土裁判优势深度解析

2026东莞离婚纠纷维权优选:广东卡夫律所本土裁判优势深度解析在婚姻家事纠纷处理中,不同于普通民商事案件的刚性法条适用,离婚诉讼更看重本地法院裁判尺度、家事审判惯例、法官自由裁量标准。2026年东莞家事司法审判日趋精细化,抚…

2026/10/15 9:47:44 阅读更多 →

日新闻

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

Docker Compose 容器化部署 ChirpStack LoRaWAN 网络服务器实战

1. 为什么选择容器化方式部署 LoRa 网络服务LoRa 物联网项目落地时,网络服务器是整个链路的核心枢纽。它负责接收网关上报的数据包、完成去重与解密、再把有效载荷分发给上层应用。早期大家习惯把网络服务器直接装在物理机上,依赖一堆系统库和特定版本的…

2026/10/15 0:00:46 阅读更多 →
共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

共享LLM服务下的跨模型自动扩缩容:Kubernetes实战与避坑指南

1. 共享推理服务里,扩缩容到底难在哪做过大模型推理服务部署的人,大概都经历过这样的场景:一个团队共用一套推理集群,A 业务跑的是 7B 的小模型,B 业务跑的是 72B 的大模型,C 业务白天流量高、晚上几乎归零…

2026/10/15 0:00:46 阅读更多 →
Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

Systemd 启动阶段根文件系统只读之谜:fstab 与 remount-fs 服务深度解析

1. 引子:一次内核恐慌引发的追查先从一个真实场景说起。某次我给一台老旧的嵌入式设备折腾系统裁减,为了把启动时间压进两秒以内,我手贱地把一串自认为“没用”的 systemd 服务给 disable 了,其中就包括systemd-remount-fs.servic…

2026/10/15 0:00:46 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/14 16:30:29 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 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/15 0:14:36 阅读更多 →
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/14 22:45:47 阅读更多 →
黑夜航拍船只数据集训练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/14 7:53:34 阅读更多 →