1. 项目概述与核心价值
这个宠物医院管理系统是我去年为一个连锁宠物医疗机构开发的商业项目,经过半年多的实际运行验证,目前稳定支撑着8家分店的日常运营。系统采用Java+SpringBoot+SSM的主流技术栈,相比传统宠物医院使用的单机版软件,解决了三大痛点:
- 多门店协同难题:通过分布式架构实现病历共享、药品库存联动和医生排班统筹,分院间的转诊率提升了40%
- 医疗流程标准化:内置17种常见宠物疾病的诊疗模板,新入职医生的培训周期从2周缩短到3天
- 客户粘性提升:集成微信服务号推送疫苗接种提醒,客户复购率提高25%
提示:系统源码已通过GPL-3.0协议开源,但商业使用需注意许可证条款
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 技术架构解析
2.1 为什么选择SpringBoot+SSM组合
在技术选型阶段,我们对比了SpringCloud和纯SSM方案,最终确定当前技术栈基于以下考量:
- 开发效率:SpringBoot的自动配置特性使模块平均开发时间减少30%
- 运维成本:内嵌Tomcat使部署包大小控制在45MB左右,内存占用稳定在800MB以下
- 扩展性:SSM的Mapper层配合PageHelper分页插件,轻松应对单表2000万+的诊疗记录
核心依赖版本:
xml复制<spring-boot.version>2.7.12</spring-boot.version>
<mybatis-spring.version>2.2.2</mybatis-spring.version>
<pagehelper.version>5.3.2</pagehelper.version>
2.2 数据库设计要点
宠物医疗业务的特殊性导致数据库设计有几个关键点:
- 病历表结构:
sql复制CREATE TABLE `pet_medical_record` (
`id` bigint NOT NULL AUTO_INCREMENT,
`pet_id` bigint NOT NULL COMMENT '关联宠物ID',
`symptom` text CHARACTER SET utf8mb4 COMMENT '症状描述',
`temperature` decimal(3,1) DEFAULT NULL COMMENT '体温(℃)',
`weight` decimal(5,2) DEFAULT NULL COMMENT '体重(kg)',
`diagnosis_result` json DEFAULT NULL COMMENT '诊断结果(JSON格式)',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
- 药品库存的特殊处理:
- 实现批次管理(效期追踪)
- 支持不同规格单位自动换算(如片剂与毫升的转换)
- 麻醉类药品的双人审核机制
3. 核心功能实现细节
3.1 智能预约调度算法
为解决高峰期就诊排队问题,我们开发了基于时间窗的预约算法:
java复制public List<TimeSlot> calculateAvailableSlots(LocalDate date, int clinicId) {
// 获取当天所有医生排班
List<Schedule> schedules = scheduleMapper.selectByClinicAndDate(clinicId, date);
// 计算每个时段的理论接诊能力
Map<LocalTime, Integer> capacityMap = schedules.stream()
.flatMap(s -> Stream.of(
new AbstractMap.SimpleEntry<>(s.getMorningStart(), s.getMorningMax()),
new AbstractMap.SimpleEntry<>(s.getAfternoonStart(), s.getAfternoonMax())
))
.collect(Collectors.groupingBy(
Map.Entry::getKey,
Collectors.summingInt(Map.Entry::getValue)
));
// 减去已预约数量
List<Appointment> existing = appointmentMapper.selectByDateAndClinic(date, clinicId);
existing.forEach(app -> {
LocalTime key = app.getAppointmentTime().toLocalTime();
capacityMap.put(key, capacityMap.getOrDefault(key, 0) - 1);
});
// 生成可用时段列表
return capacityMap.entrySet().stream()
.filter(e -> e.getValue() > 0)
.map(e -> new TimeSlot(e.getKey(), e.getValue()))
.sorted(Comparator.comparing(TimeSlot::getTime))
.collect(Collectors.toList());
}
3.2 医疗影像处理方案
针对宠物X光片、B超等影像资料的特殊需求:
- 存储策略:
- 小尺寸图片(<5MB)直接存数据库BLOB
- 大文件采用MinIO对象存储
- 自动生成缩略图用于快速预览
- 阅片工具集成:
javascript复制// 前端使用Viewer.js实现DICOM图像处理
initMedicalImageViewer() {
this.viewer = new Viewer(document.getElementById('dicom-container'), {
inline: true,
viewed() {
// 加载DICOM元数据显示
loadDicomMeta(this.image.alt);
}
});
}
4. 部署与运维实战
4.1 高可用部署方案
生产环境采用Nginx+Keepalived双机热备架构:
code复制 +----------+
| Client |
+-----+----+
|
+----------------+----------------+
| | |
+-------+------+ +-----+-------+ +----+-------+
| Nginx LB | | App Node1 | | App Node2 |
| (Keepalived) | +-------------+ +------------+
+--------------+
关键配置参数:
nginx复制upstream petclinic {
server 192.168.1.101:8080 weight=5;
server 192.168.1.102:8080 weight=5;
keepalive 32;
}
server {
listen 80;
location / {
proxy_pass http://petclinic;
proxy_http_version 1.1;
proxy_set_header Connection "";
}
}
4.2 性能优化实战
通过JMeter压测发现的三个性能瓶颈及解决方案:
- 病历查询慢(>800ms):
- 添加复合索引:
ALTER TABLE pet_medical_record ADD INDEX idx_pet_date (pet_id, create_time) - 引入Elasticsearch实现症状全文检索
- 药品库存锁冲突:
- 采用乐观锁替代悲观锁
- 库存变更消息队列化
- 报表生成卡顿:
- 预聚合统计指标
- 使用EasyExcel替代POI导出
5. 扩展开发指南
5.1 第三方服务集成
- 支付对接:
java复制@Slf4j
@Service
public class PaymentService {
@Value("${payment.wechat.appid}")
private String appId;
public PaymentResult wechatPay(PaymentRequest request) {
WXPay wxpay = new WXPay(new WXPayConfigImpl(appId));
Map<String, String> data = new HashMap<>();
data.put("body", "宠物医疗费");
data.put("out_trade_no", request.getOrderNo());
data.put("total_fee", String.valueOf(request.getAmount()));
try {
Map<String, String> resp = wxpay.unifiedOrder(data);
if("SUCCESS".equals(resp.get("return_code"))) {
return PaymentResult.success(resp.get("prepay_id"));
}
} catch (Exception e) {
log.error("微信支付异常", e);
}
return PaymentResult.fail();
}
}
5.2 移动端适配方案
采用响应式布局+微信小程序双轨策略:
- H5端关键技术:
- 使用Flex布局实现诊疗表单自适应
- 通过rem单位适配不同屏幕
- 禁止用户缩放:
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
- 小程序特色功能:
- 宠物健康档案分享
- 用药提醒推送
- 定位最近的合作医院
6. 项目演进方向
经过实际运营,下一步重点优化方向:
- AI辅助诊断:正在试验用CNN网络分析宠物皮肤病的照片特征
- 物联网集成:对接智能宠物秤、体温计等设备
- 区块链应用:宠物血统证书存证
在最近一次系统升级中,我们将SpringBoot从2.5.6升级到2.7.12时遇到MyBatis缓存冲突问题,最终通过以下方式解决:
properties复制# 在application.properties中添加
mybatis.configuration.local-cache-scope=statement
这个项目给我的深刻体会是:医疗类系统必须把数据准确性放在第一位,我们专门设计了"双人审核+操作日志+数据快照"三重保障机制。特别是在处理药品库存时,哪怕增加30%的性能开销也要保证事务的绝对可靠。
