Selaa lähdekoodia

修改
1、重构账单中带出长护险、日常费用和消费券的代码
BUGFIX
1、解决账单分页中床位费、护理费、餐饮费没有记录相关变更费用的问题
2、解决续约后产生的账单没有带入提前录入的长护险、日常费用和消费券的问题

liangwenxuan 2 kuukautta sitten
vanhempi
commit
fa0061682d

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

@@ -74,12 +74,12 @@ public class ElderlyConsumerVouchersDO extends BaseNoDeleteDO {
     private String remarks;
 
     /**
-     * 使用状态,0:未抵扣 1:已抵扣
+     * 使用状态,0:未抵扣 1:已抵扣,即是否生成账单
      */
     private Integer status;
 
     /**
-     * 返还状态
+     * 返还状态,即账单是否已经缴费
      */
     private Integer returnStatus;
 

+ 4 - 0
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/home/HomeElderlyInfoMapper.java

@@ -4,6 +4,8 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
 import cn.iocoder.yudao.module.system.controller.admin.home.vo.HomeElderlyInfoPageReqVO;
 import cn.iocoder.yudao.module.system.controller.admin.home.vo.HomeElderlyInfoPageRespVO;
+import cn.iocoder.yudao.module.system.controller.admin.yk.vo.YkElderlyMealPageReqVO;
+import cn.iocoder.yudao.module.system.controller.admin.yk.vo.YkElderlyMealRespVO;
 import cn.iocoder.yudao.module.system.dal.dataobject.home.HomeElderlyInfoDO;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import org.apache.ibatis.annotations.Mapper;
@@ -15,4 +17,6 @@ import java.util.List;
 public interface HomeElderlyInfoMapper extends BaseMapperX<HomeElderlyInfoDO> {
 
     List<HomeElderlyInfoPageRespVO> selectPageWithAccountInfo(Page<HomeElderlyInfoPageRespVO> page, @Param("params") HomeElderlyInfoPageReqVO reqVO);
+
+    List<YkElderlyMealRespVO> selectElderlyMealPage(Page<YkElderlyMealRespVO> page, @Param("pageReqVO") YkElderlyMealPageReqVO pageReqVO);
 }

+ 164 - 234
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/biz/ExpenseOrderServiceImpl.java

@@ -166,10 +166,9 @@ public class ExpenseOrderServiceImpl implements ExpenseOrderService {
     public PageResult<ExpenseOrderDO> getExpenseBillPage(ExpenseBillPageReqVO pageReqVO) {
         Page<ExpenseOrderDO> page = new Page<>(pageReqVO.getPageNo(), pageReqVO.getPageSize());
         List<ExpenseOrderDO> list = expenseOrderMapper.getExpenseBillPage(page, pageReqVO);
+        Map<String,BigDecimal> categoryAmountMap = new HashMap<>();
+        Map<Integer,String> typeCategoryMap = new HashMap<>();
         for (ExpenseOrderDO expenseOrderDO : list) {
-            BigDecimal bedAmount = BigDecimal.ZERO;
-            BigDecimal nurseAmount = BigDecimal.ZERO;
-            BigDecimal mealAmount = BigDecimal.ZERO;
             BigDecimal otherAmount = BigDecimal.ZERO;
             BigDecimal otherRoundAmount = BigDecimal.ZERO;
             BigDecimal paidAmount = BigDecimal.ZERO;
@@ -191,25 +190,33 @@ public class ExpenseOrderServiceImpl implements ExpenseOrderService {
             for (ExpenseOrderItemDO orderItem : orderItems) {
                 if(orderItem.getExpenseSource().equals(BusinessConstants.EXPENSE_ITEM)){
                     if (orderItem.getType() != null && orderItem.getType() == 1) {
-                        bedAmount = bedAmount.add(orderItem.getTotalAmount().setScale(2, RoundingMode.HALF_UP));
+                        typeCategoryMap.put(orderItem.getType(),orderItem.getItemCategoryName());
+                        categoryAmountMap.put(orderItem.getItemCategoryName(),orderItem.getTotalAmount().setScale(2, RoundingMode.HALF_UP));
                     } else if (orderItem.getType() != null && orderItem.getType() == 2) {
-                        nurseAmount = nurseAmount.add(orderItem.getTotalAmount().setScale(2, RoundingMode.HALF_UP));
+                        typeCategoryMap.put(orderItem.getType(),orderItem.getItemCategoryName());
+                        categoryAmountMap.put(orderItem.getItemCategoryName(),orderItem.getTotalAmount().setScale(2, RoundingMode.HALF_UP));
                     } else if (orderItem.getType() != null && orderItem.getType() == 3) {
-                        mealAmount = mealAmount.add(orderItem.getTotalAmount().setScale(2, RoundingMode.HALF_UP));
+                        typeCategoryMap.put(orderItem.getType(),orderItem.getItemCategoryName());
+                        categoryAmountMap.put(orderItem.getItemCategoryName(),orderItem.getTotalAmount().setScale(2, RoundingMode.HALF_UP));
                     }else {
                         otherAmount = otherAmount.add(orderItem.getTotalAmount().setScale(2, RoundingMode.HALF_UP));
                         otherRoundAmount = otherRoundAmount.add(orderItem.getTotalAmount().setScale(2, RoundingMode.HALF_UP));
                     }
                 } else {
+                    BigDecimal categoryAmount = categoryAmountMap.get(orderItem.getItemCategoryName());
+                    if(categoryAmount != null){
+                        categoryAmountMap.put(orderItem.getItemCategoryName(),categoryAmount.add(orderItem.getTotalAmount().setScale(2, RoundingMode.HALF_UP)));
+                        continue;
+                    }
                     otherAmount = otherAmount.add(orderItem.getTotalAmount().setScale(2, RoundingMode.HALF_UP));
                     otherRoundAmount = otherRoundAmount.add(orderItem.getTotalAmount().setScale(2, RoundingMode.HALF_UP));
                 }
             }
-            expenseOrderDO.setBedAmount(bedAmount);
-            expenseOrderDO.setNurseAmount(nurseAmount);
-            expenseOrderDO.setMealAmount(mealAmount);
+            expenseOrderDO.setBedAmount(categoryAmountMap.get(typeCategoryMap.get(1)));
+            expenseOrderDO.setNurseAmount(categoryAmountMap.get(typeCategoryMap.get(2)));
+            expenseOrderDO.setMealAmount(categoryAmountMap.get(typeCategoryMap.get(3)));
             expenseOrderDO.setOtherAmount(otherAmount);
-            expenseOrderDO.setPayableAmount(bedAmount.add(nurseAmount).add(mealAmount).add(otherAmount).setScale(2, RoundingMode.HALF_UP));
+            expenseOrderDO.setPayableAmount(expenseOrderDO.getBedAmount().add(expenseOrderDO.getNurseAmount()).add(expenseOrderDO.getMealAmount()).add(expenseOrderDO.getOtherAmount()).setScale(2, RoundingMode.HALF_UP));
             expenseOrderDO.setOtherRoundAmount(otherRoundAmount);
             expenseOrderDO.setPaidAmount(paidAmount.setScale(2, RoundingMode.HALF_UP));
         }
@@ -515,7 +522,7 @@ public class ExpenseOrderServiceImpl implements ExpenseOrderService {
                 }
             }
             if (expenseOrderItem.getExpenseSource().equals(BusinessConstants.CONSUMER_VOUCHER)) {
-                //修改长期护理保险缴费状态
+                //修改消费券缴费状态
                 ElderlyConsumerVouchersDO consumerVouchersDO = elderlyConsumerVouchersMapper.selectById(expenseOrderItem.getSourceExpenseItemId());
                 if (consumerVouchersDO != null) {
                     consumerVouchersDO.setReturnStatus(BooleanEnum.TRUE.getValue());
@@ -769,138 +776,162 @@ public class ExpenseOrderServiceImpl implements ExpenseOrderService {
                 actualStart = LocalDate.parse(collect.get(0).getStartTime());
                 actualEnd = LocalDate.parse(collect.get(0).getEndTime());
             }
-            //查询上月未缴费的日常费用
-            YearMonth attributionBillTime = YearMonth.parse(billingMonth, DateTimeFormatter.ofPattern("yyyy-MM"));
-            List<DailyExpensesDO> dailyExpensesList = dailyExpensesMapper.selectList(new LambdaQueryWrapperX<DailyExpensesDO>()
-                    .eq(DailyExpensesDO::getElderId, elderId)
-                    .le(DailyExpensesDO::getAttributionBillTime, attributionBillTime.toString())
-                    .eq(DailyExpensesDO::getStatus, BooleanEnum.FALSE.getValue())
-                    .eq(DailyExpensesDO::getIsGenerateBill, BooleanEnum.FALSE.getValue()));
-
-            List<ExpenseItemRespVO> dailyExpensesCollect = dailyExpensesList.stream().map(item -> {
-                ExpenseItemRespVO respVO = new ExpenseItemRespVO();
-                respVO.setExpenseType(item.getType());
-                respVO.setExpenseSource(BusinessConstants.DAILY_EXPENSES);
-                respVO.setSourceExpenseItemId(item.getId());
-                respVO.setPrice(item.getPrice());
-                respVO.setTotalAmount(item.getAmount());
-                respVO.setItemName(item.getItemName());
-                respVO.setItemCategory(item.getItemCategory());
-                respVO.setCount(item.getCount());
-                respVO.setDescription(item.getRemarks());
-                LocalDate localDate = item.getCreatedTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
-                if (item.getType() == 2 || item.getType() == 3) {  //变更和外出
-                    respVO.setStartTime(item.getStartDate() == null ? null : item.getStartDate().toString());
-                    respVO.setEndTime(item.getEndDate() == null ? null : item.getEndDate().toString());
-                } else if (item.getType() == 5) {  //分期
-                    respVO.setStartTime(localDate.toString());
-                    respVO.setEndTime(localDate.with(TemporalAdjusters.lastDayOfMonth()).toString());
-                } else {
-                    respVO.setStartTime(item.getStartDate() == null ? null : item.getStartDate().toString());
-                    respVO.setEndTime(item.getEndDate() == null ? null : item.getEndDate().toString());
-                }
-                return respVO;
-            }).collect(Collectors.toList());
-
-
-            //组装长护险抵扣的数据
-            // 查询对应月份未进行抵扣的长护险记录
-            List<ExpenseSubsidyDO> unclaimedSubsidies = expenseSubsidyMapper.selectList(new LambdaQueryWrapperX<ExpenseSubsidyDO>()
-                    .eq(ExpenseSubsidyDO::getElderId, elderId)
-                    .eq(ExpenseSubsidyDO::getDeductionBillMonth, billingMonth)
-                    .eq(ExpenseSubsidyDO::getStatus, BooleanEnum.FALSE.getValue())); // 未抵扣状态
-
-            // 组装成长护险抵扣项,参考queryExpenseBillItem中的日常和月度费用格式
-            LocalDate finalActualStart = actualStart;
-            LocalDate finalActualEnd = actualEnd;
-            List<ExpenseItemRespVO> subsidyCollect = unclaimedSubsidies.stream().map(subsidy -> {
-                ExpenseItemRespVO respVO = new ExpenseItemRespVO();
-                respVO.setExpenseType(7); // 7表示长护险抵扣项
-                respVO.setExpenseSource(BusinessConstants.LONG_TERM_CARE_INSURANCE); // 长护险费用来源标识
-                respVO.setSourceExpenseItemId(subsidy.getId());
-                respVO.setPrice(subsidy.getAmount().negate());
-                respVO.setTotalAmount(subsidy.getAmount().negate());
-                respVO.setItemName("长护险抵扣");
-                respVO.setItemCategory("长护险");
-                respVO.setCount(1);
-                respVO.setDescription(subsidy.getRemarks());
-                // 设置抵扣期间为实际区间(可能存在离住截断)
-                respVO.setStartTime(finalActualStart.toString());
-                respVO.setEndTime(finalActualEnd.toString());
-                return respVO;
-            }).collect(Collectors.toList());
+            List<ExpenseItemRespVO> dailyExpensesCollect = collectDailyExpenseItemsNoBill(elderId, billingMonth);
+            List<ExpenseItemRespVO> subsidyCollect = collectSubsidyItems(elderId, billingMonth, actualStart, actualEnd, false);
+            List<ExpenseItemRespVO> consumerVoucherCollect = collectConsumerVoucherItems(elderId, billingMonth, actualStart, actualEnd, false);
 
             // 优惠抵扣项:按实际区间折算金额 & 展示区间
             List<ExpenseItemRespVO> discountCollect = adjustDiscountByActualRange(elderId, billingMonth, actualStart, actualEnd);
             collect.addAll(discountCollect);
             collect.addAll(subsidyCollect);
+            collect.addAll(consumerVoucherCollect);
             collect.addAll(dailyExpensesCollect);
             return collect;
 
         } else {
-            //存在当月订单合并未缴费的日常费用
-            //查询上月未缴费的日常费用
             List<ExpenseItemRespVO> resultList = new ArrayList<>();
-            YearMonth attributionBillTime = YearMonth.parse(billingMonth, DateTimeFormatter.ofPattern("yyyy-MM"));
-            List<DailyExpensesDO> dailyExpensesList = dailyExpensesMapper.selectList(new LambdaQueryWrapperX<DailyExpensesDO>()
-                    .eq(DailyExpensesDO::getElderId, elderId)
-                    .le(DailyExpensesDO::getAttributionBillTime, attributionBillTime)
-                    .eq(DailyExpensesDO::getStatus, BooleanEnum.FALSE.getValue())
-                    .eq(DailyExpensesDO::getIsGenerateBill, BooleanEnum.FALSE.getValue()));
-
-            if (CollectionUtil.isNotEmpty(dailyExpensesList)) {
-                List<ExpenseItemRespVO> dailyExpenses = dailyExpensesList.stream().map(item -> {
-                    ExpenseItemRespVO respVO = new ExpenseItemRespVO();
-                    respVO.setExpenseType(item.getType());
-                    respVO.setExpenseSource(BusinessConstants.DAILY_EXPENSES);
-                    respVO.setSourceExpenseItemId(item.getId());
-                    respVO.setPrice(item.getPrice());
-                    respVO.setTotalAmount(item.getAmount());
-                    respVO.setItemName(item.getItemName());
-                    respVO.setItemCategory(item.getItemCategory());
-                    respVO.setCount(item.getCount());
-                    YearMonth yearMonth = YearMonth.parse(item.getAttributionBillTime(), DateTimeFormatter.ofPattern("yyyy-MM"));
-//                    LocalDate localDate = item.getCreatedTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
-                    respVO.setStartTime(yearMonth.atDay(1).toString());
-                    respVO.setEndTime(yearMonth.atEndOfMonth().toString());
-                    respVO.setDescription(item.getRemarks());
-                    return respVO;
-                }).collect(Collectors.toList());
-                resultList.addAll(dailyExpenses);
+            YearMonth billingYm = YearMonth.parse(billingMonth, DateTimeFormatter.ofPattern("yyyy-MM"));
+            LocalDate monthStart = billingYm.atDay(1);
+            LocalDate monthEnd = billingYm.atEndOfMonth();
+            resultList.addAll(collectDailyExpenseItemsHasBill(elderId, billingMonth));
+            resultList.addAll(collectSubsidyItems(elderId, billingMonth, monthStart, monthEnd, false));
+            resultList.addAll(collectConsumerVoucherItems(elderId, billingMonth, monthStart, monthEnd, false));
+            resultList.addAll(calculateDiscountDeduction(elderId, billingMonth));
+            return resultList;
+        }
+    }
+
+    private List<ExpenseItemRespVO> collectDailyExpenseItemsNoBill(Long elderId, String billingMonth) {
+        YearMonth attributionBillTime = YearMonth.parse(billingMonth, DateTimeFormatter.ofPattern("yyyy-MM"));
+        List<DailyExpensesDO> dailyExpensesList = dailyExpensesMapper.selectList(new LambdaQueryWrapperX<DailyExpensesDO>()
+                .eq(DailyExpensesDO::getElderId, elderId)
+                .le(DailyExpensesDO::getAttributionBillTime, attributionBillTime.toString())
+                .eq(DailyExpensesDO::getStatus, BooleanEnum.FALSE.getValue())
+                .eq(DailyExpensesDO::getIsGenerateBill, BooleanEnum.FALSE.getValue()));
+
+        return dailyExpensesList.stream().map(item -> {
+            ExpenseItemRespVO respVO = new ExpenseItemRespVO();
+            respVO.setExpenseType(item.getType());
+            respVO.setExpenseSource(BusinessConstants.DAILY_EXPENSES);
+            respVO.setSourceExpenseItemId(item.getId());
+            respVO.setPrice(item.getPrice());
+            respVO.setTotalAmount(item.getAmount());
+            respVO.setItemName(item.getItemName());
+            respVO.setItemCategory(item.getItemCategory());
+            respVO.setCount(item.getCount());
+            respVO.setDescription(item.getRemarks());
+            LocalDate localDate = item.getCreatedTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
+            if (item.getType() == 2 || item.getType() == 3) {
+                respVO.setStartTime(item.getStartDate() == null ? null : item.getStartDate().toString());
+                respVO.setEndTime(item.getEndDate() == null ? null : item.getEndDate().toString());
+            } else if (item.getType() == 5) {
+                respVO.setStartTime(localDate.toString());
+                respVO.setEndTime(localDate.with(TemporalAdjusters.lastDayOfMonth()).toString());
+            } else {
+                respVO.setStartTime(item.getStartDate() == null ? null : item.getStartDate().toString());
+                respVO.setEndTime(item.getEndDate() == null ? null : item.getEndDate().toString());
             }
+            return respVO;
+        }).collect(Collectors.toList());
+    }
 
-            List<ExpenseSubsidyDO> unclaimedSubsidies = expenseSubsidyMapper.selectList(new LambdaQueryWrapperX<ExpenseSubsidyDO>()
-                    .eq(ExpenseSubsidyDO::getElderId, elderId)
-                    .eq(ExpenseSubsidyDO::getDeductionBillMonth, billingMonth)
-                    .eq(ExpenseSubsidyDO::getStatus, BooleanEnum.FALSE.getValue())); // 未抵扣状态
+    private List<ExpenseItemRespVO> collectDailyExpenseItemsHasBill(Long elderId, String billingMonth) {
+        YearMonth attributionBillTime = YearMonth.parse(billingMonth, DateTimeFormatter.ofPattern("yyyy-MM"));
+        List<DailyExpensesDO> dailyExpensesList = dailyExpensesMapper.selectList(new LambdaQueryWrapperX<DailyExpensesDO>()
+                .eq(DailyExpensesDO::getElderId, elderId)
+                .like(DailyExpensesDO::getAttributionBillTime, attributionBillTime)
+                .eq(DailyExpensesDO::getStatus, BooleanEnum.FALSE.getValue())
+                .eq(DailyExpensesDO::getIsGenerateBill, BooleanEnum.FALSE.getValue()));
 
-            // 组装成长护险抵扣项,参考queryExpenseBillItem中的日常和月度费用格式
-            List<ExpenseItemRespVO> subsidyCollect = unclaimedSubsidies.stream().map(subsidy -> {
-                ExpenseItemRespVO respVO = new ExpenseItemRespVO();
-                respVO.setExpenseType(7); // 7表示长护险抵扣项
-                respVO.setExpenseSource(BusinessConstants.LONG_TERM_CARE_INSURANCE); // 长护险费用来源标识
-                respVO.setSourceExpenseItemId(subsidy.getId());
-                respVO.setPrice(subsidy.getAmount().negate());
-                respVO.setTotalAmount(subsidy.getAmount().negate());
-                respVO.setItemName("长护险抵扣");
-                respVO.setItemCategory("长护险");
-                respVO.setCount(1);
-                respVO.setDescription(subsidy.getRemarks());
-                // 设置抵扣期间为整个月
-                YearMonth yearMonth = YearMonth.parse(billingMonth, DateTimeFormatter.ofPattern("yyyy-MM"));
-                respVO.setStartTime(yearMonth.atDay(1).toString());
-                respVO.setEndTime(yearMonth.atEndOfMonth().toString());
+        return dailyExpensesList.stream().map(item -> {
+            ExpenseItemRespVO respVO = new ExpenseItemRespVO();
+            respVO.setExpenseType(item.getType());
+            respVO.setExpenseSource(BusinessConstants.DAILY_EXPENSES);
+            respVO.setSourceExpenseItemId(item.getId());
+            respVO.setPrice(item.getPrice());
+            respVO.setTotalAmount(item.getAmount());
+            respVO.setItemName(item.getItemName());
+            respVO.setItemCategory(item.getItemCategory());
+            respVO.setCount(item.getCount() == null ? 1 : item.getCount());
+            if (item.getStartDate() != null) {
+                respVO.setStartTime(item.getStartDate().toString());
+            }
+            if (item.getEndDate() != null) {
+                respVO.setEndTime(item.getEndDate().toString());
+            }
+            respVO.setDescription(item.getRemarks());
+            return respVO;
+        }).collect(Collectors.toList());
+    }
 
-                return respVO;
-            }).collect(Collectors.toList());
-            resultList.addAll(subsidyCollect);
+    private List<ExpenseItemRespVO> collectSubsidyItems(Long elderId, String billingMonth,
+                                                         LocalDate startDate, LocalDate endDate,
+                                                         boolean markUsed) {
+        List<ExpenseSubsidyDO> unclaimedSubsidies = expenseSubsidyMapper.selectList(new LambdaQueryWrapperX<ExpenseSubsidyDO>()
+                .eq(ExpenseSubsidyDO::getElderId, elderId)
+                .eq(ExpenseSubsidyDO::getDeductionBillMonth, billingMonth)
+                .eq(ExpenseSubsidyDO::getStatus, BooleanEnum.FALSE.getValue()));
 
-            // 优惠抵扣项
-            List<ExpenseItemRespVO> discountCollect = calculateDiscountDeduction(elderId, billingMonth);
-            resultList.addAll(discountCollect);
+        List<ExpenseSubsidyDO> updateList = new ArrayList<>();
+        List<ExpenseItemRespVO> result = unclaimedSubsidies.stream().map(subsidy -> {
+            ExpenseItemRespVO respVO = new ExpenseItemRespVO();
+            respVO.setExpenseType(7);
+            respVO.setExpenseSource(BusinessConstants.LONG_TERM_CARE_INSURANCE);
+            respVO.setSourceExpenseItemId(subsidy.getId());
+            respVO.setPrice(subsidy.getAmount().negate());
+            respVO.setTotalAmount(subsidy.getAmount().negate());
+            respVO.setItemName("长护险抵扣");
+            respVO.setItemCategory("长护险");
+            respVO.setCount(1);
+            respVO.setDescription(subsidy.getRemarks());
+            respVO.setStartTime(startDate.toString());
+            respVO.setEndTime(endDate.toString());
+            if (markUsed) {
+                subsidy.setStatus(BooleanEnum.TRUE.getValue());
+                updateList.add(subsidy);
+            }
+            return respVO;
+        }).collect(Collectors.toList());
 
-            return resultList;
+        if (markUsed && CollectionUtil.isNotEmpty(updateList)) {
+            expenseSubsidyMapper.updateBatch(updateList);
         }
+        return result;
+    }
+
+    private List<ExpenseItemRespVO> collectConsumerVoucherItems(Long elderId, String billingMonth,
+                                                                 LocalDate startDate, LocalDate endDate,
+                                                                 boolean markUsed) {
+        List<ElderlyConsumerVouchersDO> voucherList = elderlyConsumerVouchersMapper.selectList(new LambdaQueryWrapperX<ElderlyConsumerVouchersDO>()
+                .eq(ElderlyConsumerVouchersDO::getElderId, elderId)
+                .eq(ElderlyConsumerVouchersDO::getBillingMonth, billingMonth)
+                .eq(ElderlyConsumerVouchersDO::getStatus, BooleanEnum.FALSE.getValue()));
+
+        List<ElderlyConsumerVouchersDO> updateList = new ArrayList<>();
+        List<ExpenseItemRespVO> result = voucherList.stream().map(voucher -> {
+            ExpenseItemRespVO respVO = new ExpenseItemRespVO();
+            respVO.setExpenseType(7);
+            respVO.setExpenseSource(BusinessConstants.CONSUMER_VOUCHER);
+            respVO.setSourceExpenseItemId(voucher.getId());
+            respVO.setPrice(voucher.getAmount().negate());
+            respVO.setTotalAmount(voucher.getAmount().negate());
+            respVO.setItemName("消费券抵扣");
+            respVO.setItemCategory("消费券");
+            respVO.setCount(1);
+            respVO.setDescription(voucher.getRemarks());
+            respVO.setStartTime(startDate.toString());
+            respVO.setEndTime(endDate.toString());
+            if (markUsed) {
+                voucher.setStatus(BooleanEnum.TRUE.getValue());
+                updateList.add(voucher);
+            }
+            return respVO;
+        }).collect(Collectors.toList());
+
+        if (markUsed && CollectionUtil.isNotEmpty(updateList)) {
+            elderlyConsumerVouchersMapper.updateBatch(updateList);
+        }
+        return result;
     }
 
     /**
@@ -2300,66 +2331,9 @@ public class ExpenseOrderServiceImpl implements ExpenseOrderService {
             actualEnd = LocalDate.parse(collect.get(0).getEndTime());
         }
 
-        // 2、日常费用:实现对齐 queryExpenseBillItem 中无账单场景的逻辑
-        YearMonth attributionBillTime = YearMonth.parse(billingMonth, DateTimeFormatter.ofPattern("yyyy-MM"));
-        List<DailyExpensesDO> dailyExpensesList = dailyExpensesMapper.selectList(new LambdaQueryWrapperX<DailyExpensesDO>()
-                .eq(DailyExpensesDO::getElderId, elderId)
-                .le(DailyExpensesDO::getAttributionBillTime, attributionBillTime.toString())
-                .eq(DailyExpensesDO::getStatus, BooleanEnum.FALSE.getValue())
-                .eq(DailyExpensesDO::getIsGenerateBill, BooleanEnum.FALSE.getValue()));
-
-        List<ExpenseItemRespVO> dailyExpensesCollect = dailyExpensesList.stream().map(item -> {
-            ExpenseItemRespVO respVO = new ExpenseItemRespVO();
-            respVO.setExpenseType(item.getType());
-            respVO.setExpenseSource(BusinessConstants.DAILY_EXPENSES);
-            respVO.setSourceExpenseItemId(item.getId());
-            respVO.setPrice(item.getPrice());
-            respVO.setTotalAmount(item.getAmount());
-            respVO.setItemName(item.getItemName());
-            respVO.setItemCategory(item.getItemCategory());
-            respVO.setCount(item.getCount());
-            respVO.setDescription(item.getRemarks());
-            LocalDate localDate = item.getCreatedTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
-            if (item.getType() == 2 || item.getType() == 3) {  // 变更和外出
-                respVO.setStartTime(item.getStartDate() == null ? null : item.getStartDate().toString());
-                respVO.setEndTime(item.getEndDate() == null ? null : item.getEndDate().toString());
-            } else if (item.getType() == 5) {  // 分期
-                respVO.setStartTime(localDate.toString());
-                respVO.setEndTime(localDate.with(TemporalAdjusters.lastDayOfMonth()).toString());
-            } else {
-                respVO.setStartTime(item.getStartDate() == null ? null : item.getStartDate().toString());
-                respVO.setEndTime(item.getEndDate() == null ? null : item.getEndDate().toString());
-            }
-            return respVO;
-        }).collect(Collectors.toList());
-
-        // 3、长护险抵扣:参考 queryExpenseBillItem 中的实现,并复用固定费用区间
-        List<ExpenseSubsidyDO> unclaimedSubsidies = expenseSubsidyMapper.selectList(new LambdaQueryWrapperX<ExpenseSubsidyDO>()
-                .eq(ExpenseSubsidyDO::getElderId, elderId)
-                .eq(ExpenseSubsidyDO::getDeductionBillMonth, billingMonth)
-                .eq(ExpenseSubsidyDO::getStatus, BooleanEnum.FALSE.getValue())); // 未抵扣状态
-
-        LocalDate finalActualStart = actualStart;
-        LocalDate finalActualEnd = actualEnd;
-        List<ExpenseItemRespVO> subsidyCollect = unclaimedSubsidies.stream().map(subsidy -> {
-            ExpenseItemRespVO respVO = new ExpenseItemRespVO();
-            respVO.setExpenseType(7); // 7表示长护险抵扣项
-            respVO.setExpenseSource(BusinessConstants.LONG_TERM_CARE_INSURANCE); // 长护险费用来源标识
-            respVO.setSourceExpenseItemId(subsidy.getId());
-            respVO.setPrice(subsidy.getAmount().negate());
-            respVO.setTotalAmount(subsidy.getAmount().negate());
-            respVO.setItemName("长护险抵扣");
-            respVO.setItemCategory("长护险");
-            respVO.setCount(1);
-            respVO.setDescription(subsidy.getRemarks());
-            // 设置抵扣期间为实际区间(可能存在离住截断)
-            respVO.setStartTime(finalActualStart.toString());
-            respVO.setEndTime(finalActualEnd.toString());
-            // 更新抵扣记录状态为已使用
-            subsidy.setStatus(1);
-            expenseSubsidyMapper.updateById(subsidy);
-            return respVO;
-        }).collect(Collectors.toList());
+        List<ExpenseItemRespVO> dailyExpensesCollect = collectDailyExpenseItemsNoBill(elderId, billingMonth);
+        List<ExpenseItemRespVO> subsidyCollect = collectSubsidyItems(elderId, billingMonth, actualStart, actualEnd, true);
+        List<ExpenseItemRespVO> consumerVoucherCollect = collectConsumerVoucherItems(elderId, billingMonth, actualStart, actualEnd, true);
 
         // 4、优惠抵扣项:按实际区间折算金额 & 展示区间
         List<ExpenseItemRespVO> adjustedDiscountCollect = adjustDiscountByActualRange(elderId, billingMonth, actualStart, actualEnd);
@@ -2368,6 +2342,7 @@ public class ExpenseOrderServiceImpl implements ExpenseOrderService {
         dataList.addAll(dailyExpensesCollect);
         dataList.addAll(adjustedDiscountCollect);
         dataList.addAll(subsidyCollect);
+        dataList.addAll(consumerVoucherCollect);
 
         // 根据长者的入住类型确定账单类型
         // inStatusType: 1=入住(长住), 2=试住, 3=短住
@@ -2441,55 +2416,10 @@ public class ExpenseOrderServiceImpl implements ExpenseOrderService {
             return;
         }
 
-        // 已经生成的获取当月未缴费的日常费用添加到账单中去
         YearMonth attributionBillTime = YearMonth.parse(billingMonth, DateTimeFormatter.ofPattern("yyyy-MM"));
-        List<DailyExpensesDO> dailyExpensesList = dailyExpensesMapper.selectList(new LambdaQueryWrapperX<DailyExpensesDO>()
-                .eq(DailyExpensesDO::getElderId, elderId)
-                .like(DailyExpensesDO::getAttributionBillTime, attributionBillTime)
-                .eq(DailyExpensesDO::getStatus, BooleanEnum.FALSE.getValue())
-                .eq(DailyExpensesDO::getIsGenerateBill, BooleanEnum.FALSE.getValue()));
-
-        List<ExpenseItemRespVO> dataList = dailyExpensesList.stream().map(item -> {
-            ExpenseItemRespVO respVO = new ExpenseItemRespVO();
-            respVO.setExpenseType(item.getType());
-            respVO.setExpenseSource(BusinessConstants.DAILY_EXPENSES);
-            respVO.setSourceExpenseItemId(item.getId());
-            respVO.setPrice(item.getPrice());
-            respVO.setTotalAmount(item.getAmount());
-            respVO.setItemName(item.getItemName());
-            respVO.setItemCategory(item.getItemCategory());
-            respVO.setCount(item.getCount() == null ? 1 : item.getCount());
-            respVO.setStartTime(item.getStartDate().toString());
-            respVO.setEndTime(item.getEndDate().toString());
-            return respVO;
-        }).collect(Collectors.toList());
-
-        // 查询对应月份未进行抵扣的长护险记录
-        List<ExpenseSubsidyDO> unclaimedSubsidies = expenseSubsidyMapper.selectList(new LambdaQueryWrapperX<ExpenseSubsidyDO>()
-                .eq(ExpenseSubsidyDO::getElderId, elderId)
-                .eq(ExpenseSubsidyDO::getDeductionBillMonth, billingMonth)
-                .eq(ExpenseSubsidyDO::getStatus, BooleanEnum.FALSE.getValue())); // 未抵扣状态
-
-        // 组装成长护险抵扣项,参考queryExpenseBillItem中的日常和月度费用格式
-        List<ExpenseItemRespVO> subsidyCollect = unclaimedSubsidies.stream().map(subsidy -> {
-            ExpenseItemRespVO respVO = new ExpenseItemRespVO();
-            respVO.setExpenseType(7); // 7表示长护险抵扣项
-            respVO.setExpenseSource(BusinessConstants.LONG_TERM_CARE_INSURANCE); // 长护险费用来源标识
-            respVO.setSourceExpenseItemId(subsidy.getId());
-            respVO.setPrice(subsidy.getAmount().negate());
-            respVO.setTotalAmount(subsidy.getAmount().negate());
-            respVO.setItemName("长护险抵扣");
-            respVO.setItemCategory("长护险");
-            respVO.setCount(1);
-            respVO.setDescription(subsidy.getRemarks());
-            // 设置抵扣期间为整个月
-            respVO.setStartTime(attributionBillTime.atDay(1).toString());
-            respVO.setEndTime(attributionBillTime.atEndOfMonth().toString());
-            subsidy.setStatus(1);
-            expenseSubsidyMapper.updateById(subsidy);
-            return respVO;
-        }).collect(Collectors.toList());
-        dataList.addAll(subsidyCollect);
+        List<ExpenseItemRespVO> dataList = new ArrayList<>(collectDailyExpenseItemsHasBill(elderId, billingMonth));
+        dataList.addAll(collectSubsidyItems(elderId, billingMonth, attributionBillTime.atDay(1), attributionBillTime.atEndOfMonth(), true));
+        dataList.addAll(collectConsumerVoucherItems(elderId, billingMonth, attributionBillTime.atDay(1), attributionBillTime.atEndOfMonth(), true));
         dataList.addAll(calculateDiscountDeduction(elderId, billingMonth));
 
         BigDecimal amount = BigDecimal.ZERO;

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

@@ -46,6 +46,7 @@ import java.time.ZoneOffset;
 import java.time.format.DateTimeFormatter;
 import java.time.temporal.ChronoUnit;
 import java.time.temporal.TemporalAdjusters;
+import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
 import java.util.Optional;
@@ -98,6 +99,10 @@ public class ExpenseServiceImpl implements ExpenseService {
     private ElderlyContractDetailMapper elderlyContractDetailMapper;
     @Resource
     private DailyExpensesMapper dailyExpensesMapper;
+    @Resource
+    private ExpenseSubsidyMapper expenseSubsidyMapper;
+    @Resource
+    private ElderlyConsumerVouchersMapper elderlyConsumerVouchersMapper;
 
     @Autowired
     private CheckInApplyMapper checkInApplyMapper;
@@ -509,6 +514,7 @@ public class ExpenseServiceImpl implements ExpenseService {
         BigDecimal totalAmount = processMonthlyExpenses(createReqVO, expense, monthlyExpenses, date, monthEnd, monthDays, daysUntilMonthEnd, expenseOrderDO, isNewBill);
         totalAmount = totalAmount.add(processOneTimeExpenses(createReqVO, expense, oneTimeExpenses, expenseOrderDO));
         totalAmount = totalAmount.add(processStageExpenses(createReqVO, expense, stageExpenses, expenseOrderDO));
+        totalAmount = totalAmount.add(processRenewContractSupplementExpenses(createReqVO, expenseOrderDO, date, monthEnd, isNewBill));
 
         if (isNewBill) {
             expenseOrderDO.setActualAmount(totalAmount);
@@ -913,6 +919,199 @@ public class ExpenseServiceImpl implements ExpenseService {
         return totalAmount;
     }
 
+    /**
+     * 续约时补充未生成账单的长护险、消费券、日常费用
+     */
+    private BigDecimal processRenewContractSupplementExpenses(ExpenseSaveReqVO createReqVO, ExpenseOrderDO expenseOrderDO,
+                                                              LocalDate actualStart, LocalDate actualEnd, boolean isNewBill) {
+        if (!isNewBill) {
+            return BigDecimal.ZERO;
+        }
+        String billingMonth = actualStart.format(DateTimeFormatter.ofPattern("yyyy-MM"));
+        YearMonth yearMonth = YearMonth.from(actualStart);
+
+        BigDecimal totalAmount = BigDecimal.ZERO;
+        totalAmount = totalAmount.add(processRenewDailyExpenses(createReqVO, expenseOrderDO, billingMonth, yearMonth));
+        totalAmount = totalAmount.add(processRenewSubsidyExpenses(createReqVO, expenseOrderDO, billingMonth, actualStart, actualEnd));
+        totalAmount = totalAmount.add(processRenewConsumerVoucherExpenses(createReqVO, expenseOrderDO, billingMonth, actualStart, actualEnd));
+        return totalAmount;
+    }
+
+    private BigDecimal processRenewDailyExpenses(ExpenseSaveReqVO createReqVO, ExpenseOrderDO expenseOrderDO,
+                                                 String billingMonth, YearMonth yearMonth) {
+        BigDecimal totalAmount = BigDecimal.ZERO;
+        List<DailyExpensesDO> dailyExpensesList = dailyExpensesMapper.selectList(new LambdaQueryWrapperX<DailyExpensesDO>()
+                .eq(DailyExpensesDO::getElderId, createReqVO.getElderId())
+                .le(DailyExpensesDO::getAttributionBillTime, billingMonth)
+                .eq(DailyExpensesDO::getStatus, BooleanEnum.FALSE.getValue())
+                .eq(DailyExpensesDO::getIsGenerateBill, BooleanEnum.FALSE.getValue()));
+
+        List<DailyExpensesDO> dailyExpensesUpdateList = new ArrayList<>();
+        for (DailyExpensesDO item : dailyExpensesList) {
+            ExpenseItemDO expenseItem = new ExpenseItemDO();
+            expenseItem.setExpenseId(null);
+            expenseItem.setItemId(item.getItemId());
+            expenseItem.setItemCategoryName(item.getItemCategory());
+            expenseItem.setItemName(item.getItemName());
+            expenseItem.setAmount(item.getPrice());
+            expenseItem.setActualAmount(item.getAmount());
+            expenseItem.setCount(item.getCount());
+            expenseItem.setTotalAmount(item.getAmount());
+            expenseItem.setType(item.getType());
+            expenseItem.setIsMonthlyExpense(BooleanEnum.FALSE.getValue());
+            expenseItem.setIsOneTimeFee(BooleanEnum.FALSE.getValue());
+            expenseItem.setTenantId(createReqVO.getTenantId());
+            expenseItem.setCreateTime(new Date());
+            expenseItemMapper.insert(expenseItem);
+
+            ExpenseOrderItemDO orderItemDO = new ExpenseOrderItemDO();
+            orderItemDO.setExpenseOrderId(expenseOrderDO.getId());
+            orderItemDO.setSourceExpenseItemId(expenseItem.getId());
+            orderItemDO.setExpenseSource(BusinessConstants.DAILY_EXPENSES);
+            orderItemDO.setCount(item.getCount());
+            orderItemDO.setItemName(item.getItemName());
+            orderItemDO.setItemCategoryName(item.getItemCategory());
+            orderItemDO.setPrice(item.getPrice());
+            orderItemDO.setActualPrice(item.getPrice());
+            orderItemDO.setTotalAmount(item.getAmount());
+            orderItemDO.setRoundAmount(orderItemDO.getTotalAmount().setScale(0, RoundingMode.HALF_UP));
+            orderItemDO.setRoundTwoDecimalAmount(orderItemDO.getTotalAmount().setScale(2, RoundingMode.HALF_UP));
+            orderItemDO.setCreatedTime(new Date());
+            orderItemDO.setCreatedBy(SecurityFrameworkUtils.getLoginUserNickname());
+            orderItemDO.setType(item.getType());
+            orderItemDO.setTenantId(createReqVO.getTenantId());
+            orderItemDO.setStartDate(yearMonth.atDay(1));
+            orderItemDO.setEndDate(yearMonth.atEndOfMonth());
+            orderItemDO.setDescription(item.getRemarks());
+            expenseOrderItemMapper.insert(orderItemDO);
+
+            item.setStatus(BooleanEnum.TRUE.getValue());
+            item.setIsGenerateBill(BooleanEnum.TRUE.getValue());
+            item.setExpenseOrderNumber(expenseOrderDO.getBillOrderNumber());
+            dailyExpensesUpdateList.add(item);
+            totalAmount = totalAmount.add(orderItemDO.getTotalAmount().setScale(2, RoundingMode.DOWN));
+        }
+
+        if (CollectionUtil.isNotEmpty(dailyExpensesUpdateList)) {
+            dailyExpensesMapper.updateBatch(dailyExpensesUpdateList);
+        }
+        return totalAmount;
+    }
+
+    private BigDecimal processRenewSubsidyExpenses(ExpenseSaveReqVO createReqVO, ExpenseOrderDO expenseOrderDO,
+                                                   String billingMonth, LocalDate actualStart, LocalDate actualEnd) {
+        BigDecimal totalAmount = BigDecimal.ZERO;
+        List<ExpenseSubsidyDO> subsidyList = expenseSubsidyMapper.selectList(new LambdaQueryWrapperX<ExpenseSubsidyDO>()
+                .eq(ExpenseSubsidyDO::getElderId, createReqVO.getElderId())
+                .eq(ExpenseSubsidyDO::getDeductionBillMonth, billingMonth)
+                .eq(ExpenseSubsidyDO::getStatus, BooleanEnum.FALSE.getValue()));
+
+        List<ExpenseSubsidyDO> subsidyUpdateList = new ArrayList<>();
+        for (ExpenseSubsidyDO subsidy : subsidyList) {
+            ExpenseItemDO expenseItem = new ExpenseItemDO();
+            expenseItem.setExpenseId(null);
+            expenseItem.setItemName("长护险抵扣");
+            expenseItem.setItemCategoryName("长护险");
+            expenseItem.setAmount(subsidy.getAmount().negate());
+            expenseItem.setActualAmount(subsidy.getAmount().negate());
+            expenseItem.setCount(1);
+            expenseItem.setTotalAmount(subsidy.getAmount().negate());
+            expenseItem.setType(7);
+            expenseItem.setIsMonthlyExpense(BooleanEnum.FALSE.getValue());
+            expenseItem.setIsOneTimeFee(BooleanEnum.FALSE.getValue());
+            expenseItem.setTenantId(createReqVO.getTenantId());
+            expenseItem.setCreateTime(new Date());
+            expenseItemMapper.insert(expenseItem);
+
+            ExpenseOrderItemDO orderItemDO = new ExpenseOrderItemDO();
+            orderItemDO.setExpenseOrderId(expenseOrderDO.getId());
+            orderItemDO.setSourceExpenseItemId(expenseItem.getId());
+            orderItemDO.setExpenseSource(BusinessConstants.LONG_TERM_CARE_INSURANCE);
+            orderItemDO.setCount(1);
+            orderItemDO.setItemName("长护险抵扣");
+            orderItemDO.setItemCategoryName("长护险");
+            orderItemDO.setPrice(subsidy.getAmount());
+            orderItemDO.setActualPrice(subsidy.getAmount().negate());
+            orderItemDO.setTotalAmount(subsidy.getAmount().negate());
+            orderItemDO.setRoundAmount(orderItemDO.getTotalAmount().setScale(0, RoundingMode.HALF_UP));
+            orderItemDO.setRoundTwoDecimalAmount(orderItemDO.getTotalAmount().setScale(2, RoundingMode.HALF_UP));
+            orderItemDO.setCreatedTime(new Date());
+            orderItemDO.setCreatedBy(SecurityFrameworkUtils.getLoginUserNickname());
+            orderItemDO.setType(7);
+            orderItemDO.setTenantId(createReqVO.getTenantId());
+            orderItemDO.setStartDate(actualStart);
+            orderItemDO.setEndDate(actualEnd);
+            orderItemDO.setDescription(subsidy.getRemarks());
+            expenseOrderItemMapper.insert(orderItemDO);
+
+            subsidy.setStatus(BooleanEnum.TRUE.getValue());
+            subsidyUpdateList.add(subsidy);
+            totalAmount = totalAmount.add(orderItemDO.getTotalAmount().setScale(2, RoundingMode.DOWN));
+        }
+
+        if (CollectionUtil.isNotEmpty(subsidyUpdateList)) {
+            expenseSubsidyMapper.updateBatch(subsidyUpdateList);
+        }
+        return totalAmount;
+    }
+
+    private BigDecimal processRenewConsumerVoucherExpenses(ExpenseSaveReqVO createReqVO, ExpenseOrderDO expenseOrderDO,
+                                                           String billingMonth, LocalDate actualStart, LocalDate actualEnd) {
+        BigDecimal totalAmount = BigDecimal.ZERO;
+        List<ElderlyConsumerVouchersDO> consumerVoucherList = elderlyConsumerVouchersMapper.selectList(new LambdaQueryWrapperX<ElderlyConsumerVouchersDO>()
+                .eq(ElderlyConsumerVouchersDO::getElderId, createReqVO.getElderId())
+                .eq(ElderlyConsumerVouchersDO::getBillingMonth, billingMonth)
+                .eq(ElderlyConsumerVouchersDO::getStatus, BooleanEnum.FALSE.getValue()));
+
+        List<ElderlyConsumerVouchersDO> consumerVoucherUpdateList = new ArrayList<>();
+        for (ElderlyConsumerVouchersDO consumerVoucher : consumerVoucherList) {
+            ExpenseItemDO expenseItem = new ExpenseItemDO();
+            expenseItem.setExpenseId(null);
+            expenseItem.setItemName("消费券抵扣");
+            expenseItem.setItemCategoryName("消费券");
+            expenseItem.setAmount(consumerVoucher.getAmount().negate());
+            expenseItem.setActualAmount(consumerVoucher.getAmount().negate());
+            expenseItem.setCount(1);
+            expenseItem.setTotalAmount(consumerVoucher.getAmount().negate());
+            expenseItem.setType(7);
+            expenseItem.setIsMonthlyExpense(BooleanEnum.FALSE.getValue());
+            expenseItem.setIsOneTimeFee(BooleanEnum.FALSE.getValue());
+            expenseItem.setTenantId(createReqVO.getTenantId());
+            expenseItem.setCreateTime(new Date());
+            expenseItemMapper.insert(expenseItem);
+
+            ExpenseOrderItemDO orderItemDO = new ExpenseOrderItemDO();
+            orderItemDO.setExpenseOrderId(expenseOrderDO.getId());
+            orderItemDO.setSourceExpenseItemId(expenseItem.getId());
+            orderItemDO.setExpenseSource(BusinessConstants.CONSUMER_VOUCHER);
+            orderItemDO.setCount(1);
+            orderItemDO.setItemName("消费券抵扣");
+            orderItemDO.setItemCategoryName("消费券");
+            orderItemDO.setPrice(consumerVoucher.getAmount());
+            orderItemDO.setActualPrice(consumerVoucher.getAmount().negate());
+            orderItemDO.setTotalAmount(consumerVoucher.getAmount().negate());
+            orderItemDO.setRoundAmount(orderItemDO.getTotalAmount().setScale(0, RoundingMode.HALF_UP));
+            orderItemDO.setRoundTwoDecimalAmount(orderItemDO.getTotalAmount().setScale(2, RoundingMode.HALF_UP));
+            orderItemDO.setCreatedTime(new Date());
+            orderItemDO.setCreatedBy(SecurityFrameworkUtils.getLoginUserNickname());
+            orderItemDO.setType(7);
+            orderItemDO.setTenantId(createReqVO.getTenantId());
+            orderItemDO.setStartDate(actualStart);
+            orderItemDO.setEndDate(actualEnd);
+            orderItemDO.setDescription(consumerVoucher.getRemarks());
+            expenseOrderItemMapper.insert(orderItemDO);
+
+            consumerVoucher.setStatus(BooleanEnum.TRUE.getValue());
+            consumerVoucherUpdateList.add(consumerVoucher);
+            totalAmount = totalAmount.add(orderItemDO.getTotalAmount().setScale(2, RoundingMode.DOWN));
+        }
+
+        if (CollectionUtil.isNotEmpty(consumerVoucherUpdateList)) {
+            elderlyConsumerVouchersMapper.updateBatch(consumerVoucherUpdateList);
+        }
+        return totalAmount;
+    }
+
     /**
      * 根据费用项创建订单项
      */

+ 12 - 11
yudao-module-system/yudao-module-system-biz/src/main/java/cn/iocoder/yudao/module/system/service/yk/impl/YkElderlyInfoServiceImpl.java

@@ -6,9 +6,6 @@ import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
 import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
 import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
 import cn.iocoder.yudao.module.system.controller.admin.yk.vo.*;
-import cn.iocoder.yudao.module.system.convert.excel.LocalDateTimeConvert;
-import cn.iocoder.yudao.module.system.dal.dataobject.biz.ElderlyInfoDO;
-import cn.iocoder.yudao.module.system.dal.dataobject.restaurant.DishesOrderItemDO;
 import cn.iocoder.yudao.module.system.dal.dataobject.home.HomeElderlyInfoDO;
 import cn.iocoder.yudao.module.system.dal.dataobject.yk.*;
 import cn.iocoder.yudao.module.system.dal.dataobject.home.HomeElderlyAccountDO;
@@ -16,19 +13,16 @@ import cn.iocoder.yudao.module.system.dal.mysql.home.HomeElderlyAccountMapper;
 import cn.iocoder.yudao.module.system.dal.mysql.home.HomeElderlyInfoMapper;
 import cn.iocoder.yudao.module.system.dal.mysql.yk.*;
 import cn.iocoder.yudao.module.system.service.yk.YkElderlyInfoService;
-import com.alibaba.excel.annotation.ExcelProperty;
 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 org.springframework.util.StringUtils;
 
 import javax.annotation.Resource;
 import java.math.BigDecimal;
 import java.time.LocalDateTime;
 import java.time.LocalDate;
 import java.time.ZoneId;
-import java.time.YearMonth;
 import java.util.Comparator;
 import java.util.Date;
 import java.util.List;
@@ -130,14 +124,22 @@ public class YkElderlyInfoServiceImpl implements YkElderlyInfoService {
 
     @Override
     public PageResult<HomeElderlyInfoDO> getElderlyInfoPage(YkElderlyInfoPageReqVO pageReqVO) {
-        PageResult<HomeElderlyInfoDO> pageResult = homeElderlyInfoMapper.selectPage(pageReqVO);
+        PageResult<HomeElderlyInfoDO> pageResult = homeElderlyInfoMapper.selectPage(pageReqVO, new LambdaQueryWrapperX<HomeElderlyInfoDO>()
+                .likeIfPresent(HomeElderlyInfoDO::getElderName, pageReqVO.getElderName())
+                .eqIfPresent(HomeElderlyInfoDO::getIdCard, pageReqVO.getIdCard())
+                .eqIfPresent(HomeElderlyInfoDO::getTenantId, pageReqVO.getTenantId())
+                .orderByDesc(HomeElderlyInfoDO::getId));
         fillBalanceFromAccount(pageResult.getList());
         return pageResult;
     }
 
     @Override
     public List<HomeElderlyInfoDO> getElderlyInfoList(YkElderlyInfoExportReqVO exportReqVO) {
-        List<HomeElderlyInfoDO> list = homeElderlyInfoMapper.selectList(exportReqVO);
+        List<HomeElderlyInfoDO> list = homeElderlyInfoMapper.selectList(new LambdaQueryWrapperX<HomeElderlyInfoDO>()
+                .likeIfPresent(HomeElderlyInfoDO::getElderName, exportReqVO.getElderName())
+                .eqIfPresent(HomeElderlyInfoDO::getIdCard, exportReqVO.getIdCard())
+                .eqIfPresent(HomeElderlyInfoDO::getTenantId, TenantContextHolder.getTenantId())
+                .orderByDesc(HomeElderlyInfoDO::getId));
         fillBalanceFromAccount(list);
         return list;
     }
@@ -180,9 +182,9 @@ public class YkElderlyInfoServiceImpl implements YkElderlyInfoService {
             YkElderlyExpenseRecordDO recordDO = new YkElderlyExpenseRecordDO();
             recordDO.setType(2);
             recordDO.setExpenseType(1);
-            recordDO.setYkElderId(ykElderlyInfoDO.getId());
+            recordDO.setYkElderId(homeElderlyInfoDO.getId());
             recordDO.setAmount(ykElderlyDeliveryDO.getMealStandard());
-            BigDecimal accountAmount = getElderlyAccountAmount(ykElderlyInfoDO.getId());
+            BigDecimal accountAmount = getElderlyAccountAmount(homeElderlyInfoDO.getId());
             recordDO.setBalance(accountAmount.subtract(recordDO.getAmount()));
             recordDO.setRemarks("长者送餐");
             recordDO.setCreatedTime(new Date());
@@ -674,7 +676,6 @@ public class YkElderlyInfoServiceImpl implements YkElderlyInfoService {
 
         elderlyInfo.setDeliveryFee(feeAfter);
         homeElderlyInfoMapper.updateById(elderlyInfo);
-        updateElderlyAccountAmount(elderlyInfo.getId(), updateBalance);
     }
 
     @Override

+ 30 - 0
yudao-module-system/yudao-module-system-biz/src/main/resources/mapper/HomeElderlyInfoMapper.xml

@@ -52,5 +52,35 @@
         order by hei.id desc
     </select>
 
+    <select id="selectElderlyMealPage" resultType="cn.iocoder.yudao.module.system.controller.admin.yk.vo.YkElderlyMealRespVO">
+        select
+            hei.id,
+            hei.elder_name as elderName,
+            hei.phone,
+            hei.current_live_address as deliveryAddress,
+            hde.delivery_date as deliveryDate,
+            hde.meal_standard as mealStandard,
+            hde.meal_type as mealType,
+            hde.delivery_person_id as deliveryPersonId,
+            hde.delivery_person_name as deliveryPersonName,
+            hde.created_time as createdTime
+        from home_elderly_info hei
+        inner join yk_elderly_delivery hde on hde.yk_elder_id = hei.id
+        where 1 = 1
+        <if test="pageReqVO.elderName != null and pageReqVO.elderName != ''">
+            and hei.elder_name like concat('%', #{pageReqVO.elderName}, '%')
+        </if>
+        <if test="pageReqVO.phone != null and pageReqVO.phone != ''">
+            and hei.phone like concat('%', #{pageReqVO.phone}, '%')
+        </if>
+        <if test="pageReqVO.deliveryDate != null">
+            and hde.delivery_date = #{pageReqVO.deliveryDate}
+        </if>
+        <if test="pageReqVO.tenantId != null">
+            and hei.tenant_id = #{pageReqVO.tenantId}
+        </if>
+        order by hde.delivery_date desc, hde.id desc
+    </select>
+
 </mapper>