这个项目算是我最近手头复盘比较完整的一套 Java Web 全栈作品一个旅游出行指南系统技术栈是 SpringBoot2 Vue3 MyBatis-Plus MySQL8.0源码和配套文档都是齐的。做旅游类业务其实很能检验 CRUD 之外的设计能力因为景点、攻略、路线、收藏、评论这些模块天然带有检索、排序、关联查询和状态流转用这套组合来落地正好能踩一遍主流实战问题。这篇文章不打算写成开发文档而是从一个已经跑通、交付过、也踩过坑的人的角度把这个项目的技术拆解、核心实现和常见问题一次性讲透适合正在做毕业设计、课程实训或者准备前后端分离项目练手的同学直接对照着改。1. 项目整体设计与技术选型思路1.1 为什么偏偏是 SpringBoot2 Vue3 MyBatis-Plus 这套组合先聊选型。现在市面上 SpringBoot 已经出到 3.x 了但 SpringBoot2 仍然是国内生产环境和教学项目里最稳的选择原因很简单生态资料多、第三方兼容广、排坑成本低。这个项目选择 SpringBoot2 而不是 3并不是技术落后而是因为要配合 MyBatis-Plus 和一些老牌的权限、文档组件2.x 的兼容性要明显更省心。前端没有用传统的 JSP 或者 Thymeleaf而是拆成了独立的 Vue3 工程前后端通过 JSON 交互这样后期如果要把移动端、小程序接进来后端接口完全可以复用不必再动模板层。Vue3 这一版最核心的变化是组合式 API以前 Vue2 里逻辑复用靠 mixin用多了之后命名冲突和隐式依赖很让人头疼Vue3 里用 setup 函数把同一业务的数据和方法聚在一起配合 Composition API代码可读性好很多。这个系统里像登录状态、用户信息、收藏列表这种随处都要用的数据我就把它们统一放在 Pinia 的 store 里组件里只需要 useStore() 就能拿到。配合 Vite 的开发服务器冷启动和热更新速度比 Webpack 时代快太多对前端调试体验来说是很大的提升。MyBatis-Plus 在 MyBatis 基础上做了一层增强内嵌了通用 Mapper、通用 Service 和分页插件。它不替代 SQL但把单表 CRUD 里的重复样板代码砍掉了。在旅游指南系统里景点表和攻略表都有大段的文本字段一些列表接口还要联查到用户的昵称、收藏数、评论数这时候 MyBatis-Plus 的 Wrapper 构造器可以直接拼查询条件代码量大概能减少一半。更重要的是它支持逻辑删除、自动填充、乐观锁这些都是一个正规业务系统必须要有的能力如果用原生 MyBatis 手写至少要多出几十个 XML 文件和对应配置。MySQL8.0 则是在存储引擎、索引和窗口函数上比 5.7 有明显进步。这个系统虽然没有用特别复杂的分析 SQL但在统计景点热度、按地区分组查询时8.0 的窗口函数和 CTE 可以用一种更简洁的写法替代之前的子查询。加上 MySQL8.0 默认字符集是 utf8mb4对 emoji 和生僻字的支持不再是问题旅游攻略里用户经常发表情、贴特殊字符旧版本的 utf8 会直接报错或者变成问号。这一套组合下来开发速度快、维护方便、部署也不复杂很适合中小型业务系统。1.2 系统核心功能模块是怎么拆的拿到需求以后我第一件事不是建表而是先画功能边界。旅游出行指南系统如果只做一个景点列表那和普通信息网站没有区别。为了把“出行指南”这个场景做完整我把系统分成了前台用户端和后台管理端两个大块中间通过统一的接口层来联动。前台用户端主要包含这几个核心模块用户注册登录、景点检索浏览、攻略文章阅读、出行路线规划、收藏管理、评论互动。用户注册登录这里用 JWT 做无状态认证前端拿到 token 后存到 localStorage 和 Pinia 中之后每次请求通过 Axios 拦截器自动带上后端通过拦截器解析 token 并注入用户信息到 ThreadLocal。景点检索不只是简单的列表还要支持按地区、分类、热度排序以及关键词模糊搜索。攻略和路线这两个模块相对复杂一点攻略需要富文本内容路线需要保存多个景点节点的顺序这就要设计专门的关联表来存路线和景点之间的关系。后台管理端则围绕内容维护来设计管理员可以维护景点的基础信息、上下架攻略、审核评论、管理用户状态。后台和前端共用一套数据库但接口单独分组权限通过角色字段区分。刚开始有人建议直接把后台页面做得和前台一样我坚持拆成两个入口这样后期可以分服务器部署也可以针对管理端单独做更严格的访问控制。最后用一张表把权限需求理清楚用户表字段里加 role 角色管理员接口统一走 /admin/** 前缀由拦截器校验角色比引入一堆权限框架更轻量。整个模块拆分下来边界清晰每个模块都能独立测试后面写文档时也容易对应上。模块主要功能对应数据表用户中心注册、登录、个人信息、收藏列表user景点模块列表检索、详情查看、分类筛选scenic_spot攻略模块图文发布、文章详情、内容管理travel_guide路线规划路线增删、景点排序、路线详情route, route_item互动评论评论发表、评论审核、回复comment后台管理数据看板、内容维护、用户管理以上业务表 admin_log2. 核心细节解析与落地要点2.1 后端分层结构Controller 层尽量做薄项目拿到手之后我比较关注的是包结构和分层规范。一个混乱的后端项目哪怕功能能跑后面加需求也会很痛苦。这个系统的后端采用标准的三层架构Controller、Service、Mapper。实体类放 entity 包和数据库字段一一对应VO 对象放在 vo 包里用于向前端返回视图数据。为什么不直接返回实体因为像用户表里有密码字段直接序列化到前端就泄露了必须通过 VO 来过滤。Controller 层我尽量做薄只负责接收参数、调用 Service、返回统一结果。统一结果对象我定义了 R 包含 code、message、data 三个字段。成功时 code 为 200业务抛异常时由全局异常处理器捕获返回对应错误码和提示信息。这样前端 Axios 拦截器只需要判断 code 就能决定是否弹出错误提示不需要到处处理 HTTP 状态码。RestController RequestMapping(/api/scenic) public class ScenicController { Resource private ScenicService scenicService; GetMapping(/page) public RPageResultScenicVO page(RequestParam(defaultValue 1) Integer page, RequestParam(defaultValue 10) Integer size, ScenicQuery query) { return R.ok(scenicService.queryPage(page, size, query)); } }Service 层承担业务逻辑比如发布攻略的时候要校验标题是否重复、设置封面图默认值、状态置为待审核。这里我把事务标注在 Service 方法上像“保存路线及路线明细”这种跨多张表的写操作必须用 Transactional 保证一致性。Mapper 层除了 MyBatis-Plus 自带的方法复杂查询通过注解 SQL 或 XML 实现。Mapper XML 和实体类不建议分开放到两个目录可以把 XML 文件放在和 Mapper 接口同包下然后在 application.yml 里配置 mybatis-plus.mapper-locations 指向 classpath*:mapper/*.xml。还有一个常见的坑是实体类属性命名数据库字段是下划线风格Java 属性是驼峰风格。MyBatis-Plus 默认开启了 mapUnderscoreToCamelCase 映射但如果手写 SQL 返回自定义列名比如 SELECT user_name AS userName还是经常会出现映射不上。后来我统一在 XML 里给重要查询定义 resultMap或者用 SQL 里的别名保证查询结果列名和实体属性严格对应。这一点在联表查询里尤其重要如果两张表都有 id 字段不处理的话 MyBatis 会把它映射到同一个属性上。2.2 MyBatis-Plus 的拦截器、逻辑删除和自动填充配置起来要长点心MyBatis-Plus 虽然用起来方便但如果不理解它的插件机制很容易踩坑。最常见的一个问题是分页查询失效如果没配置分页插件调用 Page 对象时会查出全表数据而且不会返回 total。这不是 MyBatis-Plus 失效而是缺少了 MybatisPlusInterceptor。这个拦截器必须通过 Bean 注册而且要注意在 SpringBoot2 项目里分页插件用的是 MapperScan 扫描到的 sqlSessionFactory。正确的配置看起来是这样Configuration public class MybatisPlusConfig { Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor new MybatisPlusInterceptor(); PaginationInnerInterceptor pagination new PaginationInnerInterceptor(DbType.MYSQL); pagination.setMaxLimit(100L); interceptor.addInnerInterceptor(pagination); return interceptor; } Bean public MetaObjectHandler metaObjectHandler() { return new MetaObjectHandler() { Override public void insertFill(MetaObject metaObject) { this.strictInsertFill(metaObject, createTime, LocalDateTime.class, LocalDateTime.now()); this.strictInsertFill(metaObject, updateTime, LocalDateTime.class, LocalDateTime.now()); } Override public void updateFill(MetaObject metaObject) { this.strictUpdateFill(metaObject, updateTime, LocalDateTime.class, LocalDateTime.now()); } }; } }逻辑删除也是这个系统的关键设计。我一开始用的是物理删除结果发现用户的收藏、评论里关联的数据会变成“无主数据”历史记录根本查不出来。后来把业务表都加了 deleted 字段通过 TableLogic 注解标识MyBatis-Plus 在执行 delete 的时候会自动改成 update deleted 1查询时自动追加 deleted 0 条件。这样虽然数据会堆积但还原、审计都很方便。要注意逻辑删除后唯一约束不能被触发两次删除所以用户收藏表里的唯一索引要包含 deleted 字段或者把删除时间也写进逻辑标识里。关于自动填充createTime 和 updateTime 最好不要在数据库层用 DEFAULT CURRENT_TIMESTAMP因为 Java 后端插入数据时往往希望拿到这个时间回显到前端。用 MetaObjectHandler 填充后插入完毕的实体对象里就有 createTime 值不需要再查一次数据库。这个细节在测试接口时经常被忽略等你发现前端新增记录后列表里时间是空的就说明没做填充或者填充字段名对不上。2.3 前端 Vue3 工程化Vite、Axios、Pinia 和路由守卫一个都不能少前端工程我用了 Vite 2.x 配合 Vue3入口是 index.html开发态和构建态的配置都写在 vite.config.js 里。项目目录结构按功能划分api 目录放所有请求函数views 目录放页面组件store 目录放 Pinia 状态router 目录放路由表utils 目录放 Axios 封装和 token 工具。刚开始开发时有人把请求直接写在组件里后面接口一变就要到处搜我这次把业务请求全部收敛到 api 模块里组件只负责调用函数并处理返回结果。Axios 封装有几个细节很重要。首先要配置 baseURL开发环境通过 Vite 代理把 /api 前缀的请求转发到后端 8080 端口避免跨域其次要加请求拦截器从 localStorage 取出 token 并放入 Authorization 头响应拦截器里统一处理 code 不为 200 的情况并抽离出接口报错提示。还有一个容易忽略的点后端文件下载接口返回的是二进制流这时候不能走统一 JSON 拦截需要在拦截器里判断 responseType 是 blob 或者直接透传。const service axios.create({ baseURL: /api, timeout: 15000 }) service.interceptors.request.use(config { const token useUserStore().token || localStorage.getItem(token) if (token) { config.headers.Authorization Bearer ${token} } return config }) service.interceptors.response.use( response { if (response.data instanceof Blob) { return response.data } const res response.data if (res.code ! 200) { ElMessage.error(res.message || 请求失败) return Promise.reject(new Error(res.message)) } return res.data }, error { if (error.response?.status 401) { useUserStore().clear() router.push(/login) } ElMessage.error(error.message || 网络异常) return Promise.reject(error) } )Vue Router 的守卫主要做两件事一是未登录用户访问需要登录的页面时跳转到登录页并记录来源路径二是管理员页面校验角色。我这里用的是 beforeEach 钩子结合一个 meta 配置比如 { requiresAuth: true, roles: [admin] }。相比在组件里写 if 判断路由级控制更集中。Pinia 的 store 里保存用户信息和 token 状态用户登录成功后调用 setUser 方法同时把 token 写进 localStorage刷新页面后在 main.js 里再从 localStorage 恢复这样就不会出现刷新后用户信息丢失的问题。3. 实操过程与核心环节实现3.1 MySQL8.0 环境准备第一次启动最容易载在时区和驱动上这个项目自带 SQL 脚本但前提是 MySQL8.0 环境得装对。网上 MySQL8.0 的安装教程挺多我还是要强调几个关键点。Windows 安装时选择 Server only字符集一定要选 utf8mb4否则后面中文搜索会出问题。Linux 上安装最简单的是用 Docker 或者 apt/yum 源无论哪种方式my.cnf 里建议显式加上 character-set-serverutf8mb4 和 default-time-zone08:00。MySQL8.0 的默认时区是 UTC如果不在连接串里指定 serverTimezoneJava 连上后时间会差 8 个小时这非常坑。连接串我这里给出一份可以直接用的配置spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/travel_guide?useUnicodetruecharacterEncodingutf8useSSLfalseserverTimezoneAsia/ShanghaiallowPublicKeyRetrievaltrue username: root password: 你的密码这里面的 allowPublicKeyRetrievaltrue 是 MySQL8.0 的坑如果账号使用了 caching_sha2_password 加密方式Java 客户端第一次通信需要获取公钥某些版本会直接报 Public Key Retrieval is not allowed。加上这个参数能临时解决更稳妥的做法是在 MySQL 里把用户的认证插件改成 mysql_native_passwordALTER USER rootlocalhost IDENTIFIED WITH mysql_native_password BY 你的密码; FLUSH PRIVILEGES;数据库初始化方面项目文档里提供了 travel_guide.sql 和 init_data.sql 两份脚本建议先执行建表脚本再导入初始数据。导入前一定要确认数据库已创建并且默认字符集是 utf8mb4。可以用 Navicat 直接运行也可以用命令行mysql -uroot -p -e CREATE DATABASE IF NOT EXISTS travel_guide DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; mysql -uroot -p travel_guide travel_guide.sql3.2 后端工程导入、配置和启动jar 包版本冲突是最大的拦路虎拿到源码后第一步就是把后端工程用 IDEA 以 Maven 项目方式导入等待依赖下载。这里推荐使用 Maven 3.6 和 JDK1.8SpringBoot2.7 在 JDK8 下运行最稳。pom.xml 里我看到了这一组版本SpringBoot 2.7.14、MyBatis-Plus 3.5.3、jjwt 0.9.1、Knife4j 4.1.0。这些版本都经过验证不建议擅自升到最新因为 MyBatis-Plus 3.5.4 以后对 Jdk 版本和 SpringBoot 3 的兼容分支有变化盲目升级容易引发 Bean 冲突。启动前要修改 application.yml 里的数据库账号密码以及 Redis 配置如果项目里用了 Redis 做缓存则检查本机 Redis 是否启动。大部分源码项目跑不起来都是因为数据库连不上其次是 Maven 仓库里的依赖用了旧版本导致 MyBatis-Plus 和 SpringBoot 的自动配置类冲突。清除完报错后直接运行主类上的 main 方法。看到 Spring Boot 启动图案和“Started Application in xx seconds”就说明后端没问题。验证接口我习惯用 Knife4j 的文档页面比 Swagger 原生 UI 好看接口分组也更清晰。启动后浏览器打开 http://localhost:8080/doc.html里面能看到每个接口的请求参数和响应示例。有一回前端说列表接口返回慢我用文档里的调试功能直接压了一遍发现是景点列表的联表查询没有加索引通过 explain 一看全表扫描了后来在表上加了 area_id 和 status 的联合索引速度从 1.8 秒降到了 80 毫秒。这种问题不通过文档工具定位光看前端是查不出来的。3.3 前端工程启动、登录鉴权和业务联调前端目录是 travel-ui进入目录后先看 package.json 里的 scripts一般有 dev 和 build。安装依赖使用 npm install如果网络慢可以用淘宝镜像但注意别把 lock 文件给删了。依赖装完后执行 npm run devVite 默认起在 5173 端口然后把 /api 代理到 http://localhost:8080。登录页是整个系统联调的第一关。登录接口接收用户名和密码返回 token 和用户信息。我建议前端在拿到 token 后立刻存好并且调用一次获取用户信息的接口来初始化 Pinia 中的数据。这个做法的好处是刷新页面后不需要重复登录只要路由守卫发现有 token 但没用户信息就走一次刷新接口。很多项目图省事把用户信息也放在 localStorage一旦用户被后台禁用前端还保留着过期的用户信息就非常尴尬。景点列表联调时会遇到分页参数格式的问题。这个项目封装了 PageResult 对象包含 records、total、current、size 四个字段。前端 Table 组件需要的数据正好是 records 和 total。我最初把 query 参数拼成 JSON 格式发送后端用实体接收时局部变量死活为空。排查了半天发现是 Axios 的 params 序列化把数组拼成了 xxx[0]... 这种格式后端反而接收不了。这里统一规定分页参数和查询条件一律用 query string格式为 page1size10areaId2。如果查询条件里有多个值比如分类包含多个分类 id直接传逗号分隔的字符串后端用 split 解析简单粗暴但有效。3.4 从源码到线上部署Nginx 下 history 路由的 404 必须处理部署环节是这个项目里最容易被忽略、但实际上最难的部分。后端打成 jar 包后用 java -jar travel-server.jar --spring.profiles.activeprod 启动。如果服务器内存有限可以考虑设置 JVM 参数 -Xms256m -Xmx512m。前端构建时需要先确认 .env.production 文件里 VITE_API_BASE_URL 的值。这里有一个重点前端打包后的 JS 里请求地址是 /api所以 Nginx 需要把所有 /api 请求转发到后端端口。server { listen 80; server_name your-domain.com; location / { root /usr/share/nginx/html/travel-ui; index index.html; try_files $uri $uri/ /index.html; } location /api/ { proxy_pass http://127.0.0.1:8080/api/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }try_files 那行是 history 路由的关键。Vue3 如果开的是 history 模式直接请求 /route/detail/1 这个路径时Nginx 找不到对应文件就会返回 404所以必须回退到 index.html。而刷新 /admin 页面之所以白屏也是这个原因只要 try_files 写了就不会有问题。如果项目中使用的是 hash 模式则不需要这段配置但 URL 会带 #不太美观。后端部署时还要注意生产环境跨域问题。因为 Nginx 已经做了 /api 反向代理前后端就是同域下的不同路径所以不需要再在后端开启 CORS。如果在开发环境下后端口不同则需要使用 CorsFilter 或 WebMvcConfigurer 放行。我建议把 CORS 配置放在后端开发时方便生产时如果 Nginx 代理了CORS 配置也不会影响只要允许的来源合理即可。4. 常见问题与排查技巧实录4.1 启动项目时报“Cannot load driver class: com.mysql.cj.jdbc.Driver”这个问题的原因几乎可以锁定为 MySQL 依赖版本不对或者没有引入依赖。在 pom.xml 中mysql-connector-java 的坐标在 SpringBoot2 里由 spring-boot-starter 管理但某些 IDEA 版本不会自动下载最新驱动需要手动指定dependency groupIdcom.mysql/groupId artifactIdmysql-connector-j/artifactId version8.0.33/version /dependency注意从 MySQL Connector/J 8.0.31 开始Maven 坐标变成了 com.mysql:mysql-connector-j旧坐标虽然还能用但可能下载到旧版本。另外driver-class-name 不要写成 com.mysql.jdbc.Driver那是 5.x 的老驱动类名MySQL8.0 必须用 com.mysql.cj.jdbc.Driver。4.2 MyBatis-Plus 分页查询失效total 总是 0分页失效最常见原因是没配置分页拦截器或者配置了但是没有生效。另一个原因是数据库方言配置错误如果 DbType 写成 ORACLE那么生成的 count 语句会不一样。还有一个小概率问题是 Page 对象和参数顺序颠倒如果 Page 不是第一参数拦截器就识别不到。建议把 mapper 方法签名写成 IPage selectPage(Page page, Param(query) UserQuery query)并且把 Page 放在第一个参数位。4.3 前端请求跨域Cookie 没有带上这里要区分两个概念跨域和鉴权。如果是 JWT 放在了 Authorization 头里不涉及 Cookie。但如果有其他接口依赖 Session 或 Cookie前端 axios 需要设置 withCredentials: true。同时后端 CORS 配置里的 allowedOrigins 不能写成 *必须指定具体域名。还有在 Nginx 转发时要注意 Cookie 的 domain 是否匹配否则浏览器会拒绝写入。4.4 踩坑速查表现象大概率原因解决办法中文乱码数据库/表字符集不是 utf8mb4建库时指定 DEFAULT CHARACTER SET utf8mb4时间多8小时或少8小时JDBC 连接串未指定 serverTimezone在 url 上加 serverTimezoneAsia/Shanghai更新记录后 updateTime 不改变未配置自动填充或实体字段没有 TableField(fill FieldFill.UPDATE)配置 MetaObjectHandler 并检查注解枚举字段前端显示为数字后端返回实体未转 VO或枚举未用 JSON 序列化转换Controller 返回 VOVO 里用字符串表示逻辑删除后唯一键冲突唯一索引包含 deleted 字段不彻底使用 deleted 与唯一键相关的字段联合索引或用 delete_time 辅助Vue3 页面刷新后 404路由使用 history 模式但服务器没有回退Nginx 配置 try_files $uri $uri/ /index.htmlnpm install 报 ERESOLVE依赖版本冲突删除 node_modules 和 package-lock.json重新 install后端跨域配置后前端仍报 CORS前端请求的是 /api但没有走代理或没命中 CORS 规则检查 Vite proxy 和后端 CorsFilter 的路径匹配列表接口慢缺少索引或分页时深度分页对查询字段建立组合索引并加最大分页数限制短信接口或文件上传失败依赖了未配置的外部服务文档里会列外部服务配置检查 application.yml 中的 API key最后分享一点我个人在实际操作里的体会这套旅游出行指南系统之所以适合拿来学习不只是因为它用了当前主流的 SpringBoot2 Vue3 MyBatis-Plus MySQL8.0而是它的业务场景覆盖了项目开发里最典型的那些问题——登陆鉴权、分页检索、关联查询、内容发布、状态校验、前后端联调、部署回退。把这些问题逐个啃下来比单纯刷几十集视频课都有用。如果你拿到源码准备二次开发我建议第一个改造方向是把搜索模块从数据库模糊查询升级到 Elasticsearch景点名称、攻略标题、标签这些字段在数据量过万后like 的性能和相关性都会成为瓶颈第二个方向是给热门景点和攻略加 Redis 缓存配合 Spring Cache 注解能非常直观地感受到缓存带来的性能提升。这个项目文档里已经把表结构、接口说明和部署步骤写得很清楚按文档跑通一遍再按自己的理解重写一遍基本就能达到独立开发一个前后端分离项目的水平了。
企业数字化 ERP 产品动态
相关推荐
Apache Pulsar 安全体系总览:角色令牌、可插拔认证提供商与凭证过期刷新机制 消息队列后端流处理 【免费下载链接】pulsar Apache Pulsar - distributed pub-sub messaging system 项目地址: https://gitcode.com/gh_mirrors/pulsar28/pulsar 点击查看 免费下载 本篇基于 Apache Pulsar 2.3 版本文档 Pulsar security overview 展开,系统讲解… · 2026/9/25 4:02:17
基于微信小程序与Django的工厂生产库存一体化系统 做中小工厂的信息化项目,最怕的不是代码难写,而是需求本身是散的。车间主任要的是“今天排了几个单、做到哪一步”,库管要的是“哪个料剩多少、够不够明天用”,老板要的是“这批货到底什么时候能发”。三方看的东西不一样… · 2026/9/25 4:02:11
UltraEdit自动换行与制表符设置: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/9/25 4:02:11
MikroORM 在 Babel 与 SWC 转译环境下的装饰器元数据配置完整指南 后端 【免费下载链接】mikro-orm TypeScript ORM for Node.js based on Data Mapper, Unit of Work and Identity Map patterns. Supports MongoDB, MySQL, MariaDB, MS SQL Server, PostgreSQL and SQLite/libSQL databases. 项目地址: https://gitcode.com/gh_mir… · 2026/9/25 5:33:47
华为CE8800密码过期警告处理:机制、操作与排查实战 上周远程登一台 CE8850 做季度巡检,SSH 连上去之后,屏幕上除了正常的版本信息,还多了一行格外扎眼的提醒:Warning: The password will expire in 21 days. The password needs to be changed, Continue? [Y/N]:干网络这一行&… · 2026/9/25 5:33:41
Atlas 300V部署YOLO全记录:从ONNX到OM的推理迁移实战 前阵子在客户现场折腾了一周,核心任务就一句话:把一张Atlas 300V 24G运算加速卡塞进服务器,把原本跑在GPU上的YOLO检测服务迁过去,还要保证1080P视频能实时出结果。这卡名字看着像显卡,但实际是专为AI推理设计的加速卡… · 2026/9/25 5:33:41
xberg C FFI 实战:用 force_ocr 强制对每一页 PDF 执行 OCR 后端AI 应用NLP 【免费下载链接】xberg Polyglot document intelligence with a Rust core: extract text, metadata, images, tables, and structured data from 106 formats across 140 file extensions, plus code intelligence for 371 languages. Fifteen bindings, with … · 2026/9/25 5:33:41
创维E900V22D刷机全攻略:S905L3SB芯片兼容性解析与救砖实战 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:31
MQTT协议原理与Broker服务器搭建实战:从Mosquitto到EMQX /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/9/25 1:00:37