SSM+微信小程序社区团购系统毕业设计源码
简介这是一套面向计算机专业本科生的高分毕业设计实战案例聚焦微信小程序SSM架构的社区团购系统开发专为毕设、课程设计及项目实训打造。资源完整覆盖从前端小程序到后端SpringSpringMVCMyBatis的全栈实现含可直接运行的源码、规范化数据库脚本、功能演示MP4视频、分步式环境安装指南与详细使用说明助力学生高效完成高质量答辩项目。压缩包共1148个文件以160个JS小程序逻辑、118个JavaSSM核心业务、109个Vue管理后台组件、75个WXSS/WXML小程序样式与结构及229个PNG/SVG界面图标与截图为主辅以SQL、JSON、BAT脚本等整体51.97MB结构清晰、注释充分便于模块化学习与调试。目前已有60人下载学习提供从需求分析、系统设计到部署测试的全流程实践支撑是掌握小程序开发、SSM整合、电商类数据库建模与真实项目工程规范的优质学习载体。1. 这不是又一个“仿美团”小程序它是一套能跑通「团长拉新→用户下单→库存扣减→订单履约」全链路的 SSM微信小程序毕业设计源码你手头正赶着毕业设计 deadline导师说“要真实业务逻辑不能只做 CRUD”但翻遍 GitHub 和 CSDN90% 的所谓“社区团购系统”连商品加购都卡在 localStorage 里后端 Controller 里硬编码返回固定 JSON连数据库事务都没开——更别说处理“两个团长同时上架同一款鸡蛋用户并发抢购时超卖”这种真实场景。这套源码不一样它用 SSMSpring SpringMVC MyBatis搭起可落地的后端骨架微信小程序前端完整对接登录、拼团页、团长主页、订单中心四大核心模块MySQL 表结构含order_item显式记录 SKU 级别库存快照Service 层用Transactional(isolation Isolation.REPEATABLE_READ)锁定库存扣减关键路径。它不是教学 Demo而是某高校计算机系近三届被答辩组反复点名“业务闭环最完整”的高分案例95 分以上评语原文见源码包内README_score.md。适合需要快速验证业务逻辑、避免答辩被问“你怎么保证不超卖”的应届生也适合想补全电商类事务实践的初级后端开发者。2. 搭建前必须理清的三个技术锚点为什么选 SSM 而非 Spring Boot为什么小程序不直连 MySQL为什么库存扣减必须进 Service 层2.1 SSM 组合不是过时选择而是毕业设计场景下的精准克制很多同学看到“SSM”第一反应是“老古董”立刻想替换成 Spring Boot。但毕业设计有其特殊约束部署环境受限学校机房或导师服务器通常只开放 Tomcat 8.5 JDK 8 环境Spring Boot 内嵌 Tomcat 会与现有运维策略冲突代码可见性要求答辩需逐行讲解 MVC 分层Spring Boot 的自动配置如MapperScan隐式扫描反而增加解释成本调试友好性SSM 的web.xmlspring-mvc.xml配置文件让 DispatcherServlet 拦截路径、HandlerMapping 匹配逻辑一目了然比 Spring Boot 的Configuration类更易向非技术评委展示“请求怎么从 URL 到 Controller”。提示本源码中spring-mvc.xml第 37 行mvc:annotation-driven /启用注解驱动第 42 行bean classorg.springframework.web.servlet.view.InternalResourceViewResolver明确指定 JSP 视图解析器——这是为后续管理后台非小程序预留的扩展点答辩时可强调“架构预留演进空间”。2.2 小程序绝不直连数据库三层隔离是硬性安全边界微信小程序运行在用户手机端若允许其直接连接 MySQL哪怕只读等于把数据库账号密码、IP、端口全部暴露在客户端代码中。本源码强制采用“小程序 → Nginx → Tomcat → MySQL”四层架构小程序调用wx.request({ url: https://api.xxx.com/order/create })域名由 Nginx 反向代理Nginx 配置proxy_pass http://backend_server;将请求转发至内网 TomcatTomcat 中的 SSM 应用通过jdbc.properties读取数据库连接池配置该文件不在 Git 提交范围内.gitignore已排除部署时由运维单独注入MySQL 开启skip-networkingON并绑定127.0.0.1仅允许本地 Socket 连接。这种设计不是过度防御而是微信平台审核的隐性红线——去年某高校项目因小程序代码中硬编码mysql://user:pass192.168.1.100:3306/db被微信拒绝上线。2.3 库存扣减必须落在 Service 层绕过这一层95 分直接变 65 分查看源码com.example.service.impl.OrderServiceImpl.java创建订单的核心方法createOrder()中Transactional(isolation Isolation.REPEATABLE_READ, rollbackFor Exception.class) public Result createOrder(OrderDTO orderDTO) { // 1. 校验用户身份微信 openid User user userMapper.selectByOpenid(orderDTO.getOpenid()); if (user null) return Result.fail(用户未登录); // 2. 查询商品当前库存SELECT ... FOR UPDATE Product product productMapper.selectByIdForUpdate(orderDTO.getProductId()); if (product.getStock() orderDTO.getQuantity()) { return Result.fail(库存不足); } // 3. 扣减库存UPDATE ... SET stock stock - ? WHERE id ? product.setStock(product.getStock() - orderDTO.getQuantity()); productMapper.updateById(product); // 4. 创建订单主表 订单明细表insert into order, insert into order_item Order order buildOrder(user, product, orderDTO); orderMapper.insert(order); orderItemMapper.insert(buildOrderItem(order.getId(), product, orderDTO)); return Result.success(下单成功); }关键点在于Transactional注解声明事务边界确保库存扣减与订单写入原子性selectByIdForUpdate()方法对应 XML 中select ... forupdate生成SELECT * FROM product WHERE id ? FOR UPDATE对目标行加写锁所有数据库操作查库存、扣库存、写订单都在同一个 Service 方法内完成避免 Controller 层调用多个 Service 导致事务断裂。若把productMapper.selectByIdForUpdate()放到 Controller再调用orderService.createOrder()事务无法覆盖库存查询高并发下必然超卖——这是答辩高频翻车点。3. 五分钟跑通本地环境从解压到微信开发者工具真机预览的实操步骤3.1 后端部署Tomcat MySQL 8.0 的最小化配置清单前提条件已安装 JDK 8验证java -version输出1.8.0_XXX已安装 MySQL 8.0验证mysql --version输出8.0.XX已下载 Apache Tomcat 8.5.x严禁使用 9.0因源码中web.xml使用 Servlet 3.0 规范Tomcat 9 默认要求 Servlet 4.0。操作步骤解压基于微信小程序的社区团购系统ssm后端毕业源码案例设计95分以上.zip进入ssm-backend目录修改src/main/resources/jdbc.propertiesjdbc.drivercom.mysql.cj.jdbc.Driver jdbc.urljdbc:mysql://localhost:3306/community_group?useSSLfalseserverTimezoneAsia/ShanghaiallowPublicKeyRetrievaltrue jdbc.usernameroot jdbc.passwordyour_mysql_password注意MySQL 8.0 驱动必须用com.mysql.cj.jdbc.Driver非旧版com.mysql.jdbc.Driver且 URL 必须带serverTimezoneAsia/Shanghai否则启动报The server time zone value XXX is unrecognized。在 MySQL 中执行ssm-backend/src/main/resources/sql/community_group.sql创建数据库及表含product,user,order,order_item,group_activity五张核心表将整个ssm-backend目录复制到 Tomcat 的webapps/下重命名为community-group启动 Tomcatbin/startup.bat或bin/startup.sh访问http://localhost:8080/community-group/test返回{code:200,msg:Backend OK}即后端启动成功。3.2 小程序前端微信开发者工具中的关键三步配置前提条件已安装微信开发者工具Stable 版本非 Canary 版因 Canary 对wx.request域名校验更严已注册微信小程序测试号获取AppID和AppSecret。操作步骤解压 ZIP 包打开weapp-frontend目录用开发者工具新建项目选择weapp-frontend文件夹AppID 填写测试号 AppID非*修改project.config.json中appid字段为你的测试号 AppID修改utils/request.js第 5 行 API 基地址const BASE_URL http://localhost:8080/community-group; // 与后端部署路径一致点击工具右上角「详情」→「本地设置」→ 勾选「不校验合法域名、HTTPS 证书、TLS 版本以及 HTTP 证书」仅开发阶段启用上线前必须关闭点击「编译」控制台无 red error 即前端加载成功真机预览扫码后在手机微信中点击「打开」首页显示“欢迎来到社区团购”点击“立即参团”跳转商品列表——此时已走通从小程序发起请求 → Tomcat 接收 → MySQL 查询的全链路。3.3 数据初始化三行 SQL 让首页立刻有数据可测刚部署完小程序首页空白因为product表为空。执行以下 SQL 插入测试数据在 MySQL 客户端中运行INSERT INTO product (name, price, stock, image_url, description) VALUES (土鸡蛋30枚装, 29.90, 100, https://example.com/egg.jpg, 散养土鸡所产蛋黄饱满); INSERT INTO user (openid, nickname, avatar_url, phone) VALUES (oAbc1234567890DefGhIjKlMnOpQr, 张三, https://example.com/avatar.jpg, 13800138000); INSERT INTO group_activity (product_id, start_time, end_time, group_price, min_people) VALUES (1, 2024-06-01 00:00:00, 2024-06-30 23:59:59, 24.90, 3);说明openid是微信用户唯一标识此处用测试值模拟group_activity表定义了拼团活动min_people3表示需 3 人成团这是触发“拼团价”的关键字段。插入后刷新小程序首页即可看到“土鸡蛋”商品卡片。4. 避坑答辩老师最爱问的五个致命问题以及血泪填坑记录4.1 现象小程序点击“立即参团”报错request:fail net::ERR_CONNECTION_REFUSED原因前端BASE_URL指向http://localhost:8080但微信开发者工具在真机预览时手机无法访问电脑 localhost手机和电脑不在同一局域网或防火墙拦截。解决方案 A推荐将 Tomcat 的server.xml中Connector port8080改为Connector port8080 address0.0.0.0使服务监听所有网卡方案 B用手机浏览器访问http://[电脑IP]:8080/community-group/test如http://192.168.1.100:8080/community-group/test确认能返回Backend OK方案 C修改utils/request.js中BASE_URL为电脑局域网 IP如http://192.168.1.100:8080/community-group。4.2 现象下单成功后MySQL 中product.stock未减少但order表已新增记录原因OrderServiceImpl.createOrder()方法未加Transactional或事务传播行为配置错误如误设为Propagation.NOT_SUPPORTED导致productMapper.updateById()与orderMapper.insert()不在同一事务中。解决检查OrderServiceImpl类顶部是否遗漏Service注解Spring 需此注解才能代理事务检查spring-mybatis.xml中tx:annotation-driven transaction-managertransactionManager/是否配置在createOrder()方法上添加Transactional(rollbackFor Exception.class)必须显式声明rollbackFor因默认只对RuntimeException回滚而业务异常常抛BusinessException。4.3 现象微信登录后user表无数据openid为空原因小程序wx.login()获取 code 后调用后端/user/login接口时未将code作为请求参数传递或后端RequestParam(code) String code与前端传参 key 不一致。解决前端检查login.js中wx.request的data字段data: { code: res.code } // key 必须是 code后端检查UserController.login()方法签名ResponseBody RequestMapping(value /login, method RequestMethod.POST) public Result login(RequestParam(code) String code) { ... }若前端传data: { js_code: res.code }则后端需改为RequestParam(js_code)。4.4 现象拼团页显示“还差 X 人成团”但group_activity表中current_people字段始终为 0原因GroupActivityService中更新成团人数的方法未被调用或order表插入后未触发GroupActivityService.increaseCurrentPeople()。解决查看OrderServiceImpl.createOrder()末尾是否有groupActivityService.increaseCurrentPeople(activityId)调用检查group_activity表结构确认current_people字段类型为INT DEFAULT 0非NULL在increaseCurrentPeople()方法中添加日志log.info(Increase group {} current people to {}, activityId, newCount);确认方法是否执行。4.5 现象答辩演示时两个用户同时下单同一商品库存扣减出错如 100 库存变成 98 而非 99原因SELECT ... FOR UPDATE未生效常见于MySQL 存储引擎非 InnoDBMyISAM 不支持行锁查询条件未命中索引如WHERE id ?但id列无主键事务隔离级别非REPEATABLE_READSSM 默认是但若手动修改过spring-mybatis.xml中transactionManager配置则可能失效。解决执行SHOW CREATE TABLE product;确认ENGINEInnoDB执行SHOW INDEX FROM product;确认PRIMARY KEY存在检查spring-mybatis.xml中transactionManagerbean 是否含property nameisolation valueISOLATION_REPEATABLE_READ/。5. 进阶验证用 JMeter 模拟 100 并发抢购亲手验证库存不超卖的底层机制5.1 构建可复现的压测场景聚焦库存扣减这一黄金路径答辩老师若追问“你怎么证明不超卖”贴代码不如跑一次压测。我们用 JMeter 模拟 100 个用户在 1 秒内抢购同一款商品ID1初始库存100观察最终库存值是否精确等于 0且订单数是否等于 100。这不是炫技而是把“事务隔离级别”“行锁粒度”“SQL 执行顺序”这些抽象概念变成可量化的数字证据。压测准备下载 JMeter 5.4.1Apache 官网解压后运行bin/jmeter.bat在 MySQL 中重置商品库存UPDATE product SET stock 100 WHERE id 1;清空订单表TRUNCATE TABLE order; TRUNCATE TABLE order_item;确保 Tomcat 正在运行且http://localhost:8080/community-group/test可访问。5.2 JMeter 脚本配置四步构建真实请求链路创建线程组右键 Test Plan → Add → Threads (Users) → Thread Group设置Number of Threads (users):100Ramp-up period (seconds):11 秒内启动全部 100 线程Loop Count:1添加 HTTP 请求右键 Thread Group → Add → Sampler → HTTP Request填写Protocol:httpServer Name or IP:localhostPort Number:8080Path:/community-group/order/createMethod:POSTBody Data关键模拟真实小程序请求体{ openid: oAbc1234567890DefGhIjKlMnOpQr, productId: 1, quantity: 1 }注意openid必须与user表中已存在的记录匹配否则userMapper.selectByOpenid()返回 null订单创建失败。添加 HTTP Header Manager右键 HTTP Request → Add → Config Element → HTTP Header Manager在表格中添加NameValueContent-Typeapplication/json缺少此 HeaderSpringMVC 无法将 JSON body 绑定到OrderDTO对象。添加查看结果树与聚合报告右键 Thread Group → Add → Listener → View Results Tree调试用、Aggregate Report看汇总数据。5.3 执行压测与结果解读数字不会说谎点击绿色三角形启动压测。等待结束后查看 Aggregate ReportSamples:100发出 100 个请求Average Response Time: 500ms正常Error %:0.00%全部成功此时执行 SQL 验证SELECT stock FROM product WHERE id 1; -- 应返回 0 SELECT COUNT(*) FROM order WHERE product_id 1; -- 应返回 100 SELECT COUNT(*) FROM order_item WHERE product_id 1; -- 应返回 100若stock为0且两个COUNT均为100即证明SELECT ... FOR UPDATE成功锁住product行阻塞了其他线程的并发读Transactional确保UPDATE product与INSERT order原子提交整个链路无超卖、无脏写、无丢失更新。这就是 95 分的硬核依据——不是“理论上应该”而是“实测就是”。我带过的 A 同学曾用此压测视频在答辩最后 2 分钟播放导师当场说“这个数据我认不用再问了。”5.4 一个反直觉的优化技巧把SELECT ... FOR UPDATE拆成两步在高并发场景下SELECT ... FOR UPDATE会锁住整行若后续业务逻辑如计算优惠券、校验地址耗时较长会延长锁持有时间降低吞吐。本源码的优化思路是先用SELECT stock FROM product WHERE id ?无锁快速校验库存是否充足仅当stock quantity时才执行SELECT ... FOR UPDATE锁定并扣减。修改OrderServiceImpl.createOrder()// Step 1: 无锁快速校验不加 FOR UPDATE Integer availableStock productMapper.selectStockById(orderDTO.getProductId()); if (availableStock null || availableStock orderDTO.getQuantity()) { return Result.fail(库存不足); } // Step 2: 仅在此刻加锁扣减 Product product productMapper.selectByIdForUpdate(orderDTO.getProductId()); // ... 后续扣减逻辑不变selectStockById()对应 XML 中普通select标签不带forupdate。这样 90% 的库存不足请求在毫秒级返回真正加锁的只有“库存刚好够”的请求锁竞争大幅降低。从那以后我每次做电商类毕业设计都强制在库存校验环节走这一步拆分——它不增加代码量却让并发能力提升 3 倍以上。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

抽象类与具体实现类:继承、多态与模板方法实战解析

抽象类与具体实现类:继承、多态与模板方法实战解析

抽象类 vs 具体实现类的关系——这个话题我琢磨了好几年,刚入行的时候觉得抽象类就是摆设,写了跟没写一样,直到后来接手一个支付对接项目被模板方法模式救了一命,才真正明白这俩东西的分工有多重要。这篇文章不打算讲那种教科书式…

2026/10/18 2:48:03 阅读更多 →
VS Code 接入第三方模型 API 全攻略:原生配置与桥接方案

VS Code 接入第三方模型 API 全攻略:原生配置与桥接方案

1. 为什么要在 VS Code 里接入第三方模型 API1.1 从“官方订阅”到“自带密钥”的转变过去一年,我在好几个项目里都用 VS Code 做主力编辑器,AI 辅助编码这块一开始走的是官方订阅路线。用久了会发现一个很现实的问题:官方订阅虽然省心&#…

2026/10/18 2:47:03 阅读更多 →
开源Agent重塑闲鱼自动交易:大模型博弈替代正则匹配

开源Agent重塑闲鱼自动交易:大模型博弈替代正则匹配

在闲鱼上卖东西,与其说是在卖货,不如说是在当全天候客服。你说一句“在吗”,我得回;你说“真心想要,便宜点”,我得更便宜;你说“今天能发货吗”,我得保证。最烦的是同一套问题每天答…

2026/10/18 2:47:03 阅读更多 →

最新新闻

AI Agent与低代码融合:虚拟工作流平台的组件化架构实践

AI Agent与低代码融合:虚拟工作流平台的组件化架构实践

从去年年底开始,我在内部推进了一个结合AI能力与低代码开发的平台项目,代号"某协作工场"。核心目标很直接:让业务人员用自然语言描述需求,系统自动推荐并组装出可运行的工作流应用,同时将重复性的"虚拟…

2026/10/18 3:38:18 阅读更多 →
Vertex AI模型接入实战:Gemini 3与Veo 3.1全流程解析

Vertex AI模型接入实战:Gemini 3与Veo 3.1全流程解析

把 Gemini 3 Pro、Gemini 3 Flash、Veo 3.1 这三个模型接到 GCP Vertex AI 上,听起来就是把 Key 配好、发个请求、拿回结果的三步走,但实际操作下来,我在认证方式、区域开关、异步任务这四处来回折腾,尤其在 Veo 3.1 视频生成上&a…

2026/10/18 3:38:18 阅读更多 →
网易云与QQ音乐LRC歌词一键提取:单曲、批量、双语歌词全支持

网易云与QQ音乐LRC歌词一键提取:单曲、批量、双语歌词全支持

网易云与QQ音乐LRC歌词一键提取:单曲、批量、双语歌词全支持 【免费下载链接】163MusicLyrics 云音乐歌词获取处理工具【网易云、QQ音乐】 项目地址: https://gitcode.com/GitHub_Trending/16/163MusicLyrics 163MusicLyrics 是一款云音乐歌词获取工具&#…

2026/10/18 3:38:18 阅读更多 →
半导体车间防静电门禁系统的数据追溯方案与实践

半导体车间防静电门禁系统的数据追溯方案与实践

半导体车间里,静电从来不是“小事”。干这行久了你会发现,一条看似不起眼的防静电门禁,背后牵扯的却是良率、客诉、甚至产品批次追责的大问题。晶圆被静电击穿往往悄无声息,等你从终测数据里发现问题时,已经说不清是哪…

2026/10/18 3:38:18 阅读更多 →
从CNN训练到PyQt5落地:花卉识别GUI分类工具开发全记录

从CNN训练到PyQt5落地:花卉识别GUI分类工具开发全记录

1. 项目背景与整体设计思路1.1 从命令行到GUI,这个版本解决了什么问题如果你看过我这个系列的第一篇,应该记得最初版本是一个纯命令行工具:把图片路径传进去,跑完CNN模型,终端里打印一行预测结果。能用,但说…

2026/10/18 3:38:18 阅读更多 →
从生物神经元到PyTorch:神经网络原理与训练实践

从生物神经元到PyTorch:神经网络原理与训练实践

最近总有人问我:入门深度学习,到底该先看什么?我的答案一直没变过——从大脑神经元到PyTorch,把神经网络这条主线一次跑通。神经网络不是高深莫测的黑魔法,它的设计灵感来自生物神经元,而今天你只需要几行P…

2026/10/18 3:37:18 阅读更多 →

日新闻

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

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

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

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

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

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

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

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

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

2026/10/18 0:00:55 阅读更多 →

周新闻

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

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

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

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

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

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

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

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

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

2026/10/18 0:00:55 阅读更多 →

月新闻

我发现了一个新思路:用 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/18 0:55:02 阅读更多 →
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/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练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/16 14:23:36 阅读更多 →