news 2026/10/2 7:43:49

小区团购系统毕设全攻略:Spring Boot+Vue从选题到答辩

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
小区团购系统毕设全攻略:Spring Boot+Vue从选题到答辩

每年到毕业设计选题的时候,“小区团购系统的设计与实现”这个题目基本都会出现在热门列表里。这个题火有火的道理:场景贴近生活,导师一听就知道你要做什么;业务链路完整,设计、开发、测试每个环节都有东西可写;技术难度又刚好卡在“比纯增删改查深入一点,但不至于让人啃不动”的位置上。尤其是今年,不少学校开始要求学生必须包含订单状态流转、库存控制这类业务规则,小区团购简直就是为这类需求量身定做的。

这篇文章不打算讲大而全的系统架构,而是把我带过的、见过的、以及自己实际动手做这个题目时的整套思路整理出来,从选题拆解、技术选型、数据库设计,到核心代码怎么下手、论文怎么组织、答辩老师最喜欢问什么,一条线拉通。目标很简单:你拿着这篇内容,能自己从零搭出一个能演示、能答辩、能过查重的完整项目。

1. 选题价值拆解:为什么“小区团购”能成为毕业设计常青树

1.1 业务模式带来的天然功能纵深

先把这个题目背后的业务逻辑看明白。小区团购(有的学校叫社区团购)和普通电商最大的区别在于预售加集单。用户今天下单,平台不会马上发货,而是等到某个时间段截止,把整个小区或某个自提点的订单全部收拢,达到一定数量才统一采购、配送,最后用户到团长那里自提。

这一套模式落到系统设计上,就会产生普通电商没有的几个硬核模块:

  • 团购活动管理:一个活动有开始时间、结束时间、最低成团人数、参与商品范围。
  • 订单状态机:待支付、已支付待成团、已成团备货中、待自提、已完成、已取消、已退款,状态之间还有严格的前后关系。
  • 库存与超卖控制:既然是集单,库存就不是简单的商品可卖数量,而是活动库存、已售数量的关系。
  • 成团判定与自动退款:活动结束时如果没有达到最低成团人数,所有订单要自动退款,这个逻辑是实打实的业务规则,不是靠页面按钮就能糊弄过去的。
  • 多角色视角:普通用户、团长(自提点负责人)、平台管理员,至少三个角色,对应的界面和权限完全不一样。

正因为有了这些真实链路,这个题目才不是“又一张学生管理系统”。答辩时老师问“你的系统难点在哪里”,你能直接指出来订单状态怎么流转、超时怎么处理、库存怎么防超卖,这就是拿分点。

1.2 工作量分布与得分点规划

从时间投入来看,我带过的学生里节奏正常的,一般是这么分配的:

  • 需求分析与数据库设计:1周,这是地基,不能省。
  • 后端接口开发:3周左右,核心业务逻辑主要集中在这段时间。
  • 前端页面开发:2周,页面多但要区分优先级,后面第5章会细说。
  • 前后端联调与功能自测:1周。
  • 论文撰写与修改:2周,边写边补截图。

总计约9到10周,对一个本科毕设来说非常合理。你如果三月底开始动手,六月初答辩,时间上完全不慌。

还有一点值得说:这个题目天然适合拆成用户端、团长端、管理后台三个子系统。论文里“需求分析”章节画出三张用例图,“详细设计”章节写三个端的功能设计,篇幅一下就充实了,而且每一块都能配上截图和代码,工作量显得既饱满又扎实。很多同学担心字数不够,其实只要把三端拆开写,根本不用凑。

2. 技术栈选型与项目骨架搭建:别让版本问题消耗第一个月

2.1 为什么Spring Boot加Vue最稳妥

在技术选型上,我建议毕业设计优先选择自己最能讲清楚、资料最多、老师也认可的组合,而不是一味追求新。

后端用Spring Boot,理由很简单:它把配置做成自动装配,你不用像以前学SSH那样折腾一堆XML;内置Tomcat,打一个jar包就能跑;Java更是几乎所有学校必修的语言,答辩时不会被质疑选型动机。前端的Vue,无论是Vue 2还是Vue 3,只要你用过Element UI或Element Plus,表格表单这些后台页面写起来特别快。

有些同学问能不能用JSP加Servlet写,我的看法是:能跑,但没必要。现在不少答辩组老师看前后端分离会默认这是基本功,你如果拿出一套十年前的技术栈,就得额外解释“为什么不用框架”,解释不好很被动。反过来,你用了Spring Boot加Vue,最多被问一句“你了解自动配置原理吗”,这个问题提前背一背就能答上来。

下面是我在实际项目中验证过、也推荐给毕业设计用的一套组合:

组件推荐版本选型理由
JDK1.8(8u201以上)版本稳定,兼容性最好,大部分学校机房和演示环境都支持
Spring Boot2.7.x与JDK8匹配,MyBatis-Plus、Redis等生态兼容无坑
MyBatis-Plus3.5.x单表增删改查零SQL,省出时间写核心业务
MySQL5.7或8.0免费、文档多,8.0注意时区配置
Redis5.x / 6.x做登录Token、幂等控制,不重也能跑,但建议引入
Vue2.6 + Element UI学习成本低,后台模板可复用
Maven3.6以上依赖管理标配

这套组合的一个隐藏优势在于:网上同类毕业设计源码、教程、踩坑记录非常多,随便搜一下都能找到对应的解决方案,对独立完成的同学来说友好很多。

2.2 版本搭配和启动踩坑记录

版本之间很容易出问题的地方,我先帮你排掉,免得你卡在环境搭建上大半个月。

第一个坑是JDK和Spring Boot版本不匹配。Spring Boot 3.x是要求JDK 17起的,有些同学下载了最新的Spring Boot 3.2,结果本机是JDK8,启动直接报错;反过来用JDK17跑Spring Boot 2.7也有兼容问题。毕业设计老老实实用JDK8加Spring Boot 2.7.x就好。

第二个坑是MySQL 8.0的时区问题。如果用的8.x版本,JDBC连接串里要加上serverTimezone=Asia/Shanghai,否则会出现The server time zone value乱码的错误。有些同学为了省事改成MySQL 5.7,连接驱动也用5.1.49,这个组合更省心。

第三个坑是Maven依赖下载慢。建议在maven的settings.xml里配置阿里云镜像,不然拉一个大项目等到怀疑人生。

pom.xml里最核心的依赖大概长这样:

<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.7.18</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.3.2</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.33</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> </dependencies>

2.3 项目目录怎么划分才像“设计”过的

后端包结构我建议按业务模块组织,而不是按技术层堆。下面是我用的、也是论文里能直接截图的结构:

  • com.example.community
    • controller(用户端、团长端、管理后台分开建子包)
    • service(接口)和 service.impl
    • mapper
    • entity(对应数据库表)
    • dto(接收前端参数)
    • vo(返回给前端的数据)
    • config(跨域、Redis、拦截器配置)
    • common(统一返回结果、异常处理)
    • task(定时任务)

前端单独建一个community-web目录,用vue-cli初始化的标准结构就行。前后端分离从目录上就能看得出来,这在论文的“系统总体设计”一章里是明明白白的加分项。还有,统一返回结果类建议尽早写,所有接口都返回{code, message, data}这样一个结构,前端axios拦截器统一处理,后期联调省掉无数扯皮。

3. 业务建模与数据库设计:十几张表如何撑起完整业务闭环

3.1 角色梳理和业务闭环

小区团购系统里至少有三个角色,它们不是孤立的,而是一条完整链条上的三个节点:

  • 普通用户(业主):浏览活动商品、下单支付、查看订单、到自提点核销提货。
  • 团长(自提点负责人):管理自己的自提点、接收平台配送到店的商品、核对用户提货码完成核销。
  • 平台管理员:管理用户、管理团长和自提点、创建团购活动、上架商品、处理订单售后。

在设计表之前,先画一遍这个闭环:管理员创建活动并设置商品和库存,用户在小程序或网页里看到活动并下单支付,订单进入“待成团”状态,等到活动截止,系统判定是否成团。成团后平台发货到自提点,用户收到通知去自提,团长核销订单,订单最终完成。如果活动没达到成团人数,系统自动退款。

这个闭环就是系统的核心业务,数据库所有表都围绕它展开。

3.2 核心数据表清单与字段设计要点

我梳理了一下,一个结构完整的小区团购系统至少要有下面这些表:

表名核心作用关键字段
user用户表openid或账号、昵称、手机号、小区id、角色
community小区表名称、地址
pickup_point自提点表所属小区、团长id、地址、营业时间
manager管理员表账号、密码(加密存储)
category商品分类表名称、排序
product商品表名称、主图、描述、价格、分类id
activity团购活动表开始时间、结束时间、最低成团人数、状态
activity_product活动商品关联表活动id、商品id、活动价、活动库存
cart购物车表用户id、活动商品id、数量
order订单表订单编号、用户id、自提点id、活动id、金额、状态
order_item订单明细表订单id、商品快照信息、数量、单价
payment_log支付记录表订单id、支付流水号、金额、状态
pickup_record自提核销记录表订单id、自提点id、核销人、核销时间
refund_record退款记录表订单id、退款金额、退款时间、原因

这里面有两个设计细节是答辩必问的,也是很多同学容易忽视的:

第一,订单明细表一定要做“商品快照”。也就是说,order_item表里要冗余保存下单当时的商品名称、商品图片、单价,而不是只存一个product_id。原因很简单:商品的价格和名称是会变的,如果用户下单之后管理员改了商品价格,订单详情里的显示也会跟着变,这显然是错的。把当时的名称价格固化到订单明细里,才是正确做法。论文里写一句“采用快照模式保存下单时的商品信息,避免后续商品修改影响历史订单”,答辩老师会觉得你考虑过真实业务场景。

第二,库存字段建议设计成活动库存加已售数量。比如activity_product表里放total_stock和sold_stock两个字段,而不是直接改product表的stock。因为同一个商品可以参与多个活动,每个活动的库存是独立控制的。真正下单时,用带条件的update去扣,后面代码章节会细讲。

3.3 订单状态机怎么用数据库表达

状态机是这个系统的灵魂,也是答辩老师最感兴趣的地方。我的设计如下:

状态值含义触发条件和流转方向
0待支付用户提交订单创建成功
1已支付待成团用户支付成功(或模拟支付回调)
2已成团备货中活动结束时订单人数达标,系统批量更新
3待自提平台标记商品已到自提点(可选细分状态)
4已完成用户在自提点核销提货
5已取消超时未支付或用户主动取消
6退款中活动未成团触发退款或有售后诉求
7已退款退款处理完成

状态变化必须遵循一个原则:状态只能按设计好的方向流动,不能倒着跳。比如已成团的订单就不能再取消,只能走售后退款流程。代码里不要允许随便set状态字段,而是通过专门的Service方法去完成状态迁移,这样论文里的状态图也能画得更加标准。

4. 核心逻辑实现:下单、扣库存、成团判定与超时兜底

4.1 下单接口的完整流程与幂等控制

进入代码部分。先说下单接口,这是整个系统最核心的接口,没有之一。它是这样一条链路:

  1. 前端提交activityProductId和数量。
  2. 后端先校验用户是否登录、活动是否存在、活动是否在有效期内。
  3. 再检查活动商品库存是否充足。
  4. 原子扣减库存,这一步是防超卖的关键。
  5. 扣减成功,生成订单记录,状态置为“待支付”。
  6. 调用模拟支付或跳转支付页面。
  7. 支付成功后回调通知,订单状态变成“已支付待成团”。

这里有两个容易被忽略的细节。

第一是并发场景下的超卖问题。如果你的扣库存代码是先查库存,判断大于0,再执行update减库存,那在高并发下会出现两个请求同时读到剩余1件库存,同时通过判断,同时执行update,结果就是卖出了2件。解决方式是用一条带条件的原子update:

boolean success = activityProductMapper.update(null, new UpdateWrapper<ActivityProduct>() .eq("id", apId) .gt("sold_stock", 0) .setSql("sold_stock = sold_stock + 1")); if (!success) { throw new BizException("手慢了,库存不足"); }

把这句update当成一把锁,数据库的行锁保证了同一时刻只有一个请求能成功执行。sold_stock的初始值是0,每次下单加1,通过判断当前已售数量是否小于总库存来兜底。你可以对比一下“先查后改”和“条件更新”两种写法的区别,这就是论文里“并发控制”章节最好的素材。

第二是幂等控制。前端用户连续点击两次“提交订单”,如果没有防范,就可能生成两笔一模一样的订单。我的做法是前端在提交前向后端请求一个token,后端放进Redis并设置1分钟过期,提交订单时带上token,后端先检查Redis里是否存在,存在才允许下单并删除token;不存在就直接拒绝。这样同一令牌只能使用一次,重复点击不会产生重复订单。

4.2 成团判定与超时关单的定时兜底

订单支付之后并不是万事大吉,还有两件大事要靠后台定时任务兜底。

超时关单:用户下单后30分钟没有支付,订单要自动取消,同时把刚才扣掉的库存还回去。我习惯用Spring自带的@Scheduled注解实现,每分钟跑一次扫描:

@Scheduled(cron = "0 * * * * ?") public void cancelExpiredOrders() { List<Order> orders = orderMapper.selectList(new LambdaQueryWrapper<Order>() .eq(Order::getStatus, 0) .lt(Order::getExpireTime, new Date())); for (Order order : orders) { orderService.cancel(order.getId()); } }

成团判定:活动结束时,要对这个活动下所有“已支付待成团”的订单做批量判断。等于最低成团人数,就把这些订单状态改成“已成团”;否则全部改成“退款中”,再走退款流程。这里我建议用一个独立的方法处理:

public void processActivityResult(Long activityId) { int paidCount = orderMapper.selectCount(new LambdaQueryWrapper<Order>() .eq(Order::getActivityId, activityId) .eq(Order::getStatus, 1)); boolean success = paidCount >= activity.getMinGroupNum(); // 更新该活动所有状态为1的订单 }

这个定时任务有一个值得写进论文的细节:为了防止两台服务器同时跑定时任务导致重复处理,我扫订单时的条件里带了status=1(已支付待成团),一旦被处理就会变成其他状态,下次扫描不会再查到这些订单,天然具备幂等性。如果学校要求你写“分布式环境下的可靠性”,可以补充用Redis setnx做分布式锁,但毕设层面能讲清楚这层“状态条件自带防重”就已经很不错了。

4.3 支付回调怎么设计才不会被追问

毕业设计一般不会真的对接微信支付或支付宝,因为涉及到商户号和资质,绝大多数同学用的是模拟支付。模拟支付也要设计得像真的一样,至少要有两条接口:

一条是前端调用的模拟支付接口,传订单号,直接返回支付成功;另一条是模拟支付回调接口notify,把订单状态从“待支付”改成“已支付待成团”。把回调单独拆出来,是因为论文里可以写“本系统预留了真实支付接口的替换位置,只需要将模拟实现替换为微信支付SDK调用即可”。这句话很便宜,但能堵住答辩老师关于“支付是否真实对接”的连环问。

这里要注意,下单时就先生成订单号,用时间戳加随机数,确保唯一,支付回调里用订单号加金额做匹配校验。支付日志表也要记录流水,退款时能从日志里看到原始支付记录,整个闭环才有说服力。

5. 前端页面与前后端联调:保底页面和加分项怎么安排

5.1 页面优先级排序,别把时间浪费在花哨特效上

前端页面很多人容易走极端,要么只做几个粗糙的表单页面,要么花大量时间调动画效果,这两种都不可取。我建议按下面的优先级来排:

优先级页面模块核心功能必要性
必须登录注册页账号密码登录、注册、角色选择高
必须首页商品列表按活动展示商品卡片、分类筛选高
必须商品详情页展示活动价、库存、加入购物车或立即购买高
必须下单结算页选择自提点、填写备注、提交订单高
必须订单列表页不同状态订单切换、查看详情高
必须个人中心页我的信息、地址、自提点、退出高
必须管理后台商品管理、活动管理、订单管理、用户管理高
建议团长工作台查看自提订单、核销提货中高
加分购物车页面多商品合并下单中
加分优惠券模块满减、折扣低
加分统计报表用ECharts展示订单量、销售额中低

管理后台的表格页面用Element UI的table组件加dialog弹窗就能搞定,一天能写完一个模块。首页和商品详情页要用点心,因为这是演示时打开的第一个页面,观感直接影响老师的第一印象,宁可做得干净大方一点,也不要去堆什么跑马灯和闪动的特效。

5.2 联调阶段最容易翻车的三个问题

前后端联调时,我见到的翻车点基本集中在下面三处,提前避掉能省很多时间。

跨域问题。前后端分离部署最常见的拦路虎。后端加一个CorsFilter是最快的解决办法,允许指定来源或者直接放开本地开发环境;也可以在前端vue.config.js里配置devServer的proxy,把/api开头的请求转发到localhost:8080。我建议两种都写上,开发用proxy,生产环境演示用CORS,灵活切换。

Token传递。登录成功后后端返回一个token(我习惯用JWT或者直接存Redis返回一个随机串),前端axios的请求拦截器统一在header里加Authorization字段;响应拦截器里遇到401或code为401的情况,自动跳回登录页。这套逻辑写一次,之后所有接口都自动带上认证,不用每个页面都手动处理。

日期格式统一。后端返回的LocalDateTime默认是英文格式,前端表格显示出来很难看。我习惯在application.yml里统一配置日期格式化,或者在后端加一个Jackson的配置类,保证返回的是yyyy-MM-dd HH:mm:ss格式。这笔小配置能让演示时管理后台的订单列表看起来专业很多。

另外强烈建议:演示环境不要依赖外网数据库,把MySQL和Redis都装到本地,或者用Docker在本机起服务,不然答辩当天网络一卡,整个演示流程就崩了。提前一天在答辩机器上把后端jar包和前端打包产物部署一遍,用浏览器实际走通所有演示用例,这是最笨但也最有效的准备。

6. 论文撰写与答辩准备的实战心得

6.1 论文结构怎么组织才算“设计感”

毕业设计论文一般都有固定的框架,但同样的框架,不同人写出来的感觉差别很大。我的建议是,把重心放在三块。

需求分析章节,除了写功能需求,一定要画出用例图、画出业务流程图。“小区团购系统”的业务流程图就是用户下单到自提点提货的完整链路,用Visio或ProcessOn画清楚,这一部分在老师眼里是“你真的理解了这个系统”的证据。

数据库设计章节,把第三章里那些表用ER图展示出来,重点标注订单表、活动商品表、自提点表之间的关系。每个字段的名字、类型、含义列一张表,这部分内容量大且简单,能有效充实论文篇幅。

核心功能实现章节,不要事无巨细地贴所有代码,而是挑三个有亮点的模块:订单状态流转、防超卖的库存扣减、活动截止的成团判定。每个模块给关键代码片段加文字解释,说明“我为什么这么设计”。答辩老师翻论文时能快速抓到你的技术亮点,提问也会围绕这些地方,你提前准备好就能稳占主动。

6.2 答辩高频问题清单与回答思路

根据这几年的经验,“小区团购系统”这类题目的答辩问题高度集中,提前准备下面几个就够用了:

  • 为什么选择Spring Boot而不是SSH?答:Spring Boot简化配置、自带Tomcat、生态完善,能让开发重心集中在业务逻辑上,也更符合当前企业的主流技术栈。
  • 订单超时是怎么实现的?答:下单时记录过期时间,启动一个定时任务每分钟扫描待支付且已过期的订单,自动取消并回滚库存,同时Redis token保证了取消操作的幂等性。
  • 怎么防止库存超卖?答:不是先查后改,而是直接用带条件的update语句原子扣减,靠数据库行锁保证并发安全,库存不足时更新影响行数为0,直接抛出库存不足异常。
  • 活动没达到成团人数怎么办?答:活动结束时定时任务统计已支付订单数量,未达标则批量将订单改为退款中,调用退款接口回滚支付记录,并通知用户。
  • 支付是真实的吗?答:当前是模拟支付,预留了回调接口,只要替换为微信支付或支付宝SDK就能无缝切换真实支付。

每个问题都照着“现象、方案、为什么这样设计”三层去答,基本不会冷场。

6.3 几个容易被人忽视影响结果的小细节

最后说几个我观察到的、特别影响最终成绩的小细节。

源码和论文必须严格对应。很多同学论文贴的代码是精修过的“理想版本”,而实际源码里是另一套写法,答辩老师一翻源码就露馅。宁可论文里写得朴素一点,也要保证和真实代码一致。

截图不要造假。功能模块截图要自己真的跑到页面再截,不要为了美观P数据。有老师会现场点开你的系统看某个页面,截图和真实功能对不上,前面所有的努力都会打折扣。

要准备一套干净的演示数据。登录账号、团购活动、订单状态都要提前造好。我习惯准备三个账号:一个普通用户,账号下有待支付、已完成、已退款三种订单;一个团长账号,待核销订单摆在那里,现场演示时直接点核销,效果非常直观;一个管理员账号,数据和图表都提前生成好。演示全程两分钟,但老师感觉工作量很饱满。

做毕业设计这件事,最忌讳的就是眼高手低。小区团购系统这个题目其实给了你一个很明确的抓手:把订单这条主线的状态流转做扎实,把库存并发这块讲明白,把三端页面做得能看能用,就已经是一个合格的、能在答辩现场站得住的系统。很多同学会说“我只会写增删改查怎么办”,我的回答一直是,你就从这个题目的订单模块开始写,写一遍下来,增删改查之外的东西你自然就会了。这个项目做完,你简历上能写的东西,也远远不止一句“熟悉Java基础”了。

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

Levenshtein距离原理与Python生产级实现

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

作者头像 李华
网站建设 2026/10/2 7:42:03

从u-boot切入嵌入式:告别单片机思维,迈向系统级开发

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

作者头像 李华
网站建设 2026/10/2 7:40:55

SpringSecurity + JWT 权限认证实战:从过滤器链原理到落地

SpringSecurity JWT 实现权限认证功能&#xff1a;从原理到落地&#xff0c;一套能直接用的方案接了个前后端分离的新项目&#xff0c;用户体系、角色权限都要从零搭。说实话&#xff0c;权限这块我第一反应就是 SpringSecurity&#xff0c;理由很简单&#xff1a;这玩意是 Ja…

作者头像 李华
网站建设 2026/10/2 7:40:50

用Materials Studio片段库高效构建有机金属配合物的实践指南

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

作者头像 李华
网站建设 2026/10/2 7:40:36

aistudio云端解压zip全指南:乱码、提速与避坑

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

作者头像 李华
网站建设 2026/10/2 7:40:06

五角星坐标计算:极坐标法生成稳定DX差分序列

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

作者头像 李华