news 2026/10/14 4:13:08

SpringBoot+Android酒店管理系统开发复盘:从数据库设计到并发控制

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SpringBoot+Android酒店管理系统开发复盘:从数据库设计到并发控制

先说一个经常被问的问题:毕业设计选酒店管理系统,是不是太老套了?我的看法是,题目不怕老,怕的是做的时候不知道自己在做什么。酒店管理系统这个题材,本质上是要你把"客人从进门到离店"这条完整业务链管起来:查房、预订、入住、退房、结算,每一个动作都有明确的业务含义,做完了既能演示,也方便答辩时把技术点讲清楚。

我最近完整过了一遍这个项目:后端用SpringBoot写RESTful接口,移动端用Android原生做客户端,数据库用MySQL,整体实现了一套面向酒店前台场景的管理应用。从数据库建表、接口开发,到Android端联调、文档整理,整个过程走下来,我对SpringBoot和Android配合做前后端分离应用的节奏算是摸得比较透了。下面就把这个项目从设计到实现再到交付的全过程做一个复盘,重点讲讲那些常规教程里不会写的选型理由、设计取舍,以及我在联调阶段踩过的坑。如果你也在做类似管理系统,或者刚接触这套技术栈,这篇文章应该能给你一些实际的参考。

1. 为什么是SpringBoot加Android:一次关于选题与选型的复盘

1.1 酒店管理系统要管的"业务真相"

很多人一听到酒店管理系统,第一反应是"做个增删改查"。如果停留在这个层面,项目确实没什么含金量。但真正跑过酒店业务就会发现,系统的核心难点不在界面,而在状态流转和防并发。

酒店前台的业务可以拆成几条线:

  • 房间线:房型维护、房间状态变化,这个状态是动态的,不是一张静态表;
  • 客人线:客户信息、联系方式、入住历史;
  • 订单线:预订、入住、换房、退房、结算;
  • 权限线:管理员和前台人员能看到的界面和操作不同。

其中最重要的一条是订单线。客人查询某天有没有房,提交预订,到店后办理入住,离店时结算退房——这一串动作不是简单的增删改查,而是每一环都依赖前一个动作产生的状态。比如预订成功之后房间就不能再被订,入住之后订单状态要变成"已入住",退房之后房间要恢复"空闲"。这些业务规则才是系统的核心价值所在。

所以我在没有写任何代码之前,先把这条主链路的流程在纸上画了一遍,明确每个状态在什么条件下可以流转到下一个状态。这一步看着简单,但直接影响后面的表设计和接口设计。

1.2 SpringBoot:为什么是后端省心的选择

酒店管理系统是典型的CRUD密集型业务,后端需要的是一个"上手快、生态全、能快速出活"的框架。SpringBoot正好符合这个要求。

选择SpringBoot有几个很现实的理由。第一,它把Spring原本繁琐的配置简化了。建一个Web项目,只需要引入spring-boot-starter-web起步依赖,通过对象扫描和自动配置把Tomcat、DispatcherServlet、JSON转换器全部配好,写接口的时候就专心写业务逻辑,不需要管一堆XML配置。第二,生态成熟。SpringBoot集成了Spring Data JPA、MyBatis、Spring Security、Redis等一整套生态,遇到问题几乎都能搜到现成的解决方案。这一点对做课程设计和毕业设计特别重要——项目周期有限,时间不应该浪费在反复调试框架本身。第三,工程结构清晰。Controller、Service、Mapper分层明确,代码好组织,也方便在答辩的时候把分层架构作为系统特色讲出来。

不过也要提醒一句:SpringBoot不是没有学习曲线。如果在这之前你只写过单纯的JavaSE程序,第一次接触SpringBoot时,容易被"依赖注入""Bean""自动配置"这些概念劝退。我的建议是先不要纠结原理,动手跑一个Hello World接口,再慢慢回到概念去理解它为什么这么设计。

1.3 Android端:为什么不用Web页面而选择原生客户端

这个项目为什么不用PC端的Web管理页面,而是做Android端?主要是从选题和场景两个角度考虑。

一方面,酒店前台是一个移动属性比较强的场景。前台工作人员不固定在某个工位,要用平板或手机直接帮客人办理入住、查看房态,Android客户端比传统PC管理后台更贴合实际使用场景。在答辩的时候,这也是一个很容易讲清楚的业务背景。

另一方面,Android原生开发对这类项目来说,工作量是可接受的。用Java写Android应用,界面用XML布局,业务逻辑写在Activity或Fragment里,网络层用OkHttp,JSON解析用Gson。这个技术栈在平时的项目里已经接触过,方向比较熟悉,不担心出现"技术选型没做过、风险特别大"的情况。

也考虑过用Flutter或者H5页面包壳,但最终没有选。Flutter要多学一套Dart语言,H5包壳又显得"不够原生",对需要展示原生开发能力的项目来说,Android原生反而是最稳的方案。

1.4 持久层框架选择:MyBatis-Plus 还是 Spring Data JPA

在做数据访问层时,我在Spring Data JPA和MyBatis-Plus之间犹豫过。这里分享一下我最后的选择逻辑。

Spring Data JPA在实体关系映射上非常方便,比如查询房间订单时,通过关系映射可以级联把关联的房型、客户信息一起查出来。但问题也出在"自动"上——一旦涉及复杂查询和批量更新,JPA自定义查询的写法比SQL要绕,而且如果不熟悉Hibernate的缓存机制,还容易出现性能问题。

MyBatis-Plus继承了MyBatis的SQL可控性,同时提供了IService和BaseMapper这些内置CRUD方法,日常的单表增删改查基本不用手写SQL,分页插件也开箱即用。它的思路是"简单查询自动生成,复杂查询写XML",非常契合酒店管理系统大量标准CRUD、少量复杂统计的场景。

所以我最终选的是MyBatis-Plus。从实际体验看,开发速度确实快,单表CRUD基本零SQL,遇到比如"统计一个月内各日期的入住率"这种报表类需求,直接在XML里写SQL,也完全可控。

2. 系统架构与数据库设计:把酒店业务拆成一张张表

2.1 整体架构:从Android到MySQL的完整请求链路

整个系统分三层:Android客户端、SpringBoot服务端、MySQL数据库。

Android客户端只负责界面展示和用户交互,不直接操作数据库。所有的业务操作,比如登录、查房、提交预订,都是通过HTTP请求打到SpringBoot的Controller接口,再由Controller调用Service层业务逻辑,Service通过Mapper访问MySQL,得到结果后再逐层返回给客户端。数据和界面是分离的。

在SpringBoot工程内部,我按标准的三层结构分包:

  • controller包:接收请求、参数校验、调用service、返回统一结果;
  • service包:业务逻辑,比如预订时的状态校验、金额计算;
  • mapper包:数据库操作,继承MyBatis-Plus的BaseMapper接口。

另外还有一个common包,放统一返回体Result、异常处理器GlobalExceptionHandler、工具类JwtUtil等。这样分包的好处是依赖方向非常清楚:controller依赖service,service依赖mapper,反向不依赖,代码在哪一层一眼就能找到。

2.2 角色权限与核心业务规则

这个系统的用户分为管理员和前台两类。管理员的职责是维护房型、房间基础信息,查看经营数据和所有订单;前台主要负责为客人办理预订、入住、退房这些日常操作。

权限控制用了Token方案。用户登录成功之后,服务端生成一个包含用户id和角色信息的令牌返回给客户端;客户端在后续每次请求时把这个令牌放到请求头里提交给服务端;服务端通过拦截器解析令牌,从中获取当前用户信息。

角色不同体现在接口层面:只有管理员才能调用的房间管理、房型管理接口,在接口上加了角色判断。前台调用这些接口会得到一个权限不足的提示。这个设计是"简单够用"的——不引入Spring Security这些重量级安全框架,也能达到控制访问的目的。

2.3 核心数据表设计

数据库设计是这类系统里最需要认真对待的部分。表结构如果设计得不合理,后面接口怎么写都不顺。我最终使用的核心表有这几张。

用户表:id、username、password、real_name、role、create_time。这里有个点要注意:密码不能存明文,我用的是MD5加盐存储。做课程设计级别的项目,这个安全级别够了,生产环境当然要换更安全的算法。

房型表:id、type_name、price、area、bed_num、max_people、img_url、remark。

房间表:id、room_no、room_type_id、floor、status、remark。status字段用的是整数枚举,约定:0维修、1空闲、2已预订、3已入住。

这里解释一下为什么不用字符串存"空闲"、"已预订"这种中文值。用数字枚举的好处,一是在代码里可以用常量统一管理,避免出现"空闲"和"空置"这种中文字符不统一的问题;二是方便做条件筛选,查询状态为2的已订房间时,直接status = 2,不需要处理中文编码和模糊匹配;三是状态机逻辑更严谨,每个数字对应唯一一个业务状态。

订单表:id、order_no、user_id、customer_name、customer_phone、room_id、room_type_id、check_in_date、check_out_date、total_price、status、create_time。订单状态同样用整数枚举:1待支付、2已订房、3已入住、4已完成、5已取消。

订单和房间的关系是一对一,一个订单在同一时间段内对应一个房间;一个客户可以多次下订单,所以订单里直接冗余了customer_name和customer_phone这两个字段,而不是单独建客户表。这是一个"冗余与规范"的取舍。如果引入客户表实现第三范式,查询时要多一次连表;对于酒店前台这种轻业务,订单直接带客人姓名电话,反而更实用。

房间表和房型表是多对一关系,房间表存room_type_id,查询房型详情时用关联查询。数据库字符集统一用utf8mb4,这个地方要特别注意,否则存中文用户名或房间备注容易出现乱码。

3. 后端核心业务接口:预订、入住、退房这条主链路的实现

3.1 统一返回结果与全局异常:先把接口地基打牢

写接口前我先把统一返回结构定义好了。所有Controller接口的返回类型都是Result ,里面包含三个字段:code(200成功、4xx业务失败、5xx系统异常)、message(提示信息)、data(业务数据)。Android端收到响应之后先看code,不是200就直接弹Toast显示message,逻辑非常统一。

public class Result<T> { private Integer code; private String message; private T data; // 省略构造方法和getter/setter }

配合统一返回体的还有全局异常处理器。我在common包里写了一个GlobalExceptionHandler,用@RestControllerAdvice注解,捕获业务异常、参数校验异常和兜底的Exception。这样Service里遇到业务错误,抛一个自定义的BusinessException("房间已被预订"),全局处理器就会把它转换成一个code为400的Result返回给客户端。Controller里不需要写一堆try-catch,代码干净很多。

这个设计看起来简单,但我觉得它是整个后端工程最划算的一笔投资。没有统一返回体之前,每个接口的返回字段命名都不一样,Android端解析JSON的时候要针对每个接口写单独的解析逻辑,非常痛苦。统一之后,客户端网络层可以用一套代码处理所有接口响应。

3.2 登录认证接口:Token方案是如何工作的

登录接口的逻辑不复杂:接收用户名和密码,校验通过后生成Token返回,失败则返回"用户名或密码错误"。

Token我用的JWT格式。生成的时候把userId和role放进payload里,设置24小时的过期时间,用设定的密钥签名。后续请求拦截时,从请求头Authorization字段取出Token,验证签名和过期时间,再从payload解析出当前用户信息,放入请求上下文中,供后面的业务逻辑取用。

我在项目中实际实现了一个简单的拦截器,继承HandlerInterceptor,在preHandle里做Token校验。对登录接口放行,对其他接口统一校验。这样做的好处是不需要每个Controller方法手动接收Token,代码复用性也更好。

3.3 房间查询与预订接口:状态校验和并发控制的细节

房间查询接口是最常用的。前台打开App后,第一件事就是选择入住日期和退房日期,查询这个时间段内哪些房间可用。

这个接口的查询逻辑需要想清楚:先查出所有状态为"空闲"的房间,再排除掉"在该时间段内已经被其他订单占用"的房间。第二种情况用订单表查询实现——找出与该时间段存在交集的非取消订单对应的房间号,从空闲房间中排除。

这里有两种实现方式:一种是在Java中查出所有房间后逐条判断时间冲突;另一种是直接在SQL中通过NOT EXISTS子查询完成。我采用后者,因为性能更好,也避免了大列表在Java中做循环判断带来的代码复杂度。

预订接口是整个后端里最需要"防呆"的地方。两个前台人员同时给不同的客人订同一间房,数据库层面如果没有约束,就可能出现超订。我在预订接口上做了双重保险。

一是把"检查房间状态、创建订单、更新房间状态"这三个动作放到同一个事务方法里,用@Transactional保证原子性。任何一步失败,事务回滚,不会出现订单创建了但房间状态没更新,或者房间被订了但订单记录不存在的中间状态。

二是在更新房间状态时,UPDATE语句的WHERE条件带上status=1(空闲)。也就是先执行"UPDATE room SET status=2 WHERE id=#{roomId} AND status=1",如果更新影响行数为0,说明这间房在操作间隙已经被别人预订了,直接抛出"房间已被预订"的业务异常。

UPDATE room SET status = 2 WHERE id = #{roomId} AND status = 1

这种"条件更新"的乐观锁思路,用SQL层面的约束来防并发,比单纯在Java代码里先查再改要可靠得多。

3.4 入住、退房与结算:状态流转和金额计算

入住接口:前台选中一个已订房状态的订单,点击办理入住。后端做的事是校验订单状态是否为"已订房",如果是,将订单状态更新为"已入住",同时把对应房间状态更新为"已入住"。

退房接口则反过来:校验订单状态为"已入住",将订单状态更新为"已完成",把房间状态置回"空闲",同时计算总费用。

金额计算这块有个容易被忽略的细节:退房时费用怎么算,是按预订时算好的固定价格,还是入住期间产生了延迟退房、额外消费后重新计算。我的做法是在预订时保存一个预算金额total_price,退房时如果前台没有添加额外费用,就直接按这个金额结算;如果添加了额外消费,就在原金额基础上累加。这样既保留预订时的价格依据,又给现场场景留了口子。

日期计算上,酒店订单按"间夜"计费。比如入住3月1日,退房3月3日,就是2晚,费用等于房间单价乘以晚数。这里我用了LocalDate类型的差值计算,避免用Date类型时因时间戳导致跨天计算少算或多算一天。

4. Android端实现:从登录页到功能闭环的客户端开发

4.1 客户端技术选型与项目结构

Android端我用Java原生开发,UI用XML布局,没有引入MVVM框架。对一个业务型管理系统来说,MVP或者MVVM虽然规范,但会增加一定配置成本。我的做法是轻量分层:网络请求封装在网络工具类里,每个页面继承BaseActivity,公共方法放在基类里。

工程结构按业务模块分包:

  • model包:对应后端的实体类,用于JSON解析;
  • network包:OkHttp封装和API请求;
  • ui包:按功能划分Activity,比如login(登录)、room(房间列表)、order(订单详情)、profile(个人中心);
  • adapter包:RecyclerView适配器。

模块划分的原则是:每个页面尽量独立,通用的网络请求和工具方法下沉到底层。这样的结构对课程设计来说已经很清晰,看代码的人能快速定位每个功能对应的页面。

4.2 网络层的封装细节

网络层是整个Android端的核心,也是坑最多的部分。我用的方案是OkHttp + Gson,自己封装了一个HttpUtils工具类。

工具类的核心方法接收三个参数:接口地址、参数Map、回调接口。内部执行方式:拼接参数,通过子线程发起POST/GET请求,在回调中解析JSON,按照上面聊过的Result统一结构,先判断code再返回data,最终切换回主线程调用回调函数更新UI。

这里有一个重点:OkHttp的回调是在子线程执行的,Android不允许在子线程直接更新UI,所以回调切回主线程的方式很关键。我的做法是用Handler(Looper.getMainLooper())把回调post到主线程,或者用runOnUiThread方法。初学时我在这里犯过错误——直接在子线程里设置TextView文本,结果应用闪退,报错提示只有创建View的原始线程才能触摸View。这个错误信息很经典,遇到基本就知道问题出在哪个地方了。

4.3 关键页面与业务闭环

客户端主要包含以下页面:登录页、房间列表页、房间详情/预订页、订单列表页、订单详情/入住退房操作页、我的页面。

登录页逻辑最简单,输入用户名密码,调用登录接口,成功后将Token和用户信息保存到SharedPreferences,然后跳转到首页。这里没有引入复杂的Token刷新机制,24小时过期,过期后客户端检测到未登录状态直接跳回登录页。

首页展示房间列表,按房型分组。每张卡片显示房间照片、房型名、门市价格、可入住人数。这里要注意的是,房间列表接口返回的数据里包含了图片URL,比如"http://服务器IP:8080/uploads/room1.jpg",Android端通过Glide加载。首次做的时候图片一直加载不出来,排查了半天,后来发现是Android 9以后默认禁止明文HTTP流量,需要在AndroidManifest里配置android:usesCleartextTraffic="true"才能访问http地址。这个点几乎每个Android联调项目都会遇到。

预订页是业务闭环的关键。用户选择入住日期、退房日期,页面显示可选的房型房间,点预订后,将日期和房间号提交到后端。提交前客户端会做一个简单校验:入住日期不能早于今天,退房日期必须晚于入住日期。

订单列表页展示当前操作的所有订单,状态用不同的颜色标签区分:待支付、已订房、已入住、已完成、已取消。点击订单进入详情页,根据状态显示对应操作按钮——已订房的订单显示"办理入住",已入住的订单显示"退房结算"。

4.4 真机联调的环境配置要点

联调时候最容易卡住的不是代码逻辑,而是网络环境。这里整理几个关键配置。

第一,服务器IP地址。模拟器访问宿主机要用10.0.2.2而不是localhost;真机调试要用局域网IP,比如192.168.x.x,并且保证手机和电脑在同一个WiFi下。如果用了云服务器,就直接填公网IP。

第二,Android 9及以上对明文HTTP的限制。开发阶段最简单的方式就是在AndroidManifest的application节点加android:usesCleartextTraffic="true"。如果不加,OkHttp会直接抛异常,提示明文HTTP流量不被允许。这个报错非常典型,看到它就知道是明文流量被拦了。

第三,端口占用和防火墙。SpringBoot默认8080端口,如果部署在云服务器,要确保安全组放行;如果在本地,要确保电脑防火墙允许该端口被外部访问。真机同一WiFi下访问不了,要么是IP不对,要么是端口没通,用telnet命令可以快速验证。

5. 联调与排错:那些让人怀疑人生的"灵异问题"排查实录

5.1 图片加载不出来?先查网络策略再查URL

前面提到的图片加载问题,我在这里完整还原一下排查过程。

最开始我以为是图片URL写错了,于是在浏览器里直接访问那个地址,发现图片能打开。然后在Android端Log里打印了加载的URL,也没问题。最后看到很关键的一句异常信息,提到Cleartext HTTP traffic not permitted,才意识到是系统安全策略不允许明文HTTP流量。

这里得到的经验是:遇到"本地资源在浏览器能访问、App里加载不出来"的情况,优先检查Android网络安全配置。除了全局的usesCleartextTraffic开关,也可以用networkSecurityConfig做更精细的域名级放行,但课程设计阶段用全局开关就够了。

5.2 日期错位:JSON序列化的"隔天幻觉"

预订日期提交到后端后,查询出来发现晚了一天。这是非常经典的Java 8日期时间序列化问题。

SpringBoot默认的Jackson序列化,对Java 8的LocalDate、LocalDateTime类型需要额外配置才能正确处理。如果没有配置,LocalDate可能会被序列化成数组格式,或者因为时区换算产生一天偏移。解决方法是配置全局的JSON序列化规则,把LocalDate格式化成年月日(yyyy-MM-dd),LocalDateTime格式化成年月日时分秒,并且指定时区。

spring: jackson: date-format: yyyy-MM-dd HH:mm:ss time-zone: GMT+8

在application.yml里做全局配置,或者写一个Jackson2ObjectMapperBuilderCustomizer的Bean,统一覆盖默认的ObjectMapper。这样前后端传递日期时就稳定了。

这个坑特别容易出现在联调快结束的时候,因为它不是必现的——只有日期跨天或者时区差异明显时才会暴露。排查思路是抓接口请求和响应的原始JSON,看日期字段到底传成了什么格式,问题立刻就能定位。

5.3 并发超订:如何用日志还原现场

在真实联调中,我模拟过两个请求同时预订同一间房的场景。如果代码只做了"先查询状态再更新",两个请求可能都查到"空闲",然后都执行了更新,结果就是两个订单关联同一房间同一时间段。

排查这个问题的突破口在日志。把关键SQL打印出来,对比两个请求的执行顺序,会发现两个select都发生在两个update之前。本质上是"检查"和"更新"之间留了时间窗口,并发请求在这个窗口里都看到了旧状态。

解决办法有两种思路。一种是用前面说的条件更新,在UPDATE语句中带状态条件,影响行数为0就说明被抢了,简单有效;另一种是用MySQL的SELECT ... FOR UPDATE行锁,在事务内把房间行锁住,另一个事务必须等待。前者适合并发量不大的场景,后者更接近生产环境做法。做课程设计的话,条件更新已经足够,而且代码更好解释。

这个点老师在答辩时很喜欢问。想一下为什么不能只用synchronized或者Redis锁——因为服务端可能部署多实例,本地的线程锁只能锁住当前进程,根本锁不住跨实例的并发请求。数据库层面的约束才是最终的兜底。

6. 项目交付与答辩准备:源码、文档和运行视频的正确打开方式

6.1 让项目在别人电脑上也能跑起来

交付项目时最怕的是"在我电脑上能运行"。要让项目具备可复现性,需要准备一套完整的运行说明。

环境清单大致是:JDK 1.8及以上、Maven 3.6+、MySQL 5.7或8.0、Android Studio(含SDK)、一台Android手机或模拟器。

启动顺序要写清楚:先启动MySQL,执行数据库初始化脚本;在application.yml里修改数据库账号密码;用Maven打包或者直接用开发工具启动SpringBoot;最后在Android Studio中运行App,修改网络地址为电脑局域网IP。

这里有一个细节容易被忽略:数据库初始化脚本不要只给建表语句,还应该把测试数据一起insert进去。房型、房间、管理员账号都应该提前准备好,否则拿到项目的人连登录都做不到,第一印象就不好。

6.2 项目文档该怎么组织

文档是交付物的一部分。一份好的项目说明文档,至少要包括这几部分:需求分析(用户角色、功能模块)、数据库设计(ER图、表结构说明)、接口设计(请求方式、参数、返回示例)、核心代码说明(关键业务的实现思路)、测试方案与测试结果。

接口文档尤其建议用表格列出,包括URL、请求方式、请求参数、返回结果。这样不仅方便查看,也方便自己后期回顾。我用的方式是在文档里按模块组织接口表格,比如用户模块、房间模块、订单模块,每个模块下面列清楚所有接口的细节。写文档的过程其实也是重新梳理系统的过程,写完思路会清楚很多。

6.3 运行视频和讲解视频:答辩演示的最强辅助

运行视频的作用是让评审看到系统完整跑起来的样子,讲解视频则是把技术要点讲清楚。准备视频的时候有一个心得:一定要提前写讲解稿,对着稿子讲,控制时间在10分钟以内。

视频内容围绕三个问题展开:项目做什么、怎么做的、我做了什么。尽量少讲"增删改查"这种所有人都能做的东西,多讲状态流转、并发控制、统一异常处理这些真正体现思考的内容。比如预订接口防并发那一段,把条件更新的SQL逻辑讲清楚,比把整个项目从头演示一遍更有说服力。


最后再说一个我个人的体会。做完这套酒店管理系统,我对"系统开发"这个概念的理解比之前深了一层。以前写代码更多的关注是"能不能跑通",现在会主动去想"如果两个前台同时操作同一间房怎么办""如果客人改签日期,订单状态怎么走"这些真实业务里经常出现的问题。这些思考,其实才是做项目最大的收获。

如果你也在写SpringBoot和Android相关的项目,希望这篇复盘能帮你减少一些踩坑的时间,把精力放在真正值得研究的地方。尤其是数据库状态设计和并发控制那部分,就算不做酒店管理系统,做其他的管理类项目也会遇到类似的问题,提前想清楚,后面能省很多事。

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

SpringBoot图书馆系统三层基建实战:环境、契约与边界

简介&#xff1a;这是一套面向计算机专业本科生的毕业设计级实战项目&#xff0c;基于SpringBoot开发的阿博图书馆管理系统&#xff0c;完整覆盖用户端借阅服务与管理员端全业务管控需求&#xff0c;适用于课程设计、毕设选题及Java Web开发能力进阶学习。资源包共3个文件&…

作者头像 李华
网站建设 2026/10/14 4:11:51

Spring Boot集成Smart-Socket实现云快充TCP协议对接

简介&#xff1a;本资源是一套基于SpringBoot与Smart-Socket实现云快充协议的充电桩对接源码&#xff0c;面向Java后端开发者及智慧能源平台建设者&#xff0c;解决城市级充电平台中与硬件设备&#xff08;充电桩&#xff09;高效、标准化通信的技术难点。项目聚焦底层Socket交…

作者头像 李华
网站建设 2026/10/14 4:11:43

Flutter适配OpenHarmony实战:逆向思维训练与学习日历App开发

做这个项目的起因其实很朴素&#xff1a;我一直想验证 Flutter 这套跨端方案&#xff0c;在脱离 Android 和 iOS 这两个“舒适区”之后&#xff0c;到底能不能扛住真实业务。正好手头有一台 OpenHarmony 开发板&#xff0c;又接到一个“逆向思维训练 App 学习日历”的练习需求…

作者头像 李华
网站建设 2026/10/14 4:10:14

基于MAC地址划分VLAN:企业移动办公网络接入层改造实践

工位换到哪&#xff0c;网络就自动跟到哪——这件事看着简单&#xff0c;真要让全网都做到却不轻松。在我经手的几次企业局域网接入层改造里&#xff0c;最终稳定落地的方案都是基于MAC地址划分VLAN。它不看端口、不认位置&#xff0c;只认设备本身的MAC身份&#xff0c;插到哪…

作者头像 李华
网站建设 2026/10/14 4:10:11

自适应固定悬浮导航条:原理、实现与避坑指南

简介&#xff1a;这是一套面向网页设计初学者与前端开发新手的自适应固定悬浮导航条网站源码模板&#xff0c;基于HTML5、CSS与JavaScript技术&#xff0c;实现了页面滚动时导航栏始终固定在屏幕顶部的效果&#xff0c;同时兼顾响应式布局&#xff0c;适合系统学习固定定位、媒…

作者头像 李华
网站建设 2026/10/14 4:10:08

Linux数据盘移除与重新挂载全攻略:从卸载到UUID固定

做运维这些年&#xff0c;"Linux服务器数据盘移除&#xff0c;重新挂载"这个操作我前前后后遇过的坑&#xff0c;比正经流程多得多。尤其是线上服务器&#xff0c;拔盘、换盘、重新挂载这一套流程&#xff0c;稍有不慎轻则服务起不来&#xff0c;重则数据直接废掉。这…

作者头像 李华