Browse Source

修改
1、离住转退住功能调整

liangwenxuan 1 tuần trước cách đây
mục cha
commit
bb03f471c9

+ 1 - 2
yudao-module-bpm/yudao-module-bpm-biz/src/main/java/cn/iocoder/yudao/module/bpm/service/business/BpmElderlApplyServiceImpl.java

@@ -183,11 +183,10 @@ public class BpmElderlApplyServiceImpl implements BpmElderlApplyService {
     @LogRecord(type = DMISSION_RETREAT_TYPE, subType = DMISSION_ELDER_RETREAT_SUB_TYPE, bizNo = "{{#createReqVO.elderlyId}}",
             success = DMISSION_ELDER_RETREAT_SUCCESS, extra = "{{#createReqVO.elderlyId}}")
     public Long createApplyRetreatSimple(Long userId, BpmApplyRetreatSimpleCreateReqVO createReqVO) {
-        // 离住转退住:跳过未返院离住记录校验,但保留费用账单、未返院请假等通用校验
-        elderlyExpenseApi.applyRetreatCommonCheck(createReqVO.getElderlyId(), createReqVO.getCostDeadline());
         // 离住转退住:若费用截止日期当月无月度账单则生成;并对离住记录做返院登记(返院日期为费用截止日期)
         elderlyExpenseApi.handleTempOutReturnForRetreat(createReqVO.getTempOutId(), createReqVO.getElderlyId(),
                 TenantContextHolder.getTenantId(), createReqVO.getCostDeadline());
+        elderlyExpenseApi.applyRetreatCommonCheck(createReqVO.getElderlyId(), createReqVO.getCostDeadline());
         ElderlyRetreatRecordRespVO elderlyRetreatRecordRespVO = new ElderlyRetreatRecordRespVO();
         elderlyRetreatRecordRespVO.setElderlyId(createReqVO.getElderlyId());
         elderlyRetreatRecordRespVO.setRetreatDate(createReqVO.getRetreatDate());

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

@@ -517,15 +517,7 @@ public class BpmElderlyExpenseApiImpl implements BpmElderlyExpenseApi {
         if (tempOutId == null || elderId == null || costDeadlineDate == null) {
             return;
         }
-        // 1. 费用截止日期当月若无月度账单,则生成该长者该月账单(参考 batchGenerateExpenseBill 单长者逻辑)
-        YearMonth billingMonth = YearMonth.from(costDeadlineDate);
-        ExpenseOrderSaveVO saveVO = new ExpenseOrderSaveVO();
-        saveVO.setTenantId(tenantId);
-        saveVO.setBillingMonth(billingMonth.toString());
-        saveVO.setElderId(elderId);
-        expenseOrderService.batchGenerateExpenseBill(saveVO, null);
-
-        // 2. 对离住记录做返院登记,返院日期为费用截止日期
+        // 1. 对离住记录做返院登记,返院日期为费用截止日期+1,避免多收1天费用,后续恢复正常费用截止日期
         ElderlyTempOutDO tempOutDO = elderlyTempOutMapper.selectById(tempOutId);
         if (tempOutDO == null) {
             return;
@@ -537,9 +529,19 @@ public class BpmElderlyExpenseApiImpl implements BpmElderlyExpenseApi {
         YearMonth comeYm = YearMonth.from(costDeadlineDate);
         ElderlyTempOutDO updateDO = new ElderlyTempOutDO();
         updateDO.setId(tempOutId);
-        updateDO.setComeTime(costDeadlineDate.atStartOfDay());
+        updateDO.setComeTime(costDeadlineDate.atStartOfDay().plusDays(1));
         updateDO.setComeMonth(comeYm.toString());
         updateDO.setOutStatus(2);
         elderlyTempOutMapper.updateById(updateDO);
+        // 2. 费用截止日期当月若无月度账单,则生成该长者该月账单(参考 batchGenerateExpenseBill 单长者逻辑)
+        YearMonth billingMonth = YearMonth.from(costDeadlineDate);
+        ExpenseOrderSaveVO saveVO = new ExpenseOrderSaveVO();
+        saveVO.setTenantId(tenantId);
+        saveVO.setBillingMonth(billingMonth.toString());
+        saveVO.setElderId(elderId);
+        expenseOrderService.batchGenerateExpenseBill(saveVO, null);
+        // 3. 恢复正确返院日期
+        updateDO.setComeTime(costDeadlineDate.atStartOfDay());
+        elderlyTempOutMapper.updateById(updateDO);
     }
 }

+ 2 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/biz/NineRiskBoardController.java

@@ -1,6 +1,7 @@
 package cn.iocoder.yudao.module.system.controller.admin.biz;
 
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
 import cn.iocoder.yudao.module.system.controller.admin.biz.vo.riskboard.NineRiskBoardReqVO;
 import cn.iocoder.yudao.module.system.controller.admin.biz.vo.riskboard.NineRiskBoardRespVO;
 import cn.iocoder.yudao.module.system.service.biz.NineRiskBoardService;
@@ -32,6 +33,7 @@ public class NineRiskBoardController {
     @GetMapping("/get")
     @Operation(summary = "获取九防安全风险综合看板数据",
             description = "一次性返回核心指标、风险分布、月度趋势、热力图、高风险名单等 12 项统计")
+    @TenantIgnore
     public CommonResult<NineRiskBoardRespVO> getRiskBoard(NineRiskBoardReqVO reqVO) {
         return success(nineRiskBoardService.getRiskBoard(reqVO));
     }

+ 2 - 2
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/controller/admin/biz/vo/ElderlyTempOutPageReqVO.java

@@ -17,8 +17,8 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
 @ToString(callSuper = true)
 public class ElderlyTempOutPageReqVO extends PageParam {
 
-    @Schema(description = "长者ID")
-    private Long elderId;
+    @Schema(description = "长者姓名(模糊查询)")
+    private String elderName;
 
     @Schema(description = "床位ID")
     private Long bedId;

+ 11 - 9
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/biz/ElderlyTempOutMapper.java

@@ -2,23 +2,25 @@ package cn.iocoder.yudao.module.system.dal.mysql.biz;
 
 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.framework.mybatis.core.util.MyBatisUtils;
 import cn.iocoder.yudao.module.system.controller.admin.biz.vo.ElderlyTempOutPageReqVO;
 import cn.iocoder.yudao.module.system.dal.dataobject.biz.ElderlyTempOutDO;
+import com.baomidou.mybatisplus.core.metadata.IPage;
 import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
 
 @Mapper
 public interface ElderlyTempOutMapper extends BaseMapperX<ElderlyTempOutDO> {
 
     default PageResult<ElderlyTempOutDO> selectPage(ElderlyTempOutPageReqVO reqVO) {
-        return selectPage(reqVO, new LambdaQueryWrapperX<ElderlyTempOutDO>()
-                .eqIfPresent(ElderlyTempOutDO::getElderId, reqVO.getElderId())
-                .eqIfPresent(ElderlyTempOutDO::getBedId, reqVO.getBedId())
-                .eqIfPresent(ElderlyTempOutDO::getOutStatus, reqVO.getOutStatus())
-                .betweenIfPresent(ElderlyTempOutDO::getOutTime, reqVO.getOutTime())
-                .betweenIfPresent(ElderlyTempOutDO::getComeTime, reqVO.getComeTime())
-                .inIfPresent(ElderlyTempOutDO::getTenantId, reqVO.getTenantIds())
-                .orderByDesc(ElderlyTempOutDO::getCreateTime));
+        IPage<ElderlyTempOutDO> mpPage = MyBatisUtils.buildPage(reqVO);
+        selectTempOutPage(mpPage, reqVO);
+        return new PageResult<>(mpPage.getRecords(), mpPage.getTotal());
     }
+
+    /**
+     * 关联长者表分页查询(支持按长者姓名模糊匹配),SQL 见对应的 Mapper.xml
+     */
+    IPage<ElderlyTempOutDO> selectTempOutPage(IPage<ElderlyTempOutDO> page, @Param("reqVO") ElderlyTempOutPageReqVO reqVO);
 }
 

+ 20 - 7
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/biz/ElderlyTempOutServiceImpl.java

@@ -157,14 +157,26 @@ public class ElderlyTempOutServiceImpl implements ElderlyTempOutService {
                 continue;
             }
 
-            LocalDate outDate = outTime.toLocalDate();
-            LocalDate monthEnd = billYm.atEndOfMonth();
-            if (outDate.isAfter(monthEnd)) {
+            // 以当前遍历账单的账单月作为计算基准:离住当月从离住日起退至月末,离住之后的账单月整月退费
+            String currentBillingMonth = monthOrder.getBillingMonth();
+            if (currentBillingMonth == null) {
                 continue;
             }
-
-            int refundDays = monthEnd.getDayOfMonth() - outDate.getDayOfMonth() + 1;
-            int daysInMonth = billYm.lengthOfMonth();
+            YearMonth currentYm = YearMonth.parse(currentBillingMonth, DateTimeFormatter.ofPattern("yyyy-MM"));
+            if (currentYm.isBefore(billYm)) {
+                continue;
+            }
+            LocalDate monthEnd = currentYm.atEndOfMonth();
+            LocalDate outDate;
+            int refundDays;
+            if (currentYm.equals(billYm)) {
+                outDate = outTime.toLocalDate();
+                refundDays = (int) (monthEnd.toEpochDay() - outDate.toEpochDay() + 1);
+            } else {
+                outDate = currentYm.atDay(1);
+                refundDays = currentYm.lengthOfMonth();
+            }
+            int daysInMonth = currentYm.lengthOfMonth();
 
             for (ExpenseOrderItemDO item : orderItems) {
                 if (item.getType() == null) {
@@ -189,7 +201,7 @@ public class ElderlyTempOutServiceImpl implements ElderlyTempOutService {
                 // 账单已缴费、锁定、确认:生成日常费用记录(来源=离住)并写入已缴费账单明细
                 if (Objects.equals(monthOrder.getPayStatus(), 1) || Boolean.TRUE.equals(monthOrder.getConfirmStatus()) || Boolean.TRUE.equals(monthOrder.getIsLock())) {
                     DailyExpensesDO dailyExpenses = buildTempOutDailyExpense(elderId, tenantId, monthOrder.getBillOrderNumber(),
-                            item, dayPrice, refundAmount, refundDays, outDate, monthEnd, billingMonth);
+                            item, dayPrice, refundAmount, refundDays, outDate, monthEnd, currentBillingMonth);
                     dailyExpensesMapper.insert(dailyExpenses);
 
                     ExpenseOrderItemDO orderItem = new ExpenseOrderItemDO();
@@ -470,6 +482,7 @@ public class ElderlyTempOutServiceImpl implements ElderlyTempOutService {
         }
         ElderlyRetreatRecordDO retreatRecordDO = elderlyRetreatRecordMapper.selectOne(new LambdaQueryWrapperX<ElderlyRetreatRecordDO>()
                 .eq(ElderlyRetreatRecordDO::getElderlyId, elderId)
+                .eq(ElderlyRetreatRecordDO::getApplyType,1)
                 .orderByDesc(ElderlyRetreatRecordDO::getId)
                 .last("LIMIT 1"));
         if (retreatRecordDO == null) {

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

@@ -1605,7 +1605,7 @@ public class RefundSettlementOrderServiceImpl implements RefundSettlementOrderSe
         itemVO.setDays((int) stayDay);
         itemVO.setPrice(dayPrice.setScale(2, RoundingMode.HALF_UP));
         itemVO.setAmount(amount);
-        itemVO.setRemarks("收" + firstDayDate + "到" + endDayDate + "共" + stayDay + "天的费用");
+        itemVO.setRemarks("收" + firstDayDate + "到" + calEndDate + "共" + stayDay + "天的费用");
         // 如果账单已支付,需要计算应退金额
         if (item.getPayStatus().equals(BooleanEnum.TRUE.getValue())) {
             // 修正退费天数计算逻辑:从退住日期的下一天开始计算
@@ -1651,7 +1651,7 @@ public class RefundSettlementOrderServiceImpl implements RefundSettlementOrderSe
      */
     private void processPastMonthExpense(ExpenseOrderItemDO item, LocalDate beginDate, LocalDate endDayDate, ExpenseOrderItemVO itemVO) {
         long stayDay = ChronoUnit.DAYS.between(beginDate,endDayDate) + 1;
-        BigDecimal dayPrice = item.getPrice().divide(BigDecimal.valueOf(beginDate.lengthOfMonth()), 8, RoundingMode.DOWN);
+        BigDecimal dayPrice = item.getTotalAmount().divide(BigDecimal.valueOf(stayDay), 8, RoundingMode.DOWN);
         BigDecimal amount = dayPrice.multiply(BigDecimal.valueOf(stayDay)).setScale(2, RoundingMode.HALF_UP);
 
         itemVO.setDays((int) stayDay);

+ 52 - 0
yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/ElderlyTempOutMapper.xml

@@ -0,0 +1,52 @@
+<?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.ElderlyTempOutMapper">
+
+    <!--
+        关联长者表分页查询(支持按长者姓名模糊匹配)。
+        多表关联查询场景下使用 XML 编写 SQL,分页由 MyBatis Plus 分页插件自动处理。
+    -->
+
+    <select id="selectTempOutPage" resultType="cn.iocoder.yudao.module.system.dal.dataobject.biz.ElderlyTempOutDO">
+        SELECT
+            eo.id,
+            eo.elder_id,
+            eo.bed_id,
+            eo.out_status,
+            eo.out_time,
+            eo.come_time,
+            eo.out_reason,
+            eo.tenant_id,
+            eo.creator,
+            eo.create_time,
+            eo.updater,
+            eo.update_time
+        FROM elderly_temp_out eo
+        LEFT JOIN elderly_info ei ON eo.elder_id = ei.id
+        WHERE 1=1
+        <if test="reqVO.elderName != null and reqVO.elderName != ''">
+            AND ei.elder_name LIKE concat('%', #{reqVO.elderName}, '%')
+        </if>
+        <if test="reqVO.bedId != null">
+            AND eo.bed_id = #{reqVO.bedId}
+        </if>
+        <if test="reqVO.outStatus != null">
+            AND eo.out_status = #{reqVO.outStatus}
+        </if>
+        <if test="reqVO.outTime != null and reqVO.outTime.length == 2">
+            AND eo.out_time BETWEEN #{reqVO.outTime[0]} AND #{reqVO.outTime[1]}
+        </if>
+        <if test="reqVO.comeTime != null and reqVO.comeTime.length == 2">
+            AND eo.come_time BETWEEN #{reqVO.comeTime[0]} AND #{reqVO.comeTime[1]}
+        </if>
+        <if test="reqVO.tenantIds != null and reqVO.tenantIds.length > 0">
+            AND eo.tenant_id IN
+            <foreach item="tenantId" collection="reqVO.tenantIds" open="(" separator="," close=")">
+                #{tenantId}
+            </foreach>
+        </if>
+        ORDER BY eo.create_time DESC
+    </select>
+
+</mapper>