Merge branch 'dev'
This commit is contained in:
@@ -0,0 +1,128 @@
|
||||
package com.intc.health.controller;
|
||||
|
||||
import java.util.List;
|
||||
import java.io.IOException;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.annotation.Resource;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import com.intc.common.log.annotation.Log;
|
||||
import com.intc.common.log.enums.BusinessType;
|
||||
import com.intc.common.security.annotation.RequiresPermissions;
|
||||
import com.intc.health.domain.ChronicDiseaseRecord;
|
||||
import com.intc.health.domain.vo.ChronicDiseaseRecordVo;
|
||||
import com.intc.health.domain.dto.ChronicDiseaseRecordDto;
|
||||
import com.intc.health.service.IChronicDiseaseRecordService;
|
||||
import com.intc.common.core.web.controller.BaseController;
|
||||
import com.intc.common.core.web.domain.AjaxResult;
|
||||
import com.intc.common.core.utils.poi.ExcelUtil;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import com.intc.common.core.web.page.TableDataInfo;
|
||||
|
||||
/**
|
||||
* 慢性疾病档案Controller
|
||||
*
|
||||
* @author bot5
|
||||
* @date 2026-03-17
|
||||
*/
|
||||
@Api(tags = "慢性疾病档案")
|
||||
@RestController
|
||||
@RequestMapping("/chronicDisease")
|
||||
public class ChronicDiseaseRecordController extends BaseController
|
||||
{
|
||||
@Resource
|
||||
private IChronicDiseaseRecordService chronicDiseaseRecordService;
|
||||
|
||||
/**
|
||||
* 查询慢性疾病档案列表
|
||||
*/
|
||||
@ApiOperation(value = "查询慢性疾病档案列表", response = ChronicDiseaseRecordVo.class)
|
||||
@RequiresPermissions("health:chronicDisease:list")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo list(ChronicDiseaseRecordDto chronicDiseaseRecordDto)
|
||||
{
|
||||
startPage();
|
||||
List<ChronicDiseaseRecordVo> list = chronicDiseaseRecordService.selectChronicDiseaseRecordList(chronicDiseaseRecordDto);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据成员ID查询慢性疾病档案列表
|
||||
*/
|
||||
@ApiOperation(value = "根据成员ID查询慢性疾病档案列表", response = ChronicDiseaseRecordVo.class)
|
||||
@RequiresPermissions("health:chronicDisease:list")
|
||||
@GetMapping({"/listByPerson/{personId}", "/listByMember/{personId}"})
|
||||
public AjaxResult listByMember(@PathVariable("personId") Long personId)
|
||||
{
|
||||
List<ChronicDiseaseRecordVo> list = chronicDiseaseRecordService.selectChronicDiseaseRecordByMemberId(personId);
|
||||
return success(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出慢性疾病档案列表
|
||||
*/
|
||||
@ApiOperation(value = "导出慢性疾病档案列表")
|
||||
@RequiresPermissions("health:chronicDisease:export")
|
||||
@Log(title = "慢性疾病档案", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
public void export(HttpServletResponse response, ChronicDiseaseRecordDto chronicDiseaseRecordDto)
|
||||
{
|
||||
List<ChronicDiseaseRecordVo> list = chronicDiseaseRecordService.selectChronicDiseaseRecordList(chronicDiseaseRecordDto);
|
||||
ExcelUtil<ChronicDiseaseRecordVo> util = new ExcelUtil<ChronicDiseaseRecordVo>(ChronicDiseaseRecordVo.class);
|
||||
util.exportExcel(response, list, "慢性疾病档案数据");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取慢性疾病档案详细信息
|
||||
*/
|
||||
@ApiOperation(value = "获取慢性疾病档案详细信息")
|
||||
@RequiresPermissions("health:chronicDisease:query")
|
||||
@GetMapping(value = "/{id}")
|
||||
public AjaxResult getInfo(@PathVariable("id") Long id)
|
||||
{
|
||||
return success(chronicDiseaseRecordService.selectChronicDiseaseRecordById(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增慢性疾病档案
|
||||
*/
|
||||
@ApiOperation(value = "新增慢性疾病档案")
|
||||
@RequiresPermissions("health:chronicDisease:add")
|
||||
@Log(title = "慢性疾病档案", businessType = BusinessType.INSERT)
|
||||
@PostMapping
|
||||
public AjaxResult add(@RequestBody ChronicDiseaseRecord chronicDiseaseRecord)
|
||||
{
|
||||
return toAjax(chronicDiseaseRecordService.insertChronicDiseaseRecord(chronicDiseaseRecord));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改慢性疾病档案
|
||||
*/
|
||||
@ApiOperation(value = "修改慢性疾病档案")
|
||||
@RequiresPermissions("health:chronicDisease:edit")
|
||||
@Log(title = "慢性疾病档案", businessType = BusinessType.UPDATE)
|
||||
@PutMapping
|
||||
public AjaxResult edit(@RequestBody ChronicDiseaseRecord chronicDiseaseRecord)
|
||||
{
|
||||
return toAjax(chronicDiseaseRecordService.updateChronicDiseaseRecord(chronicDiseaseRecord));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除慢性疾病档案
|
||||
*/
|
||||
@ApiOperation(value = "删除慢性疾病档案")
|
||||
@RequiresPermissions("health:chronicDisease:remove")
|
||||
@Log(title = "慢性疾病档案", businessType = BusinessType.DELETE)
|
||||
@DeleteMapping("/{ids}")
|
||||
public AjaxResult remove(@PathVariable Long[] ids)
|
||||
{
|
||||
return toAjax(chronicDiseaseRecordService.deleteChronicDiseaseRecordByIds(ids));
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package com.intc.health.controller;
|
||||
|
||||
import com.intc.common.core.web.domain.AjaxResult;
|
||||
import com.intc.health.domain.vo.DailyAdherenceVo;
|
||||
import com.intc.health.domain.vo.MedicationAdherenceVo;
|
||||
import com.intc.health.service.IMedicationAdherenceService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 依从性统计Controller
|
||||
*
|
||||
* @author bot5
|
||||
* @date 2026-03-19
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/adherence")
|
||||
@Api(tags = "依从性统计")
|
||||
public class MedicationAdherenceController {
|
||||
|
||||
@Resource
|
||||
private IMedicationAdherenceService adherenceService;
|
||||
|
||||
@GetMapping("/overall")
|
||||
@ApiOperation("获取总体依从性统计")
|
||||
public AjaxResult getOverallAdherence(
|
||||
@RequestParam(required = false) Long personId,
|
||||
@RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate startDate,
|
||||
@RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate endDate) {
|
||||
MedicationAdherenceVo vo = adherenceService.getOverallAdherence(personId, startDate, endDate);
|
||||
return AjaxResult.success(vo);
|
||||
}
|
||||
|
||||
@GetMapping("/daily")
|
||||
@ApiOperation("获取每日依从性统计列表")
|
||||
public AjaxResult getDailyAdherenceList(
|
||||
@RequestParam(required = false) Long personId,
|
||||
@RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate startDate,
|
||||
@RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate endDate) {
|
||||
List<DailyAdherenceVo> list = adherenceService.getDailyAdherenceList(personId, startDate, endDate);
|
||||
return AjaxResult.success(list);
|
||||
}
|
||||
|
||||
@GetMapping("/calendar")
|
||||
@ApiOperation("获取日历视图数据")
|
||||
public AjaxResult getCalendarData(
|
||||
@RequestParam(required = false) Long personId,
|
||||
@RequestParam String yearMonth) {
|
||||
List<DailyAdherenceVo> list = adherenceService.getCalendarData(personId, yearMonth);
|
||||
return AjaxResult.success(list);
|
||||
}
|
||||
|
||||
@GetMapping("/timeSlot")
|
||||
@ApiOperation("获取各时段服药统计")
|
||||
public AjaxResult getTimeSlotAdherence(
|
||||
@RequestParam(required = false) Long personId,
|
||||
@RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate startDate,
|
||||
@RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate endDate) {
|
||||
Map<String, MedicationAdherenceVo> map = adherenceService.getTimeSlotAdherence(personId, startDate, endDate);
|
||||
return AjaxResult.success(map);
|
||||
}
|
||||
|
||||
@GetMapping("/dashboard")
|
||||
@ApiOperation("获取仪表盘概览数据")
|
||||
public AjaxResult getDashboard(@RequestParam(required = false) Long personId) {
|
||||
LocalDate today = LocalDate.now();
|
||||
LocalDate weekAgo = today.minusDays(7);
|
||||
|
||||
Map<String, Object> result = new java.util.HashMap<>();
|
||||
result.put("overall", adherenceService.getOverallAdherence(personId, weekAgo, today));
|
||||
result.put("dailyTrend", adherenceService.getDailyAdherenceList(personId, weekAgo, today));
|
||||
result.put("timeSlot", adherenceService.getTimeSlotAdherence(personId, weekAgo, today));
|
||||
|
||||
return AjaxResult.success(result);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
package com.intc.health.controller;
|
||||
|
||||
import com.intc.common.core.web.controller.BaseController;
|
||||
import com.intc.common.core.web.domain.AjaxResult;
|
||||
import com.intc.common.core.web.page.TableDataInfo;
|
||||
import com.intc.common.log.annotation.Log;
|
||||
import com.intc.common.log.enums.BusinessType;
|
||||
import com.intc.common.security.annotation.RequiresPermissions;
|
||||
import com.intc.health.domain.MedicationPlan;
|
||||
import com.intc.health.domain.dto.MedicationPlanDto;
|
||||
import com.intc.health.domain.vo.MedicationPlanVo;
|
||||
import com.intc.health.service.IMedicationPlanService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 用药计划Controller
|
||||
*
|
||||
* @author bot5
|
||||
* @date 2026-03-19
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/medicationPlan")
|
||||
@Api(tags = "用药计划管理")
|
||||
public class MedicationPlanController extends BaseController {
|
||||
|
||||
@Resource
|
||||
private IMedicationPlanService planService;
|
||||
|
||||
@GetMapping("/list")
|
||||
@ApiOperation("查询用药计划列表")
|
||||
@RequiresPermissions("health:medicationPlan:list")
|
||||
public TableDataInfo list(MedicationPlanDto dto) {
|
||||
startPage();
|
||||
List<MedicationPlanVo> list = planService.selectList(dto);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
@GetMapping("/{id}")
|
||||
@ApiOperation("查询用药计划详情")
|
||||
@RequiresPermissions("health:medicationPlan:query")
|
||||
public AjaxResult getInfo(@PathVariable Long id) {
|
||||
return success(planService.selectById(id));
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
@ApiOperation("新增用药计划")
|
||||
@RequiresPermissions("health:medicationPlan:add")
|
||||
@Log(title = "用药计划", businessType = BusinessType.INSERT)
|
||||
public AjaxResult add(@RequestBody MedicationPlan plan) {
|
||||
return toAjax(planService.insert(plan));
|
||||
}
|
||||
|
||||
@PutMapping
|
||||
@ApiOperation("修改用药计划")
|
||||
@RequiresPermissions("health:medicationPlan:edit")
|
||||
@Log(title = "用药计划", businessType = BusinessType.UPDATE)
|
||||
public AjaxResult edit(@RequestBody MedicationPlan plan) {
|
||||
return toAjax(planService.update(plan));
|
||||
}
|
||||
|
||||
@DeleteMapping("/{ids}")
|
||||
@ApiOperation("删除用药计划")
|
||||
@RequiresPermissions("health:medicationPlan:remove")
|
||||
@Log(title = "用药计划", businessType = BusinessType.DELETE)
|
||||
public AjaxResult remove(@PathVariable Long[] ids) {
|
||||
return toAjax(planService.deleteByIds(ids));
|
||||
}
|
||||
|
||||
@PutMapping("/pause/{id}")
|
||||
@ApiOperation("暂停用药计划")
|
||||
@RequiresPermissions("health:medicationPlan:edit")
|
||||
@Log(title = "用药计划", businessType = BusinessType.UPDATE)
|
||||
public AjaxResult pause(@PathVariable Long id) {
|
||||
return toAjax(planService.pause(id));
|
||||
}
|
||||
|
||||
@PutMapping("/resume/{id}")
|
||||
@ApiOperation("恢复用药计划")
|
||||
@RequiresPermissions("health:medicationPlan:edit")
|
||||
@Log(title = "用药计划", businessType = BusinessType.UPDATE)
|
||||
public AjaxResult resume(@PathVariable Long id) {
|
||||
return toAjax(planService.resume(id));
|
||||
}
|
||||
|
||||
@PutMapping("/end/{id}")
|
||||
@ApiOperation("结束用药计划")
|
||||
@RequiresPermissions("health:medicationPlan:edit")
|
||||
@Log(title = "用药计划", businessType = BusinessType.UPDATE)
|
||||
public AjaxResult end(@PathVariable Long id) {
|
||||
return toAjax(planService.end(id));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
package com.intc.health.controller;
|
||||
|
||||
import com.intc.common.core.web.controller.BaseController;
|
||||
import com.intc.common.core.web.domain.AjaxResult;
|
||||
import com.intc.common.core.web.page.TableDataInfo;
|
||||
import com.intc.common.log.annotation.Log;
|
||||
import com.intc.common.log.enums.BusinessType;
|
||||
import com.intc.common.security.annotation.RequiresPermissions;
|
||||
import com.intc.health.domain.dto.MedicationTaskDto;
|
||||
import com.intc.health.domain.vo.MedicationTaskVo;
|
||||
import com.intc.health.service.IMedicationTaskService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 服药任务Controller
|
||||
*
|
||||
* @author bot5
|
||||
* @date 2026-03-19
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/medicationTask")
|
||||
@Api(tags = "服药任务管理")
|
||||
public class MedicationTaskController extends BaseController {
|
||||
|
||||
@Resource
|
||||
private IMedicationTaskService taskService;
|
||||
|
||||
@GetMapping("/list")
|
||||
@ApiOperation("查询服药任务列表")
|
||||
@RequiresPermissions("health:medicationTask:list")
|
||||
public TableDataInfo list(MedicationTaskDto dto) {
|
||||
startPage();
|
||||
List<MedicationTaskVo> list = taskService.selectList(dto);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
@GetMapping("/{id}")
|
||||
@ApiOperation("查询服药任务详情")
|
||||
@RequiresPermissions("health:medicationTask:query")
|
||||
public AjaxResult getInfo(@PathVariable Long id) {
|
||||
return success(taskService.selectById(id));
|
||||
}
|
||||
|
||||
@DeleteMapping("/{ids}")
|
||||
@ApiOperation("删除服药任务")
|
||||
@RequiresPermissions("health:medicationTask:remove")
|
||||
@Log(title = "服药任务", businessType = BusinessType.DELETE)
|
||||
public AjaxResult remove(@PathVariable Long[] ids) {
|
||||
return toAjax(taskService.deleteByIds(ids));
|
||||
}
|
||||
|
||||
@PutMapping("/confirm/{id}")
|
||||
@ApiOperation("确认服药")
|
||||
@RequiresPermissions("health:medicationTask:edit")
|
||||
@Log(title = "服药任务", businessType = BusinessType.UPDATE)
|
||||
public AjaxResult confirm(@PathVariable Long id,
|
||||
@RequestParam(required = false) Integer confirmType,
|
||||
@RequestParam(required = false) String confirmTime) {
|
||||
return toAjax(taskService.confirm(id, confirmType, confirmTime));
|
||||
}
|
||||
|
||||
@PutMapping("/skip/{id}")
|
||||
@ApiOperation("跳过服药")
|
||||
@RequiresPermissions("health:medicationTask:edit")
|
||||
@Log(title = "服药任务", businessType = BusinessType.UPDATE)
|
||||
public AjaxResult skip(@PathVariable Long id, @RequestParam(required = false) String notes) {
|
||||
return toAjax(taskService.skip(id, notes));
|
||||
}
|
||||
|
||||
@PutMapping("/missed/{id}")
|
||||
@ApiOperation("标记漏服")
|
||||
@RequiresPermissions("health:medicationTask:edit")
|
||||
@Log(title = "服药任务", businessType = BusinessType.UPDATE)
|
||||
public AjaxResult missed(@PathVariable Long id, @RequestParam(required = false) String notes) {
|
||||
return toAjax(taskService.markMissed(id, notes));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package com.intc.health.domain;
|
||||
|
||||
import com.intc.common.core.web.domain.BaseEntity;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
/**
|
||||
* 慢性疾病档案对象 chronic_disease_record
|
||||
*
|
||||
* @author bot5
|
||||
* @date 2026-03-19
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ApiModel("慢性疾病档案")
|
||||
public class ChronicDiseaseRecord extends BaseEntity {
|
||||
|
||||
@ApiModelProperty("主键ID")
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty("关联成员ID")
|
||||
private Long personId;
|
||||
|
||||
@ApiModelProperty("关联疾病ID")
|
||||
private Long diseaseId;
|
||||
|
||||
@ApiModelProperty("疾病名称")
|
||||
private String diseaseName;
|
||||
|
||||
@ApiModelProperty("疾病编码(ICD-10标准)")
|
||||
private String diseaseCode;
|
||||
|
||||
@ApiModelProperty("确诊日期")
|
||||
private String diagnosisDate;
|
||||
|
||||
@ApiModelProperty("状态:1-稳定 2-需关注 3-急性期")
|
||||
private Integer diseaseStatus;
|
||||
|
||||
@ApiModelProperty("主治医生")
|
||||
private String mainDoctor;
|
||||
|
||||
@ApiModelProperty("就诊医院")
|
||||
private String hospital;
|
||||
|
||||
@ApiModelProperty("科室")
|
||||
private String department;
|
||||
|
||||
@ApiModelProperty("备注说明")
|
||||
private String notes;
|
||||
|
||||
@ApiModelProperty("是否启用:1-启用 0-禁用")
|
||||
private Integer isActive;
|
||||
|
||||
@ApiModelProperty("删除标记:0-正常 1-删除")
|
||||
private Integer delFlag;
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package com.intc.health.domain;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.intc.common.core.web.domain.BaseEntity;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
|
||||
/**
|
||||
* 用药计划对象 medication_plan
|
||||
*
|
||||
* @author bot5
|
||||
* @date 2026-03-19
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ApiModel("用药计划")
|
||||
public class MedicationPlan extends BaseEntity {
|
||||
|
||||
@ApiModelProperty("主键ID")
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty("关联成员ID")
|
||||
private Long personId;
|
||||
|
||||
@ApiModelProperty("关联慢性疾病ID")
|
||||
private Long chronicDiseaseId;
|
||||
|
||||
@ApiModelProperty("计划名称")
|
||||
private String planName;
|
||||
|
||||
@ApiModelProperty("关联药品ID")
|
||||
private Long medicineId;
|
||||
|
||||
@ApiModelProperty("药品名称")
|
||||
private String medicineName;
|
||||
|
||||
@ApiModelProperty("药品规格")
|
||||
private String specification;
|
||||
|
||||
@ApiModelProperty("单次剂量")
|
||||
private BigDecimal dosagePerTime;
|
||||
|
||||
@ApiModelProperty("剂量单位")
|
||||
private String dosageUnit;
|
||||
|
||||
@ApiModelProperty("频次类型:1-每天 2-每周 3-隔天 4-自定义")
|
||||
private Integer frequencyType;
|
||||
|
||||
@ApiModelProperty("频次配置(JSON格式)")
|
||||
private JsonNode frequencyConfig;
|
||||
|
||||
@ApiModelProperty("服药时段配置")
|
||||
private JsonNode timeSlots;
|
||||
|
||||
@ApiModelProperty("开始日期")
|
||||
private LocalDate startDate;
|
||||
|
||||
@ApiModelProperty("结束日期")
|
||||
private LocalDate endDate;
|
||||
|
||||
@ApiModelProperty("是否开启提醒:1-是 0-否")
|
||||
private Integer remindEnabled;
|
||||
|
||||
@ApiModelProperty("提前提醒分钟数")
|
||||
private Integer remindAdvanceMin;
|
||||
|
||||
@ApiModelProperty("漏服是否通知家属:1-是 0-否")
|
||||
private Integer notifyFamily;
|
||||
|
||||
@ApiModelProperty("通知家属成员ID列表")
|
||||
private JsonNode familyMemberIds;
|
||||
|
||||
@ApiModelProperty("状态:1-执行中 2-已暂停 3-已结束")
|
||||
private Integer status;
|
||||
|
||||
@ApiModelProperty("删除标记:0-正常 1-删除")
|
||||
private Integer delFlag;
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package com.intc.health.domain;
|
||||
|
||||
import com.intc.common.core.web.domain.BaseEntity;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
|
||||
/**
|
||||
* 服药任务对象 medication_task
|
||||
*
|
||||
* @author bot5
|
||||
* @date 2026-03-19
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ApiModel("服药任务")
|
||||
public class MedicationTask extends BaseEntity {
|
||||
|
||||
@ApiModelProperty("主键ID")
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty("关联用药计划ID")
|
||||
private Long planId;
|
||||
|
||||
@ApiModelProperty("关联成员ID")
|
||||
private Long personId;
|
||||
|
||||
@ApiModelProperty("药品名称")
|
||||
private String medicineName;
|
||||
|
||||
@ApiModelProperty("计划服药日期")
|
||||
private LocalDate plannedDate;
|
||||
|
||||
@ApiModelProperty("计划服药时间")
|
||||
private LocalTime plannedTime;
|
||||
|
||||
@ApiModelProperty("计划剂量")
|
||||
private BigDecimal plannedDosage;
|
||||
|
||||
@ApiModelProperty("实际服药时间")
|
||||
private LocalDateTime actualTime;
|
||||
|
||||
@ApiModelProperty("实际剂量")
|
||||
private BigDecimal actualDosage;
|
||||
|
||||
@ApiModelProperty("状态:0-待服药 1-已服药 2-漏服 3-跳过")
|
||||
private Integer status;
|
||||
|
||||
@ApiModelProperty("确认方式:1-用户确认 2-家属代确认 3-系统自动")
|
||||
private Integer confirmType;
|
||||
|
||||
@ApiModelProperty("备注(如漏服原因)")
|
||||
private String notes;
|
||||
|
||||
@ApiModelProperty("提醒状态:0-未提醒 1-已提醒 2-已超时提醒")
|
||||
private Integer remindStatus;
|
||||
|
||||
@ApiModelProperty("提醒时间")
|
||||
private LocalDateTime remindTime;
|
||||
|
||||
@ApiModelProperty("删除标记:0-正常 1-删除")
|
||||
private Integer delFlag;
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.intc.health.domain.dto;
|
||||
|
||||
import lombok.Data;
|
||||
import java.io.Serializable;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 慢性疾病档案Dto对象 chronic_disease_record
|
||||
*
|
||||
* @author bot5
|
||||
* @date 2026-03-17
|
||||
*/
|
||||
@ApiModel("慢性疾病档案Dto对象")
|
||||
@Data
|
||||
public class ChronicDiseaseRecordDto implements Serializable
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 关联成员ID */
|
||||
@ApiModelProperty(value = "关联成员ID")
|
||||
private Long personId;
|
||||
|
||||
/** 疾病名称 */
|
||||
@ApiModelProperty(value = "疾病名称")
|
||||
private String diseaseName;
|
||||
|
||||
/** 疾病编码 */
|
||||
@ApiModelProperty(value = "疾病编码")
|
||||
private String diseaseCode;
|
||||
|
||||
/** 状态:1-稳定 2-需关注 3-急性期 */
|
||||
@ApiModelProperty(value = "状态")
|
||||
private Integer diseaseStatus;
|
||||
|
||||
/** 是否启用 */
|
||||
@ApiModelProperty(value = "是否启用")
|
||||
private Integer isActive;
|
||||
|
||||
/** 确诊日期-开始 */
|
||||
@ApiModelProperty(value = "确诊日期-开始")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||
private Date diagnosisDateStart;
|
||||
|
||||
/** 确诊日期-结束 */
|
||||
@ApiModelProperty(value = "确诊日期-结束")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||
private Date diagnosisDateEnd;
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.intc.health.domain.dto;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 依从性统计查询DTO
|
||||
*
|
||||
* @author bot5
|
||||
* @date 2026-03-19
|
||||
*/
|
||||
@Data
|
||||
@ApiModel("依从性统计查询DTO")
|
||||
public class MedicationAdherenceDto {
|
||||
|
||||
@ApiModelProperty("人员ID")
|
||||
private Long personId;
|
||||
|
||||
@ApiModelProperty("计划ID")
|
||||
private Long planId;
|
||||
|
||||
@ApiModelProperty("开始日期(yyyy-MM-dd)")
|
||||
private String startDate;
|
||||
|
||||
@ApiModelProperty("结束日期(yyyy-MM-dd)")
|
||||
private String endDate;
|
||||
|
||||
@ApiModelProperty("统计类型:day-日,week-周,month-月,quarter-季度")
|
||||
private String statType;
|
||||
|
||||
@ApiModelProperty("药品ID")
|
||||
private Long medicineId;
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package com.intc.health.domain.dto;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
|
||||
/**
|
||||
* 用药计划查询DTO
|
||||
*
|
||||
* @author bot5
|
||||
* @date 2026-03-19
|
||||
*/
|
||||
@Data
|
||||
@ApiModel("用药计划查询DTO")
|
||||
public class MedicationPlanDto {
|
||||
|
||||
@ApiModelProperty("主键ID")
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty("关联成员ID")
|
||||
private Long personId;
|
||||
|
||||
@ApiModelProperty("关联慢性疾病ID")
|
||||
private Long chronicDiseaseId;
|
||||
|
||||
@ApiModelProperty("计划名称")
|
||||
private String planName;
|
||||
|
||||
@ApiModelProperty("关联药品ID")
|
||||
private Long medicineId;
|
||||
|
||||
@ApiModelProperty("药品名称")
|
||||
private String medicineName;
|
||||
|
||||
@ApiModelProperty("状态:1-执行中 2-已暂停 3-已结束")
|
||||
private Integer status;
|
||||
|
||||
@ApiModelProperty("开始日期-起")
|
||||
private String startDateBegin;
|
||||
|
||||
@ApiModelProperty("开始日期-止")
|
||||
private String startDateEnd;
|
||||
|
||||
@ApiModelProperty("结束日期-起")
|
||||
private String endDateBegin;
|
||||
|
||||
@ApiModelProperty("结束日期-止")
|
||||
private String endDateEnd;
|
||||
|
||||
@ApiModelProperty("关键字搜索")
|
||||
private String keyword;
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.intc.health.domain.dto;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDate;
|
||||
|
||||
/**
|
||||
* 服药任务查询DTO
|
||||
*
|
||||
* @author bot5
|
||||
* @date 2026-03-19
|
||||
*/
|
||||
@Data
|
||||
@ApiModel("服药任务查询DTO")
|
||||
public class MedicationTaskDto {
|
||||
|
||||
@ApiModelProperty("关联用药计划ID")
|
||||
private Long planId;
|
||||
|
||||
@ApiModelProperty("关联成员ID")
|
||||
private Long personId;
|
||||
|
||||
@ApiModelProperty("药品名称")
|
||||
private String medicineName;
|
||||
|
||||
@ApiModelProperty("计划服药日期-起")
|
||||
private String plannedDateBegin;
|
||||
|
||||
@ApiModelProperty("计划服药日期-止")
|
||||
private String plannedDateEnd;
|
||||
|
||||
@ApiModelProperty("状态:0-待服药 1-已服药 2-漏服 3-跳过")
|
||||
private Integer status;
|
||||
|
||||
@ApiModelProperty("查询日期(yyyy-MM-dd)")
|
||||
private String queryDate;
|
||||
|
||||
@ApiModelProperty("关键字搜索")
|
||||
private String keyword;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.intc.health.domain.vo;
|
||||
|
||||
import com.intc.health.domain.ChronicDiseaseRecord;
|
||||
import lombok.Data;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
|
||||
/**
|
||||
* 慢性疾病档案Vo对象 chronic_disease_record
|
||||
*
|
||||
* @author bot5
|
||||
* @date 2026-03-17
|
||||
*/
|
||||
@ApiModel("慢性疾病档案Vo对象")
|
||||
@Data
|
||||
public class ChronicDiseaseRecordVo extends ChronicDiseaseRecord
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 成员姓名(来自health_person表) */
|
||||
private String personName;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.intc.health.domain.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 每日依从性统计VO
|
||||
*
|
||||
* @author bot5
|
||||
* @date 2026-03-19
|
||||
*/
|
||||
@Data
|
||||
@ApiModel("每日依从性统计VO")
|
||||
public class DailyAdherenceVo {
|
||||
|
||||
@ApiModelProperty("日期")
|
||||
private String date;
|
||||
|
||||
@ApiModelProperty("总任务数")
|
||||
private Integer totalTasks;
|
||||
|
||||
@ApiModelProperty("已服药数")
|
||||
private Integer completedTasks;
|
||||
|
||||
@ApiModelProperty("漏服数")
|
||||
private Integer missedTasks;
|
||||
|
||||
@ApiModelProperty("跳过数")
|
||||
private Integer skippedTasks;
|
||||
|
||||
@ApiModelProperty("准时服药数")
|
||||
private Integer ontimeTasks;
|
||||
|
||||
@ApiModelProperty("服药率(%)")
|
||||
private BigDecimal adherenceRate;
|
||||
|
||||
@ApiModelProperty("准时率(%)")
|
||||
private BigDecimal ontimeRate;
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package com.intc.health.domain.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 依从性统计VO
|
||||
*
|
||||
* @author bot5
|
||||
* @date 2026-03-19
|
||||
*/
|
||||
@Data
|
||||
@ApiModel("依从性统计VO")
|
||||
public class MedicationAdherenceVo {
|
||||
|
||||
@ApiModelProperty("总任务数")
|
||||
private Integer totalTasks;
|
||||
|
||||
@ApiModelProperty("已服药数")
|
||||
private Integer completedTasks;
|
||||
|
||||
@ApiModelProperty("漏服数")
|
||||
private Integer missedTasks;
|
||||
|
||||
@ApiModelProperty("跳过数")
|
||||
private Integer skippedTasks;
|
||||
|
||||
@ApiModelProperty("待服用数")
|
||||
private Integer pendingTasks;
|
||||
|
||||
@ApiModelProperty("准时服药数")
|
||||
private Integer ontimeTasks;
|
||||
|
||||
@ApiModelProperty("服药率(%)")
|
||||
private BigDecimal adherenceRate;
|
||||
|
||||
@ApiModelProperty("准时率(%)")
|
||||
private BigDecimal ontimeRate;
|
||||
|
||||
@ApiModelProperty("统计开始日期")
|
||||
private String startDate;
|
||||
|
||||
@ApiModelProperty("统计结束日期")
|
||||
private String endDate;
|
||||
|
||||
@ApiModelProperty("人员ID")
|
||||
private Long personId;
|
||||
|
||||
@ApiModelProperty("人员名称")
|
||||
private String personName;
|
||||
|
||||
@ApiModelProperty("计划ID")
|
||||
private Long planId;
|
||||
|
||||
@ApiModelProperty("计划名称")
|
||||
private String planName;
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
package com.intc.health.domain.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 用药计划VO
|
||||
*
|
||||
* @author bot5
|
||||
* @date 2026-03-19
|
||||
*/
|
||||
@Data
|
||||
@ApiModel("用药计划VO")
|
||||
public class MedicationPlanVo {
|
||||
|
||||
@ApiModelProperty("主键ID")
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty("关联成员ID")
|
||||
private Long personId;
|
||||
|
||||
@ApiModelProperty("成员名称")
|
||||
private String personName;
|
||||
|
||||
@ApiModelProperty("关联慢性疾病ID")
|
||||
private Long chronicDiseaseId;
|
||||
|
||||
@ApiModelProperty("慢性疾病名称")
|
||||
private String chronicDiseaseName;
|
||||
|
||||
@ApiModelProperty("计划名称")
|
||||
private String planName;
|
||||
|
||||
@ApiModelProperty("关联药品ID")
|
||||
private Long medicineId;
|
||||
|
||||
@ApiModelProperty("药品名称")
|
||||
private String medicineName;
|
||||
|
||||
@ApiModelProperty("药品规格")
|
||||
private String specification;
|
||||
|
||||
@ApiModelProperty("单次剂量")
|
||||
private BigDecimal dosagePerTime;
|
||||
|
||||
@ApiModelProperty("剂量单位")
|
||||
private String dosageUnit;
|
||||
|
||||
@ApiModelProperty("频次类型:1-每天 2-每周 3-隔天 4-自定义")
|
||||
private Integer frequencyType;
|
||||
|
||||
@ApiModelProperty("频次配置(JSON格式)")
|
||||
private JsonNode frequencyConfig;
|
||||
|
||||
@ApiModelProperty("服药时段配置")
|
||||
private JsonNode timeSlots;
|
||||
|
||||
@ApiModelProperty("开始日期")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||
private Date startDate;
|
||||
|
||||
@ApiModelProperty("结束日期")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||
private Date endDate;
|
||||
|
||||
@ApiModelProperty("是否开启提醒:1-是 0-否")
|
||||
private Integer remindEnabled;
|
||||
|
||||
@ApiModelProperty("提前提醒分钟数")
|
||||
private Integer remindAdvanceMin;
|
||||
|
||||
@ApiModelProperty("漏服是否通知家属:1-是 0-否")
|
||||
private Integer notifyFamily;
|
||||
|
||||
@ApiModelProperty("通知家属成员ID列表")
|
||||
private JsonNode familyMemberIds;
|
||||
|
||||
@ApiModelProperty("状态:1-执行中 2-已暂停 3-已结束")
|
||||
private Integer status;
|
||||
|
||||
@ApiModelProperty("今日任务统计")
|
||||
private Integer todayTotal;
|
||||
|
||||
@ApiModelProperty("今日已完成")
|
||||
private Integer todayCompleted;
|
||||
|
||||
@ApiModelProperty("创建时间")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date createTime;
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package com.intc.health.domain.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 服药任务VO
|
||||
*
|
||||
* @author bot5
|
||||
* @date 2026-03-19
|
||||
*/
|
||||
@Data
|
||||
@ApiModel("服药任务VO")
|
||||
public class MedicationTaskVo {
|
||||
|
||||
@ApiModelProperty("主键ID")
|
||||
private Long id;
|
||||
|
||||
@ApiModelProperty("关联用药计划ID")
|
||||
private Long planId;
|
||||
|
||||
@ApiModelProperty("计划名称")
|
||||
private String planName;
|
||||
|
||||
@ApiModelProperty("关联成员ID")
|
||||
private Long personId;
|
||||
|
||||
@ApiModelProperty("成员名称")
|
||||
private String personName;
|
||||
|
||||
@ApiModelProperty("药品名称")
|
||||
private String medicineName;
|
||||
|
||||
@ApiModelProperty("计划服药日期")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||
private Date plannedDate;
|
||||
|
||||
@ApiModelProperty("计划服药时间")
|
||||
@JsonFormat(pattern = "HH:mm:ss")
|
||||
private Date plannedTime;
|
||||
|
||||
@ApiModelProperty("计划剂量")
|
||||
private BigDecimal plannedDosage;
|
||||
|
||||
@ApiModelProperty("实际服药时间")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date actualTime;
|
||||
|
||||
@ApiModelProperty("实际剂量")
|
||||
private BigDecimal actualDosage;
|
||||
|
||||
@ApiModelProperty("状态:0-待服药 1-已服药 2-漏服 3-跳过")
|
||||
private Integer status;
|
||||
|
||||
@ApiModelProperty("状态名称")
|
||||
private String statusName;
|
||||
|
||||
@ApiModelProperty("确认方式:1-用户确认 2-家属代确认 3-系统自动")
|
||||
private Integer confirmType;
|
||||
|
||||
@ApiModelProperty("备注(如漏服原因)")
|
||||
private String notes;
|
||||
|
||||
@ApiModelProperty("提醒状态:0-未提醒 1-已提醒 2-已超时提醒")
|
||||
private Integer remindStatus;
|
||||
|
||||
@ApiModelProperty("提醒时间")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date remindTime;
|
||||
|
||||
@ApiModelProperty("创建时间")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date createTime;
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
package com.intc.health.mapper;
|
||||
|
||||
import com.intc.common.datascope.annotation.DataScope;
|
||||
import java.util.List;
|
||||
import com.intc.health.domain.vo.ChronicDiseaseRecordVo;
|
||||
import com.intc.health.domain.dto.ChronicDiseaseRecordDto;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
/**
|
||||
* 慢性疾病档案Mapper接口
|
||||
*
|
||||
* @author bot5
|
||||
* @date 2026-03-17
|
||||
*/
|
||||
public interface ChronicDiseaseRecordMapper
|
||||
{
|
||||
/**
|
||||
* 查询慢性疾病档案
|
||||
*
|
||||
* @param id 慢性疾病档案主键
|
||||
* @return 慢性疾病档案
|
||||
*/
|
||||
public ChronicDiseaseRecordVo selectChronicDiseaseRecordById(Long id);
|
||||
|
||||
/**
|
||||
* 查询慢性疾病档案列表
|
||||
*
|
||||
* @param chronicDiseaseRecordDto 慢性疾病档案
|
||||
* @return 慢性疾病档案集合
|
||||
*/
|
||||
@DataScope(businessAlias = "a")
|
||||
public List<ChronicDiseaseRecordVo> selectChronicDiseaseRecordList(ChronicDiseaseRecordDto chronicDiseaseRecordDto);
|
||||
|
||||
/**
|
||||
* 根据成员ID查询慢性疾病档案列表
|
||||
*
|
||||
* @param memberId 成员ID
|
||||
* @return 慢性疾病档案集合
|
||||
*/
|
||||
public List<ChronicDiseaseRecordVo> selectChronicDiseaseRecordByMemberId(Long memberId);
|
||||
|
||||
/**
|
||||
* 新增慢性疾病档案
|
||||
*
|
||||
* @param chronicDiseaseRecord 慢性疾病档案
|
||||
* @return 结果
|
||||
*/
|
||||
public int insertChronicDiseaseRecord(com.intc.health.domain.ChronicDiseaseRecord chronicDiseaseRecord);
|
||||
|
||||
/**
|
||||
* 修改慢性疾病档案
|
||||
*
|
||||
* @param chronicDiseaseRecord 慢性疾病档案
|
||||
* @return 结果
|
||||
*/
|
||||
public int updateChronicDiseaseRecord(com.intc.health.domain.ChronicDiseaseRecord chronicDiseaseRecord);
|
||||
|
||||
/**
|
||||
* 删除慢性疾病档案
|
||||
*
|
||||
* @param id 慢性疾病档案主键
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteChronicDiseaseRecordById(Long id);
|
||||
|
||||
/**
|
||||
* 批量删除慢性疾病档案
|
||||
*
|
||||
* @param ids 需要删除的数据主键集合
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteChronicDiseaseRecordByIds(Long[] ids);
|
||||
|
||||
/**
|
||||
* 逻辑删除慢性疾病档案
|
||||
*
|
||||
* @param id 慢性疾病档案主键
|
||||
* @return 结果
|
||||
*/
|
||||
public int removeChronicDiseaseRecordById(Long id);
|
||||
|
||||
/**
|
||||
* 批量逻辑删除慢性疾病档案
|
||||
*
|
||||
* @param ids 需要删除的数据主键集合
|
||||
* @return 结果
|
||||
*/
|
||||
public int removeChronicDiseaseRecordByIds(Long[] ids);
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package com.intc.health.mapper;
|
||||
|
||||
import com.intc.common.datascope.annotation.DataScope;
|
||||
import com.intc.health.domain.MedicationPlan;
|
||||
import com.intc.health.domain.dto.MedicationPlanDto;
|
||||
import com.intc.health.domain.vo.MedicationPlanVo;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 用药计划Mapper接口
|
||||
*
|
||||
* @author bot5
|
||||
* @date 2026-03-19
|
||||
*/
|
||||
public interface MedicationPlanMapper {
|
||||
|
||||
/**
|
||||
* 查询用药计划
|
||||
*/
|
||||
MedicationPlanVo selectById(Long id);
|
||||
|
||||
/**
|
||||
* 查询用药计划列表
|
||||
*/
|
||||
@DataScope(businessAlias = "a")
|
||||
List<MedicationPlanVo> selectList(MedicationPlanDto dto);
|
||||
|
||||
/**
|
||||
* 查询执行中的用药计划列表(用于生成任务)
|
||||
*/
|
||||
List<MedicationPlanVo> selectActiveList();
|
||||
|
||||
/**
|
||||
* 新增用药计划
|
||||
*/
|
||||
int insert(MedicationPlan plan);
|
||||
|
||||
/**
|
||||
* 修改用药计划
|
||||
*/
|
||||
int update(MedicationPlan plan);
|
||||
|
||||
/**
|
||||
* 删除用药计划
|
||||
*/
|
||||
int deleteById(Long id);
|
||||
|
||||
/**
|
||||
* 批量删除用药计划
|
||||
*/
|
||||
int deleteByIds(Long[] ids);
|
||||
|
||||
/**
|
||||
* 逻辑删除用药计划
|
||||
*/
|
||||
int removeById(Long id);
|
||||
|
||||
/**
|
||||
* 批量逻辑删除用药计划
|
||||
*/
|
||||
int removeByIds(Long[] ids);
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
package com.intc.health.mapper;
|
||||
|
||||
import com.intc.common.datascope.annotation.DataScope;
|
||||
import com.intc.health.domain.MedicationTask;
|
||||
import com.intc.health.domain.dto.MedicationTaskDto;
|
||||
import com.intc.health.domain.vo.MedicationTaskVo;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 服药任务Mapper接口
|
||||
*
|
||||
* @author bot5
|
||||
* @date 2026-03-19
|
||||
*/
|
||||
public interface MedicationTaskMapper {
|
||||
|
||||
/**
|
||||
* 查询服药任务
|
||||
*/
|
||||
MedicationTaskVo selectById(Long id);
|
||||
|
||||
/**
|
||||
* 查询服药任务列表
|
||||
*/
|
||||
@DataScope(businessAlias = "a")
|
||||
List<MedicationTaskVo> selectList(MedicationTaskDto dto);
|
||||
|
||||
/**
|
||||
* 新增服药任务
|
||||
*/
|
||||
int insert(MedicationTask task);
|
||||
|
||||
/**
|
||||
* 批量新增服药任务
|
||||
*/
|
||||
int batchInsert(List<MedicationTask> tasks);
|
||||
|
||||
/**
|
||||
* 修改服药任务
|
||||
*/
|
||||
int update(MedicationTask task);
|
||||
|
||||
/**
|
||||
* 删除服药任务
|
||||
*/
|
||||
int deleteById(Long id);
|
||||
|
||||
/**
|
||||
* 批量删除服药任务
|
||||
*/
|
||||
int deleteByIds(Long[] ids);
|
||||
|
||||
/**
|
||||
* 逻辑删除服药任务
|
||||
*/
|
||||
int removeById(Long id);
|
||||
|
||||
/**
|
||||
* 批量逻辑删除服药任务
|
||||
*/
|
||||
int removeByIds(Long[] ids);
|
||||
|
||||
/**
|
||||
* 统计某计划某天的任务数
|
||||
*/
|
||||
int countByPlanAndDate(@Param("planId") Long planId, @Param("date") LocalDate date);
|
||||
|
||||
/**
|
||||
* 删除某计划某天的所有任务(用于重新生成时清理旧数据)
|
||||
*/
|
||||
int deleteByPlanAndDate(@Param("planId") Long planId, @Param("date") LocalDate date);
|
||||
|
||||
/**
|
||||
* 统计某计划某天的已服药数
|
||||
*/
|
||||
int countCompletedByPlanAndDate(@Param("planId") Long planId, @Param("date") LocalDate date);
|
||||
|
||||
/**
|
||||
* 标记过期任务(超过24小时未服药)
|
||||
*/
|
||||
int markExpired(@Param("expireThreshold") LocalDateTime threshold);
|
||||
|
||||
/**
|
||||
* 查询待提醒的任务
|
||||
*/
|
||||
List<MedicationTaskVo> selectPendingRemind(@Param("startTime") LocalDateTime startTime, @Param("endTime") LocalDateTime endTime);
|
||||
|
||||
// ========== 依从性统计 ==========
|
||||
|
||||
/**
|
||||
* 获取总体统计
|
||||
*/
|
||||
java.util.Map<String, Object> getOverallStats(@Param("personId") Long personId,
|
||||
@Param("startDate") LocalDate startDate,
|
||||
@Param("endDate") LocalDate endDate);
|
||||
|
||||
/**
|
||||
* 获取每日统计
|
||||
*/
|
||||
List<java.util.Map<String, Object>> getDailyStats(@Param("personId") Long personId,
|
||||
@Param("startDate") LocalDate startDate,
|
||||
@Param("endDate") LocalDate endDate);
|
||||
|
||||
/**
|
||||
* 获取时段统计
|
||||
*/
|
||||
List<java.util.Map<String, Object>> getTimeSlotStats(@Param("personId") Long personId,
|
||||
@Param("startDate") LocalDate startDate,
|
||||
@Param("endDate") LocalDate endDate);
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
package com.intc.health.service;
|
||||
|
||||
import java.util.List;
|
||||
import com.intc.health.domain.ChronicDiseaseRecord;
|
||||
import com.intc.health.domain.dto.ChronicDiseaseRecordDto;
|
||||
import com.intc.health.domain.vo.ChronicDiseaseRecordVo;
|
||||
|
||||
/**
|
||||
* 慢性疾病档案Service接口
|
||||
*
|
||||
* @author bot5
|
||||
* @date 2026-03-17
|
||||
*/
|
||||
public interface IChronicDiseaseRecordService
|
||||
{
|
||||
/**
|
||||
* 查询慢性疾病档案
|
||||
*
|
||||
* @param id 慢性疾病档案主键
|
||||
* @return 慢性疾病档案
|
||||
*/
|
||||
public ChronicDiseaseRecordVo selectChronicDiseaseRecordById(Long id);
|
||||
|
||||
/**
|
||||
* 查询慢性疾病档案列表
|
||||
*
|
||||
* @param chronicDiseaseRecordDto 慢性疾病档案
|
||||
* @return 慢性疾病档案集合
|
||||
*/
|
||||
public List<ChronicDiseaseRecordVo> selectChronicDiseaseRecordList(ChronicDiseaseRecordDto chronicDiseaseRecordDto);
|
||||
|
||||
/**
|
||||
* 根据成员ID查询慢性疾病档案列表
|
||||
*
|
||||
* @param memberId 成员ID
|
||||
* @return 慢性疾病档案集合
|
||||
*/
|
||||
public List<ChronicDiseaseRecordVo> selectChronicDiseaseRecordByMemberId(Long memberId);
|
||||
|
||||
/**
|
||||
* 新增慢性疾病档案
|
||||
*
|
||||
* @param chronicDiseaseRecord 慢性疾病档案
|
||||
* @return 结果
|
||||
*/
|
||||
public int insertChronicDiseaseRecord(ChronicDiseaseRecord chronicDiseaseRecord);
|
||||
|
||||
/**
|
||||
* 修改慢性疾病档案
|
||||
*
|
||||
* @param chronicDiseaseRecord 慢性疾病档案
|
||||
* @return 结果
|
||||
*/
|
||||
public int updateChronicDiseaseRecord(ChronicDiseaseRecord chronicDiseaseRecord);
|
||||
|
||||
/**
|
||||
* 批量删除慢性疾病档案
|
||||
*
|
||||
* @param ids 需要删除的慢性疾病档案主键集合
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteChronicDiseaseRecordByIds(Long[] ids);
|
||||
|
||||
/**
|
||||
* 删除慢性疾病档案信息
|
||||
*
|
||||
* @param id 慢性疾病档案主键
|
||||
* @return 结果
|
||||
*/
|
||||
public int deleteChronicDiseaseRecordById(Long id);
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.intc.health.service;
|
||||
|
||||
import com.intc.health.domain.vo.DailyAdherenceVo;
|
||||
import com.intc.health.domain.vo.MedicationAdherenceVo;
|
||||
|
||||
import java.time.LocalDate;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 依从性统计Service接口
|
||||
*
|
||||
* @author bot5
|
||||
* @date 2026-03-19
|
||||
*/
|
||||
public interface IMedicationAdherenceService {
|
||||
|
||||
/**
|
||||
* 获取总体依从性统计
|
||||
*/
|
||||
MedicationAdherenceVo getOverallAdherence(Long memberId, LocalDate startDate, LocalDate endDate);
|
||||
|
||||
/**
|
||||
* 获取每日依从性统计列表
|
||||
*/
|
||||
List<DailyAdherenceVo> getDailyAdherenceList(Long memberId, LocalDate startDate, LocalDate endDate);
|
||||
|
||||
/**
|
||||
* 获取日历视图数据
|
||||
*/
|
||||
List<DailyAdherenceVo> getCalendarData(Long memberId, String yearMonth);
|
||||
|
||||
/**
|
||||
* 获取各时段服药统计
|
||||
*/
|
||||
Map<String, MedicationAdherenceVo> getTimeSlotAdherence(Long memberId, LocalDate startDate, LocalDate endDate);
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package com.intc.health.service;
|
||||
|
||||
import com.intc.health.domain.MedicationPlan;
|
||||
import com.intc.health.domain.dto.MedicationPlanDto;
|
||||
import com.intc.health.domain.vo.MedicationPlanVo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 用药计划Service接口
|
||||
*
|
||||
* @author bot5
|
||||
* @date 2026-03-19
|
||||
*/
|
||||
public interface IMedicationPlanService {
|
||||
|
||||
/**
|
||||
* 查询用药计划
|
||||
*/
|
||||
MedicationPlanVo selectById(Long id);
|
||||
|
||||
/**
|
||||
* 查询用药计划列表
|
||||
*/
|
||||
List<MedicationPlanVo> selectList(MedicationPlanDto dto);
|
||||
|
||||
/**
|
||||
* 新增用药计划
|
||||
*/
|
||||
int insert(MedicationPlan plan);
|
||||
|
||||
/**
|
||||
* 修改用药计划
|
||||
*/
|
||||
int update(MedicationPlan plan);
|
||||
|
||||
/**
|
||||
* 删除用药计划
|
||||
*/
|
||||
int deleteByIds(Long[] ids);
|
||||
|
||||
/**
|
||||
* 暂停用药计划
|
||||
*/
|
||||
int pause(Long id);
|
||||
|
||||
/**
|
||||
* 恢复用药计划
|
||||
*/
|
||||
int resume(Long id);
|
||||
|
||||
/**
|
||||
* 结束用药计划
|
||||
*/
|
||||
int end(Long id);
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package com.intc.health.service;
|
||||
|
||||
import com.intc.health.domain.MedicationTask;
|
||||
import com.intc.health.domain.dto.MedicationTaskDto;
|
||||
import com.intc.health.domain.vo.MedicationTaskVo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 服药任务Service接口
|
||||
*
|
||||
* @author bot5
|
||||
* @date 2026-03-19
|
||||
*/
|
||||
public interface IMedicationTaskService {
|
||||
|
||||
/**
|
||||
* 查询服药任务
|
||||
*/
|
||||
MedicationTaskVo selectById(Long id);
|
||||
|
||||
/**
|
||||
* 查询服药任务列表
|
||||
*/
|
||||
List<MedicationTaskVo> selectList(MedicationTaskDto dto);
|
||||
|
||||
/**
|
||||
* 新增服药任务
|
||||
*/
|
||||
int insert(MedicationTask task);
|
||||
|
||||
/**
|
||||
* 修改服药任务
|
||||
*/
|
||||
int update(MedicationTask task);
|
||||
|
||||
/**
|
||||
* 删除服药任务
|
||||
*/
|
||||
int deleteByIds(Long[] ids);
|
||||
|
||||
/**
|
||||
* 确认服药
|
||||
*/
|
||||
int confirm(Long id, Integer confirmType, String confirmTime);
|
||||
|
||||
/**
|
||||
* 跳过服药
|
||||
*/
|
||||
int skip(Long id, String notes);
|
||||
|
||||
/**
|
||||
* 标记漏服
|
||||
*/
|
||||
int markMissed(Long id, String notes);
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
package com.intc.health.service.impl;
|
||||
|
||||
import com.intc.common.core.utils.DateUtils;
|
||||
import com.intc.common.core.utils.IdWorker;
|
||||
import com.intc.common.security.utils.SecurityUtils;
|
||||
import com.intc.health.domain.ChronicDiseaseRecord;
|
||||
import com.intc.health.domain.dto.ChronicDiseaseRecordDto;
|
||||
import com.intc.health.domain.vo.ChronicDiseaseRecordVo;
|
||||
import com.intc.health.mapper.ChronicDiseaseRecordMapper;
|
||||
import com.intc.health.service.IChronicDiseaseRecordService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 慢性疾病档案Service业务层处理
|
||||
*
|
||||
* @author bot5
|
||||
* @date 2026-03-17
|
||||
*/
|
||||
@Service
|
||||
public class ChronicDiseaseRecordServiceImpl implements IChronicDiseaseRecordService
|
||||
{
|
||||
@Resource
|
||||
private ChronicDiseaseRecordMapper chronicDiseaseRecordMapper;
|
||||
|
||||
/**
|
||||
* 查询慢性疾病档案
|
||||
*
|
||||
* @param id 慢性疾病档案主键
|
||||
* @return 慢性疾病档案
|
||||
*/
|
||||
@Override
|
||||
public ChronicDiseaseRecordVo selectChronicDiseaseRecordById(Long id)
|
||||
{
|
||||
return chronicDiseaseRecordMapper.selectChronicDiseaseRecordById(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询慢性疾病档案列表
|
||||
*
|
||||
* @param chronicDiseaseRecordDto 慢性疾病档案
|
||||
* @return 慢性疾病档案
|
||||
*/
|
||||
@Override
|
||||
public List<ChronicDiseaseRecordVo> selectChronicDiseaseRecordList(ChronicDiseaseRecordDto chronicDiseaseRecordDto)
|
||||
{
|
||||
return chronicDiseaseRecordMapper.selectChronicDiseaseRecordList(chronicDiseaseRecordDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据成员ID查询慢性疾病档案列表
|
||||
*
|
||||
* @param memberId 成员ID
|
||||
* @return 慢性疾病档案集合
|
||||
*/
|
||||
@Override
|
||||
public List<ChronicDiseaseRecordVo> selectChronicDiseaseRecordByMemberId(Long memberId)
|
||||
{
|
||||
return chronicDiseaseRecordMapper.selectChronicDiseaseRecordByMemberId(memberId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增慢性疾病档案
|
||||
*
|
||||
* @param chronicDiseaseRecord 慢性疾病档案
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int insertChronicDiseaseRecord(ChronicDiseaseRecord chronicDiseaseRecord)
|
||||
{
|
||||
chronicDiseaseRecord.setCreateBy(SecurityUtils.getUsername());
|
||||
chronicDiseaseRecord.setCreateTime(DateUtils.getNowDate());
|
||||
chronicDiseaseRecord.setId(IdWorker.getId());
|
||||
// 默认启用
|
||||
if (chronicDiseaseRecord.getIsActive() == null) {
|
||||
chronicDiseaseRecord.setIsActive(1);
|
||||
}
|
||||
// 默认状态为稳定
|
||||
if (chronicDiseaseRecord.getDiseaseStatus() == null) {
|
||||
chronicDiseaseRecord.setDiseaseStatus(1);
|
||||
}
|
||||
return chronicDiseaseRecordMapper.insertChronicDiseaseRecord(chronicDiseaseRecord);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改慢性疾病档案
|
||||
*
|
||||
* @param chronicDiseaseRecord 慢性疾病档案
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int updateChronicDiseaseRecord(ChronicDiseaseRecord chronicDiseaseRecord)
|
||||
{
|
||||
chronicDiseaseRecord.setUpdateBy(SecurityUtils.getUsername());
|
||||
chronicDiseaseRecord.setUpdateTime(DateUtils.getNowDate());
|
||||
return chronicDiseaseRecordMapper.updateChronicDiseaseRecord(chronicDiseaseRecord);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除慢性疾病档案
|
||||
*
|
||||
* @param ids 需要删除的慢性疾病档案主键
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int deleteChronicDiseaseRecordByIds(Long[] ids)
|
||||
{
|
||||
return chronicDiseaseRecordMapper.removeChronicDiseaseRecordByIds(ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除慢性疾病档案信息
|
||||
*
|
||||
* @param id 慢性疾病档案主键
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int deleteChronicDiseaseRecordById(Long id)
|
||||
{
|
||||
return chronicDiseaseRecordMapper.removeChronicDiseaseRecordById(id);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,203 @@
|
||||
package com.intc.health.service.impl;
|
||||
|
||||
import com.intc.health.mapper.MedicationTaskMapper;
|
||||
import com.intc.health.service.IMedicationAdherenceService;
|
||||
import com.intc.health.domain.vo.MedicationAdherenceVo;
|
||||
import com.intc.health.domain.vo.DailyAdherenceVo;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.time.LocalDate;
|
||||
import java.time.YearMonth;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 依从性统计Service实现
|
||||
*
|
||||
* @author bot5
|
||||
* @date 2026-03-19
|
||||
*/
|
||||
@Service
|
||||
public class MedicationAdherenceServiceImpl implements IMedicationAdherenceService {
|
||||
|
||||
@Resource
|
||||
private MedicationTaskMapper taskMapper;
|
||||
|
||||
@Override
|
||||
public MedicationAdherenceVo getOverallAdherence(Long memberId, LocalDate startDate, LocalDate endDate) {
|
||||
Map<String, Object> stats = taskMapper.getOverallStats(memberId, startDate, endDate);
|
||||
|
||||
MedicationAdherenceVo vo = new MedicationAdherenceVo();
|
||||
vo.setTotalTasks(getIntValue(stats, "total_tasks"));
|
||||
vo.setCompletedTasks(getIntValue(stats, "completed_tasks"));
|
||||
vo.setMissedTasks(getIntValue(stats, "missed_tasks"));
|
||||
vo.setSkippedTasks(getIntValue(stats, "skipped_tasks"));
|
||||
vo.setPendingTasks(getIntValue(stats, "pending_tasks"));
|
||||
vo.setOntimeTasks(getIntValue(stats, "ontime_tasks"));
|
||||
|
||||
// 计算服药率
|
||||
if (vo.getTotalTasks() > 0) {
|
||||
BigDecimal rate = BigDecimal.valueOf(vo.getCompletedTasks())
|
||||
.multiply(BigDecimal.valueOf(100))
|
||||
.divide(BigDecimal.valueOf(vo.getTotalTasks()), 2, RoundingMode.HALF_UP);
|
||||
vo.setAdherenceRate(rate);
|
||||
} else {
|
||||
vo.setAdherenceRate(BigDecimal.ZERO);
|
||||
}
|
||||
|
||||
// 计算准时率
|
||||
if (vo.getCompletedTasks() > 0) {
|
||||
BigDecimal rate = BigDecimal.valueOf(vo.getOntimeTasks())
|
||||
.multiply(BigDecimal.valueOf(100))
|
||||
.divide(BigDecimal.valueOf(vo.getCompletedTasks()), 2, RoundingMode.HALF_UP);
|
||||
vo.setOntimeRate(rate);
|
||||
} else {
|
||||
vo.setOntimeRate(BigDecimal.ZERO);
|
||||
}
|
||||
|
||||
return vo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DailyAdherenceVo> getDailyAdherenceList(Long memberId, LocalDate startDate, LocalDate endDate) {
|
||||
List<Map<String, Object>> dailyStats = taskMapper.getDailyStats(memberId, startDate, endDate);
|
||||
|
||||
List<DailyAdherenceVo> result = new ArrayList<>();
|
||||
for (Map<String, Object> stat : dailyStats) {
|
||||
DailyAdherenceVo vo = new DailyAdherenceVo();
|
||||
vo.setDate(getStringValue(stat, "stat_date"));
|
||||
vo.setTotalTasks(getIntValue(stat, "total_tasks"));
|
||||
vo.setCompletedTasks(getIntValue(stat, "completed_tasks"));
|
||||
vo.setMissedTasks(getIntValue(stat, "missed_tasks"));
|
||||
vo.setSkippedTasks(getIntValue(stat, "skipped_tasks"));
|
||||
vo.setOntimeTasks(getIntValue(stat, "ontime_tasks"));
|
||||
|
||||
if (vo.getTotalTasks() > 0) {
|
||||
BigDecimal rate = BigDecimal.valueOf(vo.getCompletedTasks())
|
||||
.multiply(BigDecimal.valueOf(100))
|
||||
.divide(BigDecimal.valueOf(vo.getTotalTasks()), 2, RoundingMode.HALF_UP);
|
||||
vo.setAdherenceRate(rate);
|
||||
} else {
|
||||
vo.setAdherenceRate(BigDecimal.ZERO);
|
||||
}
|
||||
|
||||
if (vo.getCompletedTasks() > 0) {
|
||||
BigDecimal rate = BigDecimal.valueOf(vo.getOntimeTasks())
|
||||
.multiply(BigDecimal.valueOf(100))
|
||||
.divide(BigDecimal.valueOf(vo.getCompletedTasks()), 2, RoundingMode.HALF_UP);
|
||||
vo.setOntimeRate(rate);
|
||||
} else {
|
||||
vo.setOntimeRate(BigDecimal.ZERO);
|
||||
}
|
||||
|
||||
result.add(vo);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DailyAdherenceVo> getCalendarData(Long memberId, String yearMonth) {
|
||||
YearMonth ym = YearMonth.parse(yearMonth, DateTimeFormatter.ofPattern("yyyy-MM"));
|
||||
LocalDate startDate = ym.atDay(1);
|
||||
LocalDate endDate = ym.atEndOfMonth();
|
||||
|
||||
List<DailyAdherenceVo> dailyList = getDailyAdherenceList(memberId, startDate, endDate);
|
||||
|
||||
// 补全缺失日期
|
||||
List<DailyAdherenceVo> result = new ArrayList<>();
|
||||
Map<String, DailyAdherenceVo> dateMap = new HashMap<>();
|
||||
for (DailyAdherenceVo vo : dailyList) {
|
||||
dateMap.put(vo.getDate(), vo);
|
||||
}
|
||||
|
||||
long days = ChronoUnit.DAYS.between(startDate, endDate) + 1;
|
||||
for (int i = 0; i < days; i++) {
|
||||
LocalDate date = startDate.plusDays(i);
|
||||
String dateStr = date.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
|
||||
|
||||
if (dateMap.containsKey(dateStr)) {
|
||||
result.add(dateMap.get(dateStr));
|
||||
} else {
|
||||
DailyAdherenceVo vo = new DailyAdherenceVo();
|
||||
vo.setDate(dateStr);
|
||||
vo.setTotalTasks(0);
|
||||
vo.setCompletedTasks(0);
|
||||
vo.setMissedTasks(0);
|
||||
vo.setSkippedTasks(0);
|
||||
vo.setOntimeTasks(0);
|
||||
vo.setAdherenceRate(BigDecimal.ZERO);
|
||||
vo.setOntimeRate(BigDecimal.ZERO);
|
||||
result.add(vo);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, MedicationAdherenceVo> getTimeSlotAdherence(Long memberId, LocalDate startDate, LocalDate endDate) {
|
||||
List<Map<String, Object>> slotStats = taskMapper.getTimeSlotStats(memberId, startDate, endDate);
|
||||
|
||||
Map<String, MedicationAdherenceVo> result = new LinkedHashMap<>();
|
||||
result.put("morning", new MedicationAdherenceVo());
|
||||
result.put("afternoon", new MedicationAdherenceVo());
|
||||
result.put("evening", new MedicationAdherenceVo());
|
||||
result.put("night", new MedicationAdherenceVo());
|
||||
|
||||
for (Map<String, Object> stat : slotStats) {
|
||||
int hour = getIntValue(stat, "hour");
|
||||
String slotKey = getTimeSlot(hour);
|
||||
|
||||
MedicationAdherenceVo vo = result.get(slotKey);
|
||||
if (vo.getTotalTasks() == null) {
|
||||
vo.setTotalTasks(0);
|
||||
vo.setCompletedTasks(0);
|
||||
vo.setMissedTasks(0);
|
||||
vo.setOntimeTasks(0);
|
||||
}
|
||||
|
||||
vo.setTotalTasks(vo.getTotalTasks() + getIntValue(stat, "total_tasks"));
|
||||
vo.setCompletedTasks(vo.getCompletedTasks() + getIntValue(stat, "completed_tasks"));
|
||||
vo.setMissedTasks(vo.getMissedTasks() + getIntValue(stat, "missed_tasks"));
|
||||
vo.setOntimeTasks(vo.getOntimeTasks() + getIntValue(stat, "ontime_tasks"));
|
||||
}
|
||||
|
||||
for (Map.Entry<String, MedicationAdherenceVo> entry : result.entrySet()) {
|
||||
MedicationAdherenceVo vo = entry.getValue();
|
||||
if (vo.getTotalTasks() != null && vo.getTotalTasks() > 0) {
|
||||
BigDecimal rate = BigDecimal.valueOf(vo.getCompletedTasks())
|
||||
.multiply(BigDecimal.valueOf(100))
|
||||
.divide(BigDecimal.valueOf(vo.getTotalTasks()), 2, RoundingMode.HALF_UP);
|
||||
vo.setAdherenceRate(rate);
|
||||
} else {
|
||||
vo.setAdherenceRate(BigDecimal.ZERO);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private String getTimeSlot(int hour) {
|
||||
if (hour >= 6 && hour < 12) return "morning";
|
||||
if (hour >= 12 && hour < 18) return "afternoon";
|
||||
if (hour >= 18 && hour < 24) return "evening";
|
||||
return "night";
|
||||
}
|
||||
|
||||
private Integer getIntValue(Map<String, Object> map, String key) {
|
||||
if (map == null || map.get(key) == null) return 0;
|
||||
Object value = map.get(key);
|
||||
if (value instanceof Number) return ((Number) value).intValue();
|
||||
return 0;
|
||||
}
|
||||
|
||||
private String getStringValue(Map<String, Object> map, String key) {
|
||||
if (map == null || map.get(key) == null) return null;
|
||||
return map.get(key).toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
package com.intc.health.service.impl;
|
||||
|
||||
import com.intc.common.core.exception.ServiceException;
|
||||
import com.intc.common.core.utils.DateUtils;
|
||||
import com.intc.common.security.utils.SecurityUtils;
|
||||
import com.intc.health.domain.MedicationPlan;
|
||||
import com.intc.health.domain.dto.MedicationPlanDto;
|
||||
import com.intc.health.domain.vo.MedicationPlanVo;
|
||||
import com.intc.health.mapper.MedicationPlanMapper;
|
||||
import com.intc.health.service.IMedicationPlanService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 用药计划Service实现
|
||||
*
|
||||
* @author bot5
|
||||
* @date 2026-03-19
|
||||
*/
|
||||
@Service
|
||||
public class MedicationPlanServiceImpl implements IMedicationPlanService {
|
||||
|
||||
@Resource
|
||||
private MedicationPlanMapper planMapper;
|
||||
|
||||
@Override
|
||||
public MedicationPlanVo selectById(Long id) {
|
||||
return planMapper.selectById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MedicationPlanVo> selectList(MedicationPlanDto dto) {
|
||||
return planMapper.selectList(dto);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int insert(MedicationPlan plan) {
|
||||
if (plan.getPersonId() == null) {
|
||||
throw new ServiceException("关联成员ID不能为空");
|
||||
}
|
||||
if (plan.getMedicineName() == null || plan.getMedicineName().isEmpty()) {
|
||||
throw new ServiceException("药品名称不能为空");
|
||||
}
|
||||
if (plan.getFrequencyType() == null) {
|
||||
throw new ServiceException("频次类型不能为空");
|
||||
}
|
||||
if (plan.getStartDate() == null) {
|
||||
throw new ServiceException("开始日期不能为空");
|
||||
}
|
||||
plan.setStatus(1); // 默认执行中
|
||||
plan.setDelFlag(0);
|
||||
plan.setCreateBy(SecurityUtils.getUsername());
|
||||
plan.setCreateTime(DateUtils.getNowDate());
|
||||
return planMapper.insert(plan);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int update(MedicationPlan plan) {
|
||||
plan.setUpdateBy(SecurityUtils.getUsername());
|
||||
plan.setUpdateTime(DateUtils.getNowDate());
|
||||
return planMapper.update(plan);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int deleteByIds(Long[] ids) {
|
||||
return planMapper.removeByIds(ids);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int pause(Long id) {
|
||||
MedicationPlan plan = new MedicationPlan();
|
||||
plan.setId(id);
|
||||
plan.setStatus(2); // 已暂停
|
||||
plan.setUpdateBy(SecurityUtils.getUsername());
|
||||
plan.setUpdateTime(DateUtils.getNowDate());
|
||||
return planMapper.update(plan);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int resume(Long id) {
|
||||
MedicationPlan plan = new MedicationPlan();
|
||||
plan.setId(id);
|
||||
plan.setStatus(1); // 执行中
|
||||
plan.setUpdateBy(SecurityUtils.getUsername());
|
||||
plan.setUpdateTime(DateUtils.getNowDate());
|
||||
return planMapper.update(plan);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int end(Long id) {
|
||||
MedicationPlan plan = new MedicationPlan();
|
||||
plan.setId(id);
|
||||
plan.setStatus(3); // 已结束
|
||||
plan.setUpdateBy(SecurityUtils.getUsername());
|
||||
plan.setUpdateTime(DateUtils.getNowDate());
|
||||
return planMapper.update(plan);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
package com.intc.health.service.impl;
|
||||
|
||||
import com.intc.common.core.utils.DateUtils;
|
||||
import com.intc.common.security.utils.SecurityUtils;
|
||||
import com.intc.health.domain.MedicationTask;
|
||||
import com.intc.health.domain.dto.MedicationTaskDto;
|
||||
import com.intc.health.domain.vo.MedicationTaskVo;
|
||||
import com.intc.health.mapper.MedicationTaskMapper;
|
||||
import com.intc.health.service.IMedicationTaskService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 服药任务Service实现
|
||||
*
|
||||
* @author bot5
|
||||
* @date 2026-03-19
|
||||
*/
|
||||
@Service
|
||||
public class MedicationTaskServiceImpl implements IMedicationTaskService {
|
||||
|
||||
@Resource
|
||||
private MedicationTaskMapper taskMapper;
|
||||
|
||||
@Override
|
||||
public MedicationTaskVo selectById(Long id) {
|
||||
return taskMapper.selectById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MedicationTaskVo> selectList(MedicationTaskDto dto) {
|
||||
return taskMapper.selectList(dto);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int insert(MedicationTask task) {
|
||||
task.setStatus(0); // 待服药
|
||||
task.setRemindStatus(0); // 未提醒
|
||||
task.setDelFlag(0);
|
||||
task.setCreateBy(SecurityUtils.getUsername());
|
||||
task.setCreateTime(DateUtils.getNowDate());
|
||||
return taskMapper.insert(task);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int update(MedicationTask task) {
|
||||
task.setUpdateBy(SecurityUtils.getUsername());
|
||||
task.setUpdateTime(DateUtils.getNowDate());
|
||||
return taskMapper.update(task);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int deleteByIds(Long[] ids) {
|
||||
return taskMapper.removeByIds(ids);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int confirm(Long id, Integer confirmType, String confirmTime) {
|
||||
MedicationTask task = new MedicationTask();
|
||||
task.setId(id);
|
||||
task.setStatus(1); // 已服药
|
||||
task.setConfirmType(confirmType != null ? confirmType : 1);
|
||||
// 优先使用前端传入的实际服药时间,没有则用当前时间
|
||||
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.setUpdateTime(DateUtils.getNowDate());
|
||||
return taskMapper.update(task);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int skip(Long id, String notes) {
|
||||
MedicationTask task = new MedicationTask();
|
||||
task.setId(id);
|
||||
task.setStatus(3); // 跳过
|
||||
task.setNotes(notes);
|
||||
task.setUpdateBy(SecurityUtils.getUsername());
|
||||
task.setUpdateTime(DateUtils.getNowDate());
|
||||
return taskMapper.update(task);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int markMissed(Long id, String notes) {
|
||||
MedicationTask task = new MedicationTask();
|
||||
task.setId(id);
|
||||
task.setStatus(2); // 漏服
|
||||
task.setNotes(notes);
|
||||
task.setUpdateBy(SecurityUtils.getUsername());
|
||||
task.setUpdateTime(DateUtils.getNowDate());
|
||||
return taskMapper.update(task);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
package com.intc.health.task;
|
||||
|
||||
import com.intc.health.domain.vo.MedicationTaskVo;
|
||||
import com.intc.health.mapper.MedicationTaskMapper;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 用药提醒定时器
|
||||
*
|
||||
* @author bot5
|
||||
* @date 2026-03-19
|
||||
*/
|
||||
@Component("medicationRemindJob")
|
||||
public class MedicationRemindJob {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(MedicationRemindJob.class);
|
||||
|
||||
@Resource
|
||||
private MedicationTaskMapper taskMapper;
|
||||
|
||||
/**
|
||||
* 扫描并发送提醒
|
||||
* 定时任务配置:每分钟执行
|
||||
*/
|
||||
public void scanAndSendReminders() {
|
||||
log.debug("========== 开始扫描服药提醒 ==========");
|
||||
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
// 扫描未来1分钟内的待服药任务
|
||||
LocalDateTime startTime = now.minusMinutes(1);
|
||||
LocalDateTime endTime = now.plusMinutes(1);
|
||||
|
||||
List<MedicationTaskVo> pendingTasks = taskMapper.selectPendingRemind(startTime, endTime);
|
||||
|
||||
if (pendingTasks == null || pendingTasks.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
log.info("发现 {} 条待提醒的服药任务", pendingTasks.size());
|
||||
|
||||
for (MedicationTaskVo task : pendingTasks) {
|
||||
try {
|
||||
sendReminder(task);
|
||||
} catch (Exception e) {
|
||||
log.error("发送提醒失败,任务ID: {}", task.getId(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送提醒
|
||||
*/
|
||||
private void sendReminder(MedicationTaskVo task) {
|
||||
log.info("发送提醒: 成员={}, 药品={}, 计划时间={} {}",
|
||||
task.getPersonName(), task.getMedicineName(),
|
||||
task.getPlannedDate(), task.getPlannedTime());
|
||||
|
||||
// TODO: 实现消息推送
|
||||
// 1. 查询用户的提醒设置
|
||||
// 2. 根据设置选择推送渠道
|
||||
// 3. 发送推送消息
|
||||
// 4. 记录提醒日志
|
||||
}
|
||||
|
||||
/**
|
||||
* 扫描超时未服药任务
|
||||
* 定时任务配置:每5分钟执行
|
||||
*/
|
||||
public void scanOverdueRecords() {
|
||||
log.debug("========== 开始扫描超时未服药任务 ==========");
|
||||
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
// 扫描超过计划时间30分钟仍未服药的任务
|
||||
LocalDateTime overdueThreshold = now.minusMinutes(30);
|
||||
|
||||
LocalDateTime startTime = overdueThreshold.minusMinutes(5);
|
||||
LocalDateTime endTime = overdueThreshold;
|
||||
|
||||
List<MedicationTaskVo> overdueTasks = taskMapper.selectPendingRemind(startTime, endTime);
|
||||
|
||||
if (overdueTasks == null || overdueTasks.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
log.info("发现 {} 条超时未服药任务", overdueTasks.size());
|
||||
|
||||
for (MedicationTaskVo task : overdueTasks) {
|
||||
try {
|
||||
sendOverdueReminder(task);
|
||||
} catch (Exception e) {
|
||||
log.error("发送超时提醒失败,任务ID: {}", task.getId(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送超时提醒
|
||||
*/
|
||||
private void sendOverdueReminder(MedicationTaskVo task) {
|
||||
log.warn("超时未服药: 成员={}, 药品={}, 计划时间={} {}",
|
||||
task.getPersonName(), task.getMedicineName(),
|
||||
task.getPlannedDate(), task.getPlannedTime());
|
||||
|
||||
// TODO: 实现超时提醒逻辑
|
||||
// 1. 发送二次提醒
|
||||
// 2. 如果配置了家属通知,通知家属
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,271 @@
|
||||
package com.intc.health.task;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.intc.common.core.utils.DateUtils;
|
||||
import com.intc.health.domain.MedicationTask;
|
||||
import com.intc.health.domain.vo.MedicationPlanVo;
|
||||
import com.intc.health.mapper.MedicationPlanMapper;
|
||||
import com.intc.health.mapper.MedicationTaskMapper;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.DayOfWeek;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 服药任务生成定时器
|
||||
* 按文档规范实现
|
||||
*
|
||||
* @author bot5
|
||||
* @date 2026-03-19
|
||||
*/
|
||||
@Component("medicationTaskJob")
|
||||
public class MedicationTaskJob {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(MedicationTaskJob.class);
|
||||
|
||||
@Resource
|
||||
private MedicationPlanMapper planMapper;
|
||||
|
||||
@Resource
|
||||
private MedicationTaskMapper taskMapper;
|
||||
|
||||
/**
|
||||
* 每日生成服药任务
|
||||
* 定时任务配置:每日 00:05 执行
|
||||
*/
|
||||
public void generateDailyTasks() {
|
||||
log.info("========== 开始生成每日服药任务 ==========");
|
||||
LocalDate today = LocalDate.now();
|
||||
int generatedCount = generateTasksForDate(today);
|
||||
log.info("========== 每日服药任务生成完成,共生成 {} 条记录 ==========", generatedCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成指定日期的服药任务
|
||||
*/
|
||||
public int generateTasksForDate(LocalDate date) {
|
||||
int generatedCount = 0;
|
||||
|
||||
// 查询所有执行中的计划
|
||||
List<MedicationPlanVo> activePlans = planMapper.selectActiveList();
|
||||
if (activePlans == null || activePlans.isEmpty()) {
|
||||
log.info("没有执行中的用药计划");
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (MedicationPlanVo plan : activePlans) {
|
||||
try {
|
||||
// 检查该计划当天是否需要服药
|
||||
if (!shouldTakeMedicineOnDate(plan, date)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 先计算本次应生成的任务列表
|
||||
List<MedicationTask> tasks = generateTasksForPlan(plan, date);
|
||||
if (tasks.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 检查已生成的任务数,只补充未生成的部分(防止重复)
|
||||
int existCount = taskMapper.countByPlanAndDate(plan.getId(), date);
|
||||
if (existCount >= tasks.size()) {
|
||||
// 已全量生成,跳过
|
||||
continue;
|
||||
}
|
||||
|
||||
// 未全量生成时,删除旧的再重新全量插入(保证幂等)
|
||||
if (existCount > 0) {
|
||||
taskMapper.deleteByPlanAndDate(plan.getId(), date);
|
||||
}
|
||||
taskMapper.batchInsert(tasks);
|
||||
generatedCount += tasks.size();
|
||||
log.info("计划 {} 在 {} 生成了 {} 条任务", plan.getPlanName(), date, tasks.size());
|
||||
} catch (Exception e) {
|
||||
log.error("生成计划 {} 的任务失败: {}", plan.getId(), e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
return generatedCount;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断某计划在指定日期是否需要服药
|
||||
*/
|
||||
private boolean shouldTakeMedicineOnDate(MedicationPlanVo plan, LocalDate date) {
|
||||
// 检查日期范围
|
||||
if (plan.getStartDate() != null && date.isBefore(toLocalDate(plan.getStartDate()))) {
|
||||
return false;
|
||||
}
|
||||
if (plan.getEndDate() != null && date.isAfter(toLocalDate(plan.getEndDate()))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 根据频次类型判断
|
||||
Integer frequencyType = plan.getFrequencyType();
|
||||
if (frequencyType == null) {
|
||||
frequencyType = 1;
|
||||
}
|
||||
|
||||
switch (frequencyType) {
|
||||
case 1: // 每天
|
||||
return true;
|
||||
case 2: // 每周
|
||||
return shouldTakeOnWeekly(plan, date);
|
||||
case 3: // 隔天
|
||||
return shouldTakeOnAlternate(plan, date);
|
||||
case 4: // 自定义
|
||||
return shouldTakeOnCustom(plan, date);
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 每周服药判断
|
||||
*/
|
||||
private boolean shouldTakeOnWeekly(MedicationPlanVo plan, LocalDate date) {
|
||||
JsonNode config = plan.getFrequencyConfig();
|
||||
if (config == null || !config.has("days")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
JsonNode daysNode = config.get("days");
|
||||
if (!daysNode.isArray()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
DayOfWeek dayOfWeek = date.getDayOfWeek();
|
||||
int dayValue = dayOfWeek.getValue(); // 1=周一, 7=周日
|
||||
|
||||
for (JsonNode day : daysNode) {
|
||||
if (day.asInt() == dayValue) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 隔天服药判断
|
||||
*/
|
||||
private boolean shouldTakeOnAlternate(MedicationPlanVo plan, LocalDate date) {
|
||||
LocalDate startDate = plan.getStartDate() != null ? toLocalDate(plan.getStartDate()) : null;
|
||||
if (startDate == null) {
|
||||
startDate = date;
|
||||
}
|
||||
|
||||
JsonNode config = plan.getFrequencyConfig();
|
||||
int intervalDays = 2; // 默认隔天
|
||||
if (config != null && config.has("interval_days")) {
|
||||
intervalDays = config.get("interval_days").asInt(2);
|
||||
}
|
||||
|
||||
long daysBetween = ChronoUnit.DAYS.between(startDate, date);
|
||||
return daysBetween % intervalDays == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 自定义频次判断
|
||||
*/
|
||||
private boolean shouldTakeOnCustom(MedicationPlanVo plan, LocalDate date) {
|
||||
// 自定义频次,暂时默认返回 true
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 为某个计划生成指定日期的任务
|
||||
*/
|
||||
private List<MedicationTask> generateTasksForPlan(MedicationPlanVo plan, LocalDate date) {
|
||||
List<MedicationTask> tasks = new ArrayList<>();
|
||||
|
||||
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()) {
|
||||
// 如果没有配置时段,使用默认时段
|
||||
timeSlots = createDefaultTimeSlots(plan);
|
||||
}
|
||||
|
||||
for (JsonNode slot : timeSlots) {
|
||||
String timeStr = slot.asText();
|
||||
BigDecimal dosage = plan.getDosagePerTime();
|
||||
LocalTime time = parseTime(timeStr);
|
||||
|
||||
MedicationTask task = new MedicationTask();
|
||||
task.setPlanId(plan.getId());
|
||||
task.setPersonId(plan.getPersonId());
|
||||
task.setMedicineName(plan.getMedicineName());
|
||||
task.setPlannedDate(date);
|
||||
task.setPlannedTime(time);
|
||||
task.setPlannedDosage(dosage);
|
||||
task.setStatus(0); // 待服药
|
||||
task.setRemindStatus(0); // 未提醒
|
||||
task.setCreateTime(DateUtils.getNowDate());
|
||||
|
||||
tasks.add(task);
|
||||
}
|
||||
|
||||
return tasks;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建默认时段配置
|
||||
*/
|
||||
private JsonNode createDefaultTimeSlots(MedicationPlanVo plan) {
|
||||
// 根据剂量单位推测服药时段
|
||||
String json = "[{\"slot_name\":\"早\",\"time\":\"08:00\",\"dosage\":1,\"enabled\":true}]";
|
||||
try {
|
||||
return new com.fasterxml.jackson.databind.ObjectMapper().readTree(json);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Date 转 LocalDate
|
||||
*/
|
||||
private LocalDate toLocalDate(Date date) {
|
||||
return date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析时间字符串
|
||||
*/
|
||||
private LocalTime parseTime(String timeStr) {
|
||||
try {
|
||||
return LocalTime.parse(timeStr, DateTimeFormatter.ofPattern("HH:mm"));
|
||||
} catch (Exception e) {
|
||||
return LocalTime.of(8, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 标记过期任务
|
||||
*/
|
||||
public void markExpiredRecords() {
|
||||
log.info("========== 开始标记过期服药任务 ==========");
|
||||
LocalDateTime expireThreshold = LocalDateTime.now().minusHours(24);
|
||||
int count = taskMapper.markExpired(expireThreshold);
|
||||
log.info("========== 标记过期任务完成,共 {} 条 ==========", count);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,167 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper
|
||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.intc.health.mapper.ChronicDiseaseRecordMapper">
|
||||
|
||||
<resultMap type="ChronicDiseaseRecordVo" id="ChronicDiseaseRecordResult">
|
||||
<result property="id" column="id"/>
|
||||
<result property="personId" column="person_id"/>
|
||||
<result property="personName" column="person_name"/>
|
||||
<result property="diseaseId" column="disease_id"/>
|
||||
<result property="diseaseName" column="disease_name"/>
|
||||
<result property="diseaseCode" column="disease_code"/>
|
||||
<result property="diagnosisDate" column="diagnosis_date"/>
|
||||
<result property="diseaseStatus" column="disease_status"/>
|
||||
<result property="mainDoctor" column="main_doctor"/>
|
||||
<result property="hospital" column="hospital"/>
|
||||
<result property="department" column="department"/>
|
||||
<result property="notes" column="notes"/>
|
||||
<result property="isActive" column="is_active"/>
|
||||
<result property="createBy" column="create_by"/>
|
||||
<result property="createTime" column="create_time"/>
|
||||
<result property="updateBy" column="update_by"/>
|
||||
<result property="updateTime" column="update_time"/>
|
||||
<result property="delFlag" column="del_flag"/>
|
||||
<result property="remark" column="remark"/>
|
||||
|
||||
</resultMap>
|
||||
|
||||
<sql id="selectChronicDiseaseRecordVo">
|
||||
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.create_by, a.create_time, a.update_by, a.update_time, a.del_flag, a.remark,
|
||||
p.name as person_name
|
||||
from chronic_disease_record a
|
||||
left join health_person p on a.person_id = p.id
|
||||
</sql>
|
||||
|
||||
<select id="selectChronicDiseaseRecordList" parameterType="ChronicDiseaseRecordDto" resultMap="ChronicDiseaseRecordResult">
|
||||
<include refid="selectChronicDiseaseRecordVo"/>
|
||||
<where>
|
||||
a.del_flag = '0'
|
||||
<if test="personId != null">
|
||||
and a.person_id = #{personId}
|
||||
</if>
|
||||
<if test="diseaseName != null and diseaseName != ''">
|
||||
and a.disease_name like '%' || #{diseaseName} || '%'
|
||||
</if>
|
||||
<if test="diseaseCode != null and diseaseCode != ''">
|
||||
and a.disease_code = #{diseaseCode}
|
||||
</if>
|
||||
<if test="diseaseStatus != null">
|
||||
and a.disease_status = #{diseaseStatus}
|
||||
</if>
|
||||
<if test="isActive != null">
|
||||
and a.is_active = #{isActive}
|
||||
</if>
|
||||
<if test="diagnosisDateStart != null">
|
||||
and a.diagnosis_date >= #{diagnosisDateStart}
|
||||
</if>
|
||||
<if test="diagnosisDateEnd != null">
|
||||
and a.diagnosis_date <= #{diagnosisDateEnd}
|
||||
</if>
|
||||
</where>
|
||||
<!-- 数据范围过滤 -->
|
||||
${params.dataScope}
|
||||
order by a.create_time desc
|
||||
</select>
|
||||
|
||||
<select id="selectChronicDiseaseRecordById" parameterType="Long" resultMap="ChronicDiseaseRecordResult">
|
||||
<include refid="selectChronicDiseaseRecordVo"/>
|
||||
where a.id = #{id}
|
||||
</select>
|
||||
|
||||
<select id="selectChronicDiseaseRecordByMemberId" parameterType="Long" resultMap="ChronicDiseaseRecordResult">
|
||||
<include refid="selectChronicDiseaseRecordVo"/>
|
||||
where a.del_flag = '0' and a.is_active = 1 and a.person_id = #{personId}
|
||||
order by a.disease_status desc, a.create_time desc
|
||||
</select>
|
||||
|
||||
<insert id="insertChronicDiseaseRecord" parameterType="ChronicDiseaseRecord">
|
||||
insert into chronic_disease_record
|
||||
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||
<if test="id != null">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="diseaseCode != null">disease_code,</if>
|
||||
<if test="diagnosisDate != null">diagnosis_date,</if>
|
||||
<if test="diseaseStatus != null">disease_status,</if>
|
||||
<if test="mainDoctor != null">main_doctor,</if>
|
||||
<if test="hospital != null">hospital,</if>
|
||||
<if test="department != null">department,</if>
|
||||
<if test="notes != null">notes,</if>
|
||||
<if test="isActive != null">is_active,</if>
|
||||
<if test="createBy != null">create_by,</if>
|
||||
<if test="createTime != null">create_time,</if>
|
||||
<if test="updateBy != null">update_by,</if>
|
||||
<if test="updateTime != null">update_time,</if>
|
||||
<if test="delFlag != null">del_flag,</if>
|
||||
<if test="remark != null">remark,</if>
|
||||
</trim>
|
||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||
<if test="id != null">#{id},</if>
|
||||
<if test="personId != null">#{personId},</if>
|
||||
<if test="diseaseId != null">#{diseaseId},</if>
|
||||
<if test="diseaseName != null and diseaseName != ''">#{diseaseName},</if>
|
||||
<if test="diseaseCode != null">#{diseaseCode},</if>
|
||||
<if test="diagnosisDate != null">#{diagnosisDate},</if>
|
||||
<if test="diseaseStatus != null">#{diseaseStatus},</if>
|
||||
<if test="mainDoctor != null">#{mainDoctor},</if>
|
||||
<if test="hospital != null">#{hospital},</if>
|
||||
<if test="department != null">#{department},</if>
|
||||
<if test="notes != null">#{notes},</if>
|
||||
<if test="isActive != null">#{isActive},</if>
|
||||
<if test="createBy != null">#{createBy},</if>
|
||||
<if test="createTime != null">#{createTime},</if>
|
||||
<if test="updateBy != null">#{updateBy},</if>
|
||||
<if test="updateTime != null">#{updateTime},</if>
|
||||
<if test="delFlag != null">#{delFlag},</if>
|
||||
<if test="remark != null">#{remark},</if>
|
||||
</trim>
|
||||
</insert>
|
||||
|
||||
<update id="updateChronicDiseaseRecord" parameterType="ChronicDiseaseRecord">
|
||||
update chronic_disease_record
|
||||
<trim prefix="SET" suffixOverrides=",">
|
||||
<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="diseaseCode != null">disease_code = #{diseaseCode},</if>
|
||||
<if test="diagnosisDate != null">diagnosis_date = #{diagnosisDate},</if>
|
||||
<if test="diseaseStatus != null">disease_status = #{diseaseStatus},</if>
|
||||
<if test="mainDoctor != null">main_doctor = #{mainDoctor},</if>
|
||||
<if test="hospital != null">hospital = #{hospital},</if>
|
||||
<if test="department != null">department = #{department},</if>
|
||||
<if test="notes != null">notes = #{notes},</if>
|
||||
<if test="isActive != null">is_active = #{isActive},</if>
|
||||
<if test="updateBy != null">update_by = #{updateBy},</if>
|
||||
<if test="updateTime != null">update_time = #{updateTime},</if>
|
||||
<if test="remark != null">remark = #{remark},</if>
|
||||
</trim>
|
||||
where id = #{id}
|
||||
</update>
|
||||
|
||||
<delete id="deleteChronicDiseaseRecordById" parameterType="Long">
|
||||
delete from chronic_disease_record where id = #{id}
|
||||
</delete>
|
||||
|
||||
<delete id="deleteChronicDiseaseRecordByIds" parameterType="String">
|
||||
delete from chronic_disease_record where id in
|
||||
<foreach item="id" collection="array" open="(" separator="," close=")">
|
||||
#{id}
|
||||
</foreach>
|
||||
</delete>
|
||||
|
||||
<update id="removeChronicDiseaseRecordById" parameterType="Long">
|
||||
update chronic_disease_record set del_flag = '1' where id = #{id}
|
||||
</update>
|
||||
|
||||
<update id="removeChronicDiseaseRecordByIds" parameterType="String">
|
||||
update chronic_disease_record set del_flag = '1' where id in
|
||||
<foreach item="id" collection="array" open="(" separator="," close=")">
|
||||
#{id}
|
||||
</foreach>
|
||||
</update>
|
||||
</mapper>
|
||||
@@ -0,0 +1,176 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.intc.health.mapper.MedicationPlanMapper">
|
||||
|
||||
<resultMap type="com.intc.health.domain.vo.MedicationPlanVo" id="MedicationPlanResult">
|
||||
<id property="id" column="id"/>
|
||||
<result property="personId" column="person_id"/>
|
||||
<result property="personName" column="person_name"/>
|
||||
<result property="chronicDiseaseId" column="chronic_disease_id"/>
|
||||
<result property="chronicDiseaseName" column="chronic_disease_name"/>
|
||||
<result property="planName" column="plan_name"/>
|
||||
<result property="medicineId" column="medicine_id"/>
|
||||
<result property="medicineName" column="medicine_name"/>
|
||||
<result property="specification" column="specification"/>
|
||||
<result property="dosagePerTime" column="dosage_per_time"/>
|
||||
<result property="dosageUnit" column="dosage_unit"/>
|
||||
<result property="frequencyType" column="frequency_type"/>
|
||||
<result property="frequencyConfig" column="frequency_config" typeHandler="com.intc.common.core.handler.JsonNodeTypeHandler"/>
|
||||
<result property="timeSlots" column="time_slots" typeHandler="com.intc.common.core.handler.JsonNodeTypeHandler"/>
|
||||
<result property="startDate" column="start_date"/>
|
||||
<result property="endDate" column="end_date"/>
|
||||
<result property="remindEnabled" column="remind_enabled"/>
|
||||
<result property="remindAdvanceMin" column="remind_advance_min"/>
|
||||
<result property="notifyFamily" column="notify_family"/>
|
||||
<result property="familyMemberIds" column="family_member_ids" typeHandler="com.intc.common.core.handler.JsonNodeTypeHandler"/>
|
||||
<result property="status" column="status"/>
|
||||
<result property="todayTotal" column="today_total"/>
|
||||
<result property="todayCompleted" column="today_completed"/>
|
||||
<result property="createTime" column="create_time"/>
|
||||
</resultMap>
|
||||
|
||||
<sql id="selectVo">
|
||||
select a.id, a.person_id, p.name as person_name, a.chronic_disease_id,
|
||||
c.disease_name as chronic_disease_name, a.plan_name, a.medicine_id,
|
||||
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.remind_enabled, a.remind_advance_min, a.notify_family, a.family_member_ids,
|
||||
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
|
||||
left join health_person p on a.person_id = p.id
|
||||
left join chronic_disease_record c on a.chronic_disease_id = c.id
|
||||
</sql>
|
||||
|
||||
<select id="selectById" parameterType="Long" resultMap="MedicationPlanResult">
|
||||
<include refid="selectVo"/>
|
||||
where a.id = #{id} and a.del_flag = 0
|
||||
</select>
|
||||
|
||||
<select id="selectList" parameterType="com.intc.health.domain.dto.MedicationPlanDto" resultMap="MedicationPlanResult">
|
||||
<include refid="selectVo"/>
|
||||
<where>
|
||||
a.del_flag = 0
|
||||
<if test="personId != null"> and a.person_id = #{personId}</if>
|
||||
<if test="chronicDiseaseId != null"> and a.chronic_disease_id = #{chronicDiseaseId}</if>
|
||||
<if test="planName != null and planName != ''"> and a.plan_name like '%' || #{planName} || '%'</if>
|
||||
<if test="medicineId != null"> and a.medicine_id = #{medicineId}</if>
|
||||
<if test="medicineName != null and medicineName != ''"> and a.medicine_name like '%' || #{medicineName} || '%'</if>
|
||||
<if test="status != null"> and a.status = #{status}</if>
|
||||
<if test="startDateBegin != null"> and a.start_date >= #{startDateBegin}</if>
|
||||
<if test="startDateEnd != null"> and a.start_date <= #{startDateEnd}</if>
|
||||
<if test="keyword != null and keyword != ''">
|
||||
and (a.plan_name like '%' || #{keyword} || '%' or a.medicine_name like '%' || #{keyword} || '%')
|
||||
</if>
|
||||
</where>
|
||||
<!-- 数据范围过滤 -->
|
||||
${params.dataScope}
|
||||
order by a.create_time desc
|
||||
</select>
|
||||
|
||||
<select id="selectActiveList" resultMap="MedicationPlanResult">
|
||||
<include refid="selectVo"/>
|
||||
where a.del_flag = 0 and a.status = 1
|
||||
and a.start_date <= current_date
|
||||
and (a.end_date is null or a.end_date >= current_date)
|
||||
</select>
|
||||
|
||||
<insert id="insert" parameterType="com.intc.health.domain.MedicationPlan" useGeneratedKeys="true" keyProperty="id">
|
||||
insert into medication_plan
|
||||
<trim prefix="(" suffix=")" suffixOverrides=",">
|
||||
<if test="personId != null">person_id,</if>
|
||||
<if test="chronicDiseaseId != null">chronic_disease_id,</if>
|
||||
<if test="planName != null and planName != ''">plan_name,</if>
|
||||
<if test="medicineId != null">medicine_id,</if>
|
||||
<if test="medicineName != null">medicine_name,</if>
|
||||
<if test="specification != null">specification,</if>
|
||||
<if test="dosagePerTime != null">dosage_per_time,</if>
|
||||
<if test="dosageUnit != null">dosage_unit,</if>
|
||||
<if test="frequencyType != null">frequency_type,</if>
|
||||
<if test="frequencyConfig != null">frequency_config,</if>
|
||||
<if test="timeSlots != null">time_slots,</if>
|
||||
<if test="startDate != null">start_date,</if>
|
||||
<if test="endDate != null">end_date,</if>
|
||||
<if test="remindEnabled != null">remind_enabled,</if>
|
||||
<if test="remindAdvanceMin != null">remind_advance_min,</if>
|
||||
<if test="notifyFamily != null">notify_family,</if>
|
||||
<if test="familyMemberIds != null">family_member_ids,</if>
|
||||
<if test="status != null">status,</if>
|
||||
<if test="createBy != null">create_by,</if>
|
||||
<if test="createTime != null">create_time,</if>
|
||||
<if test="remark != null">remark,</if>
|
||||
del_flag,
|
||||
</trim>
|
||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||
<if test="personId != null">#{personId},</if>
|
||||
<if test="chronicDiseaseId != null">#{chronicDiseaseId},</if>
|
||||
<if test="planName != null and planName != ''">#{planName},</if>
|
||||
<if test="medicineId != null">#{medicineId},</if>
|
||||
<if test="medicineName != null">#{medicineName},</if>
|
||||
<if test="specification != null">#{specification},</if>
|
||||
<if test="dosagePerTime != null">#{dosagePerTime},</if>
|
||||
<if test="dosageUnit != null">#{dosageUnit},</if>
|
||||
<if test="frequencyType != null">#{frequencyType},</if>
|
||||
<if test="frequencyConfig != null">#{frequencyConfig, typeHandler=com.intc.common.core.handler.JsonNodeTypeHandler},</if>
|
||||
<if test="timeSlots != null">#{timeSlots, typeHandler=com.intc.common.core.handler.JsonNodeTypeHandler},</if>
|
||||
<if test="startDate != null">#{startDate},</if>
|
||||
<if test="endDate != null">#{endDate},</if>
|
||||
<if test="remindEnabled != null">#{remindEnabled},</if>
|
||||
<if test="remindAdvanceMin != null">#{remindAdvanceMin},</if>
|
||||
<if test="notifyFamily != null">#{notifyFamily},</if>
|
||||
<if test="familyMemberIds != null">#{familyMemberIds, typeHandler=com.intc.common.core.handler.JsonNodeTypeHandler},</if>
|
||||
<if test="status != null">#{status},</if>
|
||||
<if test="createBy != null">#{createBy},</if>
|
||||
<if test="createTime != null">#{createTime},</if>
|
||||
<if test="remark != null">#{remark},</if>
|
||||
0,
|
||||
</trim>
|
||||
</insert>
|
||||
|
||||
<update id="update" parameterType="com.intc.health.domain.MedicationPlan">
|
||||
update medication_plan
|
||||
<set>
|
||||
<if test="personId != null">person_id = #{personId},</if>
|
||||
<if test="chronicDiseaseId != null">chronic_disease_id = #{chronicDiseaseId},</if>
|
||||
<if test="planName != null">plan_name = #{planName},</if>
|
||||
<if test="medicineId != null">medicine_id = #{medicineId},</if>
|
||||
<if test="medicineName != null">medicine_name = #{medicineName},</if>
|
||||
<if test="specification != null">specification = #{specification},</if>
|
||||
<if test="dosagePerTime != null">dosage_per_time = #{dosagePerTime},</if>
|
||||
<if test="dosageUnit != null">dosage_unit = #{dosageUnit},</if>
|
||||
<if test="frequencyType != null">frequency_type = #{frequencyType},</if>
|
||||
<if test="frequencyConfig != null">frequency_config = #{frequencyConfig, typeHandler=com.intc.common.core.handler.JsonNodeTypeHandler},</if>
|
||||
<if test="timeSlots != null">time_slots = #{timeSlots, typeHandler=com.intc.common.core.handler.JsonNodeTypeHandler},</if>
|
||||
<if test="startDate != null">start_date = #{startDate},</if>
|
||||
<if test="endDate != null">end_date = #{endDate},</if>
|
||||
<if test="remindEnabled != null">remind_enabled = #{remindEnabled},</if>
|
||||
<if test="remindAdvanceMin != null">remind_advance_min = #{remindAdvanceMin},</if>
|
||||
<if test="notifyFamily != null">notify_family = #{notifyFamily},</if>
|
||||
<if test="familyMemberIds != null">family_member_ids = #{familyMemberIds, typeHandler=com.intc.common.core.handler.JsonNodeTypeHandler},</if>
|
||||
<if test="status != null">status = #{status},</if>
|
||||
<if test="updateBy != null">update_by = #{updateBy},</if>
|
||||
<if test="updateTime != null">update_time = #{updateTime},</if>
|
||||
<if test="remark != null">remark = #{remark},</if>
|
||||
</set>
|
||||
where id = #{id}
|
||||
</update>
|
||||
|
||||
<delete id="deleteById" parameterType="Long">
|
||||
delete from medication_plan where id = #{id}
|
||||
</delete>
|
||||
|
||||
<delete id="deleteByIds" parameterType="Long">
|
||||
delete from medication_plan where id in
|
||||
<foreach item="id" collection="array" open="(" separator="," close=")">#{id}</foreach>
|
||||
</delete>
|
||||
|
||||
<update id="removeById" parameterType="Long">
|
||||
update medication_plan set del_flag = 1 where id = #{id}
|
||||
</update>
|
||||
|
||||
<update id="removeByIds" parameterType="Long">
|
||||
update medication_plan set del_flag = 1 where id in
|
||||
<foreach item="id" collection="array" open="(" separator="," close=")">#{id}</foreach>
|
||||
</update>
|
||||
</mapper>
|
||||
@@ -0,0 +1,203 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.intc.health.mapper.MedicationTaskMapper">
|
||||
|
||||
<resultMap type="com.intc.health.domain.vo.MedicationTaskVo" id="MedicationTaskResult">
|
||||
<id property="id" column="id"/>
|
||||
<result property="planId" column="plan_id"/>
|
||||
<result property="planName" column="plan_name"/>
|
||||
<result property="personId" column="person_id"/>
|
||||
<result property="personName" column="person_name"/>
|
||||
<result property="medicineName" column="medicine_name"/>
|
||||
<result property="plannedDate" column="planned_date"/>
|
||||
<result property="plannedTime" column="planned_time"/>
|
||||
<result property="plannedDosage" column="planned_dosage"/>
|
||||
<result property="actualTime" column="actual_time"/>
|
||||
<result property="actualDosage" column="actual_dosage"/>
|
||||
<result property="status" column="status"/>
|
||||
<result property="confirmType" column="confirm_type"/>
|
||||
<result property="notes" column="notes"/>
|
||||
<result property="remindStatus" column="remind_status"/>
|
||||
<result property="remindTime" column="remind_time"/>
|
||||
<result property="createTime" column="create_time"/>
|
||||
</resultMap>
|
||||
|
||||
<sql id="selectVo">
|
||||
select a.id, a.plan_id, p.plan_name, a.person_id, m.name as person_name,
|
||||
a.medicine_name, a.planned_date, a.planned_time, a.planned_dosage,
|
||||
a.actual_time, a.actual_dosage, a.status, a.confirm_type, a.notes,
|
||||
a.remind_status, a.remind_time, a.create_time
|
||||
from medication_task a
|
||||
left join medication_plan p on a.plan_id = p.id
|
||||
left join health_person m on a.person_id = m.id
|
||||
</sql>
|
||||
|
||||
<select id="selectById" parameterType="Long" resultMap="MedicationTaskResult">
|
||||
<include refid="selectVo"/>
|
||||
where a.id = #{id} and a.del_flag = 0
|
||||
</select>
|
||||
|
||||
<select id="selectList" parameterType="com.intc.health.domain.dto.MedicationTaskDto" resultMap="MedicationTaskResult">
|
||||
<include refid="selectVo"/>
|
||||
<where>
|
||||
a.del_flag = 0
|
||||
<if test="planId != null"> and a.plan_id = #{planId}</if>
|
||||
<if test="personId != null"> and a.person_id = #{personId}</if>
|
||||
<if test="medicineName != null and medicineName != ''"> and a.medicine_name like '%' || #{medicineName} || '%'</if>
|
||||
<if test="status != null"> and a.status = #{status}</if>
|
||||
<if test="plannedDateBegin != null"> and a.planned_date >= #{plannedDateBegin}</if>
|
||||
<if test="plannedDateEnd != null"> and a.planned_date <= #{plannedDateEnd}</if>
|
||||
<if test="queryDate != null"> and a.planned_date = #{queryDate}</if>
|
||||
<if test="keyword != null and keyword != ''">
|
||||
and a.medicine_name like '%' || #{keyword} || '%'
|
||||
</if>
|
||||
</where>
|
||||
<!-- 数据范围过滤 -->
|
||||
${params.dataScope}
|
||||
order by a.planned_date desc, a.planned_time desc
|
||||
</select>
|
||||
|
||||
<insert id="insert" parameterType="com.intc.health.domain.MedicationTask" useGeneratedKeys="true" keyProperty="id">
|
||||
insert into medication_task (
|
||||
plan_id, person_id, medicine_name, planned_date, planned_time,
|
||||
planned_dosage, actual_time, actual_dosage, status, confirm_type,
|
||||
notes, remind_status, remind_time, create_by, create_time, remark, del_flag
|
||||
) values (
|
||||
#{planId}, #{personId}, #{medicineName}, #{plannedDate}, #{plannedTime},
|
||||
#{plannedDosage}, #{actualTime}, #{actualDosage}, #{status}, #{confirmType},
|
||||
#{notes}, #{remindStatus}, #{remindTime}, #{createBy}, #{createTime}, #{remark}, 0
|
||||
)
|
||||
</insert>
|
||||
|
||||
<insert id="batchInsert" parameterType="java.util.List">
|
||||
insert into medication_task (
|
||||
plan_id, person_id, medicine_name, planned_date, planned_time,
|
||||
planned_dosage, status, remind_status, create_time, del_flag
|
||||
) values
|
||||
<foreach collection="list" item="item" separator=",">
|
||||
(#{item.planId}, #{item.personId}, #{item.medicineName}, #{item.plannedDate}, #{item.plannedTime},
|
||||
#{item.plannedDosage}, #{item.status}, #{item.remindStatus}, #{item.createTime}, 0)
|
||||
</foreach>
|
||||
</insert>
|
||||
|
||||
<update id="update" parameterType="com.intc.health.domain.MedicationTask">
|
||||
update medication_task
|
||||
<set>
|
||||
<if test="actualTime != null">actual_time = #{actualTime},</if>
|
||||
<if test="actualDosage != null">actual_dosage = #{actualDosage},</if>
|
||||
<if test="status != null">status = #{status},</if>
|
||||
<if test="confirmType != null">confirm_type = #{confirmType},</if>
|
||||
<if test="notes != null">notes = #{notes},</if>
|
||||
<if test="remindStatus != null">remind_status = #{remindStatus},</if>
|
||||
<if test="remindTime != null">remind_time = #{remindTime},</if>
|
||||
<if test="updateBy != null">update_by = #{updateBy},</if>
|
||||
<if test="updateTime != null">update_time = #{updateTime},</if>
|
||||
<if test="remark != null">remark = #{remark},</if>
|
||||
</set>
|
||||
where id = #{id}
|
||||
</update>
|
||||
|
||||
<delete id="deleteById" parameterType="Long">
|
||||
delete from medication_task where id = #{id}
|
||||
</delete>
|
||||
|
||||
<delete id="deleteByIds" parameterType="Long">
|
||||
delete from medication_task where id in
|
||||
<foreach item="id" collection="array" open="(" separator="," close=")">#{id}</foreach>
|
||||
</delete>
|
||||
|
||||
<update id="removeById" parameterType="Long">
|
||||
update medication_task set del_flag = 1 where id = #{id}
|
||||
</update>
|
||||
|
||||
<update id="removeByIds" parameterType="Long">
|
||||
update medication_task set del_flag = 1 where id in
|
||||
<foreach item="id" collection="array" open="(" separator="," close=")">#{id}</foreach>
|
||||
</update>
|
||||
|
||||
<select id="countByPlanAndDate" resultType="int">
|
||||
select count(1) from medication_task
|
||||
where del_flag = 0 and plan_id = #{planId} and planned_date = #{date}
|
||||
</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 count(1) from medication_task
|
||||
where del_flag = 0 and plan_id = #{planId} and planned_date = #{date} and status = 1
|
||||
</select>
|
||||
|
||||
<update id="markExpired">
|
||||
update medication_task
|
||||
set status = 2, update_time = current_timestamp
|
||||
where del_flag = 0 and status = 0
|
||||
and (planned_date || ' ' || planned_time)::timestamp < #{expireThreshold}
|
||||
</update>
|
||||
|
||||
<select id="selectPendingRemind" resultMap="MedicationTaskResult">
|
||||
<include refid="selectVo"/>
|
||||
where a.del_flag = 0 and a.status = 0 and a.remind_status = 0
|
||||
and (a.planned_date || ' ' || a.planned_time)::timestamp >= #{startTime}
|
||||
and (a.planned_date || ' ' || a.planned_time)::timestamp <= #{endTime}
|
||||
order by a.planned_date, a.planned_time
|
||||
</select>
|
||||
|
||||
<!-- ========== 依从性统计 ========== -->
|
||||
|
||||
<select id="getOverallStats" resultType="java.util.Map">
|
||||
select
|
||||
count(1) as total_tasks,
|
||||
sum(case when status = 1 then 1 else 0 end) as completed_tasks,
|
||||
sum(case when status = 2 then 1 else 0 end) as missed_tasks,
|
||||
sum(case when status = 3 then 1 else 0 end) as skipped_tasks,
|
||||
sum(case when status = 0 then 1 else 0 end) as pending_tasks,
|
||||
sum(case when status = 1 and actual_time is not null
|
||||
and extract(epoch from (actual_time - (planned_date || ' ' || planned_time)::timestamp))/3600 <= 1
|
||||
then 1 else 0 end) as ontime_tasks
|
||||
from medication_task
|
||||
where del_flag = 0
|
||||
<if test="personId != null"> and person_id = #{personId}</if>
|
||||
<if test="startDate != null"> and planned_date >= #{startDate}</if>
|
||||
<if test="endDate != null"> and planned_date <= #{endDate}</if>
|
||||
</select>
|
||||
|
||||
<select id="getDailyStats" resultType="java.util.Map">
|
||||
select
|
||||
planned_date as stat_date,
|
||||
count(1) as total_tasks,
|
||||
sum(case when status = 1 then 1 else 0 end) as completed_tasks,
|
||||
sum(case when status = 2 then 1 else 0 end) as missed_tasks,
|
||||
sum(case when status = 3 then 1 else 0 end) as skipped_tasks,
|
||||
sum(case when status = 1 and actual_time is not null
|
||||
and extract(epoch from (actual_time - (planned_date || ' ' || planned_time)::timestamp))/3600 <= 1
|
||||
then 1 else 0 end) as ontime_tasks
|
||||
from medication_task
|
||||
where del_flag = 0
|
||||
<if test="personId != null"> and person_id = #{personId}</if>
|
||||
<if test="startDate != null"> and planned_date >= #{startDate}</if>
|
||||
<if test="endDate != null"> and planned_date <= #{endDate}</if>
|
||||
group by planned_date
|
||||
order by planned_date
|
||||
</select>
|
||||
|
||||
<select id="getTimeSlotStats" resultType="java.util.Map">
|
||||
select
|
||||
extract(hour from planned_time) as hour,
|
||||
count(1) as total_tasks,
|
||||
sum(case when status = 1 then 1 else 0 end) as completed_tasks,
|
||||
sum(case when status = 2 then 1 else 0 end) as missed_tasks,
|
||||
sum(case when status = 1 and actual_time is not null
|
||||
and extract(epoch from (actual_time - (planned_date || ' ' || planned_time)::timestamp))/3600 <= 1
|
||||
then 1 else 0 end) as ontime_tasks
|
||||
from medication_task
|
||||
where del_flag = 0
|
||||
<if test="personId != null"> and person_id = #{personId}</if>
|
||||
<if test="startDate != null"> and planned_date >= #{startDate}</if>
|
||||
<if test="endDate != null"> and planned_date <= #{endDate}</if>
|
||||
group by extract(hour from planned_time)
|
||||
order by hour
|
||||
</select>
|
||||
</mapper>
|
||||
Reference in New Issue
Block a user