fix: 慢性病管理,定时任务修改完善。

This commit is contained in:
tianyongbao
2026-03-21 22:28:06 +08:00
parent 8821e01422
commit 6cff4a2e7a
24 changed files with 368 additions and 55 deletions

View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.intc</groupId>
<artifactId>intc-api</artifactId>
<version>3.6.3</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>intc-api-health</artifactId>
<description>
intc-api-health 健康模块远程调用接口
</description>
<dependencies>
<!-- RuoYi Common Core-->
<dependency>
<groupId>com.intc</groupId>
<artifactId>intc-common-core</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,40 @@
package com.intc.api.health;
import com.intc.common.core.constant.ServiceNameConstants;
import com.intc.common.core.domain.R;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
/**
* 健康模块远程调用服务
*
* @author intc
*/
@FeignClient(contextId = "remoteHealthService", value = ServiceNameConstants.INTC_HEALTH, fallbackFactory = com.intc.api.health.factory.RemoteHealthFallbackFactory.class)
public interface RemoteHealthService {
/**
* 每日生成服药任务
*
* @return 结果
*/
@RequestMapping(value = "/job/generateDailyTasks", method = RequestMethod.POST)
R generateDailyTasks();
/**
* 扫描并发送服药提醒
*
* @return 结果
*/
@RequestMapping(value = "/job/scanAndSendReminders", method = RequestMethod.POST)
R scanAndSendReminders();
/**
* 扫描超时未服药任务
*
* @return 结果
*/
@RequestMapping(value = "/job/scanOverdueRecords", method = RequestMethod.POST)
R scanOverdueRecords();
}

View File

@@ -0,0 +1,41 @@
package com.intc.api.health.factory;
import com.intc.api.health.RemoteHealthService;
import com.intc.common.core.domain.R;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cloud.openfeign.FallbackFactory;
import org.springframework.stereotype.Component;
/**
* 健康服务降级处理
*
* @author intc
*/
@Component
public class RemoteHealthFallbackFactory implements FallbackFactory<RemoteHealthService> {
private static final Logger log = LoggerFactory.getLogger(RemoteHealthFallbackFactory.class);
@Override
public RemoteHealthService create(Throwable throwable) {
log.error("健康服务调用失败:{}", throwable.getMessage());
return new RemoteHealthService() {
@Override
public R generateDailyTasks() {
return R.fail("健康服务调用每日生成服药任务失败");
}
@Override
public R scanAndSendReminders() {
return R.fail("健康服务调用扫描服药提醒失败");
}
@Override
public R scanOverdueRecords() {
return R.fail("健康服务调用扫描超时未服药记录失败");
}
};
}
}

View File

@@ -0,0 +1 @@
com.intc.api.health.factory.RemoteHealthFallbackFactory

View File

@@ -11,6 +11,7 @@
<modules> <modules>
<module>intc-api-system</module> <module>intc-api-system</module>
<module>intc-api-invest</module> <module>intc-api-invest</module>
<module>intc-api-health</module>
</modules> </modules>
<artifactId>intc-api</artifactId> <artifactId>intc-api</artifactId>
<packaging>pom</packaging> <packaging>pom</packaging>

View File

@@ -65,4 +65,9 @@ public class ServiceNameConstants
* INTC_INVEST_PROD的serviceId * INTC_INVEST_PROD的serviceId
*/ */
public static final String INTC_INVEST_PROD ="intc-invest-prod"; public static final String INTC_INVEST_PROD ="intc-invest-prod";
/**
* INTC_HEALTH的serviceId
*/
public static final String INTC_HEALTH = "intc-health";
} }

View File

@@ -0,0 +1,59 @@
package com.intc.health.controller;
import com.intc.common.core.web.domain.AjaxResult;
import com.intc.health.task.MedicationRemindJob;
import com.intc.health.task.MedicationTaskJob;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
/**
* 健康模块定时任务触发接口(供 intc-job 远程调用)
*
* @author intc
*/
@RestController
@RequestMapping("/job")
@Api(tags = "健康模块定时任务接口")
public class HealthJobController {
@Resource
private MedicationTaskJob medicationTaskJob;
@Resource
private MedicationRemindJob medicationRemindJob;
/**
* 每日生成服药任务
*/
@PostMapping("/generateDailyTasks")
@ApiOperation("每日生成服药任务")
public AjaxResult generateDailyTasks() {
medicationTaskJob.generateDailyTasks();
return AjaxResult.success();
}
/**
* 扫描并发送服药提醒
*/
@PostMapping("/scanAndSendReminders")
@ApiOperation("扫描并发送服药提醒")
public AjaxResult scanAndSendReminders() {
medicationRemindJob.scanAndSendReminders();
return AjaxResult.success();
}
/**
* 扫描超时未服药任务
*/
@PostMapping("/scanOverdueRecords")
@ApiOperation("扫描超时未服药任务")
public AjaxResult scanOverdueRecords() {
medicationRemindJob.scanOverdueRecords();
return AjaxResult.success();
}
}

View File

@@ -58,8 +58,10 @@ public class MedicationTaskController extends BaseController {
@ApiOperation("确认服药") @ApiOperation("确认服药")
@RequiresPermissions("health:medicationTask:edit") @RequiresPermissions("health:medicationTask:edit")
@Log(title = "服药任务", businessType = BusinessType.UPDATE) @Log(title = "服药任务", businessType = BusinessType.UPDATE)
public AjaxResult confirm(@PathVariable Long id, @RequestParam(required = false) Integer confirmType) { public AjaxResult confirm(@PathVariable Long id,
return toAjax(taskService.confirm(id, confirmType)); @RequestParam(required = false) Integer confirmType,
@RequestParam(required = false) String confirmTime) {
return toAjax(taskService.confirm(id, confirmType, confirmTime));
} }
@PutMapping("/skip/{id}") @PutMapping("/skip/{id}")

View File

@@ -23,6 +23,9 @@ public class ChronicDiseaseRecord extends BaseEntity {
@ApiModelProperty("关联成员ID") @ApiModelProperty("关联成员ID")
private Long personId; private Long personId;
@ApiModelProperty("关联疾病ID")
private Long diseaseId;
@ApiModelProperty("疾病名称") @ApiModelProperty("疾病名称")
private String diseaseName; private String diseaseName;

View File

@@ -1,13 +1,13 @@
package com.intc.health.domain.vo; package com.intc.health.domain.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.time.LocalDate; import java.util.Date;
import java.time.LocalDateTime;
/** /**
* 用药计划VO * 用药计划VO
@@ -62,10 +62,12 @@ public class MedicationPlanVo {
private JsonNode timeSlots; private JsonNode timeSlots;
@ApiModelProperty("开始日期") @ApiModelProperty("开始日期")
private LocalDate startDate; @JsonFormat(pattern = "yyyy-MM-dd")
private Date startDate;
@ApiModelProperty("结束日期") @ApiModelProperty("结束日期")
private LocalDate endDate; @JsonFormat(pattern = "yyyy-MM-dd")
private Date endDate;
@ApiModelProperty("是否开启提醒1-是 0-否") @ApiModelProperty("是否开启提醒1-是 0-否")
private Integer remindEnabled; private Integer remindEnabled;
@@ -89,5 +91,6 @@ public class MedicationPlanVo {
private Integer todayCompleted; private Integer todayCompleted;
@ApiModelProperty("创建时间") @ApiModelProperty("创建时间")
private LocalDateTime createTime; @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
} }

View File

@@ -1,13 +1,12 @@
package com.intc.health.domain.vo; package com.intc.health.domain.vo;
import com.fasterxml.jackson.annotation.JsonFormat;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.time.LocalDate; import java.util.Date;
import java.time.LocalDateTime;
import java.time.LocalTime;
/** /**
* 服药任务VO * 服药任务VO
@@ -38,16 +37,19 @@ public class MedicationTaskVo {
private String medicineName; private String medicineName;
@ApiModelProperty("计划服药日期") @ApiModelProperty("计划服药日期")
private LocalDate plannedDate; @JsonFormat(pattern = "yyyy-MM-dd")
private Date plannedDate;
@ApiModelProperty("计划服药时间") @ApiModelProperty("计划服药时间")
private LocalTime plannedTime; @JsonFormat(pattern = "HH:mm:ss")
private Date plannedTime;
@ApiModelProperty("计划剂量") @ApiModelProperty("计划剂量")
private BigDecimal plannedDosage; private BigDecimal plannedDosage;
@ApiModelProperty("实际服药时间") @ApiModelProperty("实际服药时间")
private LocalDateTime actualTime; @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date actualTime;
@ApiModelProperty("实际剂量") @ApiModelProperty("实际剂量")
private BigDecimal actualDosage; private BigDecimal actualDosage;
@@ -68,8 +70,10 @@ public class MedicationTaskVo {
private Integer remindStatus; private Integer remindStatus;
@ApiModelProperty("提醒时间") @ApiModelProperty("提醒时间")
private LocalDateTime remindTime; @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date remindTime;
@ApiModelProperty("创建时间") @ApiModelProperty("创建时间")
private LocalDateTime createTime; @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
} }

View File

@@ -1,5 +1,6 @@
package com.intc.health.mapper; package com.intc.health.mapper;
import com.intc.common.datascope.annotation.DataScope;
import java.util.List; import java.util.List;
import com.intc.health.domain.vo.ChronicDiseaseRecordVo; import com.intc.health.domain.vo.ChronicDiseaseRecordVo;
import com.intc.health.domain.dto.ChronicDiseaseRecordDto; import com.intc.health.domain.dto.ChronicDiseaseRecordDto;
@@ -27,6 +28,7 @@ public interface ChronicDiseaseRecordMapper
* @param chronicDiseaseRecordDto 慢性疾病档案 * @param chronicDiseaseRecordDto 慢性疾病档案
* @return 慢性疾病档案集合 * @return 慢性疾病档案集合
*/ */
@DataScope(businessAlias = "a")
public List<ChronicDiseaseRecordVo> selectChronicDiseaseRecordList(ChronicDiseaseRecordDto chronicDiseaseRecordDto); public List<ChronicDiseaseRecordVo> selectChronicDiseaseRecordList(ChronicDiseaseRecordDto chronicDiseaseRecordDto);
/** /**

View File

@@ -1,5 +1,6 @@
package com.intc.health.mapper; package com.intc.health.mapper;
import com.intc.common.datascope.annotation.DataScope;
import com.intc.health.domain.MedicationPlan; import com.intc.health.domain.MedicationPlan;
import com.intc.health.domain.dto.MedicationPlanDto; import com.intc.health.domain.dto.MedicationPlanDto;
import com.intc.health.domain.vo.MedicationPlanVo; import com.intc.health.domain.vo.MedicationPlanVo;
@@ -23,6 +24,7 @@ public interface MedicationPlanMapper {
/** /**
* 查询用药计划列表 * 查询用药计划列表
*/ */
@DataScope(businessAlias = "a")
List<MedicationPlanVo> selectList(MedicationPlanDto dto); List<MedicationPlanVo> selectList(MedicationPlanDto dto);
/** /**

View File

@@ -1,5 +1,6 @@
package com.intc.health.mapper; package com.intc.health.mapper;
import com.intc.common.datascope.annotation.DataScope;
import com.intc.health.domain.MedicationTask; import com.intc.health.domain.MedicationTask;
import com.intc.health.domain.dto.MedicationTaskDto; import com.intc.health.domain.dto.MedicationTaskDto;
import com.intc.health.domain.vo.MedicationTaskVo; import com.intc.health.domain.vo.MedicationTaskVo;
@@ -25,6 +26,7 @@ public interface MedicationTaskMapper {
/** /**
* 查询服药任务列表 * 查询服药任务列表
*/ */
@DataScope(businessAlias = "a")
List<MedicationTaskVo> selectList(MedicationTaskDto dto); List<MedicationTaskVo> selectList(MedicationTaskDto dto);
/** /**
@@ -67,6 +69,11 @@ public interface MedicationTaskMapper {
*/ */
int countByPlanAndDate(@Param("planId") Long planId, @Param("date") LocalDate date); int countByPlanAndDate(@Param("planId") Long planId, @Param("date") LocalDate date);
/**
* 删除某计划某天的所有任务(用于重新生成时清理旧数据)
*/
int deleteByPlanAndDate(@Param("planId") Long planId, @Param("date") LocalDate date);
/** /**
* 统计某计划某天的已服药数 * 统计某计划某天的已服药数
*/ */
@@ -87,21 +94,21 @@ public interface MedicationTaskMapper {
/** /**
* 获取总体统计 * 获取总体统计
*/ */
java.util.Map<String, Object> getOverallStats(@Param("memberId") Long memberId, java.util.Map<String, Object> getOverallStats(@Param("personId") Long personId,
@Param("startDate") LocalDate startDate, @Param("startDate") LocalDate startDate,
@Param("endDate") LocalDate endDate); @Param("endDate") LocalDate endDate);
/** /**
* 获取每日统计 * 获取每日统计
*/ */
List<java.util.Map<String, Object>> getDailyStats(@Param("memberId") Long memberId, List<java.util.Map<String, Object>> getDailyStats(@Param("personId") Long personId,
@Param("startDate") LocalDate startDate, @Param("startDate") LocalDate startDate,
@Param("endDate") LocalDate endDate); @Param("endDate") LocalDate endDate);
/** /**
* 获取时段统计 * 获取时段统计
*/ */
List<java.util.Map<String, Object>> getTimeSlotStats(@Param("memberId") Long memberId, List<java.util.Map<String, Object>> getTimeSlotStats(@Param("personId") Long personId,
@Param("startDate") LocalDate startDate, @Param("startDate") LocalDate startDate,
@Param("endDate") LocalDate endDate); @Param("endDate") LocalDate endDate);
} }

View File

@@ -42,7 +42,7 @@ public interface IMedicationTaskService {
/** /**
* 确认服药 * 确认服药
*/ */
int confirm(Long id, Integer confirmType); int confirm(Long id, Integer confirmType, String confirmTime);
/** /**
* 跳过服药 * 跳过服药

View File

@@ -27,19 +27,12 @@ public class MedicationPlanServiceImpl implements IMedicationPlanService {
@Override @Override
public MedicationPlanVo selectById(Long id) { public MedicationPlanVo selectById(Long id) {
MedicationPlanVo vo = planMapper.selectById(id); return planMapper.selectById(id);
if (vo != null) {
// 统计今日任务情况
// TODO: 添加今日任务统计
}
return vo;
} }
@Override @Override
public List<MedicationPlanVo> selectList(MedicationPlanDto dto) { public List<MedicationPlanVo> selectList(MedicationPlanDto dto) {
List<MedicationPlanVo> list = planMapper.selectList(dto); return planMapper.selectList(dto);
// TODO: 可以添加今日任务统计
return list;
} }
@Override @Override

View File

@@ -10,7 +10,9 @@ import com.intc.health.service.IMedicationTaskService;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.List; import java.util.List;
/** /**
@@ -58,12 +60,27 @@ public class MedicationTaskServiceImpl implements IMedicationTaskService {
} }
@Override @Override
public int confirm(Long id, Integer confirmType) { public int confirm(Long id, Integer confirmType, String confirmTime) {
MedicationTask task = new MedicationTask(); MedicationTask task = new MedicationTask();
task.setId(id); task.setId(id);
task.setStatus(1); // 已服药 task.setStatus(1); // 已服药
task.setConfirmType(confirmType != null ? confirmType : 1); task.setConfirmType(confirmType != null ? confirmType : 1);
task.setActualTime(LocalDateTime.now()); // 优先使用前端传入的实际服药时间,没有则用当前时间
if (confirmTime != null && !confirmTime.isEmpty()) {
try {
LocalTime time = LocalTime.parse(confirmTime, java.time.format.DateTimeFormatter.ofPattern("HH:mm"));
task.setActualTime(LocalDateTime.of(LocalDate.now(), time));
} catch (Exception e1) {
try {
LocalTime time = LocalTime.parse(confirmTime, java.time.format.DateTimeFormatter.ofPattern("HH:mm:ss"));
task.setActualTime(LocalDateTime.of(LocalDate.now(), time));
} catch (Exception e2) {
task.setActualTime(LocalDateTime.now());
}
}
} else {
task.setActualTime(LocalDateTime.now());
}
task.setUpdateBy(SecurityUtils.getUsername()); task.setUpdateBy(SecurityUtils.getUsername());
task.setUpdateTime(DateUtils.getNowDate()); task.setUpdateTime(DateUtils.getNowDate());
return taskMapper.update(task); return taskMapper.update(task);

View File

@@ -16,9 +16,11 @@ import java.time.DayOfWeek;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.LocalTime; import java.time.LocalTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit; import java.time.temporal.ChronoUnit;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date;
import java.util.List; import java.util.List;
/** /**
@@ -70,19 +72,26 @@ public class MedicationTaskJob {
continue; continue;
} }
// 检查是否已生成任务 // 先计算本次应生成任务列表
int existCount = taskMapper.countByPlanAndDate(plan.getId(), date); List<MedicationTask> tasks = generateTasksForPlan(plan, date);
if (existCount > 0) { if (tasks.isEmpty()) {
continue; continue;
} }
// 生成任务 // 检查已生成任务数,只补充未生成的部分(防止重复)
List<MedicationTask> tasks = generateTasksForPlan(plan, date); int existCount = taskMapper.countByPlanAndDate(plan.getId(), date);
if (!tasks.isEmpty()) { if (existCount >= tasks.size()) {
taskMapper.batchInsert(tasks); // 已全量生成,跳过
generatedCount += tasks.size(); continue;
log.info("计划 {} 在 {} 生成了 {} 条任务", plan.getPlanName(), date, tasks.size());
} }
// 未全量生成时,删除旧的再重新全量插入(保证幂等)
if (existCount > 0) {
taskMapper.deleteByPlanAndDate(plan.getId(), date);
}
taskMapper.batchInsert(tasks);
generatedCount += tasks.size();
log.info("计划 {} 在 {} 生成了 {} 条任务", plan.getPlanName(), date, tasks.size());
} catch (Exception e) { } catch (Exception e) {
log.error("生成计划 {} 的任务失败: {}", plan.getId(), e.getMessage(), e); log.error("生成计划 {} 的任务失败: {}", plan.getId(), e.getMessage(), e);
} }
@@ -96,10 +105,10 @@ public class MedicationTaskJob {
*/ */
private boolean shouldTakeMedicineOnDate(MedicationPlanVo plan, LocalDate date) { private boolean shouldTakeMedicineOnDate(MedicationPlanVo plan, LocalDate date) {
// 检查日期范围 // 检查日期范围
if (plan.getStartDate() != null && date.isBefore(plan.getStartDate())) { if (plan.getStartDate() != null && date.isBefore(toLocalDate(plan.getStartDate()))) {
return false; return false;
} }
if (plan.getEndDate() != null && date.isAfter(plan.getEndDate())) { if (plan.getEndDate() != null && date.isAfter(toLocalDate(plan.getEndDate()))) {
return false; return false;
} }
@@ -152,7 +161,7 @@ public class MedicationTaskJob {
* 隔天服药判断 * 隔天服药判断
*/ */
private boolean shouldTakeOnAlternate(MedicationPlanVo plan, LocalDate date) { private boolean shouldTakeOnAlternate(MedicationPlanVo plan, LocalDate date) {
LocalDate startDate = plan.getStartDate(); LocalDate startDate = plan.getStartDate() != null ? toLocalDate(plan.getStartDate()) : null;
if (startDate == null) { if (startDate == null) {
startDate = date; startDate = date;
} }
@@ -182,23 +191,25 @@ public class MedicationTaskJob {
List<MedicationTask> tasks = new ArrayList<>(); List<MedicationTask> tasks = new ArrayList<>();
JsonNode timeSlots = plan.getTimeSlots(); JsonNode timeSlots = plan.getTimeSlots();
log.info("计划 {} timeSlots原始值={}, isArray={}, nodeType={}",
plan.getId(), timeSlots, timeSlots != null && timeSlots.isArray(), timeSlots != null ? timeSlots.getNodeType() : null);
// TextNode说明存储时被二次序列化需要再解析一次
if (timeSlots != null && timeSlots.isTextual()) {
try {
timeSlots = new com.fasterxml.jackson.databind.ObjectMapper().readTree(timeSlots.asText());
} catch (Exception e) {
timeSlots = null;
}
}
if (timeSlots == null || !timeSlots.isArray()) { if (timeSlots == null || !timeSlots.isArray()) {
// 如果没有配置时段,使用默认时段 // 如果没有配置时段,使用默认时段
timeSlots = createDefaultTimeSlots(plan); timeSlots = createDefaultTimeSlots(plan);
} }
for (JsonNode slot : timeSlots) { for (JsonNode slot : timeSlots) {
if (!slot.has("enabled") || !slot.get("enabled").asBoolean(true)) { String timeStr = slot.asText();
continue;
}
String timeStr = slot.has("time") ? slot.get("time").asText() : "08:00";
LocalTime time = parseTime(timeStr);
BigDecimal dosage = plan.getDosagePerTime(); BigDecimal dosage = plan.getDosagePerTime();
if (slot.has("dosage")) { LocalTime time = parseTime(timeStr);
dosage = new BigDecimal(slot.get("dosage").asText());
}
MedicationTask task = new MedicationTask(); MedicationTask task = new MedicationTask();
task.setPlanId(plan.getId()); task.setPlanId(plan.getId());
@@ -230,6 +241,13 @@ public class MedicationTaskJob {
} }
} }
/**
* Date 转 LocalDate
*/
private LocalDate toLocalDate(Date date) {
return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
}
/** /**
* 解析时间字符串 * 解析时间字符串
*/ */

View File

@@ -8,7 +8,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="id" column="id"/> <result property="id" column="id"/>
<result property="personId" column="person_id"/> <result property="personId" column="person_id"/>
<result property="personName" column="person_name"/> <result property="personName" column="person_name"/>
<result property="diseaseId" column="disease_id"/>
<result property="diseaseName" column="disease_name"/> <result property="diseaseName" column="disease_name"/>
<result property="diseaseCode" column="disease_code"/> <result property="diseaseCode" column="disease_code"/>
<result property="diagnosisDate" column="diagnosis_date"/> <result property="diagnosisDate" column="diagnosis_date"/>
@@ -28,7 +28,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</resultMap> </resultMap>
<sql id="selectChronicDiseaseRecordVo"> <sql id="selectChronicDiseaseRecordVo">
select a.id, a.person_id, a.disease_name, a.disease_code, a.diagnosis_date, select a.id, a.person_id,a.disease_id, a.disease_name, a.disease_code, a.diagnosis_date,
a.disease_status, a.main_doctor, a.hospital, a.department, a.notes, a.is_active, a.disease_status, a.main_doctor, a.hospital, a.department, a.notes, a.is_active,
a.create_by, a.create_time, a.update_by, a.update_time, a.del_flag, a.remark, a.create_by, a.create_time, a.update_by, a.update_time, a.del_flag, a.remark,
p.name as person_name p.name as person_name
@@ -62,6 +62,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
and a.diagnosis_date &lt;= #{diagnosisDateEnd} and a.diagnosis_date &lt;= #{diagnosisDateEnd}
</if> </if>
</where> </where>
<!-- 数据范围过滤 -->
${params.dataScope}
order by a.create_time desc order by a.create_time desc
</select> </select>
@@ -81,6 +83,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<trim prefix="(" suffix=")" suffixOverrides=","> <trim prefix="(" suffix=")" suffixOverrides=",">
<if test="id != null">id,</if> <if test="id != null">id,</if>
<if test="personId != null">person_id,</if> <if test="personId != null">person_id,</if>
<if test="diseaseId != null">disease_id,</if>
<if test="diseaseName != null and diseaseName != ''">disease_name,</if> <if test="diseaseName != null and diseaseName != ''">disease_name,</if>
<if test="diseaseCode != null">disease_code,</if> <if test="diseaseCode != null">disease_code,</if>
<if test="diagnosisDate != null">diagnosis_date,</if> <if test="diagnosisDate != null">diagnosis_date,</if>
@@ -100,6 +103,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<trim prefix="values (" suffix=")" suffixOverrides=","> <trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">#{id},</if> <if test="id != null">#{id},</if>
<if test="personId != null">#{personId},</if> <if test="personId != null">#{personId},</if>
<if test="diseaseId != null">#{diseaseId},</if>
<if test="diseaseName != null and diseaseName != ''">#{diseaseName},</if> <if test="diseaseName != null and diseaseName != ''">#{diseaseName},</if>
<if test="diseaseCode != null">#{diseaseCode},</if> <if test="diseaseCode != null">#{diseaseCode},</if>
<if test="diagnosisDate != null">#{diagnosisDate},</if> <if test="diagnosisDate != null">#{diagnosisDate},</if>
@@ -122,6 +126,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
update chronic_disease_record update chronic_disease_record
<trim prefix="SET" suffixOverrides=","> <trim prefix="SET" suffixOverrides=",">
<if test="personId != null">person_id = #{personId},</if> <if test="personId != null">person_id = #{personId},</if>
<if test="diseaseId != null">disease_id = #{diseaseId},</if>
<if test="diseaseName != null and diseaseName != ''">disease_name = #{diseaseName},</if> <if test="diseaseName != null and diseaseName != ''">disease_name = #{diseaseName},</if>
<if test="diseaseCode != null">disease_code = #{diseaseCode},</if> <if test="diseaseCode != null">disease_code = #{diseaseCode},</if>
<if test="diagnosisDate != null">diagnosis_date = #{diagnosisDate},</if> <if test="diagnosisDate != null">diagnosis_date = #{diagnosisDate},</if>

View File

@@ -24,6 +24,8 @@
<result property="notifyFamily" column="notify_family"/> <result property="notifyFamily" column="notify_family"/>
<result property="familyMemberIds" column="family_member_ids" typeHandler="com.intc.common.core.handler.JsonNodeTypeHandler"/> <result property="familyMemberIds" column="family_member_ids" typeHandler="com.intc.common.core.handler.JsonNodeTypeHandler"/>
<result property="status" column="status"/> <result property="status" column="status"/>
<result property="todayTotal" column="today_total"/>
<result property="todayCompleted" column="today_completed"/>
<result property="createTime" column="create_time"/> <result property="createTime" column="create_time"/>
</resultMap> </resultMap>
@@ -33,7 +35,9 @@
a.medicine_name, a.specification, a.dosage_per_time, a.dosage_unit, a.medicine_name, a.specification, a.dosage_per_time, a.dosage_unit,
a.frequency_type, a.frequency_config, a.time_slots, a.start_date, a.end_date, a.frequency_type, a.frequency_config, a.time_slots, a.start_date, a.end_date,
a.remind_enabled, a.remind_advance_min, a.notify_family, a.family_member_ids, a.remind_enabled, a.remind_advance_min, a.notify_family, a.family_member_ids,
a.status, a.create_time a.status, a.create_time,
(select count(1) from medication_task t where t.plan_id = a.id and t.del_flag = 0 and t.planned_date = current_date) as today_total,
(select count(1) from medication_task t where t.plan_id = a.id and t.del_flag = 0 and t.planned_date = current_date and t.status = 1) as today_completed
from medication_plan a from medication_plan a
left join health_person p on a.person_id = p.id left join health_person p on a.person_id = p.id
left join chronic_disease_record c on a.chronic_disease_id = c.id left join chronic_disease_record c on a.chronic_disease_id = c.id
@@ -60,6 +64,8 @@
and (a.plan_name like '%' || #{keyword} || '%' or a.medicine_name like '%' || #{keyword} || '%') and (a.plan_name like '%' || #{keyword} || '%' or a.medicine_name like '%' || #{keyword} || '%')
</if> </if>
</where> </where>
<!-- 数据范围过滤 -->
${params.dataScope}
order by a.create_time desc order by a.create_time desc
</select> </select>

View File

@@ -52,6 +52,8 @@
and a.medicine_name like '%' || #{keyword} || '%' and a.medicine_name like '%' || #{keyword} || '%'
</if> </if>
</where> </where>
<!-- 数据范围过滤 -->
${params.dataScope}
order by a.planned_date desc, a.planned_time desc order by a.planned_date desc, a.planned_time desc
</select> </select>
@@ -118,6 +120,11 @@
where del_flag = 0 and plan_id = #{planId} and planned_date = #{date} where del_flag = 0 and plan_id = #{planId} and planned_date = #{date}
</select> </select>
<delete id="deleteByPlanAndDate">
delete from medication_task
where plan_id = #{planId} and planned_date = #{date} and status = 0
</delete>
<select id="countCompletedByPlanAndDate" resultType="int"> <select id="countCompletedByPlanAndDate" resultType="int">
select count(1) from medication_task select count(1) from medication_task
where del_flag = 0 and plan_id = #{planId} and planned_date = #{date} and status = 1 where del_flag = 0 and plan_id = #{planId} and planned_date = #{date} and status = 1

View File

@@ -92,6 +92,12 @@
<version>3.6.3</version> <version>3.6.3</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency>
<groupId>com.intc</groupId>
<artifactId>intc-api-health</artifactId>
<version>3.6.3</version>
<scope>compile</scope>
</dependency>
</dependencies> </dependencies>
<build> <build>

View File

@@ -0,0 +1,36 @@
package com.intc.job.task;
import com.intc.api.health.RemoteHealthService;
import com.intc.common.core.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* 用药提醒定时任务(通过 Feign 调用 intc-health 服务)
*
* @author intc
*/
@Component("medicationRemindJob")
public class MedicationRemindJobTask {
@Autowired
private RemoteHealthService remoteHealthService;
/**
* 扫描并发送服药提醒(每分钟执行)
*/
public void scanAndSendReminders() {
System.out.println("================================开始扫描服药提醒(" + DateUtils.getTime() + ")=================================");
remoteHealthService.scanAndSendReminders();
System.out.println("================================结束扫描服药提醒(" + DateUtils.getTime() + ")=================================");
}
/**
* 扫描超时未服药任务每5分钟执行
*/
public void scanOverdueRecords() {
System.out.println("================================开始扫描超时未服药任务(" + DateUtils.getTime() + ")=================================");
remoteHealthService.scanOverdueRecords();
System.out.println("================================结束扫描超时未服药任务(" + DateUtils.getTime() + ")=================================");
}
}

View File

@@ -0,0 +1,27 @@
package com.intc.job.task;
import com.intc.api.health.RemoteHealthService;
import com.intc.common.core.utils.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* 健康模块定时任务(通过 Feign 调用 intc-health 服务)
*
* @author intc
*/
@Component("medicationTaskJob")
public class MedicationTaskJobTask {
@Autowired
private RemoteHealthService remoteHealthService;
/**
* 每日生成服药任务(每日 00:05 执行)
*/
public void generateDailyTasks() {
System.out.println("================================开始每日生成服药任务(" + DateUtils.getTime() + ")=================================");
remoteHealthService.generateDailyTasks();
System.out.println("================================结束每日生成服药任务(" + DateUtils.getTime() + ")=================================");
}
}