소스 검색

新增
1、新增长者特殊护理计划执行日志模块
2、新增根据楼层ID获取长者未完成的特殊照护计划明细接口
3、新增执行特殊照护计划接口
BUGFIX
1、解决删除消费券时对应月账单已经删除报错问题
2、解决批量账单生成,异步执行任务中执行业务前没有初始化threadLocal导致偶然生成账单金额错误问题
3、解决撤销账单没有对明细的已缴金额字段进行初始化问题

liangwenxuan 3 주 전
부모
커밋
049f37b9f6
28개의 변경된 파일691개의 추가작업 그리고 131개의 파일을 삭제
  1. 0 1
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/bpm/BpmElderlyChangeApiImpl.java
  2. 12 8
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/biz/ExpenseOrderController.java
  3. 52 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/nursing/ElderlySpecialNursingLogController.java
  4. 14 38
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/nursing/SpecialNursingPlanItemController.java
  5. 28 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/nursing/vo/ElderlySpecialNursingLogListReqVO.java
  6. 29 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/nursing/vo/ElderlySpecialNursingLogPageReqVO.java
  7. 42 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/nursing/vo/ElderlySpecialNursingLogRespVO.java
  8. 35 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/nursing/vo/SpecialNursingPlanItemExecuteReqVO.java
  9. 0 15
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/nursing/vo/SpecialNursingPlanItemSaveReqVO.java
  10. 20 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/nursing/vo/SpecialNursingPlanItemUnfinishedByFloorRespVO.java
  11. 4 1
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/nursing/vo/SpecialNursingPlanRespVO.java
  12. 4 1
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/nursing/vo/SpecialNursingPlanSaveReqVO.java
  13. 50 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/biz/ElderlySpecialNursingLogDO.java
  14. 1 1
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/biz/ElderlySpecialNursingPlanDO.java
  15. 1 1
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/biz/ElderlySpecialNursingPlanItemDO.java
  16. 19 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/biz/ElderlySpecialNursingLogMapper.java
  17. 10 10
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/biz/SpecialNursingPlanItemMapper.java
  18. 8 8
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/biz/SpecialNursingPlanMapper.java
  19. 8 4
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/biz/ElderlyConsumerVouchersServiceImpl.java
  20. 1 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/biz/ExpenseOrderServiceImpl.java
  21. 1 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/biz/ExpenseServiceImpl.java
  22. 16 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/nursing/ElderlySpecialNursingLogService.java
  23. 97 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/nursing/ElderlySpecialNursingLogServiceImpl.java
  24. 6 12
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/nursing/SpecialNursingPlanItemService.java
  25. 147 24
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/nursing/SpecialNursingPlanItemServiceImpl.java
  26. 45 7
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/nursing/SpecialNursingPlanServiceImpl.java
  27. 39 0
      yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/ElderlySpecialNursingLogMapper.xml
  28. 2 0
      yudao-server/src/main/resources/application.yaml

+ 0 - 1
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/bpm/BpmElderlyChangeApiImpl.java

@@ -340,7 +340,6 @@ public class BpmElderlyChangeApiImpl implements BpmElderlyChangeApi {
             // 最终价格 = 新 - 原
             finalAmount = changeFinalAmount.subtract(currentFinalAmount);
         }
-        log.info("创建人:{}", SecurityFrameworkUtils.getLoginUserNickname());
         if(finalAmount.compareTo(BigDecimal.ZERO) != 0){
             Date currentDate = new Date();
             BigDecimal dailyExpensesDOAmount = finalAmount;

+ 12 - 8
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/biz/ExpenseOrderController.java

@@ -6,6 +6,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
 import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
 import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
+import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils;
 import cn.iocoder.yudao.module.system.controller.admin.biz.task.TaskStatusManager;
 import cn.iocoder.yudao.module.system.controller.admin.biz.vo.*;
 import cn.iocoder.yudao.module.system.controller.admin.biz.vo.excel.ElderlyExpenseOrderExportExcelVO;
@@ -204,13 +205,16 @@ public class ExpenseOrderController {
 
             // 异步执行任务
             CompletableFuture.runAsync(() -> {
-                try {
-                    // 调用你现有的异步方法
-                    expenseOrderService.batchGenerateExpenseBill(saveVO, taskId);
-                    taskStatusManager.completeTask(taskId);
-                } catch (Exception e) {
-                    taskStatusManager.failTask(taskId, e.getMessage());
-                }
+                TenantUtils.executeIgnore(() -> {
+                    try {
+                        expenseOrderService.batchGenerateExpenseBill(saveVO, taskId);
+                        taskStatusManager.completeTask(taskId);
+                    } catch (Exception e) {
+                        taskStatusManager.failTask(taskId, e.getMessage());
+                    } finally {
+                        TenantContextHolder.clear();
+                    }
+                });
             });
 
             // 立即返回任务ID
@@ -333,4 +337,4 @@ public class ExpenseOrderController {
     public CommonResult<List<ExpenseOrderDO>> getBillOrderList(ExpenseBillPageReqVO pageReqVO) {
         return success(expenseOrderService.getBillOrderList(pageReqVO));
     }
-}
+}

+ 52 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/nursing/ElderlySpecialNursingLogController.java

@@ -0,0 +1,52 @@
+package cn.iocoder.yudao.module.system.controller.admin.nursing;
+
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
+import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
+import cn.iocoder.yudao.module.system.controller.admin.nursing.vo.ElderlySpecialNursingLogListReqVO;
+import cn.iocoder.yudao.module.system.controller.admin.nursing.vo.ElderlySpecialNursingLogPageReqVO;
+import cn.iocoder.yudao.module.system.controller.admin.nursing.vo.ElderlySpecialNursingLogRespVO;
+import cn.iocoder.yudao.module.system.service.nursing.ElderlySpecialNursingLogService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.validation.Valid;
+import java.util.List;
+import java.util.Objects;
+
+import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+
+@Tag(name = "管理后台 - 长者特殊护理计划执行日志")
+@RestController
+@RequestMapping("/nursing/special-nursing-log")
+@Validated
+public class ElderlySpecialNursingLogController {
+
+    @Resource
+    private ElderlySpecialNursingLogService elderlySpecialNursingLogService;
+
+    @GetMapping("/page")
+    @Operation(summary = "获得长者特殊护理计划执行日志分页")
+    @TenantIgnore
+    public CommonResult<PageResult<ElderlySpecialNursingLogRespVO>> getPage(@Valid ElderlySpecialNursingLogPageReqVO pageReqVO) {
+        pageReqVO.setTenantIds(Objects.isNull(pageReqVO.getTenantIds())
+                ? new Long[]{TenantContextHolder.getTenantId()} : pageReqVO.getTenantIds());
+        return success(elderlySpecialNursingLogService.getPage(pageReqVO));
+    }
+
+    @GetMapping("/list-by-elder-and-finish-time")
+    @Operation(summary = "根据长者ID和完成日期范围查询执行日志")
+    @TenantIgnore
+    public CommonResult<List<ElderlySpecialNursingLogRespVO>> getListByElderIdAndFinishTime(@Valid ElderlySpecialNursingLogListReqVO listReqVO) {
+        listReqVO.setTenantId(Objects.isNull(listReqVO.getTenantId())
+                ? TenantContextHolder.getTenantId() : listReqVO.getTenantId());
+        return success(elderlySpecialNursingLogService.getListByElderIdAndFinishTime(listReqVO));
+    }
+}
+

+ 14 - 38
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/nursing/SpecialNursingPlanItemController.java

@@ -1,12 +1,10 @@
 package cn.iocoder.yudao.module.system.controller.admin.nursing;
 
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
-import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
-import cn.iocoder.yudao.module.system.controller.admin.nursing.vo.SpecialNursingPlanItemPageReqVO;
-import cn.iocoder.yudao.module.system.controller.admin.nursing.vo.SpecialNursingPlanItemRespVO;
+import cn.iocoder.yudao.module.system.controller.admin.nursing.vo.SpecialNursingPlanItemExecuteReqVO;
 import cn.iocoder.yudao.module.system.controller.admin.nursing.vo.SpecialNursingPlanItemSaveReqVO;
+import cn.iocoder.yudao.module.system.controller.admin.nursing.vo.SpecialNursingPlanItemUnfinishedByFloorRespVO;
 import cn.iocoder.yudao.module.system.service.nursing.SpecialNursingPlanItemService;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.Parameter;
@@ -15,7 +13,9 @@ import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
 import javax.annotation.Resource;
+import javax.annotation.security.PermitAll;
 import javax.validation.Valid;
+import java.util.List;
 
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
 
@@ -28,51 +28,27 @@ public class SpecialNursingPlanItemController {
     @Resource
     private SpecialNursingPlanItemService specialNursingPlanItemService;
 
-    @PostMapping("/create")
-    @Operation(summary = "创建特殊照护计划明细")
-    public CommonResult<Long> create(@Valid @RequestBody SpecialNursingPlanItemSaveReqVO createReqVO) {
-        if (createReqVO.getTenantId() == null) {
-            createReqVO.setTenantId(TenantContextHolder.getTenantId());
-        }
-        return success(specialNursingPlanItemService.create(createReqVO));
-    }
-
     @PutMapping("/update")
     @Operation(summary = "更新特殊照护计划明细")
     @TenantIgnore
     public CommonResult<Boolean> update(@Valid @RequestBody SpecialNursingPlanItemSaveReqVO updateReqVO) {
-        if (updateReqVO.getTenantId() == null) {
-            updateReqVO.setTenantId(TenantContextHolder.getTenantId());
-        }
         specialNursingPlanItemService.update(updateReqVO);
         return success(true);
     }
-
-    @DeleteMapping("/delete")
-    @Operation(summary = "删除特殊照护计划明细")
-    @Parameter(name = "id", description = "编号", required = true)
+    @PostMapping("/execute")
+    @Operation(summary = "执行特殊照护计划")
     @TenantIgnore
-    public CommonResult<Boolean> delete(@RequestParam("id") Long id) {
-        specialNursingPlanItemService.delete(id);
+    public CommonResult<Boolean> execute(@Valid @RequestBody SpecialNursingPlanItemExecuteReqVO executeReqVO) {
+        specialNursingPlanItemService.executePlan(executeReqVO);
         return success(true);
     }
 
-    @GetMapping("/get")
-    @Operation(summary = "获得特殊照护计划明细详情")
-    @Parameter(name = "id", description = "编号", required = true, example = "1")
+    @GetMapping("/getUnfinishedByFloorId")
+    @Operation(summary = "根据楼层ID获取长者未完成的特殊照护计划明细")
+    @Parameter(name = "floorId", description = "楼层ID", required = true, example = "1024")
     @TenantIgnore
-    public CommonResult<SpecialNursingPlanItemRespVO> get(@RequestParam("id") Long id) {
-        return success(specialNursingPlanItemService.get(id));
-    }
-
-    @GetMapping("/page")
-    @Operation(summary = "获得特殊照护计划明细分页")
-    @TenantIgnore
-    public CommonResult<PageResult<SpecialNursingPlanItemRespVO>> page(@Valid SpecialNursingPlanItemPageReqVO pageReqVO) {
-        if (pageReqVO.getTenantIds() == null) {
-            pageReqVO.setTenantIds(new Long[]{TenantContextHolder.getTenantId()});
-        }
-        return success(specialNursingPlanItemService.getPage(pageReqVO));
+    @PermitAll
+    public CommonResult<List<SpecialNursingPlanItemUnfinishedByFloorRespVO>> getUnfinishedByFloorId(@RequestParam("floorId") Long floorId) {
+        return success(specialNursingPlanItemService.getUnfinishedByFloorId(floorId));
     }
 }
-

+ 28 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/nursing/vo/ElderlySpecialNursingLogListReqVO.java

@@ -0,0 +1,28 @@
+package cn.iocoder.yudao.module.system.controller.admin.nursing.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import javax.validation.constraints.NotNull;
+import java.time.LocalDate;
+
+import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY;
+
+@Schema(description = "管理后台 - 长者特殊护理计划执行日志列表 Request VO")
+@Data
+public class ElderlySpecialNursingLogListReqVO {
+
+    @Schema(description = "长者ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+    @NotNull(message = "长者ID不能为空")
+    private Long elderId;
+
+    @Schema(description = "完成日期范围", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotNull(message = "完成日期范围不能为空")
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY)
+    private LocalDate[] finishTime;
+
+    @Schema(description = "租户ID", example = "1")
+    private Long tenantId;
+}
+

+ 29 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/nursing/vo/ElderlySpecialNursingLogPageReqVO.java

@@ -0,0 +1,29 @@
+package cn.iocoder.yudao.module.system.controller.admin.nursing.vo;
+
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.time.LocalDate;
+
+import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY;
+
+@Schema(description = "管理后台 - 长者特殊护理计划执行日志分页 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class ElderlySpecialNursingLogPageReqVO extends PageParam {
+
+    @Schema(description = "长者姓名(模糊匹配)")
+    private String elderName;
+
+    @Schema(description = "长者ID", example = "1")
+    private Long elderId;
+
+    @Schema(description = "租户ID数组")
+    private Long[] tenantIds;
+}
+

+ 42 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/nursing/vo/ElderlySpecialNursingLogRespVO.java

@@ -0,0 +1,42 @@
+package cn.iocoder.yudao.module.system.controller.admin.nursing.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Schema(description = "管理后台 - 长者特殊护理计划执行日志 Response VO")
+@Data
+public class ElderlySpecialNursingLogRespVO {
+
+    @Schema(description = "id", example = "1")
+    private Long id;
+
+    @Schema(description = "特殊护理计划明细id", example = "1")
+    private Long specialPlanItemId;
+
+    @Schema(description = "长者id", example = "1")
+    private Long elderId;
+
+    @Schema(description = "长者姓名")
+    private String elderName;
+
+    @Schema(description = "床号")
+    private String bedName;
+
+    @Schema(description = "护理等级")
+    private String nurseLevelName;
+
+    @Schema(description = "完成时间")
+    private LocalDateTime finishTime;
+
+    @Schema(description = "备注")
+    private String remark;
+
+    @Schema(description = "图片")
+    private String imageUrl;
+
+    @Schema(description = "租户ID", example = "1")
+    private Long tenantId;
+}
+

+ 35 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/nursing/vo/SpecialNursingPlanItemExecuteReqVO.java

@@ -0,0 +1,35 @@
+package cn.iocoder.yudao.module.system.controller.admin.nursing.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+import java.time.LocalDateTime;
+
+@Schema(description = "管理后台 - 特殊照护计划明细执行 Request VO")
+@Data
+public class SpecialNursingPlanItemExecuteReqVO {
+
+    @Schema(description = "长者id", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+    @NotNull(message = "长者id不能为空")
+    private Long elderId;
+
+    @Schema(description = "特殊护理计划明细id", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+    @NotNull(message = "特殊护理计划明细id不能为空")
+    private Long specialPlanItemId;
+
+    @Schema(description = "完成时间", requiredMode = Schema.RequiredMode.REQUIRED)
+    @NotNull(message = "完成时间不能为空")
+    private LocalDateTime finishTime;
+
+    @Schema(description = "备注")
+    private String remark;
+
+    @Schema(description = "图片")
+    private String imageUrl;
+
+    @Schema(description = "租户ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+    @NotNull(message = "租户ID不能为空")
+    private Long tenantId;
+}
+

+ 0 - 15
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/nursing/vo/SpecialNursingPlanItemSaveReqVO.java

@@ -12,22 +12,7 @@ public class SpecialNursingPlanItemSaveReqVO {
     @Schema(description = "主键ID(修改时必传)", example = "1")
     private Long id;
 
-    @Schema(description = "特殊护理计划ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
-    @NotNull(message = "特殊护理计划ID不能为空")
-    private Long specialNursingPlanId;
-
-    @Schema(description = "护理项目ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
-    @NotNull(message = "护理项目ID不能为空")
-    private Long nurseItemId;
-
-    @Schema(description = "护理项目名称")
-    private String nurseItemName;
-
     @Schema(description = "状态,0:未完成,1:已完成")
     private Integer status;
-
-    @Schema(description = "租户ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
-    @NotNull(message = "租户ID不能为空")
-    private Long tenantId;
 }
 

+ 20 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/nursing/vo/SpecialNursingPlanItemUnfinishedByFloorRespVO.java

@@ -0,0 +1,20 @@
+package cn.iocoder.yudao.module.system.controller.admin.nursing.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.util.List;
+
+@Schema(description = "管理后台 - 楼层长者未完成特殊照护计划明细 Response VO")
+@Data
+public class SpecialNursingPlanItemUnfinishedByFloorRespVO {
+
+    @Schema(description = "长者名称")
+    private String elderName;
+
+    @Schema(description = "长者id")
+    private Long elderId;
+
+    @Schema(description = "未完成特殊照护计划明细列表")
+    private List<SpecialNursingPlanItemRespVO> specialItem;
+}

+ 4 - 1
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/nursing/vo/SpecialNursingPlanRespVO.java

@@ -4,6 +4,7 @@ import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 
 import java.time.LocalDateTime;
+import java.util.List;
 
 @Schema(description = "管理后台 - 特殊照护计划 Response VO")
 @Data
@@ -32,5 +33,7 @@ public class SpecialNursingPlanRespVO {
 
     @Schema(description = "更新人")
     private String updater;
-}
 
+    @Schema(description = "护理计划明细列表")
+    private List<SpecialNursingPlanItemRespVO> items;
+}

+ 4 - 1
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/nursing/vo/SpecialNursingPlanSaveReqVO.java

@@ -4,6 +4,7 @@ import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
 
 import javax.validation.constraints.NotNull;
+import java.util.List;
 
 @Schema(description = "管理后台 - 特殊照护计划新增/修改 Request VO")
 @Data
@@ -22,5 +23,7 @@ public class SpecialNursingPlanSaveReqVO {
     @Schema(description = "租户ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
     @NotNull(message = "租户ID不能为空")
     private Long tenantId;
-}
 
+    @Schema(description = "护理计划明细列表")
+    private List<SpecialNursingPlanItemSaveReqVO> items;
+}

+ 50 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/biz/ElderlySpecialNursingLogDO.java

@@ -0,0 +1,50 @@
+package cn.iocoder.yudao.module.system.dal.dataobject.biz;
+
+import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseNoDeleteDO;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import lombok.ToString;
+
+import java.time.LocalDateTime;
+
+/**
+ * 长者特殊护理计划执行日志 DO
+ */
+@TableName("elderly_special_nursing_log")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class ElderlySpecialNursingLogDO extends BaseNoDeleteDO {
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    @Schema(description = "特殊护理计划明细id")
+    private Long specialPlanItemId;
+
+    @Schema(description = "长者id")
+    private Long elderId;
+
+    @Schema(description = "完成时间")
+    private LocalDateTime finishTime;
+
+    @Schema(description = "备注")
+    private String remark;
+
+    @Schema(description = "图片")
+    private String imageUrl;
+
+    @Schema(description = "租户ID")
+    private Long tenantId;
+}
+

+ 1 - 1
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/biz/SpecialNursingPlanDO.java → yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/biz/ElderlySpecialNursingPlanDO.java

@@ -22,7 +22,7 @@ import lombok.ToString;
 @Builder
 @NoArgsConstructor
 @AllArgsConstructor
-public class SpecialNursingPlanDO extends BaseNoDeleteDO {
+public class ElderlySpecialNursingPlanDO extends BaseNoDeleteDO {
 
     @TableId(value = "id", type = IdType.AUTO)
     private Long id;

+ 1 - 1
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/biz/SpecialNursingPlanItemDO.java → yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/biz/ElderlySpecialNursingPlanItemDO.java

@@ -22,7 +22,7 @@ import lombok.ToString;
 @Builder
 @NoArgsConstructor
 @AllArgsConstructor
-public class SpecialNursingPlanItemDO extends BaseNoDeleteDO {
+public class ElderlySpecialNursingPlanItemDO extends BaseNoDeleteDO {
 
     @TableId(value = "id", type = IdType.AUTO)
     private Long id;

+ 19 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/biz/ElderlySpecialNursingLogMapper.java

@@ -0,0 +1,19 @@
+package cn.iocoder.yudao.module.system.dal.mysql.biz;
+
+import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
+import cn.iocoder.yudao.module.system.controller.admin.nursing.vo.ElderlySpecialNursingLogPageReqVO;
+import cn.iocoder.yudao.module.system.controller.admin.nursing.vo.ElderlySpecialNursingLogRespVO;
+import cn.iocoder.yudao.module.system.dal.dataobject.biz.ElderlySpecialNursingLogDO;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+@Mapper
+public interface ElderlySpecialNursingLogMapper extends BaseMapperX<ElderlySpecialNursingLogDO> {
+
+    List<ElderlySpecialNursingLogRespVO> selectPageWithElderInfo(@Param("page") Page<ElderlySpecialNursingLogRespVO> page,
+                                                                 @Param("pageVO") ElderlySpecialNursingLogPageReqVO pageReqVO);
+}

+ 10 - 10
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/biz/SpecialNursingPlanItemMapper.java

@@ -4,20 +4,20 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
 import cn.iocoder.yudao.module.system.controller.admin.nursing.vo.SpecialNursingPlanItemPageReqVO;
-import cn.iocoder.yudao.module.system.dal.dataobject.biz.SpecialNursingPlanItemDO;
+import cn.iocoder.yudao.module.system.dal.dataobject.biz.ElderlySpecialNursingPlanItemDO;
 import org.apache.ibatis.annotations.Mapper;
 
 @Mapper
-public interface SpecialNursingPlanItemMapper extends BaseMapperX<SpecialNursingPlanItemDO> {
+public interface SpecialNursingPlanItemMapper extends BaseMapperX<ElderlySpecialNursingPlanItemDO> {
 
-    default PageResult<SpecialNursingPlanItemDO> selectPage(SpecialNursingPlanItemPageReqVO reqVO) {
-        return selectPage(reqVO, new LambdaQueryWrapperX<SpecialNursingPlanItemDO>()
-                .eqIfPresent(SpecialNursingPlanItemDO::getSpecialNursingPlanId, reqVO.getSpecialNursingPlanId())
-                .eqIfPresent(SpecialNursingPlanItemDO::getNurseItemId, reqVO.getNurseItemId())
-                .likeIfPresent(SpecialNursingPlanItemDO::getNurseItemName, reqVO.getNurseItemName())
-                .eqIfPresent(SpecialNursingPlanItemDO::getStatus, reqVO.getStatus())
-                .inIfPresent(SpecialNursingPlanItemDO::getTenantId, reqVO.getTenantIds())
-                .orderByDesc(SpecialNursingPlanItemDO::getId));
+    default PageResult<ElderlySpecialNursingPlanItemDO> selectPage(SpecialNursingPlanItemPageReqVO reqVO) {
+        return selectPage(reqVO, new LambdaQueryWrapperX<ElderlySpecialNursingPlanItemDO>()
+                .eqIfPresent(ElderlySpecialNursingPlanItemDO::getSpecialNursingPlanId, reqVO.getSpecialNursingPlanId())
+                .eqIfPresent(ElderlySpecialNursingPlanItemDO::getNurseItemId, reqVO.getNurseItemId())
+                .likeIfPresent(ElderlySpecialNursingPlanItemDO::getNurseItemName, reqVO.getNurseItemName())
+                .eqIfPresent(ElderlySpecialNursingPlanItemDO::getStatus, reqVO.getStatus())
+                .inIfPresent(ElderlySpecialNursingPlanItemDO::getTenantId, reqVO.getTenantIds())
+                .orderByDesc(ElderlySpecialNursingPlanItemDO::getId));
     }
 }
 

+ 8 - 8
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/biz/SpecialNursingPlanMapper.java

@@ -4,18 +4,18 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
 import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
 import cn.iocoder.yudao.module.system.controller.admin.nursing.vo.SpecialNursingPlanPageReqVO;
-import cn.iocoder.yudao.module.system.dal.dataobject.biz.SpecialNursingPlanDO;
+import cn.iocoder.yudao.module.system.dal.dataobject.biz.ElderlySpecialNursingPlanDO;
 import org.apache.ibatis.annotations.Mapper;
 
 @Mapper
-public interface SpecialNursingPlanMapper extends BaseMapperX<SpecialNursingPlanDO> {
+public interface SpecialNursingPlanMapper extends BaseMapperX<ElderlySpecialNursingPlanDO> {
 
-    default PageResult<SpecialNursingPlanDO> selectPage(SpecialNursingPlanPageReqVO reqVO) {
-        return selectPage(reqVO, new LambdaQueryWrapperX<SpecialNursingPlanDO>()
-                .eqIfPresent(SpecialNursingPlanDO::getElderId, reqVO.getElderId())
-                .likeIfPresent(SpecialNursingPlanDO::getElderName, reqVO.getElderName())
-                .inIfPresent(SpecialNursingPlanDO::getTenantId, reqVO.getTenantIds())
-                .orderByDesc(SpecialNursingPlanDO::getId));
+    default PageResult<ElderlySpecialNursingPlanDO> selectPage(SpecialNursingPlanPageReqVO reqVO) {
+        return selectPage(reqVO, new LambdaQueryWrapperX<ElderlySpecialNursingPlanDO>()
+                .eqIfPresent(ElderlySpecialNursingPlanDO::getElderId, reqVO.getElderId())
+                .likeIfPresent(ElderlySpecialNursingPlanDO::getElderName, reqVO.getElderName())
+                .inIfPresent(ElderlySpecialNursingPlanDO::getTenantId, reqVO.getTenantIds())
+                .orderByDesc(ElderlySpecialNursingPlanDO::getId));
     }
 }
 

+ 8 - 4
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/biz/ElderlyConsumerVouchersServiceImpl.java

@@ -80,10 +80,14 @@ public class ElderlyConsumerVouchersServiceImpl implements ElderlyConsumerVouche
     public void delete(Long id) {
         validateExists(id);
         ExpenseOrderItemDO expenseOrderItemDO = expenseOrderItemMapper.selectOne(new LambdaQueryWrapperX<ExpenseOrderItemDO>().eq(ExpenseOrderItemDO::getSourceExpenseItemId, id));
-        ExpenseOrderDO expenseOrderDO = expenseOrderMapper.selectById(expenseOrderItemDO.getExpenseOrderId());
-        expenseOrderDO.setActualAmount(expenseOrderDO.getActualAmount().subtract(expenseOrderItemDO.getTotalAmount()));
-        expenseOrderMapper.updateById(expenseOrderDO);
-        expenseOrderItemMapper.deleteById(expenseOrderItemDO);
+        if(expenseOrderItemDO != null){
+            expenseOrderItemMapper.deleteById(expenseOrderItemDO);
+            ExpenseOrderDO expenseOrderDO = expenseOrderMapper.selectById(expenseOrderItemDO.getExpenseOrderId());
+            if(expenseOrderDO != null){
+                expenseOrderDO.setActualAmount(expenseOrderDO.getActualAmount().subtract(expenseOrderItemDO.getTotalAmount()));
+                expenseOrderMapper.updateById(expenseOrderDO);
+            }
+        }
         elderlyConsumerVouchersMapper.deleteById(id);
         deleteRefundOrderItem(id);
     }

+ 1 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/biz/ExpenseOrderServiceImpl.java

@@ -2666,6 +2666,7 @@ public class ExpenseOrderServiceImpl implements ExpenseOrderService {
                 .set(ExpenseOrderItemDO::getPayStatus, BooleanEnum.FALSE.getValue())
                 .set(ExpenseOrderItemDO::getPayTime, null)
                 .set(ExpenseOrderItemDO::getPayOrderId, null)
+                .set(ExpenseOrderItemDO::getPayAmount,BigDecimal.ZERO)
                 .eq(ExpenseOrderItemDO::getExpenseOrderId, id));
 
         // 6. 更新账单状态为未缴费

+ 1 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/biz/ExpenseServiceImpl.java

@@ -491,6 +491,7 @@ public class ExpenseServiceImpl implements ExpenseService {
         BeanUtils.copyProperties(createReqVO, expense);
         expense.setCreatedTime(new Date());
         expense.setCreatedBy(SecurityFrameworkUtils.getLoginUserNickname());
+        expense.setTenantId(TenantContextHolder.getTenantId());
         expenseMapper.insert(expense);
 
         updateElderlyInfo(createReqVO, expense);

+ 16 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/nursing/ElderlySpecialNursingLogService.java

@@ -0,0 +1,16 @@
+package cn.iocoder.yudao.module.system.service.nursing;
+
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.module.system.controller.admin.nursing.vo.ElderlySpecialNursingLogListReqVO;
+import cn.iocoder.yudao.module.system.controller.admin.nursing.vo.ElderlySpecialNursingLogPageReqVO;
+import cn.iocoder.yudao.module.system.controller.admin.nursing.vo.ElderlySpecialNursingLogRespVO;
+
+import java.util.List;
+
+public interface ElderlySpecialNursingLogService {
+
+    PageResult<ElderlySpecialNursingLogRespVO> getPage(ElderlySpecialNursingLogPageReqVO pageReqVO);
+
+    List<ElderlySpecialNursingLogRespVO> getListByElderIdAndFinishTime(ElderlySpecialNursingLogListReqVO listReqVO);
+}
+

+ 97 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/nursing/ElderlySpecialNursingLogServiceImpl.java

@@ -0,0 +1,97 @@
+package cn.iocoder.yudao.module.system.service.nursing;
+
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
+import cn.iocoder.yudao.module.system.controller.admin.nursing.vo.ElderlySpecialNursingLogListReqVO;
+import cn.iocoder.yudao.module.system.controller.admin.nursing.vo.ElderlySpecialNursingLogPageReqVO;
+import cn.iocoder.yudao.module.system.controller.admin.nursing.vo.ElderlySpecialNursingLogRespVO;
+import cn.iocoder.yudao.module.system.dal.dataobject.biz.ElderlyInfoDO;
+import cn.iocoder.yudao.module.system.dal.dataobject.biz.ElderlySpecialNursingLogDO;
+import cn.iocoder.yudao.module.system.dal.mysql.biz.ElderlyInfoMapper;
+import cn.iocoder.yudao.module.system.dal.mysql.biz.ElderlySpecialNursingLogMapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.springframework.stereotype.Service;
+import org.springframework.validation.annotation.Validated;
+
+import javax.annotation.Resource;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.util.*;
+import java.util.stream.Collectors;
+
+@Service
+@Validated
+public class ElderlySpecialNursingLogServiceImpl implements ElderlySpecialNursingLogService {
+
+    @Resource
+    private ElderlySpecialNursingLogMapper elderlySpecialNursingLogMapper;
+    @Resource
+    private ElderlyInfoMapper elderlyInfoMapper;
+
+    @Override
+    public PageResult<ElderlySpecialNursingLogRespVO> getPage(ElderlySpecialNursingLogPageReqVO pageReqVO) {
+
+        Page<ElderlySpecialNursingLogRespVO> page = new Page<>(pageReqVO.getPageNo(), pageReqVO.getPageSize());
+        List<ElderlySpecialNursingLogRespVO> records = elderlySpecialNursingLogMapper
+                .selectPageWithElderInfo(page, pageReqVO);
+        page.setRecords(records);
+        return new PageResult<>(records, page.getTotal());
+    }
+
+    @Override
+    public List<ElderlySpecialNursingLogRespVO> getListByElderIdAndFinishTime(ElderlySpecialNursingLogListReqVO listReqVO) {
+        LocalDateTime begin = toBegin(listReqVO.getFinishTime());
+        LocalDateTime endExclusive = toEndExclusive(listReqVO.getFinishTime());
+
+        LambdaQueryWrapperX<ElderlySpecialNursingLogDO> wrapper = new LambdaQueryWrapperX<ElderlySpecialNursingLogDO>()
+                .eq(ElderlySpecialNursingLogDO::getElderId, listReqVO.getElderId())
+                .eqIfPresent(ElderlySpecialNursingLogDO::getTenantId, listReqVO.getTenantId())
+                .geIfPresent(ElderlySpecialNursingLogDO::getFinishTime, begin)
+                .ltIfPresent(ElderlySpecialNursingLogDO::getFinishTime, endExclusive)
+                .orderByDesc(ElderlySpecialNursingLogDO::getFinishTime)
+                .orderByDesc(ElderlySpecialNursingLogDO::getId);
+        List<ElderlySpecialNursingLogDO> list = elderlySpecialNursingLogMapper.selectList(wrapper);
+        if (list.isEmpty()) {
+            return Collections.emptyList();
+        }
+        List<ElderlySpecialNursingLogRespVO> respList = BeanUtils.toBean(list, ElderlySpecialNursingLogRespVO.class);
+        enrichElderInfo(respList);
+        return respList;
+    }
+
+    private void enrichElderInfo(List<ElderlySpecialNursingLogRespVO> respList) {
+        Set<Long> elderIds = respList.stream()
+                .map(ElderlySpecialNursingLogRespVO::getElderId)
+                .filter(Objects::nonNull)
+                .collect(Collectors.toSet());
+        if (elderIds.isEmpty()) {
+            return;
+        }
+        Map<Long, ElderlyInfoDO> elderMap = elderlyInfoMapper.selectBatchIds(elderIds).stream()
+                .collect(Collectors.toMap(ElderlyInfoDO::getId, e -> e, (a, b) -> a));
+        for (ElderlySpecialNursingLogRespVO vo : respList) {
+            ElderlyInfoDO elder = elderMap.get(vo.getElderId());
+            if (elder == null) {
+                continue;
+            }
+            vo.setElderName(elder.getElderName());
+            vo.setBedName(elder.getBedName());
+            vo.setNurseLevelName(elder.getNurseLevelName());
+        }
+    }
+
+    private static LocalDateTime toBegin(LocalDate[] range) {
+        if (range == null || range.length == 0 || range[0] == null) {
+            return null;
+        }
+        return range[0].atStartOfDay();
+    }
+
+    private static LocalDateTime toEndExclusive(LocalDate[] range) {
+        if (range == null || range.length < 2 || range[1] == null) {
+            return null;
+        }
+        return range[1].plusDays(1).atStartOfDay();
+    }
+}

+ 6 - 12
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/nursing/SpecialNursingPlanItemService.java

@@ -1,20 +1,14 @@
 package cn.iocoder.yudao.module.system.service.nursing;
 
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.module.system.controller.admin.nursing.vo.SpecialNursingPlanItemPageReqVO;
-import cn.iocoder.yudao.module.system.controller.admin.nursing.vo.SpecialNursingPlanItemRespVO;
+import cn.iocoder.yudao.module.system.controller.admin.nursing.vo.SpecialNursingPlanItemExecuteReqVO;
 import cn.iocoder.yudao.module.system.controller.admin.nursing.vo.SpecialNursingPlanItemSaveReqVO;
+import cn.iocoder.yudao.module.system.controller.admin.nursing.vo.SpecialNursingPlanItemUnfinishedByFloorRespVO;
 
-public interface SpecialNursingPlanItemService {
-
-    Long create(SpecialNursingPlanItemSaveReqVO createReqVO);
+import java.util.List;
 
+public interface SpecialNursingPlanItemService {
     void update(SpecialNursingPlanItemSaveReqVO updateReqVO);
+    void executePlan(SpecialNursingPlanItemExecuteReqVO executeReqVO);
 
-    void delete(Long id);
-
-    SpecialNursingPlanItemRespVO get(Long id);
-
-    PageResult<SpecialNursingPlanItemRespVO> getPage(SpecialNursingPlanItemPageReqVO pageReqVO);
+    List<SpecialNursingPlanItemUnfinishedByFloorRespVO> getUnfinishedByFloorId(Long floorId);
 }
-

+ 147 - 24
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/nursing/SpecialNursingPlanItemServiceImpl.java

@@ -1,16 +1,32 @@
 package cn.iocoder.yudao.module.system.service.nursing;
 
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
-import cn.iocoder.yudao.module.system.controller.admin.nursing.vo.SpecialNursingPlanItemPageReqVO;
+import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
+import cn.hutool.core.collection.CollectionUtil;
+import cn.iocoder.yudao.module.system.controller.admin.biz.vo.BuildBedInfoVO;
+import cn.iocoder.yudao.module.system.controller.admin.biz.vo.BuildRoomInfoVO;
+import cn.iocoder.yudao.module.system.controller.admin.nursing.vo.SpecialNursingPlanItemExecuteReqVO;
 import cn.iocoder.yudao.module.system.controller.admin.nursing.vo.SpecialNursingPlanItemRespVO;
 import cn.iocoder.yudao.module.system.controller.admin.nursing.vo.SpecialNursingPlanItemSaveReqVO;
-import cn.iocoder.yudao.module.system.dal.dataobject.biz.SpecialNursingPlanItemDO;
+import cn.iocoder.yudao.module.system.controller.admin.nursing.vo.SpecialNursingPlanItemUnfinishedByFloorRespVO;
+import cn.iocoder.yudao.module.system.dal.dataobject.biz.ElderlyInfoDO;
+import cn.iocoder.yudao.module.system.dal.dataobject.biz.ElderlySpecialNursingLogDO;
+import cn.iocoder.yudao.module.system.dal.dataobject.biz.ElderlySpecialNursingPlanDO;
+import cn.iocoder.yudao.module.system.dal.dataobject.biz.ElderlySpecialNursingPlanItemDO;
+import cn.iocoder.yudao.module.system.dal.mysql.biz.ElderlyInfoMapper;
+import cn.iocoder.yudao.module.system.dal.mysql.biz.ElderlySpecialNursingLogMapper;
 import cn.iocoder.yudao.module.system.dal.mysql.biz.SpecialNursingPlanItemMapper;
+import cn.iocoder.yudao.module.system.dal.mysql.biz.SpecialNursingPlanMapper;
+import cn.iocoder.yudao.module.system.service.biz.BuildService;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
 
 import javax.annotation.Resource;
+import java.util.*;
+import java.util.stream.Collectors;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.COMMON_NOT_FOUND;
@@ -21,40 +37,148 @@ public class SpecialNursingPlanItemServiceImpl implements SpecialNursingPlanItem
 
     @Resource
     private SpecialNursingPlanItemMapper specialNursingPlanItemMapper;
+    @Resource
+    private ElderlySpecialNursingLogMapper elderlySpecialNursingLogMapper;
+    @Resource
+    private BuildService buildService;
+    @Resource
+    private SpecialNursingPlanMapper specialNursingPlanMapper;
+
+    @Autowired
+    private ElderlyInfoMapper elderlyInfoMapper;
 
-    @Override
-    public Long create(SpecialNursingPlanItemSaveReqVO createReqVO) {
-        SpecialNursingPlanItemDO item = BeanUtils.toBean(createReqVO, SpecialNursingPlanItemDO.class);
-        specialNursingPlanItemMapper.insert(item);
-        return item.getId();
-    }
 
     @Override
     public void update(SpecialNursingPlanItemSaveReqVO updateReqVO) {
         validateExists(updateReqVO.getId());
-        SpecialNursingPlanItemDO updateObj = BeanUtils.toBean(updateReqVO, SpecialNursingPlanItemDO.class);
+        ElderlySpecialNursingPlanItemDO updateObj = BeanUtils.toBean(updateReqVO, ElderlySpecialNursingPlanItemDO.class);
         specialNursingPlanItemMapper.updateById(updateObj);
     }
 
     @Override
-    public void delete(Long id) {
-        validateExists(id);
-        specialNursingPlanItemMapper.deleteById(id);
-    }
-
-    @Override
-    public SpecialNursingPlanItemRespVO get(Long id) {
-        SpecialNursingPlanItemDO item = specialNursingPlanItemMapper.selectById(id);
-        if (item == null) {
+    @Transactional(rollbackFor = Exception.class)
+    public void executePlan(SpecialNursingPlanItemExecuteReqVO executeReqVO) {
+        ElderlySpecialNursingPlanItemDO specialItem = specialNursingPlanItemMapper.selectById(executeReqVO.getSpecialPlanItemId());
+        if (specialItem == null) {
             throw exception(COMMON_NOT_FOUND);
         }
-        return BeanUtils.toBean(item, SpecialNursingPlanItemRespVO.class);
+        specialItem.setStatus(1);
+        specialNursingPlanItemMapper.updateById(specialItem);
+
+        ElderlySpecialNursingLogDO logDO = new ElderlySpecialNursingLogDO();
+        logDO.setSpecialPlanItemId(executeReqVO.getSpecialPlanItemId());
+        logDO.setElderId(executeReqVO.getElderId());
+        logDO.setFinishTime(executeReqVO.getFinishTime());
+        logDO.setRemark(executeReqVO.getRemark());
+        logDO.setImageUrl(executeReqVO.getImageUrl());
+        logDO.setTenantId(executeReqVO.getTenantId() != null ? executeReqVO.getTenantId() : specialItem.getTenantId());
+        elderlySpecialNursingLogMapper.insert(logDO);
     }
 
     @Override
-    public PageResult<SpecialNursingPlanItemRespVO> getPage(SpecialNursingPlanItemPageReqVO pageReqVO) {
-        PageResult<SpecialNursingPlanItemDO> pageResult = specialNursingPlanItemMapper.selectPage(pageReqVO);
-        return BeanUtils.toBean(pageResult, SpecialNursingPlanItemRespVO.class);
+    public List<SpecialNursingPlanItemUnfinishedByFloorRespVO> getUnfinishedByFloorId(Long floorId) {
+        List<ElderlyInfoDO> elderlyInfoDOS = elderlyInfoMapper.selectList(new LambdaQueryWrapperX<ElderlyInfoDO>()
+                .eq(ElderlyInfoDO::getFloorId, floorId)
+                .eq(ElderlyInfoDO::getInStatus, 1));
+//        List<BuildRoomInfoVO> rooms = buildService.getElderListByFloorId(floorId);
+//        if (CollectionUtil.isEmpty(rooms)) {
+//            return Collections.emptyList();
+//        }
+//
+//        Map<Long, String> elderNameById = new LinkedHashMap<>();
+//        for (BuildRoomInfoVO room : rooms) {
+//            List<BuildBedInfoVO> bedList = room.getBedList();
+//            if (CollectionUtil.isEmpty(bedList)) {
+//                continue;
+//            }
+//            for (BuildBedInfoVO bed : bedList) {
+//                if (bed.getElderId() == null) {
+//                    continue;
+//                }
+//                elderNameById.putIfAbsent(bed.getElderId(), bed.getElderName());
+//            }
+//        }
+//
+//        if (elderNameById.isEmpty()) {
+//            return Collections.emptyList();
+//        }
+        Map<Long, String> elderNameById = elderlyInfoDOS.stream().collect(Collectors.toMap(ElderlyInfoDO::getId, ElderlyInfoDO::getElderName));
+        List<Long> elderIds = new ArrayList<>(elderNameById.keySet());
+        if(CollectionUtil.isEmpty(elderIds)){
+            return Collections.emptyList();
+        }
+        List<ElderlySpecialNursingPlanDO> plans = specialNursingPlanMapper.selectList(
+                new LambdaQueryWrapperX<ElderlySpecialNursingPlanDO>()
+                        .in(ElderlySpecialNursingPlanDO::getElderId, elderIds)
+        );
+        if (CollectionUtil.isEmpty(plans)) {
+            return Collections.emptyList();
+        }
+
+        Map<Long, String> fallbackElderNameById = plans.stream()
+                .filter(p -> p.getElderId() != null)
+                .collect(Collectors.toMap(ElderlySpecialNursingPlanDO::getElderId, ElderlySpecialNursingPlanDO::getElderName, (a, b) -> a));
+
+        Map<Long, List<Long>> planIdsByElderId = plans.stream()
+                .filter(p -> p.getElderId() != null && p.getId() != null)
+                .collect(Collectors.groupingBy(ElderlySpecialNursingPlanDO::getElderId,
+                        Collectors.mapping(ElderlySpecialNursingPlanDO::getId, Collectors.toList())));
+
+        List<Long> planIds = plans.stream()
+                .map(ElderlySpecialNursingPlanDO::getId)
+                .filter(Objects::nonNull)
+                .collect(Collectors.toList());
+
+        if (CollectionUtil.isEmpty(planIds)) {
+            return Collections.emptyList();
+        }
+
+        List<ElderlySpecialNursingPlanItemDO> unfinishedItems = specialNursingPlanItemMapper.selectList(
+                new LambdaQueryWrapperX<ElderlySpecialNursingPlanItemDO>()
+                        .in(ElderlySpecialNursingPlanItemDO::getSpecialNursingPlanId, planIds)
+                        .eq(ElderlySpecialNursingPlanItemDO::getStatus, 0)
+                        .orderByAsc(ElderlySpecialNursingPlanItemDO::getId)
+        );
+        if (CollectionUtil.isEmpty(unfinishedItems)) {
+            return Collections.emptyList();
+        }
+
+        Map<Long, List<ElderlySpecialNursingPlanItemDO>> itemsByPlanId = unfinishedItems.stream()
+                .collect(Collectors.groupingBy(ElderlySpecialNursingPlanItemDO::getSpecialNursingPlanId));
+
+        List<SpecialNursingPlanItemUnfinishedByFloorRespVO> result = new ArrayList<>();
+        for (Map.Entry<Long, List<Long>> entry : planIdsByElderId.entrySet()) {
+            Long elderId = entry.getKey();
+            List<Long> elderPlanIds = entry.getValue();
+            if (CollectionUtil.isEmpty(elderPlanIds)) {
+                continue;
+            }
+
+            List<ElderlySpecialNursingPlanItemDO> elderItems = new ArrayList<>();
+            for (Long planId : elderPlanIds) {
+                List<ElderlySpecialNursingPlanItemDO> planItems = itemsByPlanId.get(planId);
+                if (CollectionUtil.isEmpty(planItems)) {
+                    continue;
+                }
+                elderItems.addAll(planItems);
+            }
+            if (CollectionUtil.isEmpty(elderItems)) {
+                continue;
+            }
+
+            String elderName = elderNameById.get(elderId);
+            if (StringUtils.isBlank(elderName)) {
+                elderName = fallbackElderNameById.get(elderId);
+            }
+
+            SpecialNursingPlanItemUnfinishedByFloorRespVO respVO = new SpecialNursingPlanItemUnfinishedByFloorRespVO();
+            respVO.setElderName(elderName);
+            respVO.setElderId(elderId);
+            respVO.setSpecialItem(BeanUtils.toBean(elderItems, SpecialNursingPlanItemRespVO.class));
+            result.add(respVO);
+        }
+
+        return result;
     }
 
     private void validateExists(Long id) {
@@ -63,4 +187,3 @@ public class SpecialNursingPlanItemServiceImpl implements SpecialNursingPlanItem
         }
     }
 }
-

+ 45 - 7
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/nursing/SpecialNursingPlanServiceImpl.java

@@ -2,15 +2,22 @@ package cn.iocoder.yudao.module.system.service.nursing;
 
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
+import cn.iocoder.yudao.module.system.controller.admin.nursing.vo.SpecialNursingPlanItemRespVO;
+import cn.iocoder.yudao.module.system.controller.admin.nursing.vo.SpecialNursingPlanItemSaveReqVO;
 import cn.iocoder.yudao.module.system.controller.admin.nursing.vo.SpecialNursingPlanPageReqVO;
 import cn.iocoder.yudao.module.system.controller.admin.nursing.vo.SpecialNursingPlanRespVO;
 import cn.iocoder.yudao.module.system.controller.admin.nursing.vo.SpecialNursingPlanSaveReqVO;
-import cn.iocoder.yudao.module.system.dal.dataobject.biz.SpecialNursingPlanDO;
+import cn.iocoder.yudao.module.system.dal.dataobject.biz.ElderlySpecialNursingPlanItemDO;
+import cn.iocoder.yudao.module.system.dal.mysql.biz.SpecialNursingPlanItemMapper;
+import cn.iocoder.yudao.module.system.dal.dataobject.biz.ElderlySpecialNursingPlanDO;
 import cn.iocoder.yudao.module.system.dal.mysql.biz.SpecialNursingPlanMapper;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
 
 import javax.annotation.Resource;
+import java.util.List;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.COMMON_NOT_FOUND;
@@ -21,39 +28,58 @@ public class SpecialNursingPlanServiceImpl implements SpecialNursingPlanService
 
     @Resource
     private SpecialNursingPlanMapper specialNursingPlanMapper;
+    @Resource
+    private SpecialNursingPlanItemMapper specialNursingPlanItemMapper;
 
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public Long create(SpecialNursingPlanSaveReqVO createReqVO) {
-        SpecialNursingPlanDO specialNursingPlan = BeanUtils.toBean(createReqVO, SpecialNursingPlanDO.class);
+        ElderlySpecialNursingPlanDO specialNursingPlan = BeanUtils.toBean(createReqVO, ElderlySpecialNursingPlanDO.class);
         specialNursingPlanMapper.insert(specialNursingPlan);
+        saveItems(specialNursingPlan.getId(), createReqVO.getTenantId(), createReqVO.getItems());
         return specialNursingPlan.getId();
     }
 
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public void update(SpecialNursingPlanSaveReqVO updateReqVO) {
         validateExists(updateReqVO.getId());
-        SpecialNursingPlanDO updateObj = BeanUtils.toBean(updateReqVO, SpecialNursingPlanDO.class);
+        ElderlySpecialNursingPlanDO updateObj = BeanUtils.toBean(updateReqVO, ElderlySpecialNursingPlanDO.class);
         specialNursingPlanMapper.updateById(updateObj);
+        // 按要求使用先删除后插入的方式更新明细
+        specialNursingPlanItemMapper.delete(new LambdaQueryWrapperX<ElderlySpecialNursingPlanItemDO>()
+                .eq(ElderlySpecialNursingPlanItemDO::getSpecialNursingPlanId, updateReqVO.getId()));
+        saveItems(updateReqVO.getId(), updateReqVO.getTenantId(), updateReqVO.getItems());
     }
 
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public void delete(Long id) {
         validateExists(id);
+        specialNursingPlanItemMapper.delete(new LambdaQueryWrapperX<ElderlySpecialNursingPlanItemDO>()
+                .eq(ElderlySpecialNursingPlanItemDO::getSpecialNursingPlanId, id));
         specialNursingPlanMapper.deleteById(id);
     }
 
     @Override
     public SpecialNursingPlanRespVO get(Long id) {
-        SpecialNursingPlanDO record = specialNursingPlanMapper.selectById(id);
+        ElderlySpecialNursingPlanDO record = specialNursingPlanMapper.selectById(id);
         if (record == null) {
             throw exception(COMMON_NOT_FOUND);
         }
-        return BeanUtils.toBean(record, SpecialNursingPlanRespVO.class);
+        SpecialNursingPlanRespVO respVO = BeanUtils.toBean(record, SpecialNursingPlanRespVO.class);
+        List<ElderlySpecialNursingPlanItemDO> items = specialNursingPlanItemMapper.selectList(
+                new LambdaQueryWrapperX<ElderlySpecialNursingPlanItemDO>()
+                        .eq(ElderlySpecialNursingPlanItemDO::getSpecialNursingPlanId, id)
+                        .orderByAsc(ElderlySpecialNursingPlanItemDO::getId)
+        );
+        respVO.setItems(BeanUtils.toBean(items, SpecialNursingPlanItemRespVO.class));
+        return respVO;
     }
 
     @Override
     public PageResult<SpecialNursingPlanRespVO> getPage(SpecialNursingPlanPageReqVO pageReqVO) {
-        PageResult<SpecialNursingPlanDO> pageResult = specialNursingPlanMapper.selectPage(pageReqVO);
+        PageResult<ElderlySpecialNursingPlanDO> pageResult = specialNursingPlanMapper.selectPage(pageReqVO);
         return BeanUtils.toBean(pageResult, SpecialNursingPlanRespVO.class);
     }
 
@@ -62,5 +88,17 @@ public class SpecialNursingPlanServiceImpl implements SpecialNursingPlanService
             throw exception(COMMON_NOT_FOUND);
         }
     }
-}
 
+    private void saveItems(Long specialNursingPlanId, Long tenantId, List<SpecialNursingPlanItemSaveReqVO> items) {
+        if (items == null || items.isEmpty()) {
+            return;
+        }
+        for (SpecialNursingPlanItemSaveReqVO item : items) {
+            ElderlySpecialNursingPlanItemDO itemDO = BeanUtils.toBean(item, ElderlySpecialNursingPlanItemDO.class);
+            itemDO.setId(null);
+            itemDO.setSpecialNursingPlanId(specialNursingPlanId);
+            itemDO.setTenantId(itemDO.getTenantId() == null ? tenantId : itemDO.getTenantId());
+            specialNursingPlanItemMapper.insert(itemDO);
+        }
+    }
+}

+ 39 - 0
yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/ElderlySpecialNursingLogMapper.xml

@@ -0,0 +1,39 @@
+<?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="cn.iocoder.yudao.module.system.dal.mysql.biz.ElderlySpecialNursingLogMapper">
+
+    <select id="selectPageWithElderInfo"
+            resultType="cn.iocoder.yudao.module.system.controller.admin.nursing.vo.ElderlySpecialNursingLogRespVO">
+        SELECT
+            log.id,
+            log.speical_plan_item_id AS speicalPlanItemId,
+            log.elder_id AS elderId,
+            ei.elder_name AS elderName,
+            ei.bed_name AS bedName,
+            ei.nurse_level_name AS nurseLevelName,
+            log.finish_time AS finishTime,
+            log.remark,
+            log.image_url AS imageUrl,
+            log.tenant_id AS tenantId
+        FROM elderly_special_nursing_log log
+        LEFT JOIN elderly_info ei
+            ON ei.id = log.elder_id
+            AND ei.tenant_id = log.tenant_id
+        WHERE 1 = 1
+            <if test="pageVO.tenantIds != null and pageVO.tenantIds.length > 0">
+                AND log.tenant_id IN
+                <foreach collection="pageVO.tenantIds" item="tenantId" open="(" separator="," close=")">
+                    #{tenantId}
+                </foreach>
+            </if>
+            <if test="pageVO.elderId != null">
+                AND log.elder_id = #{pageVO.elderId}
+            </if>
+            <if test="pageVO.elderName != null and pageVO.elderName != ''">
+                AND ei.elder_name LIKE CONCAT('%', #{pageVO.elderName}, '%')
+            </if>
+        ORDER BY log.finish_time DESC, log.id DESC
+    </select>
+
+</mapper>
+

+ 2 - 0
yudao-server/src/main/resources/application.yaml

@@ -241,6 +241,8 @@ yudao:
       - /admin-api/infra/file/upload
       - /admin-api/build/getBedListByTenantIdAndKeyword
       - /admin-api/nurse/nurseLeve/simple-list
+      - /admin-api/nursing/special-plan-item/getUnfinishedByFloorId
+      - /admin-api/nursing/special-plan-item/execute
 #      - /admin-api/bpm/check-in-wait/create
     ignore-tables:
       - system_tenant