苍穹外卖从零开发:Spring Boot+MyBatis项目骨架与数据库设计
苍穹外卖这个系列我打算从零开始把一整套外卖系统完整跑通。名字虽然是“外卖”但真正做进去你会发现它不只是一个点餐软件而是用户、门店、调度、履约、结算全链路都在里面。很多同学跟着教程做项目最大的问题是只照着敲代码不知道每一步为什么这样做最后换一个需求又不会了。所以这个系列的每一篇我都会把“为什么”讲清楚再给可以落地验证的代码和配置。01篇先把地基打起来业务边界、技术选型、项目骨架、数据库设计以及第一个真正能登录的接口。1. 苍穹外卖要做的不是“点餐”而是一整套履约链路1.1 业务边界谁在用在用什么流程接到“外卖系统”这个需求时如果第一反应是写“用户点餐、商家出餐、骑手配送”三个模块方向没错但颗粒度太粗。真实约束比这复杂一个门店可能同时接多个平台渠道一个用户在不同地址有不同的配送条件一个订单从用户下单到结算要经历十几个状态变更。如果一开始不把闭环画清楚后面每接一个模块都要返工。从使用角色来看苍穹外卖至少覆盖四个端用户端的小程序/H5主要是浏览门店和菜品、加购、下单支付、查看订单商家端的管理后台负责门店信息、菜品上下架、订单接单自营骑手端负责接单、取餐、送达再往后还有运营后台管用户、管门店、管活动。01篇不需要立刻实现四个端但数据库和项目结构要为这四个端预留清晰的边界否则后面推倒重来的成本非常高。我把核心业务链路画在纸上纸上画不算违规建议你也画一遍用户打开小程序 → 定位/选择门店 → 查看分类和菜品SKU→ 加入购物车 → 提交订单 → 生成待支付订单 → 支付回调 → 订单进入商家工作台 → 商家接单/出餐 → 骑手取餐/配送 → 用户确认送达 → 订单完成 → 对账结算。1.2 项目拆分从一个单体原型开始的节奏很多团队一上来就拆微服务用户服务、订单服务、支付服务、门店服务。我不反对微服务但对于一个从零起步、目标是用最快速度验证业务闭环的项目单体应用是最理性的选择。原因很简单单体部署简单、调试直观、事务边界好控制外卖核心流程对事务一致性要求高比如下单要同时扣库存、生成订单、清空购物车在一个事务里比跨服务去协调要稳得多。苍穹外卖01篇的计划范围是搭建单体后端工程、完成基础公共模块、设计核心表、跑通小程序登录。除此之外的通告、秒杀、骑手派单留给后续章节。这个节奏的目的不是“少做”而是先把最小可用闭环跑通让后面的功能都有地基可放。1.3 01篇做到哪里算合格给一个可量化的验收标准你别用“能启动就算成功”敷衍自己第一条启动Spring Boot应用后能通过统一入口访问到健康检查接口返回统一结果封装。第二条连接MySQL数据库按章节4的表结构执行建表脚本后能在IDE和命令行客户端里看到完整的表。第三条小程序登录接口能在数据库内新增用户、返回Token并且带Token访问用户信息接口能拿到当前用户不带Token则被拦截并返回标准错误体。如果你按01篇走完这三件事都满足说明项目的基础层已经立住了后续写任何业务功能都只是往上堆砖。如果第三条还没通先别急着往下看登录态是几乎所有业务接口的前提这里偷懒后面全是坑。2. 技术选型我为什么坚持Spring Boot MyBatis这套“保守组合”2.1 选型标准先问团队和后续维护技术选型不是“哪个火用哪个”而是结合团队熟悉度、招聘难度、运维成本、生态成熟度来做选择题。苍穹外卖这种业务特点是CRUD密集、状态流转复杂、多表查询多但对并发的要求不是“从第一分钟就要扛百万QPS”这种级别。Spring Boot MyBatis MySQL Redis这个组合最大优点是生态完备、文档多、招人容易。遇到问题网上能搜到的实战案例非常多这对项目长期维护是很重要的一件事。Java体系里的MyBatis半自动SQL的特点适合外卖这种查询条件多变的场景你可以在XML里手写联表查询把SQL执行计划完全掌控在自己手里不像全自动ORM在复杂查询时生成出灾难SQL。2.2 关键依赖清单与版本策略01篇我用的是Spring Boot 2.x系列JDK用1.8。如果你是新机器也可以用JDK17和Spring Boot 3.x但要注意3.x里javax命名空间改成了jakarta很多老教程代码不能直接复制。为了少踩版本坑我这里给出一份能直接用的依赖清单。spring-boot-starter-web提供Web容器和Spring MVCmybatis-spring-boot-starterMyBatis官方提供的Spring Boot整合包mysql-connector-javaMySQL驱动注意8.x驱动在URL里要加时区参数spring-boot-starter-data-redis后面做缓存和登录态会用到01篇先把Redis连上jjwt-api / jjwt-impl / jjwt-jackson生成和解析JWT这个组合比老旧的jjwt 0.9.1更规范lombok减少实体类样板代码但记住它只是编译期工具别让团队对它的心智依赖过重spring-boot-starter-validation参数校验登录接口的入参非空校验就靠它springfox-boot-starter 或 knife4j接口文档我建议直接上knife4j对OpenAPI3的支持更省心2.3 为什么不用那些更“时髦”的框架有人问为什么不用Spring Cloud Alibaba全套为什么不用MyBatis-Plus为什么不用GraphQL我的回答是如果你的系统连单机并发都还没撑住就不要为微服务治理的复杂度买单。Spring Cloud全家桶至少引入注册中心、配置中心、网关、链路追踪运维成本直接上一个数量级01篇的核心目标是业务闭环不是证明你会用中间件。MyBatis-Plus我本身不反对单表CRUD确实快但外卖核心查询大量是报表、聚合、多表联查你迟早要回到XML手写SQL。如果团队更习惯MP用它做单表操作、手写XML做复杂查询也完全可以选型原则是“别让自己被框架绑架”。GraphQL则是另一个极端对外卖这种后台管理会员端场景收益低、复杂度高RESTful在这个体量下依然是性价比最高的方案。3. 项目目录与后端骨架先把模块边界画清楚3.1 controller-service-mapper 三层划分的细节很多初学者把项目结构写成放一堆包每个包叫utils、common、entity、controller、service、mapper看起来挺标准但实际写起来会出现“controller里写业务、service里面全是if-else、mapper接口对应几百行XML”的现象。苍穹外卖的工程结构我建议按业务维度做顶层分包再在包内做三层划分。一种很好用的结构如下com.sky启动类com.sky.controller接入层入口用户端和商家端可以进一步拆user、admin两个子包因为后面很多接口虽然操作同一张表但权限和返回体完全不同com.sky.service业务逻辑层每个业务用例对应一个服务方法不要一个Service类几十个方法方法超过两屏就要考虑拆类com.sky.mapper数据访问层只做SQL映射不要在里面写业务判断com.sky.entity对应数据库表的实体字段类型必须和数据库严格对应com.sky.dto / com.sky.vo入参对象和出参对象不要直接把Entity抛给前端因为前端不需要的字段和内部状态暴露出去既不安全也浪费流量com.sky.common公共结果封装、异常定义、工具类、全局异常处理com.sky.config配置类比如WebMvc配置、Redis配置、Knife4j配置、拦截器注册为什么要把DTO和VO单独拆出来以订单为例数据库订单表里有支付平台回调的签名信息、内部备注、结算状态这些字段如果直接序列化给用户端等于把内部逻辑泄露出去。电商和外卖公司非常在意接口返回结构的一致性前端靠JSON解包你后端今天多返回个null、明天少返回个字段前端就要跟着改一次所以对外契约要稳定内部表结构随便变没关系。3.2 公共模块统一返回体、异常处理、JWT工具不管哪个接口对外返回格式一定要统一。我用的返回体很简单Data public class ResultT { private Integer code; private String msg; private T data; public static T ResultT success(T data) { ResultT r new Result(); r.setCode(1); r.setMsg(ok); r.setData(data); return r; } public static T ResultT error(String msg) { ResultT r new Result(); r.setCode(0); r.setMsg(msg); return r; } }这里的code我建议不要用HTTP状态码业务码和传输状态码混在一起会让前端很痛苦。前端只关心“我是1还是0”其他业务状态通过data里的字段继续细分。全局异常处理也很关键不然MyBatis抛一个SQL语法异常时用户收到的就是一堆堆栈信息既不安全也不友好。我写了一个全局异常处理类捕获自定义业务异常后只返回msg捕获参数校验异常后返回第一条具体错误信息未知异常打日志后返回“系统繁忙”。JWT工具类我直接封装了生成、解析、获取userId三个方法。注意JWT的payload里不要放敏感信息签名密钥要放到配置文件中而不是写死在代码里否则部署时泄露密钥所有Token都能被伪造。3.3 配置文件yml里容易踩的坑application.yml里最容易被坑的是MySQL8的时区问题。如果你在连接串里不加serverTimezoneAsia/Shanghai大概率启动时会报“The server time zone value ‘йʱ’ is unrecognized”的乱码错误。我的配置server: port: 8080 spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/sky_take_out?serverTimezoneAsia/ShanghaiuseUnicodetruecharacterEncodingutf8useSSLfalseallowPublicKeyRetrievaltrue username: root password: 123456 data: redis: host: localhost port: 6379 database: 0 mybatis: mapper-locations: classpath:mapper/*.xml type-aliases-package: com.sky.entity configuration: map-underscore-to-camel-case: truemap-underscore-to-camel-case这个配置和mapUnderscoreToCamelCase一定要开不然数据库字段user_id在实体类里映射不上userId你会查出一堆null。mapper.xml我是放在resources/mapper目录下别和Java接口类的包路径搞混前者是XML后者是接口位置不同但命名要对应上。4. 数据库设计核心表不是订单而是门店和SKU4.1 表清单与实际作用外卖系统最核心的表我个人的理解不是订单表而是门店表和SKU表。因为订单是“结果”门店和菜品才是“源头”没有门店覆盖用户根本不会下单没有SKU的库存和价格订单就没有可计算的对象。所以01篇建表时优先把这五类表设计好。user用户表userId作为主键openId在第三方授权登录场景下必须唯一加唯一索引手机号允许为空但唯一创建时间。shop门店表门店名称、地址、营业状态、配送范围、评分、起送价、配送费。category分类表分类名称、类型1表示菜品分类2表示套餐分类、排序、状态。dish菜品表和setmeal套餐表菜品表存基础信息、价格、图片、分类套餐表对应多个菜品要额外建setmeal_dish关系表维护套餐和菜品的关系。orders订单表订单号、用户id、门店id、订单状态、支付状态、总金额、地址快照、下单时间。order_detail订单明细表记录每个菜品快照、数量、价格。shopping_cart购物车表用户加购记录其中冗余了菜品名称和图片避免查询购物车时反复联表。address_book地址簿用户地址信息标签家/公司/学校是否默认地址。4.2 订单表为什么必须冗余快照我先说一个很多人踩过坑的结论订单明细里的菜品名称、价格、图片一定要在下单那一刻把当时的菜品数据复制一份进来而不是只存dishId查询时再去菜表拿最新数据。为什么因为菜品是可以上下架、改价、改名的。用户下单时商品是25元商家晚上改成了30元如果明细表只存一个dishId用户查订单时看到的是30元客诉就来了。从履约角度看订单是企业发生交易的凭证单据里记录的信息必须是生成那一刻的快照而不是未来随时变化的状态。这个思想不只适用于外卖电商、票务、酒店全通用。另外建议给orders表加一个order_number业务上展示给用户的是它而不是自增主键。自增主键会泄露业务量比如今天注册用户10001和10002很容易推断出新增规模。随机字符串订单号虽然冗长但对用户和运营来说更安全。4.3 金额、状态、时间的字段规范外卖和钱相关的字段是重点规范定下来后整个团队都要遵守金额一律用Decimal类型Java实体对应BigDecimal禁止用float和double存金额浮点数在二进制下无法精确表达1.0 - 0.9可能会得到0.09999999999999998对账时差一分钱都查得头大。订单总金额、配送费、实付金额这几列默认值是0.00不允许null。状态一律用tinyint并且在Java常量类里定义不要散落在代码各个位置。比如订单状态1待付款、2待接单、3待配送、4配送中、5已完成、6已取消。为什么用状态值而不是字符串枚举值占空间小、索引效率高而且不会出现“已发货”和“发货完成”这种语义模糊。所有表必须有create_time和update_time并让数据库默认值自动维护实体类映射LocalDateTime。update_time用ON UPDATE CURRENT_TIMESTAMP自动更新这样排查数据问题时知道是什么时候变的。建表脚本我不在这里全部贴上篇幅太长但给一张核心表结构参考后面的代码都依赖这个schema表名核心字段说明useropenid, phone, nicknameopenid唯一索引手机号允许空但唯一shopname, status, delivery_range营业状态给商家端即时上下架用categorytype, name, sorttype区分菜品和套餐dishshop_id, category_id, price, status菜品价格Decimal(10,2)setmealdish_ids, price, status套餐价格同样Decimalordersorder_number, user_id, shop_id, status, amount订单号唯一索引amount精度Decimal(10,2)order_detailorder_id, dish_name, dish_price, quantity菜品快照冗余shopping_cartuser_id, dish_id, quantity, amount用户维度加购记录address_bookuser_id, consignee, phone, address, is_default默认地址用唯一布尔字段注意同一用户只能有一个默认地址5. 第一个能跑通的功能小程序登录的完整链路5.1 登录流程拆解01篇的业务功能就从登录开始。苍穹外卖的登录本质是“用第三方平台的授权身份换取我们后端颁发的Token”。我把流程拆成四步每一步你都要知道为什么第一步前端调用第三方平台获得登录凭证code。第二步后端拿着code调用平台接口获取用户在该平台的唯一标识openid。第三步用openid去user表里查查得到就说明老用户直接走登录成功查不到就自动创建一个新用户再走登录成功。第四步生成Token返回给前端前端后续请求带上这个Token后端解析通过后就知道当前用户是谁。这个方案最核心的价值在于后端永远不用存用户密码也接触不到用户的原始登录凭证。认证事务交给平台我们只做业务账号关联。哪怕user表泄露也只是openid列表不涉及密码。5.2 后端接口与JWT签发登录接口的Controller长这样为了演示方便我把第三方码换成了一个模拟参数真实项目里要在这个位置完成平台code的校验RestController RequestMapping(/user/user) public class UserController { Autowired private UserService userService; PostMapping(/login) public ResultLoginVO login(RequestBody LoginDTO dto) { User user userService.login(dto.getCode()); String token JwtUtils.generateToken(user.getId()); LoginVO vo new LoginVO(); vo.setToken(token); vo.setNickname(user.getNickname()); return Result.success(vo); } }Service的核心逻辑Override public User login(String code) { // 这里在真实项目里要调用平台接口解析code String mockOpenid mock_openid_ code; User user userMapper.getByOpenid(mockOpenid); if (user null) { user new User(); user.setOpenid(mockOpenid); user.setNickname(新用户); user.setCreateTime(LocalDateTime.now()); userMapper.insert(user); } return user; }如果你在本地调试时不方便真正对接平台接口我建议用一个以mock开头的固定openid来跑通后续逻辑但上线前一定要替换成真实解析逻辑使用mock数据时也要确认生产环境配置不能误用。JWT生成用的是jjwt版本public static String generateToken(Long userId) { Date now new Date(); Date expire new Date(now.getTime() 7 * 24 * 3600 * 1000L); return Jwts.builder() .setSubject(userId.toString()) .setIssuedAt(now) .setExpiration(expire) .signWith(SignatureAlgorithm.HS256, SECRET_KEY) .compact(); }有效期设为7天比较合理。太短了用户体验差动不动要求重新登录太长了安全隐患大Token泄露后有很长的攻击窗口。如果后面要做“记住我”可以再拆分accessToken和refreshToken但那是后话01篇先不给自己加戏。5.3 登录态校验拦截器与ThreadLocal登录接口本身不需要校验Token但用户信息接口、购物车接口、下单接口都必须校验。我用了Spring MVC的HandlerInterceptor统一处理只拦截/user/下的请求并排除/loginpublic class JwtTokenInterceptor implements HandlerInterceptor { Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String token request.getHeader(Authorization); if (token ! null token.startsWith(Bearer )) { token token.substring(7); } try { Long userId JwtUtils.parseToken(token); UserContext.set(userId); return true; } catch (Exception e) { response.setStatus(401); response.setContentType(application/json;charsetUTF-8); response.getWriter().write({\code\:0,\msg\:\未登录\}); return false; } } Override public void afterCompletion(...) { UserContext.remove(); } }这里有个细节经验分享UserContext用ThreadLocal保存当前登录用户拦截器里设置好controller和service直接用但千万要在afterCompletion里remove。因为Tomcat的线程池是复用的如果ThreadLocal不清理下一次同一个线程处理别的用户请求时还能读到上一个用户的信息这就是严重的越权漏洞。别问我怎么知道的排查这种偶发串号问题极其折磨人。注册拦截器时记住排除登录、退出、接口文档相关的路径。Knife4j的静态资源路径如果被拦截你打开文档页面时可能会看到空白或无法访问这个坑很常见。5.4 接口自测用Debug和工具模拟请求整个链路写完先别急着写前端页面。用IDE的Debug启动然后直接调接口。我通常的做法是先用一个HTTP工具发起POST /user/user/loginBody是JSON比如{code:test001}。看返回结果是否包含token。拿到Token后发起GET /user/user/info在Header里加上Authorization: Bearer 返回的Token看能否正确返回当前用户信息。如果返回401优先检查拦截器的排除路径写没写对以及Token的Header名称是不是一致。如果返回500去看日志重点看MyBatis的mapper有没有映射上用DEBUG级别把SQL日志打开它会打印执行的SQL和参数能很清楚地发现字段名不匹配。基于01篇的项目结构下一个功能无论是做门店列表还是菜品展示核心套路都一样建表、写mapper、写service、写controller、走登录态自测。你可以把这一篇当作一张地图后续所有功能都贴着这张地图走方向就不会歪。

相关新闻

语音预处理全流程详解:从原始音频到特征提取的完整链路

语音预处理全流程详解:从原始音频到特征提取的完整链路

作为这个系列的第二章,我想把语音预处理这块彻底讲透。上一篇我们聊了语音识别任务的整体框架,不少朋友看完后跑来问我:模型结构我大概懂了,但“把音频喂给模型之前,到底要做什么?”——这个问题问得特别好…

2026/10/14 14:30:45 阅读更多 →
BASE64加密源码完整JAR包集成指南:从拆包到避坑

BASE64加密源码完整JAR包集成指南:从拆包到避坑

简介:这份BASE64加密源码完整JAR包面向Java开发者,尤其是需要在项目中集成编码解码能力的初中级工程师。资源围绕java.util.Base64类库展开,涵盖encodeToString、decode、encode及ByteBuffer解码等核心方法,并延伸至电子邮件正文嵌…

2026/10/14 14:30:45 阅读更多 →
循环神经网络RNN完全解读:梯度消失、LSTM门控机制与工程实战

循环神经网络RNN完全解读:梯度消失、LSTM门控机制与工程实战

做了一段时间序列相关项目之后,我有一个很强烈的感受:很多人把循环神经网络RNN当成一个黑盒,会用框架里现成的nn.RNN、nn.LSTM,但一旦遇到梯度爆炸、loss震荡、预测结果出现“复制粘贴”这类问题,就完全无从下手。这篇…

2026/10/14 14:30:45 阅读更多 →

最新新闻

库存扣减的并发控制:乐观锁的应用

库存扣减的并发控制:乐观锁的应用

财务主管跨界写技术文,先交代缘由:公司商城搞限时促销,活动结束对账,账面库存和实物对不上,多卖了四十七件。排查一周,病根是库存扣减没做并发控制,两个请求同时读到同样的库存数,各…

2026/10/14 19:10:22 阅读更多 →
Python案例练习:图书管理系统

Python案例练习:图书管理系统

Python案例练习:图书管理系统、新增图书、查看所有图书、按书名搜索、修改图书信息、删除图书、保存数据到本地文件、从文件加载数据 """ 图书管理系统 新增图书、 查看所有图书、 按书名搜索、 修改图书信息、 删除图书、 保存数据到本地文件、 从文…

2026/10/14 19:10:22 阅读更多 →
防拍照泄密核心知识点合集精讲

防拍照泄密核心知识点合集精讲

在企业数据安全建设过程里,很多运维新人学习防泄密体系都是碎片化的。大多优先关注 U 盘拷贝、聊天软件外发、邮件附件导出这类传统泄密通道,很容易漏掉手机拍摄电脑屏幕这个低成本、高隐蔽性的泄密途径。很多企业投入预算搭建文档加密体系,管…

2026/10/14 19:10:22 阅读更多 →
Keepalived + DRBD 实现 NFS 文件服务高可用:架构、配置与避坑指南

Keepalived + DRBD 实现 NFS 文件服务高可用:架构、配置与避坑指南

简介:这份资源面向运维工程师与VoIP通信系统开发者,聚焦Freeswitch高可用架构的落地实践,通过Keepalived实现主备节点故障自动切换,解决单点故障导致通信服务中断的问题。压缩包共4个文件,约38KB,包含2个Sh…

2026/10/14 19:10:22 阅读更多 →
Reactor 3背压机制深度解析与生产级实践

Reactor 3背压机制深度解析与生产级实践

1. 项目概述:为什么背压不是“可选项”,而是Reactor 3的生存底线 你写完第一个 Flux.create() ,用 onNext() 疯狂发射数据,下游用 subscribe(System.out::println) 接收——一切丝滑。直到某天压测时,控制台突然…

2026/10/14 19:10:22 阅读更多 →
Python车险理赔车型识别与合规校验:数据工程实践指南

Python车险理赔车型识别与合规校验:数据工程实践指南

1. 项目背景与整体设计思路1.1 车型信息在车险理赔中的关键作用车险理赔看起来是“拍照—定损—打款”的简单流程,但真正做过车险数据的人都知道,车型信息是贯穿整个理赔链路的一个隐形骨架。从承保端的车型定价,到理赔端的配件价格与工时费计…

2026/10/14 19:09:21 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战: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/13 22:01:27 阅读更多 →
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/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练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 阅读更多 →