1. 项目概述:宠物生活馆全栈解决方案
去年帮朋友改造他的传统宠物店时,我深刻体会到线下业务的数字化转型痛点。这个基于SpringBoot+Vue的宠物生活馆网站,正是为解决这类需求而设计的全栈解决方案。它不仅仅是个展示窗口,更是整合了商品管理、服务预约、会员系统等核心功能的业务中台。
技术栈选择上,后端采用SpringBoot 2.7 + MyBatis Plus组合,前端使用Vue 3 + Element Plus构建。数据库选用MySQL 8.0,配合Redis缓存提升性能。这种架构既保证了开发效率,又能承载中小型宠物服务机构的业务体量。特别在高峰期预约场景下,我们的压力测试显示能稳定处理每秒300+的并发请求。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 核心功能模块设计
2.1 多角色权限体系
系统设计了三级权限控制:
- 管理员:拥有商品上下架、服务项目配置、订单核销等全部权限
- 店员:可处理服务预约、商品销售等前台业务
- 会员:享受预约、购物、积分兑换等服务
权限实现采用RBAC模型,通过Spring Security的@PreAuthorize注解进行方法级控制。前端路由则根据用户角色动态生成,关键代码片段:
java复制// 后端权限校验示例
@PreAuthorize("hasRole('ADMIN') or hasAuthority('product:edit')")
@PostMapping("/products")
public Result addProduct(@Valid @RequestBody Product product) {
return productService.save(product)
? Result.success("添加成功")
: Result.error("添加失败");
}
2.2 服务预约引擎
这是最复杂的核心模块,包含三个关键技术点:
-
资源时间片管理:
将美容师、洗浴间等资源按15分钟为单位分片存储。数据库设计采用位图索引优化查询:sql复制CREATE TABLE `time_slot` ( `resource_id` int NOT NULL, `date` date NOT NULL, `time_bits` bigint DEFAULT 0, PRIMARY KEY (`resource_id`,`date`) ) ENGINE=InnoDB; -
冲突检测算法:
使用Redis的BITFIELD命令实现原子化操作,确保并发安全:java复制public boolean checkAvailability(int resourceId, LocalDateTime start, int duration) { String key = "res:" + resourceId + ":" + start.toLocalDate(); long offset = start.getHour() * 4 + start.getMinute() / 15; long value = redisTemplate.opsForValue() .bitField(key, BitFieldSubCommands.create() .get(BitFieldSubCommands.BitFieldType.unsigned(96)) .valueAt(0)); return (value & (1L << offset)) == 0; } -
动态定价策略:
周末和节假日自动上浮20%价格,通过策略模式实现:java复制public interface PricingStrategy { BigDecimal calculate(BigDecimal basePrice); } @Component @ConditionalOnProperty(name = "pricing.mode", havingValue = "holiday") public class HolidayPricing implements PricingStrategy { @Override public BigDecimal calculate(BigDecimal basePrice) { return basePrice.multiply(new BigDecimal("1.2")); } }
3. 技术实现细节
3.1 前后端分离架构
采用Nginx作为静态资源服务器和反向代理,部署结构如下:
code复制请求流程:
客户端 -> Nginx(80)
-> 静态资源(vue打包文件)
-> /api/* -> SpringBoot(8080)
Vue axios配置示例:
javascript复制const service = axios.create({
baseURL: process.env.VUE_APP_BASE_API,
timeout: 10000,
withCredentials: true
})
// 请求拦截器
service.interceptors.request.use(config => {
if (store.getters.token) {
config.headers['X-Token'] = getToken()
}
return config
})
3.2 数据库优化实践
针对宠物店业务特点,我们做了这些优化:
-
垂直分表:
将商品详情等大字段单独存放:sql复制CREATE TABLE `product` ( `id` bigint NOT NULL AUTO_INCREMENT, `name` varchar(100) NOT NULL, `price` decimal(10,2) NOT NULL, PRIMARY KEY (`id`) ); CREATE TABLE `product_detail` ( `product_id` bigint NOT NULL, `description` text, `specs` json DEFAULT NULL, PRIMARY KEY (`product_id`) ); -
智能搜索方案:
使用Elasticsearch实现商品多维度搜索,通过Logstash同步MySQL数据:json复制// ES索引映射 { "mappings": { "properties": { "name": {"type": "text", "analyzer": "ik_max_word"}, "category": {"type": "keyword"}, "price": {"type": "double"}, "tags": {"type": "keyword"} } } }
4. 部署与运维方案
4.1 容器化部署
采用Docker Compose编排服务,关键配置:
yaml复制version: '3'
services:
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: pet@1234
volumes:
- ./mysql/data:/var/lib/mysql
- ./mysql/conf:/etc/mysql/conf.d
redis:
image: redis:6-alpine
ports:
- "6379:6379"
app:
build: .
ports:
- "8080:8080"
depends_on:
- mysql
- redis
SpringBoot的Dockerfile示例:
dockerfile复制FROM openjdk:11-jre
VOLUME /tmp
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
4.2 监控与日志
-
Prometheus监控:
通过actuator暴露指标:yaml复制management: endpoints: web: exposure: include: health,info,metrics,prometheus metrics: tags: application: ${spring.application.name} -
日志收集方案:
使用ELK栈处理日志,Logback配置示例:xml复制<appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender"> <destination>logstash:5044</destination> <encoder class="net.logstash.logback.encoder.LogstashEncoder"> <customFields>{"app":"pet-shop","env":"${spring.profiles.active}"}</customFields> </encoder> </appender>
5. 典型问题解决方案
5.1 微信支付集成
遇到的证书加载问题解决方案:
java复制@Bean
public WXPay wxPay() throws Exception {
InputStream certStream = getClass().getResourceAsStream("/cert/apiclient_cert.p12");
WXPayConfig config = new WXPayConfig() {
@Override
public InputStream getCertStream() {
return certStream;
}
// 其他配置方法...
};
return new WXPay(config, WXPayConstants.SignType.HMACSHA256);
}
5.2 图片存储优化
采用七牛云OSS存储图片,前端直传方案:
javascript复制// 获取上传token
async getToken() {
const res = await getOssToken()
this.token = res.data.token
this.domain = res.data.domain
}
// 上传回调处理
handleSuccess(response, file) {
this.imageUrl = `https://${this.domain}/${response.key}`
}
6. 性能优化记录
通过JMeter压测发现的三个性能瓶颈及解决方案:
-
预约查询慢:
- 问题:高峰期查询响应时间>2s
- 解决:添加复合索引
(resource_id, date, status) - 效果:降至200ms内
-
购物车并发:
- 问题:秒杀场景出现超卖
- 解决:Redis Lua脚本实现原子操作
lua复制local stock = tonumber(redis.call('GET', KEYS[1])) if stock > 0 then redis.call('DECR', KEYS[1]) return 1 end return 0 -
首页加载慢:
- 问题:首屏资源>3MB
- 解决:
- 图片WebP格式转换
- Vue路由懒加载
- Nginx开启Brotli压缩
- 效果:降至800KB
这套系统在正式环境运行半年后,帮助客户将业务量提升了40%,店员工作效率提高60%。特别是预约模块的智能化改造,使得每天可多处理30%的服务订单。
