一、技术设计

1.1 数据库设计

CREATE TABLE medication_reminder_log (
    id BIGSERIAL PRIMARY KEY,
    schedule_time_id BIGINT NOT NULL,           -- 关联 medication_schedule_time.id
    elderly_id BIGINT NOT NULL,                 -- 老人ID
    plan_date DATE NOT NULL,                    -- 计划服药日期
    dose_time TIME NOT NULL,                    -- 计划服药时间
    remind_status SMALLINT DEFAULT 0,           -- 0待发送 1已发送短信 2已确认服药
    push_time TIMESTAMP,                        -- 短信发送时间
    confirm_time TIMESTAMP,                     -- 确认服药时间
    created_at TIMESTAMP DEFAULT now(),
    
    CONSTRAINT uk_schedule_date UNIQUE(schedule_time_id, plan_date),
    CONSTRAINT fk_reminder_schedule FOREIGN KEY (schedule_time_id) REFERENCES medication_schedule_time(id),
    CONSTRAINT fk_reminder_elderly FOREIGN KEY (elderly_id) REFERENCES elderly(id)
);

设计要点

  • 唯一约束:schedule_time_id + plan_date 防止同一天重复提醒
  • 索引设计:优化查询性能
  • 外键约束:保证数据完整性

1.2 索引设计

CREATE INDEX idx_reminder_elderly_date ON medication_reminder_log(elderly_id, plan_date);
CREATE INDEX idx_reminder_status ON medication_reminder_log(remind_status, plan_date);
CREATE INDEX idx_reminder_dose_time ON medication_reminder_log(dose_time);
索引 用途
idx_reminder_elderly_date 查询老人今日用药计划
idx_reminder_status 查询未确认的提醒
idx_reminder_dose_time 定时任务按时间扫描

1.3 实体映射

@Data
@TableName("medication_reminder_log")
public class MedicationReminderLog implements Serializable {
    
    @TableId(type = IdType.AUTO)
    private Long id;
    
    @TableField("schedule_time_id")
    private Long scheduleTimeId;
    
    @TableField("elderly_id")
    private Long elderlyId;
    
    @TableField("plan_date")
    private LocalDate planDate;
    
    @TableField("dose_time")
    private LocalTime doseTime;
    
    @TableField("remind_status")
    private Integer remindStatus;  // 0待发送 1已发送 2已确认
    
    @TableField("push_time")
    private LocalDateTime pushTime;
    
    @TableField("confirm_time")
    private LocalDateTime confirmTime;
    
    @TableField(value = "created_at", fill = FieldFill.INSERT)
    private LocalDateTime createdAt;
}

1.4 定时任务配置

@Configuration
@EnableScheduling
public class ScheduleConfig {

    @Bean
    public ThreadPoolTaskScheduler taskScheduler() {
        ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
        scheduler.setPoolSize(5);
        scheduler.setThreadNamePrefix("medication-");
        scheduler.setWaitForTasksToCompleteOnShutdown(true);
        scheduler.setAwaitTerminationSeconds(60);
        return scheduler;
    }
}

配置说明

  • 线程池大小:5个线程
  • 线程前缀:medication-
  • 优雅关闭:等待任务完成

1.5 短信配置扩展

@Data
@Component
@ConfigurationProperties(prefix = "sms.aliyun-dypns")
public class AliyunSmsProperties {
    
    // 原有配置...
    
    /** 用药提醒短信模板编码 */
    private String reminderTemplateCode;
}

二、配置文件变更

2.1 application.yml

sms:
  aliyun-dypns:
    # 原有配置...
    
    # 用药提醒短信模板编码(需在阿里云控制台申请)
    reminder-template-code: ""

三、接口定义(供人员B调用)

3.1 MedicationReminderLogService

public interface MedicationReminderLogService extends IService<MedicationReminderLog> {
    // 继承MyBatis-Plus的CRUD方法
}

3.2 常用方法

方法 说明
save(entity) 保存提醒记录
updateById(entity) 更新提醒状态
list(wrapper) 查询提醒列表
count(wrapper) 统计提醒数量
getById(id) 根据ID查询

四、依赖关系

数据层(个人负责)
    ↓
    ├── MedicationReminderLogService
    ├── MedicationPlanService(已有)
    ├── MedicationScheduleTimeService(已有)
    ├── ElderlyService(已有)
    ├── ElderlyFamilyService(已有)
    ├── FamilyService(已有)
    └── SmsService(扩展)
    ↓
业务层(队友负责)

五、测试验证

5.1 编译验证

$env:JAVA_HOME = "C:\Users\20803\.jdks\ms-21.0.10"
mvn compile -q

结果:编译通过 ✅

5.2 数据库验证

-- 执行建表脚本后
SELECT table_name FROM information_schema.tables 
WHERE table_name = 'medication_reminder_log';
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐