1. 项目概述
乡村医疗上门服务预约平台是一个基于SpringBoot后端框架和微信小程序前端技术的便民医疗系统。这个平台主要解决农村地区医疗资源分布不均、老年人出行不便等实际问题,通过线上预约方式连接村民与基层医护人员,实现诊疗服务的"最后一公里"覆盖。
我在开发这个系统时,重点考虑了三个核心场景:村民通过小程序快速发起预约请求、医护人员移动端接单处理、卫生院后台进行服务管理与数据分析。整个系统采用微服务架构设计,包含用户端小程序、医护端小程序和管理后台三个子系统,通过RESTful API进行数据交互。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 技术架构解析
2.1 后端技术栈选型
SpringBoot 2.7.3作为基础框架,主要基于以下考量:
- 内嵌Tomcat服务器简化部署
- 自动配置特性快速集成MyBatis-Plus、Redis等组件
- Actuator端点提供应用监控能力
数据库采用MySQL 8.0,关键设计包括:
sql复制CREATE TABLE `appointment` (
`id` bigint NOT NULL AUTO_INCREMENT,
`user_id` varchar(32) NOT NULL COMMENT '微信openid',
`doctor_id` bigint NOT NULL,
`service_type` tinyint NOT NULL COMMENT '1-上门诊疗 2-送药服务',
`address` varchar(255) NOT NULL,
`appoint_time` datetime NOT NULL,
`status` tinyint DEFAULT '0' COMMENT '0-待接单 1-已接单 2-已完成 3-已取消',
`symptoms` text COMMENT '症状描述',
PRIMARY KEY (`id`),
KEY `idx_doctor` (`doctor_id`),
KEY `idx_user` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
2.2 微信小程序端实现
小程序端采用原生框架+WeUI组件库,核心页面包括:
- 服务类型选择页(诊疗/送药)
- 医生列表页(带距离排序)
- 预约表单页(集成腾讯地图选址)
- 订单跟踪页(实时状态更新)
地理位置服务实现代码示例:
javascript复制wx.getLocation({
type: 'gcj02',
success: (res) => {
this.setData({
location: {
latitude: res.latitude,
longitude: res.longitude
}
})
this.loadNearbyDoctors()
}
})
3. 核心功能实现
3.1 预约调度算法
考虑到乡村道路特点和医护人员分布,设计了基于加权因子的调度算法:
- 距离权重(50%):使用Haversine公式计算直线距离
- 专业匹配度(30%):根据症状关键词匹配医生专长
- 负荷均衡(20%):当前待处理预约数
Java实现核心逻辑:
java复制public List<Doctor> recommendDoctors(String symptom, double lat, double lng) {
// 获取10公里内的医生
List<Doctor> candidates = doctorMapper.selectNearby(lat, lng, 10);
return candidates.stream()
.map(d -> {
double distanceScore = 1 - (calculateDistance(lat,lng,d)/10);
double specialtyScore = matchSpecialty(d.getSpecialties(), symptom);
double loadScore = 1 - (d.getPendingOrders()/20.0);
d.setRecommendScore(
0.5 * distanceScore +
0.3 * specialtyScore +
0.2 * loadScore
);
return d;
})
.sorted(Comparator.comparing(Doctor::getRecommendScore).reversed())
.limit(5)
.collect(Collectors.toList());
}
3.2 实时状态通知
采用WebSocket+微信模板消息双通道保障通知可达性:
- 新订单推送:使用Spring的SimpMessagingTemplate
java复制@Async
public void notifyNewOrder(Appointment order) {
// WebSocket推送
messagingTemplate.convertAndSendToUser(
order.getDoctorId().toString(),
"/queue/orders",
new OrderNotification(order)
);
// 微信模板消息
wxMiniService.sendTemplateMsg(
order.getDoctorId(),
"新预约通知",
"您有新的上门服务预约",
order.getId().toString()
);
}
- 状态变更时同步更新小程序前端:
javascript复制const socket = wx.connectSocket({
url: 'wss://yourdomain.com/ws',
success: () => {
socket.onMessage((res) => {
const data = JSON.parse(res.data)
if(data.type === 'ORDER_UPDATE') {
this.updateOrderStatus(data.payload)
}
})
}
})
4. 关键问题解决方案
4.1 高并发预约处理
针对赶集日等预约高峰场景,采用以下优化方案:
- Redis缓存医生可预约时段
java复制@Cacheable(value = "doctor_slots", key = "#doctorId")
public List<TimeSlot> getAvailableSlots(Long doctorId) {
// 数据库查询逻辑
}
@CacheEvict(value = "doctor_slots", key = "#doctorId")
public void makeAppointment(Long doctorId, LocalDateTime time) {
// 预约处理逻辑
}
- 使用Redisson分布式锁防止超订:
java复制public boolean tryLockAppointment(Long doctorId, LocalDateTime time) {
RLock lock = redissonClient.getLock("appoint:"+doctorId+":"+time);
try {
return lock.tryLock(3, 10, TimeUnit.SECONDS);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return false;
}
}
4.2 离线环境数据同步
考虑部分乡村地区网络不稳定,实现离线操作后自动同步机制:
- 小程序端使用localStorage暂存数据
javascript复制// 离线状态提交预约
if(!networkAvailable) {
const pendingOrders = wx.getStorageSync('pendingOrders') || []
pendingOrders.push(orderData)
wx.setStorageSync('pendingOrders', pendingOrders)
}
- 网络恢复后自动同步:
javascript复制wx.onNetworkStatusChange((res) => {
if(res.isConnected && wx.getStorageSync('pendingOrders')) {
this.syncPendingOrders()
}
})
5. 部署与运维实践
5.1 服务器配置建议
最低生产环境要求:
- 2核4G云服务器(推荐腾讯云轻量应用服务器)
- MySQL 8.0 配置建议:
ini复制[mysqld] innodb_buffer_pool_size = 1G max_connections = 200 - Redis缓存配置:
properties复制spring.redis.timeout=3000 spring.redis.lettuce.pool.max-active=20
5.2 监控方案
基于SpringBoot Actuator+Prometheus+Grafana搭建监控看板:
- 应用配置:
yaml复制management:
endpoints:
web:
exposure:
include: "*"
metrics:
export:
prometheus:
enabled: true
- 关键监控指标:
- 预约请求QPS
- 平均响应时间
- 医生接单延迟
- 异常订单比例
6. 开发经验总结
6.1 微信小程序适配要点
- 导航栏高度兼容方案:
javascript复制const getNavHeight = () => {
const systemInfo = wx.getSystemInfoSync()
const menuRect = wx.getMenuButtonBoundingClientRect()
return menuRect.bottom + menuRect.top - systemInfo.statusBarHeight
}
- 视频播放问题解决:
xml复制<video
src="{{videoUrl}}"
controls
enable-danmu
danmu-btn
vslide-gesture
binderror="handleVideoError"
/>
6.2 性能优化实践
- 小程序分包加载:
json复制{
"subPackages": [{
"root": "packageA",
"pages": [
"pages/doctorList",
"pages/orderDetail"
]
}]
}
- 接口响应优化技巧:
- 使用DTO投影减少数据传输
java复制public interface DoctorProjection {
Long getId();
String getName();
String getTitle();
@Value("#{target.distance}")
Double getDistance();
}
- 启用HTTP/2和Gzip压缩
properties复制server.http2.enabled=true
server.compression.enabled=true
7. 扩展方向建议
- 智能排班系统:结合历史数据预测需求高峰
- 药品库存联动:对接村级卫生室库存系统
- 健康档案管理:建立村民电子健康档案
- 语音交互功能:方便老年用户操作
实际部署时发现,在赶集日等特殊时段,预约量会突增3-5倍。我们通过预先扩容Redis集群和增加消息队列消费者实例来应对这种场景。建议在节假日前后特别关注系统监控指标,提前做好资源准备。
