Java全栈项目实战 - 社区养老服务平台开发

一、项目介绍

随着我国老龄化程度不断加深,社区养老服务需求日益增长。本项目旨在开发一个面向社区的养老服务平台,为老年人提供便捷的生活服务和健康管理支持。

1.1 项目功能

  • 老人信息管理
  • 健康档案管理
  • 服务预约系统
  • 健康监测预警
  • 社区活动管理
  • 志愿者服务对接
  • 远程看护系统
  • 紧急求助功能

1.2 技术架构

  • 前端:Vue.js + Element UI
  • 后端:Spring Boot + Spring Security + MyBatis Plus
  • 数据库:MySQL
  • 缓存:Redis
  • 消息队列:RabbitMQ
  • 文件存储:阿里云OSS
  • 短信服务:阿里云SMS

二、核心功能实现

2.1 健康监测预警系统

@Service
public class HealthMonitorServiceImpl implements HealthMonitorService {
    
    @Autowired
    private RedisTemplate redisTemplate;
    
    @Autowired
    private AlarmService alarmService;
    
    public void processHealthData(HealthData data) {
        // 检查生命体征数据
        if (isAbnormal(data)) {
            // 触发预警
            AlarmInfo alarm = new AlarmInfo();
            alarm.setElderlyId(data.getElderlyId());
            alarm.setType(AlarmType.HEALTH_ABNORMAL);
            alarm.setContent("检测到异常体征数据");
            
            alarmService.sendAlarm(alarm);
        }
        
        // 存储健康数据
        redisTemplate.opsForHash().put(
            "health:" + data.getElderlyId(),
            data.getMetricType(),
            data
        );
    }
}

2.2 服务预约系统

@RestController
@RequestMapping("/api/appointment")
public class AppointmentController {

    @Autowired
    private AppointmentService appointmentService;
    
    @PostMapping("/create")
    public Result createAppointment(@RequestBody AppointmentDTO dto) {
        // 检查服务时段是否可用
        if (!appointmentService.checkTimeSlotAvailable(dto)) {
            return Result.fail("该时段已被预约");
        }
        
        // 创建预约记录
        Appointment appointment = appointmentService.createAppointment(dto);
        
        // 发送预约确认通知
        notificationService.sendAppointmentConfirm(appointment);
        
        return Result.ok(appointment);
    }
}

三、技术难点解决

3.1 高并发预约处理

为解决服务预约的高并发问题,采用以下方案:

  1. 使用Redis实现分布式锁
  2. 预约时段库存使用Redis原子操作
  3. 采用消息队列异步处理预约确认
@Service
public class AppointmentServiceImpl {
    
    private final String LOCK_KEY = "appointment:lock:";
    
    @Autowired
    private RedisTemplate redisTemplate;
    
    @Autowired
    private RabbitTemplate rabbitTemplate;
    
    public boolean createAppointment(AppointmentDTO dto) {
        String lockKey = LOCK_KEY + dto.getServiceId() + ":" + dto.getTimeSlot();
        
        try {
            // 获取分布式锁
            Boolean locked = redisTemplate.opsForValue()
                .setIfAbsent(lockKey, "1", 10, TimeUnit.SECONDS);
                
            if (Boolean.TRUE.equals(locked)) {
                // 检查并扣减库存
                Long stock = redisTemplate.opsForValue()
                    .decrement("stock:" + dto.getServiceId());
                    
                if (stock >= 0) {
                    // 发送消息到预约队列
                    rabbitTemplate.convertAndSend(
                        "appointment.exchange",
                        "appointment.create",
                        dto
                    );
                    return true;
                }
            }
        } finally {
            // 释放锁
            redisTemplate.delete(lockKey);
        }
        return false;
    }
}

3.2 实时监测告警

采用WebSocket实现实时数据推送,结合消息队列处理告警信息:

@ServerEndpoint("/websocket/{userId}")
@Component
public class WebSocketServer {

    @OnMessage
    public void onMessage(String message, Session session) {
        // 处理接收到的消息
        JSONObject json = JSON.parseObject(message);
        
        if ("HEALTH_DATA".equals(json.getString("type"))) {
            // 处理健康数据
            HealthData data = json.toJavaObject(HealthData.class);
            healthMonitorService.processHealthData(data);
        }
    }
    
    // 推送告警信息
    public void sendAlarm(String userId, AlarmInfo alarm) {
        Session session = SESSION_MAP.get(userId);
        if (session != null) {
            session.getAsyncRemote().sendText(
                JSON.toJSONString(alarm)
            );
        }
    }
}

四、项目部署

4.1 部署架构

  • 采用Docker容器化部署
  • Nginx实现负载均衡
  • Jenkins实现CI/CD自动化部署

4.2 性能优化

  1. 接口响应时间优化

    • 使用Redis缓存热点数据
    • 使用本地缓存Caffeine
    • SQL语句优化
  2. 系统稳定性保障

    • 服务限流和熔断
    • 分布式事务处理
    • 完善的日志监控

五、项目总结

通过本项目的开发,不仅实现了社区养老服务的信息化管理,也积累了丰富的技术经验:

  1. 掌握了分布式系统开发的关键技术
  2. 提升了高并发场景下的问题解决能力
  3. 加深了对微服务架构的理解
  4. 积累了实际项目开发和运维经验

未来还可以在以下方面进行优化和扩展:

  1. 引入人工智能技术,提供智能化服务推荐
  2. 开发移动端应用,提升服务可及性
  3. 接入更多智能硬件设备,增强健康监测能力
  4. 完善数据分析功能,为社区养老决策提供支持

社区养老服务平台核心模块详解

一、老人信息管理模块

1.1 数据模型设计

-- 老人基本信息表
CREATE TABLE elderly_info (
    id BIGINT PRIMARY KEY,
    name VARCHAR(50) NOT NULL,
    gender TINYINT,
    birth_date DATE,
    id_card VARCHAR(18),
    phone VARCHAR(11),
    address VARCHAR(200),
    emergency_contact VARCHAR(50),
    emergency_phone VARCHAR(11),
    medical_insurance VARCHAR(50),
    living_status TINYINT COMMENT '居住状态:1-独居,2-与配偶,3-与子女',
    care_level TINYINT COMMENT '照护等级:1-自理,2-半自理,3-完全不能自理',
    create_time DATETIME,
    update_time DATETIME
);

-- 老人家属信息表
CREATE TABLE elderly_family (
    id BIGINT PRIMARY KEY,
    elderly_id BIGINT,
    name VARCHAR(50),
    relationship VARCHAR(20),
    phone VARCHAR(11),
    address VARCHAR(200)
);

1.2 核心功能实现

@Service
public class ElderlyServiceImpl implements ElderlyService {

    @Autowired
    private ElderlyMapper elderlyMapper;
    
    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 新增老人信息
     */
    @Transactional
    public void addElderly(ElderlyDTO dto) {
        // 数据校验
        validateElderlyInfo(dto);
        
        // 转换并保存基本信息
        ElderlyInfo elderly = convertToEntity(dto);
        elderlyMapper.insert(elderly);
        
        // 保存家属信息
        saveElderlyFamily(dto.getFamilyList(), elderly.getId());
        
        // 更新缓存
        updateElderlyCache(elderly);
    }

    /**
     * 智能分析老人关怀等级
     */
    public CareLevel analyzeCareLevel(ElderlyInfo elderly) {
        // 基于年龄、身体状况等多维度打分
        int score = 0;
        
        // 年龄分
        int age = calculateAge(elderly.getBirthDate());
        score += age >= 80 ? 30 : (age >= 70 ? 20 : 10);
        
        // 居住状况分
        score += elderly.getLivingStatus() == 1 ? 30 : 10;
        
        // 根据总分判定关怀等级
        if(score >= 80) {
            return CareLevel.SPECIAL_CARE;
        } else if(score >= 50) {
            return CareLevel.REGULAR_CARE; 
        } else {
            return CareLevel.SELF_CARE;
        }
    }
}

二、健康档案管理模块

2.1 数据模型设计

-- 健康档案主表
CREATE TABLE health_record (
    id BIGINT PRIMARY KEY,
    elderly_id BIGINT,
    blood_type VARCHAR(10),
    height DECIMAL(5,2),
    weight DECIMAL(5,2),
    allergies TEXT,
    medical_history TEXT,
    create_time DATETIME
);

-- 体检记录表
CREATE TABLE physical_exam (
    id BIGINT PRIMARY KEY,
    elderly_id BIGINT,
    exam_date DATE,
    blood_pressure VARCHAR(20),
    blood_sugar DECIMAL(5,2),
    heart_rate INT,
    exam_result TEXT,
    doctor_advice TEXT
);

-- 用药记录表
CREATE TABLE medication_record (
    id BIGINT PRIMARY KEY,
    elderly_id BIGINT,
    medicine_name VARCHAR(100),
    dosage VARCHAR(50),
    frequency VARCHAR(50),
    start_date DATE,
    end_date DATE,
    notes TEXT
);

2.2 核心功能实现

@Service
public class HealthRecordServiceImpl implements HealthRecordService {

    @Autowired
    private HealthRecordMapper healthRecordMapper;
    
    @Autowired
    private PhysicalExamMapper examMapper;

    /**
     * 健康趋势分析
     */
    public HealthTrendVO analyzeHealthTrend(Long elderlyId) {
        // 获取最近3个月的体检数据
        List<PhysicalExam> examList = examMapper.getRecentExams(
            elderlyId, 
            LocalDate.now().minusMonths(3)
        );
        
        // 分析血压趋势
        List<BloodPressure> bpList = examList.stream()
            .map(exam -> parseBP(exam.getBloodPressure()))
            .collect(Collectors.toList());
            
        boolean bpAbnormal = analyzeBPTrend(bpList);
        
        // 分析血糖趋势
        List<BigDecimal> bsList = examList.stream()
            .map(PhysicalExam::getBloodSugar)
            .collect(Collectors.toList());
            
        boolean bsAbnormal = analyzeBSTrend(bsList);
        
        // 生成健康报告
        return generateHealthReport(bpAbnormal, bsAbnormal);
    }

    /**
     * 智能用药提醒
     */
    @Scheduled(cron = "0 0 8,12,18 * * ?")
    public void medicationReminder() {
        // 获取需要提醒的用药记录
        List<MedicationRecord> records = medicationMapper
            .getNeedRemindRecords(LocalDate.now());
            
        for(MedicationRecord record : records) {
            // 发送提醒消息
            messageService.sendMedicationReminder(
                record.getElderlyId(),
                record.getMedicineName(),
                record.getDosage()
            );
        }
    }
}

三、服务预约系统

3.1 数据模型设计

-- 服务项目表
CREATE TABLE service_item (
    id BIGINT PRIMARY KEY,
    name VARCHAR(100),
    category VARCHAR(50),
    price DECIMAL(10,2),
    description TEXT,
    status TINYINT
);

-- 服务时段表
CREATE TABLE service_time_slot (
    id BIGINT PRIMARY KEY,
    service_id BIGINT,
    date DATE,
    time_period VARCHAR(20),
    capacity INT,
    booked_count INT,
    status TINYINT
);

-- 预约记录表
CREATE TABLE appointment (
    id BIGINT PRIMARY KEY,
    elderly_id BIGINT,
    service_id BIGINT,
    time_slot_id BIGINT,
    status TINYINT,
    create_time DATETIME,
    cancel_time DATETIME,
    cancel_reason VARCHAR(200)
);

3.2 核心功能实现

@Service
public class AppointmentServiceImpl implements AppointmentService {

    @Autowired
    private RedisTemplate redisTemplate;
    
    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * 创建预约
     */
    @Transactional
    public Result createAppointment(AppointmentDTO dto) {
        // 分布式锁key
        String lockKey = "appointment:lock:" + dto.getTimeSlotId();
        
        try {
            // 获取分布式锁
            boolean locked = redisTemplate.opsForValue()
                .setIfAbsent(lockKey, "1", 10, TimeUnit.SECONDS);
                
            if(!locked) {
                return Result.fail("系统繁忙,请稍后重试");
            }
            
            // 检查时段是否已满
            TimeSlot slot = timeSlotMapper.selectById(dto.getTimeSlotId());
            if(slot.getBookedCount() >= slot.getCapacity()) {
                return Result.fail("该时段预约已满");
            }
            
            // 创建预约记录
            Appointment appointment = createAppointmentRecord(dto);
            
            // 更新预约数
            timeSlotMapper.incrementBookedCount(dto.getTimeSlotId());
            
            // 发送预约确认消息
            sendAppointmentConfirm(appointment);
            
            return Result.ok(appointment);
            
        } finally {
            // 释放锁
            redisTemplate.delete(lockKey);
        }
    }

    /**
     * 智能推荐服务时段
     */
    public List<TimeSlot> recommendTimeSlots(Long elderlyId) {
        // 获取老人历史预约偏好
        List<Appointment> history = appointmentMapper
            .getElderlyAppointments(elderlyId);
            
        // 分析偏好时段
        Map<String, Integer> periodScore = analyzePeriodPreference(history);
        
        // 获取可预约时段
        List<TimeSlot> availableSlots = timeSlotMapper
            .getAvailableSlots(LocalDate.now(), LocalDate.now().plusDays(7));
            
        // 根据偏好评分排序
        return availableSlots.stream()
            .sorted((a, b) -> {
                Integer scoreA = periodScore.get(a.getTimePeriod());
                Integer scoreB = periodScore.get(b.getTimePeriod());
                return scoreB.compareTo(scoreA);
            })
            .collect(Collectors.toList());
    }
}

四、健康监测预警

4.1 数据模型设计

-- 健康监测数据表
CREATE TABLE health_monitor_data (
    id BIGINT PRIMARY KEY,
    elderly_id BIGINT,
    device_id VARCHAR(50),
    metric_type VARCHAR(20),
    metric_value DECIMAL(10,2),
    measure_time DATETIME
);

-- 预警规则表
CREATE TABLE alert_rule (
    id BIGINT PRIMARY KEY,
    metric_type VARCHAR(20),
    min_value DECIMAL(10,2),
    max_value DECIMAL(10,2),
    continuous_times INT,
    alert_level TINYINT
);

-- 预警记录表
CREATE TABLE alert_record (
    id BIGINT PRIMARY KEY,
    elderly_id BIGINT,
    rule_id BIGINT,
    metric_type VARCHAR(20),
    metric_value DECIMAL(10,2),
    alert_time DATETIME,
    handle_status TINYINT,
    handle_time DATETIME,
    handle_note TEXT
);

4.2 核心功能实现

@Service
public class HealthMonitorServiceImpl implements HealthMonitorService {

    @Autowired
    private RedisTemplate redisTemplate;
    
    @Autowired
    private AlertService alertService;

    /**
     * 处理设备上报的健康数据
     */
    public void processHealthData(HealthData data) {
        // 保存原始数据
        healthDataMapper.insert(data);
        
        // 缓存最新数据
        String cacheKey = "health:" + data.getElderlyId() + ":" 
            + data.getMetricType();
        redisTemplate.opsForList().leftPush(cacheKey, data);
        redisTemplate.expire(cacheKey, 24, TimeUnit.HOURS);
        
        // 检查是否触发预警
        checkAlert(data);
    }

    /**
     * 预警检查
     */
    private void checkAlert(HealthData data) {
        // 获取对应的预警规则
        List<AlertRule> rules = alertRuleMapper
            .getByMetricType(data.getMetricType());
            
        for(AlertRule rule : rules) {
            // 检查是否超出阈值
            if(isExceedThreshold(data.getMetricValue(), rule)) {
                // 检查连续次数
                String countKey = "alert:count:" + data.getElderlyId() 
                    + ":" + rule.getId();
                Long count = redisTemplate.opsForValue()
                    .increment(countKey);
                    
                if(count >= rule.getContinuousTimes()) {
                    // 触发预警
                    AlertRecord alert = createAlert(data, rule);
                    
                    // 发送预警通知
                    alertService.sendAlert(alert);
                    
                    // 重置计数
                    redisTemplate.delete(countKey);
                }
            } else {
                // 清除计数
                redisTemplate.delete("alert:count:" + data.getElderlyId() 
                    + ":" + rule.getId());
            }
        }
    }

    /**
     * 智能预警分析
     */
    public List<AlertVO> analyzeAlertTrend(Long elderlyId) {
        // 获取历史预警数据
        List<AlertRecord> history = alertMapper
            .getElderlyAlerts(elderlyId, LocalDate.now().minusDays(30));
            
        // 按指标类型分组统计
        Map<String, List<AlertRecord>> groupByMetric = history.stream()
            .collect(Collectors.groupingBy(AlertRecord::getMetricType));
            
        // 分析每类指标的预警趋势
        List<AlertVO> result = new ArrayList<>();
        for(Map.Entry<String, List<AlertRecord>> entry : 
            groupByMetric.entrySet()) {
            
            AlertVO vo = new AlertVO();
            vo.setMetricType(entry.getKey());
            
            // 计算预警频率
            vo.setAlertFrequency(calculateAlertFrequency(entry.getValue()));
            
            // 预测未来预警风险
            vo.setRiskLevel(predictRiskLevel(entry.getValue()));
            
            result.add(vo);
        }
        
        return result;
    }
}

4.3 实时监控大屏

// 使用Vue + ECharts实现监控大屏
export default {
    data() {
        return {
            // 图表配置
            chartOptions: {
                title: {
                    text: '实时健康监测'
                },
                xAxis: {
                    type: 'time'
                },
                yAxis: {
                    type: 'value'
                },
                series: [{
                    name: '血压',
                    type: 'line',
                    data: []
                }, {
                    name: '心率',
                    type: 'line',
                    data: []
                }]
            }
        }
    },
    
    mounted() {
        // 建立WebSocket连接
        this.initWebSocket();
    },
    
    methods: {
        initWebSocket() {
            const ws = new WebSocket('ws://localhost:8080/monitor');
            
            ws.onmessage = (event) => {
                const data = JSON.parse(event.data);
                
                // 更新图表数据
                this.updateChart(data);
                
                // 检查是否需要报警
                this.checkAlert(data);
            }
        },
        
        updateChart(data) {
            // 更新血压数据
            this.chartOptions.series[0].data.push({
                name: data.time,
                value: [data.time, data.bloodPressure]
            });
            
            // 更新心率数据
            this.chartOptions.series[1].data.push({
                name: data.time,
                value: [data.time, data.heartRate]
            });
            
            // 保持最近100条数据
            if(this.chartOptions.series[0].data.length > 100) {
                this.chartOptions.series[0].data.shift();
                this.chartOptions.series[1].data.shift();
            }
        },
        
        checkAlert(data) {
            // 检查数据是否超出警戒值
            if(data.bloodPressure > 140 || data.heartRate > 100) {
                this.$notify({
                    title: '预警提醒',
                    message: '检测到异常数据',
                    type: 'warning'
                });
            }
        }
    }
}

这些模块的实现考虑了以下关键点:

  1. 数据安全性:敏感数据加密存储
  2. 高并发处理:使用分布式锁和缓存
  3. 实时性:采用WebSocket实现实时数据推送
  4. 可扩展性:模块化设计,便于功能扩展
  5. 容错性:关键操作添加重试机制
  6. 智能化:加入数据分析和智能推荐功能

通过这些模块的协同工作,可以为社区老年人提供全方位的养老服务支持。

社区养老服务平台功能模块详解(二)

一、社区活动管理

1.1 数据模型设计

-- 活动信息表
CREATE TABLE community_activity (
    id BIGINT PRIMARY KEY,
    title VARCHAR(100),
    category VARCHAR(50),
    start_time DATETIME,
    end_time DATETIME,
    location VARCHAR(200),
    capacity INT,
    enrolled_count INT,
    description TEXT,
    status TINYINT COMMENT '1-未开始 2-进行中 3-已结束 4-已取消',
    create_time DATETIME
);

-- 活动报名表
CREATE TABLE activity_enrollment (
    id BIGINT PRIMARY KEY,
    activity_id BIGINT,
    elderly_id BIGINT,
    status TINYINT COMMENT '1-已报名 2-已签到 3-已取消',
    enroll_time DATETIME,
    cancel_time DATETIME,
    cancel_reason VARCHAR(200)
);

-- 活动评价表
CREATE TABLE activity_feedback (
    id BIGINT PRIMARY KEY,
    activity_id BIGINT,
    elderly_id BIGINT,
    rating INT COMMENT '1-5星评分',
    content TEXT,
    create_time DATETIME
);

1.2 核心功能实现

@Service
public class CommunityActivityServiceImpl implements CommunityActivityService {

    @Autowired
    private ActivityMapper activityMapper;
    
    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 智能活动推荐
     */
    public List<ActivityVO> recommendActivities(Long elderlyId) {
        // 获取老人兴趣标签
        List<String> interests = elderlyMapper.getInterests(elderlyId);
        
        // 获取历史参与活动
        List<ActivityEnrollment> history = enrollmentMapper
            .getElderlyEnrollments(elderlyId);
            
        // 分析活动偏好
        Map<String, Double> categoryScores = analyzePreference(history);
        
        // 获取近期活动
        List<CommunityActivity> activities = activityMapper
            .getUpcomingActivities(LocalDate.now());
            
        // 计算推荐分数并排序
        return activities.stream()
            .map(activity -> {
                ActivityVO vo = convertToVO(activity);
                double score = calculateRecommendScore(
                    activity, 
                    interests, 
                    categoryScores
                );
                vo.setRecommendScore(score);
                return vo;
            })
            .sorted((a, b) -> 
                Double.compare(b.getRecommendScore(), a.getRecommendScore())
            )
            .collect(Collectors.toList());
    }

    /**
     * 活动签到
     */
    public Result checkIn(CheckInDTO dto) {
        String key = "checkin:" + dto.getActivityId();
        
        try {
            // 获取分布式锁
            boolean locked = redisTemplate.opsForValue()
                .setIfAbsent(key, "1", 5, TimeUnit.SECONDS);
                
            if(!locked) {
                return Result.fail("操作太频繁,请稍后重试");
            }
            
            // 验证签到码
            String codeKey = "checkcode:" + dto.getActivityId();
            String validCode = redisTemplate.opsForValue().get(codeKey);
            
            if(!dto.getCheckCode().equals(validCode)) {
                return Result.fail("签到码无效");
            }
            
            // 更新签到状态
            enrollmentMapper.updateStatus(
                dto.getActivityId(), 
                dto.getElderlyId(), 
                EnrollStatus.CHECKED_IN
            );
            
            // 记录签到积分
            pointsService.addPoints(
                dto.getElderlyId(), 
                PointsType.ACTIVITY_CHECKIN, 
                10
            );
            
            return Result.ok();
            
        } finally {
            redisTemplate.delete(key);
        }
    }
}

二、志愿者服务对接

2.1 数据模型设计

-- 志愿者信息表
CREATE TABLE volunteer (
    id BIGINT PRIMARY KEY,
    name VARCHAR(50),
    gender TINYINT,
    phone VARCHAR(11),
    id_card VARCHAR(18),
    skills TEXT,
    available_time TEXT,
    status TINYINT,
    total_service_hours INT,
    create_time DATETIME
);

-- 志愿服务项目表
CREATE TABLE volunteer_service (
    id BIGINT PRIMARY KEY,
    title VARCHAR(100),
    category VARCHAR(50),
    required_skills TEXT,
    service_time VARCHAR(200),
    description TEXT,
    status TINYINT
);

-- 服务匹配记录表
CREATE TABLE service_matching (
    id BIGINT PRIMARY KEY,
    service_id BIGINT,
    volunteer_id BIGINT,
    elderly_id BIGINT,
    start_time DATETIME,
    end_time DATETIME,
    status TINYINT,
    feedback_score INT,
    feedback_content TEXT
);

2.2 核心功能实现

@Service
public class VolunteerServiceImpl implements VolunteerService {

    @Autowired
    private VolunteerMapper volunteerMapper;
    
    @Autowired
    private ServiceMatchingMapper matchingMapper;

    /**
     * 智能匹配志愿者
     */
    public List<VolunteerVO> matchVolunteers(ServiceRequest request) {
        // 获取符合时间要求的志愿者
        List<Volunteer> volunteers = volunteerMapper
            .getAvailableVolunteers(request.getServiceTime());
            
        // 计算技能匹配度
        return volunteers.stream()
            .map(volunteer -> {
                VolunteerVO vo = convertToVO(volunteer);
                
                // 计算技能匹配分数
                double skillScore = calculateSkillMatch(
                    volunteer.getSkills(),
                    request.getRequiredSkills()
                );
                
                // 计算历史服务评分
                double ratingScore = calculateServiceRating(volunteer.getId());
                
                // 综合评分
                vo.setMatchScore(skillScore * 0.6 + ratingScore * 0.4);
                
                return vo;
            })
            .sorted((a, b) -> 
                Double.compare(b.getMatchScore(), a.getMatchScore())
            )
            .collect(Collectors.toList());
    }

    /**
     * 服务评价
     */
    @Transactional
    public void submitFeedback(FeedbackDTO dto) {
        // 更新服务记录评价
        ServiceMatching matching = matchingMapper
            .selectById(dto.getMatchingId());
        matching.setFeedbackScore(dto.getScore());
        matching.setFeedbackContent(dto.getContent());
        matchingMapper.updateById(matching);
        
        // 更新志愿者总服务时长
        Volunteer volunteer = volunteerMapper
            .selectById(matching.getVolunteerId());
        int hours = calculateServiceHours(
            matching.getStartTime(), 
            matching.getEndTime()
        );
        volunteer.setTotalServiceHours(
            volunteer.getTotalServiceHours() + hours
        );
        volunteerMapper.updateById(volunteer);
        
        // 发放志愿者积分奖励
        pointsService.addPoints(
            matching.getVolunteerId(),
            PointsType.VOLUNTEER_SERVICE,
            hours * 10
        );
    }
}

三、远程看护系统

3.1 数据模型设计

-- 摄像头设备表
CREATE TABLE camera_device (
    id BIGINT PRIMARY KEY,
    elderly_id BIGINT,
    device_code VARCHAR(50),
    room_location VARCHAR(50),
    status TINYINT,
    create_time DATETIME
);

-- 看护记录表
CREATE TABLE care_record (
    id BIGINT PRIMARY KEY,
    elderly_id BIGINT,
    camera_id BIGINT,
    start_time DATETIME,
    end_time DATETIME,
    care_type TINYINT COMMENT '1-家属看护 2-护工看护',
    watcher_id BIGINT,
    notes TEXT
);

-- AI异常行为记录表
CREATE TABLE abnormal_behavior (
    id BIGINT PRIMARY KEY,
    elderly_id BIGINT,
    camera_id BIGINT,
    behavior_type VARCHAR(50),
    confidence DECIMAL(5,2),
    capture_time DATETIME,
    image_url VARCHAR(200),
    handle_status TINYINT,
    handle_time DATETIME,
    handle_note TEXT
);

3.2 核心功能实现

@Service
public class RemoteCareServiceImpl implements RemoteCareService {

    @Autowired
    private WebSocketServer webSocketServer;
    
    @Autowired
    private AiAnalysisService aiService;

    /**
     * 处理视频流
     */
    @Async
    public void processVideoStream(String deviceCode, byte[] frameData) {
        try {
            // 保存视频帧
            String framePath = saveVideoFrame(deviceCode, frameData);
            
            // AI行为分析
            List<BehaviorResult> behaviors = aiService
                .analyzeBehavior(framePath);
            
            // 检查是否有异常行为
            for(BehaviorResult behavior : behaviors) {
                if(behavior.getConfidence() > 0.8) {
                    // 记录异常行为
                    AbnormalBehavior record = createBehaviorRecord(
                        deviceCode, 
                        behavior
                    );
                    
                    // 推送告警消息
                    pushAlertMessage(record);
                    
                    // 存储异常截图
                    saveAlertImage(framePath, record.getId());
                }
            }
            
            // 推送实时画面
            pushRealTimeFrame(deviceCode, frameData);
            
        } catch(Exception e) {
            log.error("处理视频流异常", e);
        }
    }

    /**
     * 推送实时画面
     */
    private void pushRealTimeFrame(String deviceCode, byte[] frameData) {
        // 获取当前查看该设备的所有用户
        Set<String> userIds = getCameraWatchers(deviceCode);
        
        // 推送画面数据
        for(String userId : userIds) {
            webSocketServer.sendBinary(userId, frameData);
        }
    }

    /**
     * AI分析异常行为
     */
    private List<BehaviorResult> analyzeAbnormalBehavior(String imagePath) {
        // 使用OpenCV进行图像预处理
        Mat image = imread(imagePath);
        resize(image, image, new Size(416, 416));
        
        // 行为识别模型推理
        float[] input = preprocessImage(image);
        float[] output = behaviorModel.predict(input);
        
        // 后处理识别结果
        return postprocessBehaviorResult(output);
    }
}

四、紧急求助功能

4.1 数据模型设计

-- 紧急求助设备表
CREATE TABLE sos_device (
    id BIGINT PRIMARY KEY,
    elderly_id BIGINT,
    device_code VARCHAR(50),
    device_type VARCHAR(50),
    location VARCHAR(200),
    battery_level INT,
    status TINYINT,
    last_heartbeat DATETIME
);

-- 紧急求助记录表
CREATE TABLE sos_alert (
    id BIGINT PRIMARY KEY,
    elderly_id BIGINT,
    device_id BIGINT,
    alert_time DATETIME,
    location_type TINYINT COMMENT '1-GPS定位 2-基站定位',
    longitude DECIMAL(10,6),
    latitude DECIMAL(10,6),
    address VARCHAR(200),
    status TINYINT COMMENT '1-待处理 2-处理中 3-已处理',
    handle_time DATETIME,
    handler_id BIGINT,
    handle_note TEXT
);

-- 处理流程记录表
CREATE TABLE sos_process (
    id BIGINT PRIMARY KEY,
    alert_id BIGINT,
    process_type TINYINT,
    operator_id BIGINT,
    operator_name VARCHAR(50),
    process_time DATETIME,
    process_note TEXT
);

4.2 核心功能实现

@Service
public class EmergencyServiceImpl implements EmergencyService {

    @Autowired
    private AlertMapper alertMapper;
    
    @Autowired
    private LocationService locationService;
    
    @Autowired
    private NotificationService notificationService;

    /**
     * 处理紧急求助信号
     */
    public void handleSosSignal(SosSignalDTO signal) {
        // 创建求助记录
        SosAlert alert = createSosAlert(signal);
        
        // 获取定位信息
        LocationInfo location = locationService
            .getLocation(signal.getLongitude(), signal.getLatitude());
        alert.setAddress(location.getAddress());
        
        // 保存记录
        alertMapper.insert(alert);
        
        // 通知处理人员
        notifyHandlers(alert);
        
        // 通知家属
        notifyFamily(alert);
        
        // 记录处理流程
        addProcessRecord(
            alert.getId(), 
            ProcessType.CREATED, 
            "系统自动创建求助记录"
        );
    }

    /**
     * 智能分配处理人员
     */
    public List<HandlerVO> assignHandlers(SosAlert alert) {
        // 获取附近的处理人员
        List<Handler> nearbyHandlers = handlerMapper
            .getNearbyHandlers(
                alert.getLatitude(), 
                alert.getLongitude(), 
                5000  // 5公里范围内
            );
            
        // 计算最优处理人选
        return nearbyHandlers.stream()
            .map(handler -> {
                HandlerVO vo = convertToVO(handler);
                
                // 计算距离分数
                double distanceScore = calculateDistanceScore(
                    handler.getLatitude(),
                    handler.getLongitude(),
                    alert.getLatitude(),
                    alert.getLongitude()
                );
                
                // 计算处理能力分数
                double abilityScore = calculateAbilityScore(handler);
                
                // 计算当前任务量分数
                double workloadScore = calculateWorkloadScore(handler.getId());
                
                // 综合评分
                vo.setAssignScore(
                    distanceScore * 0.4 + 
                    abilityScore * 0.3 + 
                    workloadScore * 0.3
                );
                
                return vo;
            })
            .sorted((a, b) -> 
                Double.compare(b.getAssignScore(), a.getAssignScore())
            )
            .collect(Collectors.toList());
    }

    /**
     * 实时位置追踪
     */
    public void trackLocation(String deviceCode, LocationDTO location) {
        // 更新设备位置
        String key = "device:location:" + deviceCode;
        redisTemplate.opsForHash().putAll(key, 
            Map.of(
                "longitude", location.getLongitude(),
                "latitude", location.getLatitude(),
                "updateTime", LocalDateTime.now()
            )
        );
        
        // 检查是否有关注此设备的用户
        Set<String> watchers = getLocationWatchers(deviceCode);
        if(!watchers.isEmpty()) {
            // 推送位置更新
            webSocketServer.sendToUsers(
                watchers,
                JSON.toJSONString(location)
            );
        }
    }

    /**
     * 紧急联系人通知
     */
    private void notifyContacts(SosAlert alert) {
        // 获取紧急联系人
        List<EmergencyContact> contacts = contactMapper
            .getElderlyContacts(alert.getElderlyId());
            
        // 按优先级排序
        contacts.sort((a, b) -> 
            Integer.compare(a.getPriority(), b.getPriority())
        );
        
        // 逐个尝试通知
        for(EmergencyContact contact : contacts) {
            try {
                // 发送短信通知
                boolean smsSent = smsService.sendSos(
                    contact.getPhone(),
                    alert
                );
                
                // 发送APP推送
                boolean pushSent = pushService.sendSos(
                    contact.getUserId(),
                    alert
                );
                
                // 记录通知状态
                addNotifyRecord(
                    alert.getId(),
                    contact.getId(),
                    smsSent,
                    pushSent
                );
                
                // 如果通知成功,等待确认
                if(smsSent || pushSent) {
                    waitForConfirm(alert.getId(), contact.getId());
                }
                
            } catch(Exception e) {
                log.error("通知紧急联系人异常", e);
                continue;
            }
        }
    }
}

4.3 前端实现

<!-- 紧急求助组件 -->
<template>
  <div class="emergency-panel">
    <!-- 求助按钮 -->
    <div class="sos-button" @click="sendSos">
      <i class="el-icon-warning"></i>
      <span>紧急求助</span>
    </div>
    
    <!-- 实时位置地图 -->
    <div class="location-map">
      <el-amap 
        ref="map"
        :center="currentLocation"
        :zoom="15"
      >
        <!-- 当前位置标记 -->
        <el-amap-marker
          :position="currentLocation"
          :icon="currentIcon"
        ></el-amap-marker>
        
        <!-- 救援人员标记 -->
        <el-amap-marker
          v-for="handler in handlers"
          :key="handler.id"
          :position="handler.location"
          :icon="handlerIcon"
        ></el-amap-marker>
      </el-amap>
    </div>
    
    <!-- 求助状态面板 -->
    <div class="status-panel" v-if="activeAlert">
      <div class="status-header">
        <span class="status-text">处理中</span>
        <span class="time">{{formatTime(activeAlert.createTime)}}</span>
      </div>
      
      <!-- 处理进度时间轴 -->
      <el-timeline>
        <el-timeline-item
          v-for="process in processList"
          :key="process.id"
          :timestamp="formatTime(process.processTime)"
        >
          {{process.processNote}}
        </el-timeline-item>
      </el-timeline>
      
      <!-- 救援人员信息 -->
      <div class="handler-info" v-if="currentHandler">
        <img :src="currentHandler.avatar" class="avatar">
        <div class="info">
          <div class="name">{{currentHandler.name}}</div>
          <div class="phone">{{currentHandler.phone}}</div>
        </div>
        <el-button type="primary" @click="callHandler">
          立即联系
        </el-button>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      currentLocation: null,
      activeAlert: null,
      handlers: [],
      processList: [],
      currentHandler: null
    }
  },
  
  methods: {
    // 发送求助信号
    async sendSos() {
      try {
        // 获取当前位置
        const position = await this.getCurrentPosition();
        
        // 发送求助请求
        const result = await this.createSosAlert({
          longitude: position.longitude,
          latitude: position.latitude,
          deviceCode: this.deviceCode
        });
        
        // 更新状态
        this.activeAlert = result.data;
        
        // 开始位置追踪
        this.startLocationTracking();
        
        // 连接WebSocket接收实时更新
        this.connectWebSocket();
        
      } catch(error) {
        this.$message.error('发送求助信号失败');
      }
    },
    
    // 获取当前位置
    getCurrentPosition() {
      return new Promise((resolve, reject) => {
        if(navigator.geolocation) {
          navigator.geolocation.getCurrentPosition(
            position => {
              resolve({
                longitude: position.coords.longitude,
                latitude: position.coords.latitude
              });
            },
            error => {
              reject(error);
            }
          );
        } else {
          reject(new Error('不支持地理定位'));
        }
      });
    },
    
    // 开始位置追踪
    startLocationTracking() {
      // 定时上报位置
      this.trackingTimer = setInterval(async () => {
        try {
          const position = await this.getCurrentPosition();
          
          // 上报位置
          await this.reportLocation({
            deviceCode: this.deviceCode,
            longitude: position.longitude,
            latitude: position.latitude
          });
          
          // 更新地图中心点
          this.currentLocation = [
            position.longitude,
            position.latitude
          ];
          
        } catch(error) {
          console.error('位置上报失败', error);
        }
      }, 10000);  // 每10秒上报一次
    },
    
    // 连接WebSocket
    connectWebSocket() {
      const ws = new WebSocket(
        `ws://localhost:8080/emergency/${this.activeAlert.id}`
      );
      
      ws.onmessage = event => {
        const data = JSON.parse(event.data);
        
        switch(data.type) {
          case 'PROCESS_UPDATE':
            // 更新处理进度
            this.processList.push(data.process);
            break;
            
          case 'HANDLER_LOCATION':
            // 更新救援人员位置
            this.updateHandlerLocation(data.handler);
            break;
            
          case 'ALERT_FINISH':
            // 求助处理完成
            this.handleAlertFinish(data.alert);
            break;
        }
      }
    }
  }
}
</script>

这些功能模块的实现要点:

  1. 社区活动管理

    • 活动智能推荐
    • 防重复报名
    • 签到积分机制
    • 活动评价反馈
  2. 志愿者服务对接

    • 智能匹配算法
    • 服务质量评价
    • 志愿者积分体系
    • 服务时长统计
  3. 远程看护系统

    • 实时视频推送
    • AI行为分析
    • 异常行为告警
    • 多人同时查看
  4. 紧急求助功能

    • 实时位置追踪
    • 智能分配处理人员
    • 多级通知机制
    • 处理进度跟踪

通过这些功能模块的协同工作,可以为社区老年人提供全方位的智能化养老服务支持。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天天进步2015

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值