浏览代码

新增
1、新增长者安全检查模块
2、合同管理分页增加是否有合同附件的过滤条件
3、外出配置增加减底价模式
4、长者档案分页增加是否有合同附件的过滤条件
BUGFIX
1、解决批量生成账单时,该月合同到期的长者,合同结束时间显示未月末的问题
2、解决检查是否包房存在床位变更时返回结果写反的问题

liangwenxuan 2 天之前
父节点
当前提交
efb94d951c
共有 20 个文件被更改,包括 613 次插入13 次删除
  1. 1 1
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/api/bpm/BpmElderlyExpenseApiImpl.java
  2. 3 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/biz/vo/ContractPageReqVO.java
  3. 3 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/biz/vo/ElderlyInfoPageReqVO.java
  4. 83 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/elderly/ElderlySafeCheckController.java
  5. 33 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/elderly/vo/ElderlySafeCheckElderPageReqVO.java
  6. 22 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/elderly/vo/ElderlySafeCheckElderPageRespVO.java
  7. 30 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/elderly/vo/ElderlySafeCheckPageReqVO.java
  8. 51 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/elderly/vo/ElderlySafeCheckRespVO.java
  9. 40 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/elderly/vo/ElderlySafeCheckSaveReqVO.java
  10. 9 2
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/biz/OutboundRefundItemDO.java
  11. 49 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/elderly/ElderlySafeCheckDO.java
  12. 66 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/elderly/ElderlySafeCheckMapper.java
  13. 28 3
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/biz/ElderlyAskLeaveServiceImpl.java
  14. 3 2
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/biz/ExpenseOrderServiceImpl.java
  15. 2 2
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/biz/NurseChangeRecordServiceImpl.java
  16. 26 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/elderly/ElderlySafeCheckService.java
  17. 146 0
      yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/elderly/ElderlySafeCheckServiceImpl.java
  18. 10 1
      yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/ElderlyContractMapper.xml
  19. 6 0
      yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/ElderlyInfoMapper.xml
  20. 2 2
      yudao-server/src/main/resources/application.yaml

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

@@ -461,7 +461,7 @@ public class BpmElderlyExpenseApiImpl implements BpmElderlyExpenseApi {
                 .eq(ExpenseItemDO::getIsMonthlyExpense, BooleanEnum.TRUE.getValue())
                 .isNull(ExpenseItemDO::getChangeEndDate)
                 .inSql(ExpenseItemDO::getExpenseId,
-                        "SELECT id FROM expense WHERE elder_id = " + elderId)
+                        "SELECT id FROM elderly_expense WHERE elder_id = " + elderId)
                 .set(ExpenseItemDO::getChangeEndDate, endDate);
         expenseItemMapper.update(null, updateWrapper);
     }

+ 3 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/biz/vo/ContractPageReqVO.java

@@ -27,5 +27,8 @@ public class ContractPageReqVO extends PageParam {
     @Schema(description = "入住类型")
     private Integer inStatusType;
 
+    @Schema(description = "是否有合同附件")
+    private Integer hasExtra;
+
 
 }

+ 3 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/biz/vo/ElderlyInfoPageReqVO.java

@@ -82,6 +82,9 @@ public class ElderlyInfoPageReqVO extends PageParam {
 
     @Schema(description = "床位id")
     private Long bedId;
+
+    @Schema(description = "是否有长者附件")
+    private Integer hasExtra;
 }
 
 

+ 83 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/elderly/ElderlySafeCheckController.java

@@ -0,0 +1,83 @@
+package cn.iocoder.yudao.module.system.controller.admin.elderly;
+
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
+import cn.iocoder.yudao.module.system.controller.admin.elderly.vo.ElderlySafeCheckElderPageReqVO;
+import cn.iocoder.yudao.module.system.controller.admin.elderly.vo.ElderlySafeCheckElderPageRespVO;
+import cn.iocoder.yudao.module.system.controller.admin.elderly.vo.ElderlySafeCheckPageReqVO;
+import cn.iocoder.yudao.module.system.controller.admin.elderly.vo.ElderlySafeCheckRespVO;
+import cn.iocoder.yudao.module.system.controller.admin.elderly.vo.ElderlySafeCheckSaveReqVO;
+import cn.iocoder.yudao.module.system.service.elderly.ElderlySafeCheckService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+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("/elderly-safe-check")
+@Validated
+public class ElderlySafeCheckController {
+
+    @Resource
+    private ElderlySafeCheckService safeCheckService;
+
+    @PostMapping("/create")
+    @Operation(summary = "创建长者安全检查")
+    public CommonResult<Integer> create(@Valid @RequestBody List<ElderlySafeCheckSaveReqVO> createReqList) {
+        for (ElderlySafeCheckSaveReqVO createReqVO : createReqList) {
+            createReqVO.setTenantId(Objects.isNull(createReqVO.getTenantId())
+                    ? TenantContextHolder.getTenantId() : createReqVO.getTenantId());
+        }
+        return success(safeCheckService.createBatch(createReqList));
+    }
+
+    @PutMapping("/update")
+    @Operation(summary = "更新长者安全检查")
+    public CommonResult<Boolean> update(@Valid @RequestBody ElderlySafeCheckSaveReqVO updateReqVO) {
+        updateReqVO.setTenantId(Objects.isNull(updateReqVO.getTenantId())
+                ? TenantContextHolder.getTenantId() : updateReqVO.getTenantId());
+        safeCheckService.update(updateReqVO);
+        return success(Boolean.TRUE);
+    }
+
+    @DeleteMapping("/delete")
+    @Operation(summary = "删除长者安全检查")
+    @Parameter(name = "id", description = "记录编号", required = true)
+    public CommonResult<Boolean> delete(@RequestParam("id") Long id) {
+        safeCheckService.delete(id);
+        return success(Boolean.TRUE);
+    }
+
+    @GetMapping("/get")
+    @Operation(summary = "获得长者安全检查")
+    @Parameter(name = "id", description = "记录编号", required = true, example = "1024")
+    public CommonResult<ElderlySafeCheckRespVO> get(@RequestParam("id") Long id) {
+        return success(safeCheckService.get(id));
+    }
+
+    @GetMapping("/page")
+    @Operation(summary = "获得长者安全检查分页(按长者分组)")
+    public CommonResult<PageResult<ElderlySafeCheckElderPageRespVO>> getElderPage(@Valid ElderlySafeCheckElderPageReqVO pageReqVO) {
+        pageReqVO.setTenantIds(Objects.isNull(pageReqVO.getTenantIds())
+                ? new Long[]{TenantContextHolder.getTenantId()} : pageReqVO.getTenantIds());
+        return success(safeCheckService.getElderPage(pageReqVO));
+    }
+
+    @GetMapping("/page-record")
+    @Operation(summary = "获得长者安全检查记录分页")
+    public CommonResult<PageResult<ElderlySafeCheckRespVO>> getPage(@Valid ElderlySafeCheckPageReqVO pageReqVO) {
+        pageReqVO.setTenantIds(Objects.isNull(pageReqVO.getTenantIds())
+                ? new Long[]{TenantContextHolder.getTenantId()} : pageReqVO.getTenantIds());
+        return success(safeCheckService.getPage(pageReqVO));
+    }
+}

+ 33 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/elderly/vo/ElderlySafeCheckElderPageReqVO.java

@@ -0,0 +1,33 @@
+package cn.iocoder.yudao.module.system.controller.admin.elderly.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 ElderlySafeCheckElderPageReqVO extends PageParam {
+
+    @Schema(description = "长者id", example = "1")
+    private Long elderId;
+
+    @Schema(description = "长者姓名(模糊)")
+    private String elderName;
+
+    @Schema(description = "检查日期(yyyy-MM-dd)范围,按创建时间过滤")
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY)
+    private LocalDate[] checkDate;
+
+    @Schema(description = "机构id数组")
+    private Long[] tenantIds;
+}
+

+ 22 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/elderly/vo/ElderlySafeCheckElderPageRespVO.java

@@ -0,0 +1,22 @@
+package cn.iocoder.yudao.module.system.controller.admin.elderly.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+@Schema(description = "管理后台 - 长者安全检查(按长者分组)分页 Response VO")
+@Data
+public class ElderlySafeCheckElderPageRespVO {
+
+    @Schema(description = "长者id", example = "1")
+    private Long elderId;
+
+    @Schema(description = "长者姓名")
+    private String elderName;
+
+    @Schema(description = "房间号")
+    private String roomName;
+
+    @Schema(description = "床位号")
+    private String bedName;
+}
+

+ 30 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/elderly/vo/ElderlySafeCheckPageReqVO.java

@@ -0,0 +1,30 @@
+package cn.iocoder.yudao.module.system.controller.admin.elderly.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 ElderlySafeCheckPageReqVO extends PageParam {
+
+    @Schema(description = "长者id", example = "1")
+    private Long elderId;
+
+    @Schema(description = "检查日期(yyyy-MM-dd)范围,按创建时间过滤")
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY)
+    private LocalDate[] checkDate;
+
+    @Schema(description = "机构id数组")
+    private Long[] tenantIds;
+}
+

+ 51 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/elderly/vo/ElderlySafeCheckRespVO.java

@@ -0,0 +1,51 @@
+package cn.iocoder.yudao.module.system.controller.admin.elderly.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Schema(description = "管理后台 - 长者安全检查 Response VO")
+@Data
+public class ElderlySafeCheckRespVO {
+
+    @Schema(description = "id", example = "1024")
+    private Long id;
+
+    @Schema(description = "长者id", example = "1")
+    private Long elderId;
+
+    @Schema(description = "长者姓名")
+    private String elderName;
+
+    @Schema(description = "房间号")
+    private String roomName;
+
+    @Schema(description = "床位号")
+    private String bedName;
+
+    @Schema(description = "安全情况")
+    private String safeSituation;
+
+    @Schema(description = "安全备注")
+    private String safeRemark;
+
+    @Schema(description = "长者自带设备")
+    private String elderSelfEquipment;
+
+    @Schema(description = "问题与要求")
+    private String question;
+
+    @Schema(description = "被检查人签名")
+    private String beCheckSign;
+
+    @Schema(description = "异常数量")
+    private Integer failCount;
+
+    @Schema(description = "记录人")
+    private String creator;
+
+    @Schema(description = "创建时间")
+    private LocalDateTime createTime;
+}
+

+ 40 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/elderly/vo/ElderlySafeCheckSaveReqVO.java

@@ -0,0 +1,40 @@
+package cn.iocoder.yudao.module.system.controller.admin.elderly.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+
+@Schema(description = "管理后台 - 长者安全检查新增/修改 Request VO")
+@Data
+public class ElderlySafeCheckSaveReqVO {
+
+    @Schema(description = "id", example = "1024")
+    private Long id;
+
+    @Schema(description = "长者id", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+    @NotNull(message = "长者id不能为空")
+    private Long elderId;
+
+    @Schema(description = "安全情况")
+    private String safeSituation;
+
+    @Schema(description = "安全备注")
+    private String safeRemark;
+
+    @Schema(description = "长者自带设备")
+    private String elderSelfEquipment;
+
+    @Schema(description = "问题与要求")
+    private String question;
+
+    @Schema(description = "被检查人签名")
+    private String beCheckSign;
+
+    @Schema(description = "异常数量")
+    private Integer failCount;
+
+    @Schema(description = "机构id", example = "1")
+    private Long tenantId;
+}
+

+ 9 - 2
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/biz/OutboundRefundItemDO.java

@@ -1,10 +1,9 @@
 package cn.iocoder.yudao.module.system.dal.dataobject.biz;
 
 import lombok.*;
-import java.util.*;
+
 import java.math.BigDecimal;
 import com.baomidou.mybatisplus.annotation.*;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
 
 /**
  * 外出退费配置项 DO
@@ -70,4 +69,12 @@ public class OutboundRefundItemDO  {
      * 自定义金额
      */
     private BigDecimal customAmount;
+    /**
+     * 是否减底价:0 否,1 是
+     */
+    private Integer isSubtract;
+    /**
+     * 底价金额
+     */
+    private BigDecimal subtractAmount;
 }

+ 49 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/dataobject/elderly/ElderlySafeCheckDO.java

@@ -0,0 +1,49 @@
+package cn.iocoder.yudao.module.system.dal.dataobject.elderly;
+
+import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseNoDeleteDO;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.KeySequence;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.*;
+
+/**
+ * 长者安全检查 DO
+ */
+@TableName("elderly_safe_check")
+@KeySequence("elderly_safe_check_seq")
+@Data
+@ToString(callSuper = true)
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class ElderlySafeCheckDO extends BaseNoDeleteDO {
+
+    @TableId(type = IdType.AUTO)
+    private Long id;
+
+    /** 长者id */
+    private Long elderId;
+
+    /** 安全情况 */
+    private String safeSituation;
+
+    /** 安全备注 */
+    private String safeRemark;
+
+    /** 长者自带设备 */
+    private String elderSelfEquipment;
+
+    /** 问题与要求 */
+    private String question;
+
+    /** 被检查人签名 */
+    private String beCheckSign;
+
+    /** 异常数量 */
+    private Integer failCount;
+
+    /** 机构id */
+    private Long tenantId;
+}
+

+ 66 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/elderly/ElderlySafeCheckMapper.java

@@ -0,0 +1,66 @@
+package cn.iocoder.yudao.module.system.dal.mysql.elderly;
+
+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.elderly.vo.ElderlySafeCheckElderPageReqVO;
+import cn.iocoder.yudao.module.system.controller.admin.elderly.vo.ElderlySafeCheckElderPageRespVO;
+import cn.iocoder.yudao.module.system.controller.admin.elderly.vo.ElderlySafeCheckPageReqVO;
+import cn.iocoder.yudao.module.system.dal.dataobject.elderly.ElderlySafeCheckDO;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+@Mapper
+public interface ElderlySafeCheckMapper extends BaseMapperX<ElderlySafeCheckDO> {
+
+    default PageResult<ElderlySafeCheckDO> selectRecordPage(ElderlySafeCheckPageReqVO reqVO,
+                                                           LocalDateTime startTime,
+                                                           LocalDateTime endTimeExclusive) {
+        return selectPage(reqVO, new LambdaQueryWrapperX<ElderlySafeCheckDO>()
+                .eqIfPresent(ElderlySafeCheckDO::getElderId, reqVO.getElderId())
+                .geIfPresent(ElderlySafeCheckDO::getCreateTime, startTime)
+                .ltIfPresent(ElderlySafeCheckDO::getCreateTime, endTimeExclusive)
+                .inIfPresent(ElderlySafeCheckDO::getTenantId, reqVO.getTenantIds())
+                .orderByDesc(ElderlySafeCheckDO::getCreateTime)
+                .orderByDesc(ElderlySafeCheckDO::getId));
+    }
+
+    @Select({"<script>",
+            "SELECT",
+            "  esc.elder_id AS elderId,",
+            "  ei.elder_name AS elderName,",
+            "  ei.room_name AS roomName,",
+            "  ei.bed_name AS bedName",
+            "FROM elderly_safe_check esc",
+            "LEFT JOIN elderly_info ei ON ei.id = esc.elder_id",
+            "WHERE 1 = 1",
+            "  <if test='pageVO.elderId != null'>",
+            "    AND esc.elder_id = #{pageVO.elderId}",
+            "  </if>",
+            "  <if test='pageVO.elderName != null and pageVO.elderName != \"\"'>",
+            "    AND ei.elder_name LIKE CONCAT('%', #{pageVO.elderName}, '%')",
+            "  </if>",
+            "  <if test='pageVO.checkDate != null and pageVO.checkDate.length &gt; 0 and pageVO.checkDate[0] != null'>",
+            "    AND esc.create_time &gt;= TIMESTAMP(#{pageVO.checkDate[0]}, '00:00:00')",
+            "  </if>",
+            "  <if test='pageVO.checkDate != null and pageVO.checkDate.length &gt; 1 and pageVO.checkDate[1] != null'>",
+            "    AND esc.create_time &lt; TIMESTAMP(DATE_ADD(#{pageVO.checkDate[1]}, INTERVAL 1 DAY), '00:00:00')",
+            "  </if>",
+            "  <if test='pageVO.tenantIds != null and pageVO.tenantIds.length &gt; 0'>",
+            "    AND esc.tenant_id IN",
+            "    <foreach item='id' collection='pageVO.tenantIds' open='(' separator=',' close=')'>",
+            "      #{id}",
+            "    </foreach>",
+            "  </if>",
+            "GROUP BY esc.elder_id, ei.elder_name, ei.room_name, ei.bed_name",
+            "ORDER BY ei.elder_name ASC, esc.elder_id DESC",
+            "</script>"})
+    List<ElderlySafeCheckElderPageRespVO> selectElderPage(@Param("page") Page<?> page,
+                                                         @Param("pageVO") ElderlySafeCheckElderPageReqVO pageReqVO);
+}
+

+ 28 - 3
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/biz/ElderlyAskLeaveServiceImpl.java

@@ -509,8 +509,7 @@ public class ElderlyAskLeaveServiceImpl implements ElderlyAskLeaveService {
 
         // 计算金额
         BigDecimal actualAmount = resolveCustomAmount(outboundRefundItem, expenseItemDO.getActualAmount());
-        int monthTotalDays = yearMonth.lengthOfMonth();
-        BigDecimal dayPrice = expenseItemDO.getIsDayCalculate() == 1 ? expenseItemDO.getActualAmount() :actualAmount.divide(BigDecimal.valueOf(monthTotalDays), 5, RoundingMode.HALF_UP);
+        BigDecimal dayPrice = resolveDayPrice(outboundRefundItem, expenseItemDO, yearMonth, actualAmount);
         BigDecimal monthAmount = dayPrice.multiply(BigDecimal.valueOf(daysInMonth)).setScale(2, RoundingMode.HALF_UP);
 
         dailyExpenses.setPrice(dayPrice);
@@ -522,9 +521,15 @@ public class ElderlyAskLeaveServiceImpl implements ElderlyAskLeaveService {
         dailyExpenses.setAttributionBillTime(attributionBillTime);
 
         // 设置备注
+        String subtractMark = "";
+        if (Objects.equals(outboundRefundItem.getIsSubtract(), BooleanEnum.TRUE.getValue())) {
+            BigDecimal baseAmount = expenseItemDO.getActualAmount() == null ? BigDecimal.ZERO : expenseItemDO.getActualAmount();
+            BigDecimal calculateAmount = resolveCalculateAmount(outboundRefundItem, expenseItemDO.getActualAmount(), actualAmount);
+            subtractMark = "减底价,原始金额:" + baseAmount.setScale(2, RoundingMode.HALF_UP) + ",减底价后金额:" + calculateAmount.setScale(2, RoundingMode.HALF_UP) + ",";
+        }
         String customMark = BooleanEnum.TRUE.getValue().equals(outboundRefundItem.getIsCustom()) ? "使用自定义金额,退费计算金额:" + actualAmount.setScale(2,RoundingMode.HALF_UP) + ",": "";
         String endDayInfo = !includeEndDay ? "包含最后一天" : "不包含最后一天";
-        dailyExpenses.setRemarks(customMark + configName + "退费:长者外出,退" + startDate + "到" + endDate + "的费用(" + yearMonth + "月份共" + daysInMonth + "天," + endDayInfo + ")");
+        dailyExpenses.setRemarks(subtractMark + customMark + configName + "退费:长者外出,退" + startDate + "到" + endDate + "的费用(" + yearMonth + "月份共" + daysInMonth + "天," + endDayInfo + ")");
 
         saveDailyExpenseAndAttachBill(elderlyAskLeaveDO, dailyExpenses);
     }
@@ -564,6 +569,26 @@ public class ElderlyAskLeaveServiceImpl implements ElderlyAskLeaveService {
         return defaultAmount == null ? BigDecimal.ZERO : defaultAmount;
     }
 
+    private BigDecimal resolveCalculateAmount(OutboundRefundItemDO outboundRefundItem, BigDecimal baseAmount, BigDecimal resolvedActualAmount) {
+        if (!Objects.equals(outboundRefundItem.getIsSubtract(), BooleanEnum.TRUE.getValue())) {
+            return resolvedActualAmount;
+        }
+        BigDecimal subtractAmount = outboundRefundItem.getSubtractAmount() == null ? BigDecimal.ZERO : outboundRefundItem.getSubtractAmount();
+        BigDecimal calculateAmount = (baseAmount == null ? BigDecimal.ZERO : baseAmount).subtract(subtractAmount);
+        if (calculateAmount.compareTo(BigDecimal.ZERO) < 0) {
+            calculateAmount = BigDecimal.ZERO;
+        }
+        return calculateAmount;
+    }
+
+    private BigDecimal resolveDayPrice(OutboundRefundItemDO outboundRefundItem, ExpenseItemDO expenseItemDO, YearMonth yearMonth, BigDecimal resolvedActualAmount) {
+        if (Objects.equals(expenseItemDO.getIsDayCalculate(), 1)) {
+            return resolvedActualAmount;
+        }
+        BigDecimal calculateAmount = resolveCalculateAmount(outboundRefundItem, expenseItemDO.getActualAmount(), resolvedActualAmount);
+        return calculateAmount.divide(BigDecimal.valueOf(yearMonth.lengthOfMonth()), 5, RoundingMode.HALF_UP);
+    }
+
     /**
      * 保存外出日常费用,并在账单未缴费/部分缴费时自动写入对应归属月账单
      */

+ 3 - 2
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/biz/ExpenseOrderServiceImpl.java

@@ -63,6 +63,7 @@ import org.springframework.web.client.RestTemplate;
 
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exceptionCustomMsg;
+import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY;
 import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
 import static cn.iocoder.yudao.module.system.enums.LogRecordConstants.*;
 
@@ -2429,10 +2430,10 @@ public class ExpenseOrderServiceImpl implements ExpenseOrderService {
             orderItem.setItemCategoryName(item.getItemCategory());
             orderItem.setCreatedBy(SecurityFrameworkUtils.getLoginUserNickname());
             orderItem.setDescription(StringUtils.isBlank(item.getDescription()) ? LocalDateTimeUtil.format(yearMonth.atDay(1), DatePattern.NORM_DATE_PATTERN)
-                    + "至" + LocalDateTimeUtil.format(yearMonth.atEndOfMonth(), DatePattern.NORM_DATE_PATTERN) + "的" + item.getItemName() : item.getDescription());
+                    + "至" + (StringUtils.isBlank(item.getEndTime()) ? LocalDateTimeUtil.format(yearMonth.atEndOfMonth(), DatePattern.NORM_DATE_PATTERN) : item.getEndTime()) + "的" + item.getItemName() : item.getDescription());
             orderItem.setTenantId(expenseOrder.getTenantId());
             orderItem.setStartDate(billYearMonth.atDay(1));
-            orderItem.setEndDate(billYearMonth.atEndOfMonth());
+            orderItem.setEndDate(StringUtils.isBlank(item.getEndTime()) ? billYearMonth.atEndOfMonth() : LocalDate.parse(item.getEndTime(),DateTimeFormatter.ofPattern(FORMAT_YEAR_MONTH_DAY)));
             orderItem.setContractId(item.getContractId());
             expenseOrderItemMapper.insert(orderItem);
             if (item.getExpenseSource().equals(BusinessConstants.DISCOUNT_DEDUCTION)) {

+ 2 - 2
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/biz/NurseChangeRecordServiceImpl.java

@@ -215,9 +215,9 @@ public class NurseChangeRecordServiceImpl implements ElderlyChangeRecordService
                 if (!otherBedRecordList.isEmpty()) {
                     ElderlyChangeRecordDO elderlyChangeRecordDO = otherBedRecordList.get(0);
                     if (elderlyInfoMapper.selectById(elderlyChangeRecordDO.getElderlyId()).getInStatus() == 1) {
-                        return Boolean.TRUE;
+                        return Boolean.FALSE;
                     }
-                    return Boolean.FALSE;
+                    return Boolean.TRUE;
                 }
             }
         }

+ 26 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/elderly/ElderlySafeCheckService.java

@@ -0,0 +1,26 @@
+package cn.iocoder.yudao.module.system.service.elderly;
+
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.module.system.controller.admin.elderly.vo.ElderlySafeCheckElderPageReqVO;
+import cn.iocoder.yudao.module.system.controller.admin.elderly.vo.ElderlySafeCheckElderPageRespVO;
+import cn.iocoder.yudao.module.system.controller.admin.elderly.vo.ElderlySafeCheckPageReqVO;
+import cn.iocoder.yudao.module.system.controller.admin.elderly.vo.ElderlySafeCheckRespVO;
+import cn.iocoder.yudao.module.system.controller.admin.elderly.vo.ElderlySafeCheckSaveReqVO;
+
+import javax.validation.Valid;
+import java.util.List;
+
+public interface ElderlySafeCheckService {
+
+    Integer createBatch(@Valid List<ElderlySafeCheckSaveReqVO> createReqList);
+
+    void update(@Valid ElderlySafeCheckSaveReqVO updateReqVO);
+
+    void delete(Long id);
+
+    ElderlySafeCheckRespVO get(Long id);
+
+    PageResult<ElderlySafeCheckElderPageRespVO> getElderPage(ElderlySafeCheckElderPageReqVO pageReqVO);
+
+    PageResult<ElderlySafeCheckRespVO> getPage(ElderlySafeCheckPageReqVO pageReqVO);
+}

+ 146 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/elderly/ElderlySafeCheckServiceImpl.java

@@ -0,0 +1,146 @@
+package cn.iocoder.yudao.module.system.service.elderly;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
+import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
+import cn.iocoder.yudao.module.system.controller.admin.elderly.vo.ElderlySafeCheckElderPageReqVO;
+import cn.iocoder.yudao.module.system.controller.admin.elderly.vo.ElderlySafeCheckElderPageRespVO;
+import cn.iocoder.yudao.module.system.controller.admin.elderly.vo.ElderlySafeCheckPageReqVO;
+import cn.iocoder.yudao.module.system.controller.admin.elderly.vo.ElderlySafeCheckRespVO;
+import cn.iocoder.yudao.module.system.controller.admin.elderly.vo.ElderlySafeCheckSaveReqVO;
+import cn.iocoder.yudao.module.system.dal.dataobject.biz.ElderlyInfoDO;
+import cn.iocoder.yudao.module.system.dal.dataobject.elderly.ElderlySafeCheckDO;
+import cn.iocoder.yudao.module.system.dal.mysql.biz.ElderlyInfoMapper;
+import cn.iocoder.yudao.module.system.dal.mysql.elderly.ElderlySafeCheckMapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.validation.annotation.Validated;
+
+import javax.annotation.Resource;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.util.*;
+import java.util.function.Function;
+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;
+
+@Service
+@Validated
+public class ElderlySafeCheckServiceImpl implements ElderlySafeCheckService {
+
+    @Resource
+    private ElderlySafeCheckMapper safeCheckMapper;
+    @Resource
+    private ElderlyInfoMapper elderlyInfoMapper;
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Integer createBatch(List<ElderlySafeCheckSaveReqVO> createReqList) {
+        if (CollectionUtil.isEmpty(createReqList)) {
+            return 0;
+        }
+        List<ElderlySafeCheckDO> saveList = new ArrayList<>();
+        for (ElderlySafeCheckSaveReqVO createReqVO : createReqList) {
+            ElderlySafeCheckDO safeCheck = BeanUtils.toBean(createReqVO, ElderlySafeCheckDO.class);
+            if (safeCheck.getTenantId() == null) {
+                safeCheck.setTenantId(TenantContextHolder.getTenantId());
+            }
+            saveList.add(safeCheck);
+        }
+        safeCheckMapper.insertBatch(saveList);
+        return saveList.size();
+    }
+
+    @Override
+    public void update(ElderlySafeCheckSaveReqVO updateReqVO) {
+        validateExists(updateReqVO.getId());
+        ElderlySafeCheckDO updateObj = BeanUtils.toBean(updateReqVO, ElderlySafeCheckDO.class);
+        if (updateObj.getTenantId() == null) {
+            updateObj.setTenantId(TenantContextHolder.getTenantId());
+        }
+        safeCheckMapper.updateById(updateObj);
+    }
+
+    @Override
+    public void delete(Long id) {
+        validateExists(id);
+        safeCheckMapper.deleteById(id);
+    }
+
+    @Override
+    public ElderlySafeCheckRespVO get(Long id) {
+        ElderlySafeCheckDO safeCheck = safeCheckMapper.selectById(id);
+        if (safeCheck == null) {
+            return null;
+        }
+        ElderlySafeCheckRespVO respVO = BeanUtils.toBean(safeCheck, ElderlySafeCheckRespVO.class);
+        fillElderInfo(Collections.singletonList(respVO));
+        return respVO;
+    }
+
+    @Override
+    public PageResult<ElderlySafeCheckElderPageRespVO> getElderPage(ElderlySafeCheckElderPageReqVO pageReqVO) {
+        if (pageReqVO.getTenantIds() == null || pageReqVO.getTenantIds().length == 0) {
+            pageReqVO.setTenantIds(new Long[]{TenantContextHolder.getTenantId()});
+        }
+        Page<Object> page = new Page<>(pageReqVO.getPageNo(), pageReqVO.getPageSize());
+        List<ElderlySafeCheckElderPageRespVO> list = safeCheckMapper.selectElderPage(page, pageReqVO);
+        return new PageResult<>(list, page.getTotal());
+    }
+
+    @Override
+    public PageResult<ElderlySafeCheckRespVO> getPage(ElderlySafeCheckPageReqVO pageReqVO) {
+        if (pageReqVO.getTenantIds() == null || pageReqVO.getTenantIds().length == 0) {
+            pageReqVO.setTenantIds(new Long[]{TenantContextHolder.getTenantId()});
+        }
+        LocalDateTime startTime = null;
+        LocalDateTime endTimeExclusive = null;
+        LocalDate[] checkDate = pageReqVO.getCheckDate();
+        if (checkDate != null) {
+            if (checkDate.length > 0 && checkDate[0] != null) {
+                startTime = checkDate[0].atStartOfDay();
+            }
+            if (checkDate.length > 1 && checkDate[1] != null) {
+                endTimeExclusive = checkDate[1].plusDays(1).atStartOfDay();
+            }
+        }
+
+        PageResult<ElderlySafeCheckDO> pageResult = safeCheckMapper.selectRecordPage(pageReqVO, startTime, endTimeExclusive);
+        List<ElderlySafeCheckRespVO> list = BeanUtils.toBean(pageResult.getList(), ElderlySafeCheckRespVO.class);
+        fillElderInfo(list);
+        return new PageResult<>(list, pageResult.getTotal());
+    }
+
+    private void fillElderInfo(List<ElderlySafeCheckRespVO> list) {
+        if (CollectionUtil.isEmpty(list)) {
+            return;
+        }
+        Set<Long> elderIds = list.stream().map(ElderlySafeCheckRespVO::getElderId)
+                .filter(Objects::nonNull).collect(Collectors.toSet());
+        if (CollectionUtil.isEmpty(elderIds)) {
+            return;
+        }
+        Map<Long, ElderlyInfoDO> elderMap = elderlyInfoMapper.selectBatchIds(elderIds).stream()
+                .filter(e -> e.getId() != null)
+                .collect(Collectors.toMap(ElderlyInfoDO::getId, Function.identity(), (a, b) -> a));
+        for (ElderlySafeCheckRespVO vo : list) {
+            ElderlyInfoDO elder = elderMap.get(vo.getElderId());
+            if (elder == null) {
+                continue;
+            }
+            vo.setElderName(elder.getElderName());
+            vo.setRoomName(elder.getRoomName());
+            vo.setBedName(elder.getBedName());
+        }
+    }
+
+    private void validateExists(Long id) {
+        if (id == null || safeCheckMapper.selectById(id) == null) {
+            throw exception(COMMON_NOT_FOUND);
+        }
+    }
+}

+ 10 - 1
yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/ElderlyContractMapper.xml

@@ -9,7 +9,10 @@
         文档可见:https://www.iocoder.cn/MyBatis/x-plugins/
      -->
     <select id="findPage" resultType="cn.iocoder.yudao.module.system.dal.dataobject.biz.ElderlyContractDO">
-        select ec.*,ei.in_status_type from elderly_contract ec left join elderly_info ei on ei.id = ec.elder_id
+        select ec.*,ei.in_status_type
+        from elderly_contract ec
+        left join elderly_info ei on ei.id = ec.elder_id
+        left join elderly_contract_detail ecd on  ec.id = ecd.contract_id
         left join system_tenant st on st.id = ec.tenant_id
         <where>
             <if test="params.elderName != null and params.elderName != ''">
@@ -21,6 +24,12 @@
             <if test="params.inStatusType != null">
                 and ei.in_status_type = #{params.inStatusType}
             </if>
+            <if test="params.hasExtra != null and params.hasExtra == 1">
+                and ecd.file_name is not null
+            </if>
+            <if test="params.hasExtra != null and params.hasExtra == 0">
+                and ecd.file_name is null
+            </if>
             <if test="params.orgType != null">
                 and ei.org_type = #{params.orgType}
             </if>

+ 6 - 0
yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/ElderlyInfoMapper.xml

@@ -102,6 +102,12 @@
         <if test="pageVO.careType != null">
             and ei.care_type = #{pageVO.careType}
         </if>
+        <if test="pageVO.hasExtra != null and pageVO.hasExtra == 1">
+            and ei.hasExtra is not null and ei.hasExtra != ''
+        </if>
+        <if test="pageVO.hasExtra != null and pageVO.hasExtra == 0">
+            and ei.hasExtra is null and ei.hasExtra == ''
+        </if>
         <if test="pageVO.checkInTime != null">
             and ei.create_time between #{pageVO.checkInTime[0]} and #{pageVO.checkInTime[1]}
         </if>

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

@@ -3,8 +3,8 @@ spring:
     name: yudao-server
 
   profiles:
-#    active: test
-    active: dev
+    active: test
+#    active: dev
 
 
   main: