去年参与本地流浪动物救助站信息化改造时,发现纸质登记本上密密麻麻的记录难以检索,志愿者调度全靠微信群接龙,物资捐赠和使用情况更是笔糊涂账。这种低效的管理方式直接影响了救助效率——曾有受伤犬只因信息传递延误错过了最佳救治时间。这正是我们开发这套系统的初衷:用技术手段解决救助过程中的信息孤岛问题。
系统设计聚焦三个核心痛点:
技术选型上采用SpringBoot+Vue3的分离架构,主要考虑:
后端架构:
java复制@SpringBootApplication
@EnableTransactionManagement // 确保救助申请的事务一致性
public class RescueSystemApplication {
public static void main(String[] args) {
SpringApplication.run(RescueSystemApplication.class, args);
}
}
采用SpringBoot 2.7 + MyBatis-Plus组合,相比纯JPA方案:
前端架构:
javascript复制// 使用Pinia管理跨组件状态
export const useAnimalStore = defineStore('animal', {
state: () => ({
filterConditions: { type: null, healthStatus: [] }
}),
actions: { /* 过滤逻辑 */ }
})
Vue3 + Vite构建速度比Webpack快3倍,这对需要频繁更新救助信息的场景至关重要
动物信息表优化方案:
sql复制ALTER TABLE animal_info
ADD FULLTEXT INDEX idx_search (animal_name, rescue_location) -- 支持模糊搜索
ADD SPATIAL INDEX idx_location (coordinates); -- 地理围栏查询
实际踩坑:最初使用VARCHAR存储坐标,导致距离计算性能低下,后改用POINT类型+空间索引,附近志愿者查询速度提升20倍
状态字段设计原则:
状态机设计:
mermaid复制stateDiagram-v2
[*] --> PENDING
PENDING --> PROCESSING: 分配志愿者
PROCESSING --> COMPLETED: 完成救助
PROCESSING --> FAILED: 救助失败
FAILED --> ARCHIVED
COMPLETED --> ARCHIVED
关键代码实现:
java复制@Transactional
public void processApplication(Long applyId, Long volunteerId) {
// 验证志愿者资质
if (!volunteerService.checkQualification(volunteerId)) {
throw new IllegalOperationException("志愿者未通过考核");
}
// 更新状态(乐观锁控制)
int updated = applicationMapper.updateStatus(
applyId, "PROCESSING", volunteerId, LocalDateTime.now());
if (updated == 0) {
throw new ConcurrentModificationException("申请已被其他管理员处理");
}
// 发送通知
messageService.pushVolunteerAssignment(volunteerId, applyId);
}
志愿者-任务匹配逻辑:
java复制public List<Volunteer> matchVolunteers(RescueTask task) {
return volunteerMapper.selectList(new QueryWrapper<Volunteer>()
.eq("active_status", 1)
.apply("ST_Distance_Sphere(coordinates, {0}) <= {1}",
task.getCoordinate(),
MAX_DISTANCE)
.orderByDesc(() -> "compute_similarity(skill_tags, '"
+ task.getRequiredSkills() + "')")
.last("LIMIT 10"));
}
安全增强措施:
java复制@PreAuthorize("hasRole('ADMIN') or "
+ "(hasRole('VOLUNTEER') and #userId == authentication.principal.id)")
public void updateAnimalInfo(Long userId, AnimalInfo info) { ... }
压力测试发现的问题及解决方案:
yaml复制# SpringBoot配置示例
spring:
redis:
cache:
animal-info: 3600s # 动物信息缓存1小时
rabbitmq:
listener:
simple:
prefetch: 10 # 控制志愿者任务分配速率
Docker Compose编排要点:
dockerfile复制services:
app:
image: rescue-backend:${TAG}
deploy:
resources:
limits:
cpus: '2'
memory: 2G
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/actuator/health"]
interval: 30s
重点监控项:
实际开发中发现,简单的"救助进度看板"功能最能提升用户体验。通过WebSocket实时推送状态变更,使志愿者参与感提升40%。技术方案往往不是最关键的,对业务场景的深度理解才是项目成功的关键。