package com.sinata.appointment.service; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.sinata.appointment.dto.MiniAppointmentListVo; import com.sinata.appointment.dto.MiniApprovalAllVo; import com.sinata.appointment.dto.MiniApprovalTodoVo; import java.time.LocalDate; import java.util.ArrayList; import java.util.Comparator; import java.util.List; import java.util.Locale; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @Service @RequiredArgsConstructor public class MiniApprovalAggregateApplicationService { private static final long MAX_FETCH_SIZE = 1000L; private final MiniHandlerApprovalApplicationService miniHandlerApprovalApplicationService; private final MiniAppointmentApplicationService miniAppointmentApplicationService; public IPage pageMyAll(long page, long size, String visitorNameKeyword, LocalDate visitDate) { long safePage = Math.max(1L, page); long safeSize = Math.max(1L, size); long fetchSize = Math.min(MAX_FETCH_SIZE, safePage * safeSize); IPage todoPage = miniHandlerApprovalApplicationService.pageMyTodoAll(1L, fetchSize, visitorNameKeyword, visitDate); IPage historyPage = miniAppointmentApplicationService.pageMine(1L, fetchSize, null, visitorNameKeyword, visitDate); List merged = new ArrayList<>(); merged.addAll(mapTodoRows(todoPage.getRecords())); merged.addAll(mapHistoryRows(historyPage.getRecords())); merged.sort(Comparator.comparing(MiniApprovalAllVo::getCreateTime, Comparator.nullsLast(Comparator.naturalOrder())).reversed()); return slicePage(safePage, safeSize, merged); } private List mapTodoRows(List rows) { if (rows == null || rows.isEmpty()) { return List.of(); } List out = new ArrayList<>(rows.size()); for (MiniApprovalTodoVo row : rows) { MiniApprovalAllVo vo = new MiniApprovalAllVo(); vo.setTaskId(row.getTaskId()); vo.setTaskUuid(row.getTaskUuid()); vo.setOrderId(row.getOrderId()); vo.setOrderUuid(row.getOrderUuid()); vo.setOrderNo(row.getOrderNo()); vo.setStatus("PENDING"); vo.setStatusText("待审核"); vo.setNodeText(row.getNodeName() == null ? "待审核" : row.getNodeName()); vo.setVisitorDisplayText(row.getVisitorDisplayText()); vo.setPlateNoText(row.getPlateNoText()); vo.setVisitTimeText(row.getVisitTimeText()); vo.setVisitReasonCode(row.getVisitReasonCode()); vo.setVisitReasonText(row.getVisitReasonText()); vo.setVisitReasonOther(row.getVisitReasonOther()); vo.setCreateTime(row.getCreateTime()); out.add(vo); } return out; } private List mapHistoryRows(List rows) { if (rows == null || rows.isEmpty()) { return List.of(); } List out = new ArrayList<>(rows.size()); for (MiniAppointmentListVo row : rows) { MiniApprovalAllVo vo = new MiniApprovalAllVo(); vo.setOrderId(row.getId()); vo.setOrderUuid(row.getUuid()); vo.setOrderNo(row.getOrderNo()); String status = normalizeStatus(row.getStatus()); vo.setStatus(status); vo.setStatusText(resolveStatusText(status)); vo.setNodeText(resolveStatusText(status)); vo.setVisitorDisplayText(row.getVisitorDisplayText()); vo.setPlateNoText(row.getPlateNoText()); vo.setVisitTimeText(row.getVisitTimeText()); vo.setVisitReasonCode(row.getVisitReasonCode()); vo.setVisitReasonText(row.getVisitReasonText()); vo.setVisitReasonOther(row.getVisitReasonOther()); vo.setCreateTime(row.getCreateTime()); out.add(vo); } return out; } private String normalizeStatus(String status) { if (status == null) { return "OTHER"; } String upper = status.toUpperCase(Locale.ROOT); return switch (upper) { case "PENDING", "APPROVED", "REJECTED", "CANCELLED" -> upper; default -> "OTHER"; }; } private String resolveStatusText(String status) { return switch (status) { case "APPROVED" -> "已同意"; case "REJECTED" -> "已拒绝"; case "CANCELLED" -> "已取消"; case "PENDING" -> "待审核"; default -> "已处理"; }; } private IPage slicePage(long page, long size, List rowsAll) { long total = rowsAll == null ? 0 : rowsAll.size(); int from = (int) Math.min(total, (page - 1) * size); int to = (int) Math.min(total, from + size); List records = from >= to ? List.of() : rowsAll.subList(from, to); Page out = new Page<>(page, size); out.setTotal(total); out.setRecords(records); return out; } }