1. 项目概述
这个宠物诊所管理系统采用Vue+SpringBoot+Node.js技术栈构建,专为中小型宠物医院设计。我在实际开发中发现,传统宠物医院普遍存在预约混乱、病历管理低效、药品库存不清等问题。这套系统通过数字化手段,将诊所日常运营的各个环节串联起来,从预约挂号到诊疗记录,从药品管理到财务统计,形成完整闭环。
系统前端使用Vue3+Element Plus实现响应式界面,后端采用SpringBoot提供RESTful API,Node.js则负责处理实时通信等特定场景。这种架构既保证了系统的稳定性,又能快速响应业务需求变化。特别适合日接待量在20-50只宠物的小型诊所使用。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 核心功能模块设计
2.1 预约挂号子系统
采用日历组件+时间片管理实现智能预约:
vue复制<template>
<el-calendar v-model="currentDate">
<template #dateCell="{date, data}">
<div class="time-slots">
<el-tag
v-for="slot in timeSlots"
:type="getSlotStatus(date, slot)"
@click="handleSlotClick(date, slot)">
{{ slot }}
</el-tag>
</div>
</template>
</el-calendar>
</template>
关键设计点:
- 时间片粒度设置为30分钟,支持自定义工作时间段
- 医生排班数据通过WebSocket实时同步
- 预约冲突检测采用乐观锁机制
注意:实际部署时要根据诊所规模调整时间片密度,小型诊所建议30分钟,大型诊所可能需要15分钟间隔
2.2 电子病历管理系统
病历数据结构设计:
java复制@Entity
public class MedicalRecord {
@Id
@GeneratedValue
private Long id;
@ManyToOne
private Pet pet;
@Lob
private String diagnosis;
@ElementCollection
private List<String> images;
@OneToMany(cascade = CascadeType.ALL)
private List<Prescription> prescriptions;
// 其他字段...
}
特色功能:
- 支持富文本编辑和图片上传
- 病历模板可自定义
- 历史病历关联展示
2.3 药品库存管理
库存预警算法实现:
javascript复制// Node.js定时任务
cron.schedule('0 9 * * *', () => {
const alertItems = await Medicine.find({
stock: { $lte: '$minStock' },
$expr: { $lte: ['$stock', '$minStock'] }
});
if(alertItems.length > 0) {
sendStockAlert(alertItems);
}
});
3. 技术架构详解
3.1 前后端分离架构
系统采用典型的前后端分离架构:
code复制前端(Vue3) ← HTTP → SpringBoot(REST API)
↑ WebSocket ↓
Node.js(实时服务)
通信规范:
- 正常业务请求:HTTP + JWT认证
- 实时通知:WebSocket + STOMP协议
- 文件上传:分块上传+断点续传
3.2 数据库设计
核心表关系图:
code复制[Owner] 1---n [Pet]
|
n---n [MedicalRecord]
|
1---n [Prescription]---n [Medicine]
索引优化建议:
- 宠物表:owner_id + name 联合索引
- 预约表:date + doctor_id 联合索引
- 药品表:name + specification 联合索引
3.3 安全设计
采用四层安全防护:
- 网络层:HTTPS + CORS白名单
- 应用层:JWT + RBAC
- 数据层:AES加密敏感字段
- 审计层:操作日志全记录
Spring Security配置示例:
java复制@Configuration
@EnableWebSecurity
public class SecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.csrf().disable()
.authorizeRequests()
.antMatchers("/api/public/**").permitAll()
.antMatchers("/api/doctor/**").hasRole("DOCTOR")
.anyRequest().authenticated()
.and()
.addFilter(new JwtAuthenticationFilter(authenticationManager()))
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
return http.build();
}
}
4. 关键问题解决方案
4.1 高并发预约冲突
采用Redis分布式锁方案:
java复制public boolean makeAppointment(AppointmentDTO dto) {
String lockKey = "appt:" + dto.getDoctorId() + ":" + dto.getTimeSlot();
try {
// 获取分布式锁
boolean locked = redisTemplate.opsForValue()
.setIfAbsent(lockKey, "1", 30, TimeUnit.SECONDS);
if(!locked) {
throw new ConcurrentModificationException("当前时段正在被其他用户预约");
}
// 执行业务逻辑
return appointmentService.create(dto);
} finally {
redisTemplate.delete(lockKey);
}
}
4.2 病历图片存储
使用MinIO对象存储方案:
- 前端直传MinIO获取预签名URL
- 后端只保存文件引用
- 设置图片压缩策略:
javascript复制// Node.js图片处理中间件
sharp(inputBuffer)
.resize(800, 800, { fit: 'inside' })
.jpeg({ quality: 80 })
.toBuffer();
4.3 跨平台数据同步
基于WebSocket的实时同步机制:
javascript复制// Node.js WebSocket服务
wss.on('connection', (ws) => {
ws.on('message', (message) => {
const data = JSON.parse(message);
switch(data.type) {
case 'APPOINTMENT_UPDATE':
broadcastToRole('RECEPTIONIST', message);
break;
case 'MEDICINE_ALERT':
broadcastToRole('PHARMACIST', message);
break;
}
});
});
5. 部署实践
5.1 容器化部署方案
Docker Compose配置示例:
yaml复制version: '3'
services:
frontend:
build: ./frontend
ports:
- "8080:80"
backend:
build: ./backend
environment:
- SPRING_PROFILES_ACTIVE=prod
depends_on:
- redis
- mysql
node:
build: ./node-service
ports:
- "3000:3000"
mysql:
image: mysql:8.0
volumes:
- mysql_data:/var/lib/mysql
redis:
image: redis:alpine
5.2 性能优化建议
- 前端:
- 路由懒加载
- 组件按需引入
- 图片懒加载
- 后端:
- JVM参数调优:
bash复制java -jar -Xms512m -Xmx1024m -XX:MaxMetaspaceSize=256m
- 启用Gzip压缩
- 配置HTTP缓存头
- 数据库:
- 查询缓存
- 连接池配置
- 定期执行ANALYZE TABLE
6. 常见问题排查
6.1 预约时间显示异常
可能原因及解决方案:
- 时区不一致:
- 确保所有服务器使用Asia/Shanghai时区
- 前端moment.js配置本地时区
- 缓存未更新:
- 清除浏览器缓存
- 重置Redis缓存
6.2 图片上传失败
排查步骤:
- 检查MinIO服务状态
- 验证预签名URL有效期
- 查看Nginx上传大小限制:
nginx复制client_max_body_size 20M;
6.3 系统响应缓慢
性能分析工具链:
- 前端:Chrome DevTools Performance面板
- 后端:Arthas + SkyWalking
- 数据库:Slow Query Log
我在实际部署中发现,80%的性能问题都源于不当的数据库查询。建议为所有列表查询添加分页限制,默认不超过50条记录。
