diff --git a/intc-api/intc-api-health/pom.xml b/intc-api/intc-api-health/pom.xml
new file mode 100644
index 0000000..fd7279c
--- /dev/null
+++ b/intc-api/intc-api-health/pom.xml
@@ -0,0 +1,28 @@
+
+
+
+ com.intc
+ intc-api
+ 3.6.3
+
+ 4.0.0
+
+ intc-api-health
+
+
+ intc-api-health 健康模块远程调用接口
+
+
+
+
+
+
+ com.intc
+ intc-common-core
+
+
+
+
+
diff --git a/intc-api/intc-api-health/src/main/java/com/intc/api/health/RemoteHealthService.java b/intc-api/intc-api-health/src/main/java/com/intc/api/health/RemoteHealthService.java
new file mode 100644
index 0000000..817b03a
--- /dev/null
+++ b/intc-api/intc-api-health/src/main/java/com/intc/api/health/RemoteHealthService.java
@@ -0,0 +1,40 @@
+package com.intc.api.health;
+
+import com.intc.common.core.constant.ServiceNameConstants;
+import com.intc.common.core.domain.R;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+
+/**
+ * 健康模块远程调用服务
+ *
+ * @author intc
+ */
+@FeignClient(contextId = "remoteHealthService", value = ServiceNameConstants.INTC_HEALTH, fallbackFactory = com.intc.api.health.factory.RemoteHealthFallbackFactory.class)
+public interface RemoteHealthService {
+
+ /**
+ * 每日生成服药任务
+ *
+ * @return 结果
+ */
+ @RequestMapping(value = "/job/generateDailyTasks", method = RequestMethod.POST)
+ R generateDailyTasks();
+
+ /**
+ * 扫描并发送服药提醒
+ *
+ * @return 结果
+ */
+ @RequestMapping(value = "/job/scanAndSendReminders", method = RequestMethod.POST)
+ R scanAndSendReminders();
+
+ /**
+ * 扫描超时未服药任务
+ *
+ * @return 结果
+ */
+ @RequestMapping(value = "/job/scanOverdueRecords", method = RequestMethod.POST)
+ R scanOverdueRecords();
+}
diff --git a/intc-api/intc-api-health/src/main/java/com/intc/api/health/factory/RemoteHealthFallbackFactory.java b/intc-api/intc-api-health/src/main/java/com/intc/api/health/factory/RemoteHealthFallbackFactory.java
new file mode 100644
index 0000000..935c7c4
--- /dev/null
+++ b/intc-api/intc-api-health/src/main/java/com/intc/api/health/factory/RemoteHealthFallbackFactory.java
@@ -0,0 +1,41 @@
+package com.intc.api.health.factory;
+
+import com.intc.api.health.RemoteHealthService;
+import com.intc.common.core.domain.R;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.cloud.openfeign.FallbackFactory;
+import org.springframework.stereotype.Component;
+
+/**
+ * 健康服务降级处理
+ *
+ * @author intc
+ */
+@Component
+public class RemoteHealthFallbackFactory implements FallbackFactory {
+
+ private static final Logger log = LoggerFactory.getLogger(RemoteHealthFallbackFactory.class);
+
+ @Override
+ public RemoteHealthService create(Throwable throwable) {
+ log.error("健康服务调用失败:{}", throwable.getMessage());
+ return new RemoteHealthService() {
+
+ @Override
+ public R generateDailyTasks() {
+ return R.fail("健康服务调用每日生成服药任务失败");
+ }
+
+ @Override
+ public R scanAndSendReminders() {
+ return R.fail("健康服务调用扫描服药提醒失败");
+ }
+
+ @Override
+ public R scanOverdueRecords() {
+ return R.fail("健康服务调用扫描超时未服药记录失败");
+ }
+ };
+ }
+}
diff --git a/intc-api/intc-api-health/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/intc-api/intc-api-health/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
new file mode 100644
index 0000000..4389ae5
--- /dev/null
+++ b/intc-api/intc-api-health/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
@@ -0,0 +1 @@
+com.intc.api.health.factory.RemoteHealthFallbackFactory
\ No newline at end of file
diff --git a/intc-api/pom.xml b/intc-api/pom.xml
index 3395678..db3a536 100644
--- a/intc-api/pom.xml
+++ b/intc-api/pom.xml
@@ -11,6 +11,7 @@
intc-api-system
intc-api-invest
+ intc-api-health
intc-api
pom
diff --git a/intc-common/intc-common-core/pom.xml b/intc-common/intc-common-core/pom.xml
index 7ae2228..33431b0 100644
--- a/intc-common/intc-common-core/pom.xml
+++ b/intc-common/intc-common-core/pom.xml
@@ -145,6 +145,12 @@
mybatis-plus-extension
3.5.5
+
+
+ org.postgresql
+ postgresql
+ provided
+
diff --git a/intc-common/intc-common-core/src/main/java/com/intc/common/core/constant/ServiceNameConstants.java b/intc-common/intc-common-core/src/main/java/com/intc/common/core/constant/ServiceNameConstants.java
index da07691..55d79d9 100644
--- a/intc-common/intc-common-core/src/main/java/com/intc/common/core/constant/ServiceNameConstants.java
+++ b/intc-common/intc-common-core/src/main/java/com/intc/common/core/constant/ServiceNameConstants.java
@@ -65,4 +65,9 @@ public class ServiceNameConstants
* INTC_INVEST_PROD的serviceId
*/
public static final String INTC_INVEST_PROD ="intc-invest-prod";
+
+ /**
+ * INTC_HEALTH的serviceId
+ */
+ public static final String INTC_HEALTH = "intc-health";
}
diff --git a/intc-common/intc-common-core/src/main/java/com/intc/common/core/handler/JsonNodeTypeHandler.java b/intc-common/intc-common-core/src/main/java/com/intc/common/core/handler/JsonNodeTypeHandler.java
new file mode 100644
index 0000000..cdb6ee5
--- /dev/null
+++ b/intc-common/intc-common-core/src/main/java/com/intc/common/core/handler/JsonNodeTypeHandler.java
@@ -0,0 +1,63 @@
+package com.intc.common.core.handler;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.apache.ibatis.type.BaseTypeHandler;
+import org.apache.ibatis.type.JdbcType;
+import org.apache.ibatis.type.MappedTypes;
+import org.postgresql.util.PGobject;
+
+import java.sql.CallableStatement;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+/**
+ * PostgreSQL JSONB 类型处理器
+ * 用于 MyBatis 映射 JsonNode 类型
+ *
+ * @author bot5
+ * @date 2026-03-19
+ */
+@MappedTypes(JsonNode.class)
+public class JsonNodeTypeHandler extends BaseTypeHandler {
+
+ private static final ObjectMapper objectMapper = new ObjectMapper();
+
+ @Override
+ public void setNonNullParameter(PreparedStatement ps, int i, JsonNode parameter, JdbcType jdbcType) throws SQLException {
+ PGobject pgObject = new PGobject();
+ pgObject.setType("jsonb");
+ pgObject.setValue(parameter.toString());
+ ps.setObject(i, pgObject);
+ }
+
+ @Override
+ public JsonNode getNullableResult(ResultSet rs, String columnName) throws SQLException {
+ String value = rs.getString(columnName);
+ return parseJson(value);
+ }
+
+ @Override
+ public JsonNode getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
+ String value = rs.getString(columnIndex);
+ return parseJson(value);
+ }
+
+ @Override
+ public JsonNode getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
+ String value = cs.getString(columnIndex);
+ return parseJson(value);
+ }
+
+ private JsonNode parseJson(String value) {
+ if (value == null || value.isEmpty()) {
+ return null;
+ }
+ try {
+ return objectMapper.readTree(value);
+ } catch (Exception e) {
+ return null;
+ }
+ }
+}
\ No newline at end of file
diff --git a/intc-modules/intc-health/src/main/java/com/intc/health/controller/ChronicDiseaseRecordController.java b/intc-modules/intc-health/src/main/java/com/intc/health/controller/ChronicDiseaseRecordController.java
new file mode 100644
index 0000000..44e7e5b
--- /dev/null
+++ b/intc-modules/intc-health/src/main/java/com/intc/health/controller/ChronicDiseaseRecordController.java
@@ -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 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 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 list = chronicDiseaseRecordService.selectChronicDiseaseRecordList(chronicDiseaseRecordDto);
+ ExcelUtil util = new ExcelUtil(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));
+ }
+}
\ No newline at end of file
diff --git a/intc-modules/intc-health/src/main/java/com/intc/health/controller/HealthJobController.java b/intc-modules/intc-health/src/main/java/com/intc/health/controller/HealthJobController.java
new file mode 100644
index 0000000..b5c8270
--- /dev/null
+++ b/intc-modules/intc-health/src/main/java/com/intc/health/controller/HealthJobController.java
@@ -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();
+ }
+}
diff --git a/intc-modules/intc-health/src/main/java/com/intc/health/controller/MedicationAdherenceController.java b/intc-modules/intc-health/src/main/java/com/intc/health/controller/MedicationAdherenceController.java
new file mode 100644
index 0000000..692df09
--- /dev/null
+++ b/intc-modules/intc-health/src/main/java/com/intc/health/controller/MedicationAdherenceController.java
@@ -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 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 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 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 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);
+ }
+}
\ No newline at end of file
diff --git a/intc-modules/intc-health/src/main/java/com/intc/health/controller/MedicationPlanController.java b/intc-modules/intc-health/src/main/java/com/intc/health/controller/MedicationPlanController.java
new file mode 100644
index 0000000..4f3ff56
--- /dev/null
+++ b/intc-modules/intc-health/src/main/java/com/intc/health/controller/MedicationPlanController.java
@@ -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 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));
+ }
+}
\ No newline at end of file
diff --git a/intc-modules/intc-health/src/main/java/com/intc/health/controller/MedicationTaskController.java b/intc-modules/intc-health/src/main/java/com/intc/health/controller/MedicationTaskController.java
new file mode 100644
index 0000000..15c8f8b
--- /dev/null
+++ b/intc-modules/intc-health/src/main/java/com/intc/health/controller/MedicationTaskController.java
@@ -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 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));
+ }
+}
\ No newline at end of file
diff --git a/intc-modules/intc-health/src/main/java/com/intc/health/domain/ChronicDiseaseRecord.java b/intc-modules/intc-health/src/main/java/com/intc/health/domain/ChronicDiseaseRecord.java
new file mode 100644
index 0000000..a9ec46d
--- /dev/null
+++ b/intc-modules/intc-health/src/main/java/com/intc/health/domain/ChronicDiseaseRecord.java
@@ -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;
+}
\ No newline at end of file
diff --git a/intc-modules/intc-health/src/main/java/com/intc/health/domain/MedicationPlan.java b/intc-modules/intc-health/src/main/java/com/intc/health/domain/MedicationPlan.java
new file mode 100644
index 0000000..76460b3
--- /dev/null
+++ b/intc-modules/intc-health/src/main/java/com/intc/health/domain/MedicationPlan.java
@@ -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;
+}
\ No newline at end of file
diff --git a/intc-modules/intc-health/src/main/java/com/intc/health/domain/MedicationTask.java b/intc-modules/intc-health/src/main/java/com/intc/health/domain/MedicationTask.java
new file mode 100644
index 0000000..235e3cb
--- /dev/null
+++ b/intc-modules/intc-health/src/main/java/com/intc/health/domain/MedicationTask.java
@@ -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;
+}
\ No newline at end of file
diff --git a/intc-modules/intc-health/src/main/java/com/intc/health/domain/dto/ChronicDiseaseRecordDto.java b/intc-modules/intc-health/src/main/java/com/intc/health/domain/dto/ChronicDiseaseRecordDto.java
new file mode 100644
index 0000000..e2d8b76
--- /dev/null
+++ b/intc-modules/intc-health/src/main/java/com/intc/health/domain/dto/ChronicDiseaseRecordDto.java
@@ -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;
+}
\ No newline at end of file
diff --git a/intc-modules/intc-health/src/main/java/com/intc/health/domain/dto/MedicationAdherenceDto.java b/intc-modules/intc-health/src/main/java/com/intc/health/domain/dto/MedicationAdherenceDto.java
new file mode 100644
index 0000000..422edae
--- /dev/null
+++ b/intc-modules/intc-health/src/main/java/com/intc/health/domain/dto/MedicationAdherenceDto.java
@@ -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;
+}
\ No newline at end of file
diff --git a/intc-modules/intc-health/src/main/java/com/intc/health/domain/dto/MedicationPlanDto.java b/intc-modules/intc-health/src/main/java/com/intc/health/domain/dto/MedicationPlanDto.java
new file mode 100644
index 0000000..bb49c58
--- /dev/null
+++ b/intc-modules/intc-health/src/main/java/com/intc/health/domain/dto/MedicationPlanDto.java
@@ -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;
+}
\ No newline at end of file
diff --git a/intc-modules/intc-health/src/main/java/com/intc/health/domain/dto/MedicationTaskDto.java b/intc-modules/intc-health/src/main/java/com/intc/health/domain/dto/MedicationTaskDto.java
new file mode 100644
index 0000000..13a5a4d
--- /dev/null
+++ b/intc-modules/intc-health/src/main/java/com/intc/health/domain/dto/MedicationTaskDto.java
@@ -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;
+}
\ No newline at end of file
diff --git a/intc-modules/intc-health/src/main/java/com/intc/health/domain/vo/ChronicDiseaseRecordVo.java b/intc-modules/intc-health/src/main/java/com/intc/health/domain/vo/ChronicDiseaseRecordVo.java
new file mode 100644
index 0000000..dda41d7
--- /dev/null
+++ b/intc-modules/intc-health/src/main/java/com/intc/health/domain/vo/ChronicDiseaseRecordVo.java
@@ -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;
+
+}
\ No newline at end of file
diff --git a/intc-modules/intc-health/src/main/java/com/intc/health/domain/vo/DailyAdherenceVo.java b/intc-modules/intc-health/src/main/java/com/intc/health/domain/vo/DailyAdherenceVo.java
new file mode 100644
index 0000000..94598c5
--- /dev/null
+++ b/intc-modules/intc-health/src/main/java/com/intc/health/domain/vo/DailyAdherenceVo.java
@@ -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;
+}
\ No newline at end of file
diff --git a/intc-modules/intc-health/src/main/java/com/intc/health/domain/vo/MedicationAdherenceVo.java b/intc-modules/intc-health/src/main/java/com/intc/health/domain/vo/MedicationAdherenceVo.java
new file mode 100644
index 0000000..88db068
--- /dev/null
+++ b/intc-modules/intc-health/src/main/java/com/intc/health/domain/vo/MedicationAdherenceVo.java
@@ -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;
+}
\ No newline at end of file
diff --git a/intc-modules/intc-health/src/main/java/com/intc/health/domain/vo/MedicationPlanVo.java b/intc-modules/intc-health/src/main/java/com/intc/health/domain/vo/MedicationPlanVo.java
new file mode 100644
index 0000000..11615f8
--- /dev/null
+++ b/intc-modules/intc-health/src/main/java/com/intc/health/domain/vo/MedicationPlanVo.java
@@ -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;
+}
\ No newline at end of file
diff --git a/intc-modules/intc-health/src/main/java/com/intc/health/domain/vo/MedicationTaskVo.java b/intc-modules/intc-health/src/main/java/com/intc/health/domain/vo/MedicationTaskVo.java
new file mode 100644
index 0000000..9cb2312
--- /dev/null
+++ b/intc-modules/intc-health/src/main/java/com/intc/health/domain/vo/MedicationTaskVo.java
@@ -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;
+}
\ No newline at end of file
diff --git a/intc-modules/intc-health/src/main/java/com/intc/health/mapper/ChronicDiseaseRecordMapper.java b/intc-modules/intc-health/src/main/java/com/intc/health/mapper/ChronicDiseaseRecordMapper.java
new file mode 100644
index 0000000..8680d1b
--- /dev/null
+++ b/intc-modules/intc-health/src/main/java/com/intc/health/mapper/ChronicDiseaseRecordMapper.java
@@ -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 selectChronicDiseaseRecordList(ChronicDiseaseRecordDto chronicDiseaseRecordDto);
+
+ /**
+ * 根据成员ID查询慢性疾病档案列表
+ *
+ * @param memberId 成员ID
+ * @return 慢性疾病档案集合
+ */
+ public List 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);
+}
\ No newline at end of file
diff --git a/intc-modules/intc-health/src/main/java/com/intc/health/mapper/MedicationPlanMapper.java b/intc-modules/intc-health/src/main/java/com/intc/health/mapper/MedicationPlanMapper.java
new file mode 100644
index 0000000..44c56b3
--- /dev/null
+++ b/intc-modules/intc-health/src/main/java/com/intc/health/mapper/MedicationPlanMapper.java
@@ -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 selectList(MedicationPlanDto dto);
+
+ /**
+ * 查询执行中的用药计划列表(用于生成任务)
+ */
+ List 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);
+}
\ No newline at end of file
diff --git a/intc-modules/intc-health/src/main/java/com/intc/health/mapper/MedicationTaskMapper.java b/intc-modules/intc-health/src/main/java/com/intc/health/mapper/MedicationTaskMapper.java
new file mode 100644
index 0000000..993cdfd
--- /dev/null
+++ b/intc-modules/intc-health/src/main/java/com/intc/health/mapper/MedicationTaskMapper.java
@@ -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 selectList(MedicationTaskDto dto);
+
+ /**
+ * 新增服药任务
+ */
+ int insert(MedicationTask task);
+
+ /**
+ * 批量新增服药任务
+ */
+ int batchInsert(List 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 selectPendingRemind(@Param("startTime") LocalDateTime startTime, @Param("endTime") LocalDateTime endTime);
+
+ // ========== 依从性统计 ==========
+
+ /**
+ * 获取总体统计
+ */
+ java.util.Map getOverallStats(@Param("personId") Long personId,
+ @Param("startDate") LocalDate startDate,
+ @Param("endDate") LocalDate endDate);
+
+ /**
+ * 获取每日统计
+ */
+ List> getDailyStats(@Param("personId") Long personId,
+ @Param("startDate") LocalDate startDate,
+ @Param("endDate") LocalDate endDate);
+
+ /**
+ * 获取时段统计
+ */
+ List> getTimeSlotStats(@Param("personId") Long personId,
+ @Param("startDate") LocalDate startDate,
+ @Param("endDate") LocalDate endDate);
+}
\ No newline at end of file
diff --git a/intc-modules/intc-health/src/main/java/com/intc/health/service/IChronicDiseaseRecordService.java b/intc-modules/intc-health/src/main/java/com/intc/health/service/IChronicDiseaseRecordService.java
new file mode 100644
index 0000000..8a07b49
--- /dev/null
+++ b/intc-modules/intc-health/src/main/java/com/intc/health/service/IChronicDiseaseRecordService.java
@@ -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 selectChronicDiseaseRecordList(ChronicDiseaseRecordDto chronicDiseaseRecordDto);
+
+ /**
+ * 根据成员ID查询慢性疾病档案列表
+ *
+ * @param memberId 成员ID
+ * @return 慢性疾病档案集合
+ */
+ public List 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);
+}
\ No newline at end of file
diff --git a/intc-modules/intc-health/src/main/java/com/intc/health/service/IMedicationAdherenceService.java b/intc-modules/intc-health/src/main/java/com/intc/health/service/IMedicationAdherenceService.java
new file mode 100644
index 0000000..8d4b5e4
--- /dev/null
+++ b/intc-modules/intc-health/src/main/java/com/intc/health/service/IMedicationAdherenceService.java
@@ -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 getDailyAdherenceList(Long memberId, LocalDate startDate, LocalDate endDate);
+
+ /**
+ * 获取日历视图数据
+ */
+ List getCalendarData(Long memberId, String yearMonth);
+
+ /**
+ * 获取各时段服药统计
+ */
+ Map getTimeSlotAdherence(Long memberId, LocalDate startDate, LocalDate endDate);
+}
\ No newline at end of file
diff --git a/intc-modules/intc-health/src/main/java/com/intc/health/service/IMedicationPlanService.java b/intc-modules/intc-health/src/main/java/com/intc/health/service/IMedicationPlanService.java
new file mode 100644
index 0000000..0a5df55
--- /dev/null
+++ b/intc-modules/intc-health/src/main/java/com/intc/health/service/IMedicationPlanService.java
@@ -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 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);
+}
\ No newline at end of file
diff --git a/intc-modules/intc-health/src/main/java/com/intc/health/service/IMedicationTaskService.java b/intc-modules/intc-health/src/main/java/com/intc/health/service/IMedicationTaskService.java
new file mode 100644
index 0000000..af445b9
--- /dev/null
+++ b/intc-modules/intc-health/src/main/java/com/intc/health/service/IMedicationTaskService.java
@@ -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 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);
+}
\ No newline at end of file
diff --git a/intc-modules/intc-health/src/main/java/com/intc/health/service/impl/ChronicDiseaseRecordServiceImpl.java b/intc-modules/intc-health/src/main/java/com/intc/health/service/impl/ChronicDiseaseRecordServiceImpl.java
new file mode 100644
index 0000000..8c6de32
--- /dev/null
+++ b/intc-modules/intc-health/src/main/java/com/intc/health/service/impl/ChronicDiseaseRecordServiceImpl.java
@@ -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 selectChronicDiseaseRecordList(ChronicDiseaseRecordDto chronicDiseaseRecordDto)
+ {
+ return chronicDiseaseRecordMapper.selectChronicDiseaseRecordList(chronicDiseaseRecordDto);
+ }
+
+ /**
+ * 根据成员ID查询慢性疾病档案列表
+ *
+ * @param memberId 成员ID
+ * @return 慢性疾病档案集合
+ */
+ @Override
+ public List 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);
+ }
+}
\ No newline at end of file
diff --git a/intc-modules/intc-health/src/main/java/com/intc/health/service/impl/MedicationAdherenceServiceImpl.java b/intc-modules/intc-health/src/main/java/com/intc/health/service/impl/MedicationAdherenceServiceImpl.java
new file mode 100644
index 0000000..e16a7d6
--- /dev/null
+++ b/intc-modules/intc-health/src/main/java/com/intc/health/service/impl/MedicationAdherenceServiceImpl.java
@@ -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 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 getDailyAdherenceList(Long memberId, LocalDate startDate, LocalDate endDate) {
+ List