作为一名长期从事企业级应用开发的工程师,最近我完成了一个基于SpringBoot的酒店运营系统前端项目。这个系统专为中小型酒店设计,旨在通过数字化手段提升酒店运营效率和客户体验。在开发过程中,我积累了不少实战经验,特别是关于如何将SpringBoot后端与现代化前端技术栈高效整合的实践心得。
系统采用典型的三层架构设计:
这种架构选择主要基于以下考虑:
用户认证采用了JWT(JSON Web Token)方案,这是考虑到:
关键实现代码片段:
java复制// JWT生成器配置
@Bean
public JwtGenerator jwtGenerator() {
return new JwtGenerator()
.setSecretKey("hotel-secret-2023")
.setExpiration(3600000); // 1小时有效期
}
// 登录接口
@PostMapping("/login")
public ResponseEntity<AuthResponse> login(@Valid @RequestBody LoginRequest request) {
User user = userService.authenticate(request);
String token = jwtGenerator.generateToken(user);
return ResponseEntity.ok(new AuthResponse(token));
}
重要提示:在实际生产环境中,secretKey应该从配置中心获取,而不是硬编码在代码中。同时建议设置refreshToken机制来处理token过期问题。
这个模块采用了微前端架构,主要包含:
技术亮点:
数据库设计关键表结构:
sql复制CREATE TABLE `hotel_info` (
`id` bigint NOT NULL AUTO_INCREMENT,
`name` varchar(100) NOT NULL,
`address` varchar(255) NOT NULL,
`star_level` tinyint DEFAULT '3',
`contact_phone` varchar(20) NOT NULL,
`description` text,
`status` tinyint DEFAULT '1' COMMENT '0-下线 1-上线',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
KEY `idx_status` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
预订流程是系统的核心,我们实现了:
关键业务逻辑:
java复制public BookingResult createBooking(BookingRequest request) {
// 1. 验证房态
Room room = roomService.getAvailableRoom(request);
if (room == null) {
throw new BusinessException("所选房型已售罄");
}
// 2. 价格计算
BigDecimal amount = pricingService.calculatePrice(room, request);
// 3. 创建订单
Order order = orderService.createOrder(request, room, amount);
// 4. 调用支付
Payment payment = paymentService.createPayment(order);
return new BookingResult(order, payment);
}
酒店系统最关键的挑战就是避免超卖。我们采用了以下方案:
sql复制UPDATE room_inventory
SET available = available - 1
WHERE room_type_id = ? AND date = ? AND available > 0
java复制public boolean tryLock(String key, long expireSeconds) {
return redisTemplate.opsForValue()
.setIfAbsent(key, "1", expireSeconds, TimeUnit.SECONDS);
}
java复制@Cacheable(value = "roomStatus", key = "#hotelId+'-'+#date")
public RoomStatus getRoomStatus(Long hotelId, LocalDate date) {
// 数据库查询逻辑
}
支付模块我们抽象出了统一的支付网关,支持:
支付状态机设计:
mermaid复制stateDiagram
[*] --> UNPAID
UNPAID --> PAYING: 发起支付
PAYING --> PAID: 支付成功
PAYING --> FAILED: 支付失败
FAILED --> UNPAID: 重新支付
PAID --> REFUNDING: 申请退款
REFUNDING --> REFUNDED: 退款成功
经验分享:支付回调一定要做好幂等处理,我们通过唯一交易号+状态机校验来避免重复处理。
javascript复制const HotelList = () => import('./components/HotelList.vue')
API请求合并:将多个细粒度请求合并为单个批量请求
图片懒加载:使用Intersection Observer API
Webpack优化:
javascript复制// vue.config.js
module.exports = {
configureWebpack: {
optimization: {
splitChunks: {
chunks: 'all',
maxSize: 244 * 1024 // 244KB
}
}
}
}
code复制-XX:+UseG1GC
-XX:MaxGCPauseMillis=200
-XX:InitiatingHeapOccupancyPercent=45
sql复制-- 优化前
SELECT * FROM orders WHERE DATE(create_time) = '2023-01-01';
-- 优化后
SELECT * FROM orders
WHERE create_time >= '2023-01-01 00:00:00'
AND create_time < '2023-01-02 00:00:00';
yaml复制spring:
datasource:
hikari:
maximum-pool-size: 20
minimum-idle: 5
idle-timeout: 30000
max-lifetime: 1800000
connection-timeout: 30000
java复制@Configuration
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.headers()
.xssProtection()
.and()
.contentSecurityPolicy("script-src 'self'");
}
}
javascript复制// axios配置
axios.defaults.xsrfCookieName = 'XSRF-TOKEN';
axios.defaults.xsrfHeaderName = 'X-XSRF-TOKEN';
java复制@Column(columnDefinition = "varchar(255) COMMENT '手机号'")
@EncryptedField(algorithm = "AES")
private String phone;
java复制@Aspect
@Component
public class AuditLogAspect {
@AfterReturning(pointcut = "@annotation(auditLog)", returning = "result")
public void afterReturning(JoinPoint joinPoint, AuditLog auditLog, Object result) {
// 记录操作日志
}
}
我们采用Docker+ Kubernetes的部署架构:
dockerfile复制FROM openjdk:11-jre-slim
VOLUME /tmp
COPY target/*.jar app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
yaml复制apiVersion: apps/v1
kind: Deployment
metadata:
name: hotel-web
spec:
replicas: 3
selector:
matchLabels:
app: hotel-web
template:
metadata:
labels:
app: hotel-web
spec:
containers:
- name: hotel-web
image: registry.example.com/hotel-web:1.0.0
ports:
- containerPort: 8080
resources:
limits:
cpu: "1"
memory: 1Gi
yaml复制management:
endpoints:
web:
exposure:
include: health,info,metrics,prometheus
metrics:
export:
prometheus:
enabled: true
xml复制<!-- logback-spring.xml -->
<appender name="ELK" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<destination>logstash:5044</destination>
<encoder class="net.logstash.logback.encoder.LogstashEncoder"/>
</appender>
经过三个月的开发和优化,系统已经稳定运行在客户生产环境,支撑日均10万+的访问量。主要技术指标:
未来演进方向:
在开发过程中,我深刻体会到几个关键点:
这个项目让我对SpringBoot生态有了更深入的理解,特别是在高并发场景下的实战经验非常宝贵。后续我会将部分通用模块开源,回馈技术社区。