longz
2026-04-27 25df88d0ab9d7444ed1d162b9efa1259ac2f6f66
backend/src/main/java/com/sinata/appointment/service/AppointmentApplicationService.java
@@ -87,19 +87,21 @@
            String approvalStatus,
            String visitorKeyword,
            String visitReasonCode) {
        List<AppointmentAdminListVo> all =
                listAdminOrders(
                        visitedUserName,
        Page<AppointmentOrder> orderPage = new Page<>(Math.max(1L, page), Math.max(1L, size));
        IPage<AppointmentOrder> pagedOrders =
                appointmentOrderMapper.pageAdminOrders(
                        orderPage,
                        trimToNull(visitedUserName),
                        visitedDeptId,
                        accessArea,
                        localUnit,
                        trimToNull(accessArea),
                        trimToNull(localUnit),
                        visitDateStart,
                        visitDateEnd,
                        displayStatus,
                        approvalStatus,
                        visitorKeyword,
                        visitReasonCode);
        return slicePage(page, size, all);
                        trimToNull(displayStatus),
                        trimToNull(approvalStatus),
                        trimToNull(visitorKeyword),
                        trimToNull(visitReasonCode));
        return buildAdminPage(pagedOrders);
    }
    public byte[] exportExcel(
@@ -113,51 +115,40 @@
            String approvalStatus,
            String visitorKeyword,
            String visitReasonCode) {
        Set<Long> visitorOrderIds = findOrderIdsByVisitorKeyword(visitorKeyword);
        if (visitorOrderIds != null && visitorOrderIds.isEmpty()) {
            return writeExportRows(List.of());
        }
        List<AppointmentOrder> orders =
                appointmentOrderMapper.selectList(
                        buildOrderQuery(
                                visitedUserName,
                                visitedDeptId,
                                accessArea,
                                localUnit,
                                visitDateStart,
                                visitDateEnd,
                                visitReasonCode,
                                visitorOrderIds));
        if (orders.isEmpty()) {
            return writeExportRows(List.of());
        }
        List<Long> orderIds = orders.stream().map(AppointmentOrder::getId).filter(Objects::nonNull).toList();
        Map<Long, List<AppointmentVisitor>> visitorRowsMap = loadVisitorRows(orderIds);
        Map<Long, ApprovalInstance> approvalInstanceMap = loadApprovalInstanceMap(orderIds);
        Map<Long, String> deptNameMap = loadDeptNameMap(orders);
        Map<String, String> reasonNameMap = loadReasonNameMap(orders);
        List<AppointmentOrder> filteredOrders = new ArrayList<>();
        for (AppointmentOrder order : orders) {
            AppointmentAdminListVo vo =
                    toAdminListVo(
                            order,
                            deptNameMap.get(order.getVisitedDeptId()),
                            reasonNameMap,
                            visitorRowsMap.get(order.getId()),
                            approvalInstanceMap.get(order.getId()));
            if (matchesDisplayStatus(vo, displayStatus) && matchesApprovalStatus(vo, approvalStatus)) {
                filteredOrders.add(order);
        long pageNo = 1L;
        long pageSize = 200L;
        List<AppointmentAdminExportRow> rows = new ArrayList<>();
        while (true) {
            Page<AppointmentOrder> orderPage = new Page<>(pageNo, pageSize);
            IPage<AppointmentOrder> pagedOrders =
                    appointmentOrderMapper.pageAdminOrders(
                            orderPage,
                            trimToNull(visitedUserName),
                            visitedDeptId,
                            trimToNull(accessArea),
                            trimToNull(localUnit),
                            visitDateStart,
                            visitDateEnd,
                            trimToNull(displayStatus),
                            trimToNull(approvalStatus),
                            trimToNull(visitorKeyword),
                            trimToNull(visitReasonCode));
            List<AppointmentOrder> orders = pagedOrders.getRecords();
            if (orders == null || orders.isEmpty()) {
                break;
            }
            AdminPageData pageData = loadAdminPageData(orders);
            rows.addAll(
                    buildExportRows(
                            orders,
                            pageData.visitorRowsMap(),
                            pageData.approvalInstanceMap(),
                            pageData.reasonNameMap()));
            if (pageNo * pageSize >= pagedOrders.getTotal()) {
                break;
            }
            pageNo++;
        }
        List<AppointmentAdminExportRow> rows = buildExportRows(filteredOrders, visitorRowsMap, approvalInstanceMap, reasonNameMap);
        return writeExportRows(rows);
    }
    private byte[] writeExportRows(List<AppointmentAdminExportRow> rows) {
        try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
            EasyExcel.write(bos, AppointmentAdminExportRow.class).sheet("预约记录").doWrite(rows);
            return bos.toByteArray();
@@ -193,7 +184,7 @@
        vo.setVisitedDeptName(defaultText(trimToNull(deptName)));
        vo.setAccessAreaText(defaultText(buildJsonNameText(order.getPassAccessAreaNames())));
        vo.setLocalUnitText(defaultText(buildJsonNameText(order.getPassLocalUnitNames())));
        vo.setPlateNoText(defaultText(joinUniqueTexts(visitorRows, AppointmentVisitor::getPlateNo)));
        vo.setPlateNoText(defaultText(loadOrderPlateText(id)));
        vo.setVisitReasonText(defaultText(buildVisitReasonText(order, reasonNameMap)));
        vo.setVisitStartText(defaultText(resolveVisitStartText(order)));
        vo.setVisitEndText(defaultText(resolveVisitEndText(order)));
@@ -215,99 +206,37 @@
                        .orderByAsc(AppointmentVisitor::getId));
    }
    private List<AppointmentAdminListVo> listAdminOrders(
            String visitedUserName,
            Long visitedDeptId,
            String accessArea,
            String localUnit,
            LocalDate visitDateStart,
            LocalDate visitDateEnd,
            String displayStatus,
            String approvalStatus,
            String visitorKeyword,
            String visitReasonCode) {
        Set<Long> visitorOrderIds = findOrderIdsByVisitorKeyword(visitorKeyword);
        if (visitorOrderIds != null && visitorOrderIds.isEmpty()) {
            return List.of();
    private IPage<AppointmentAdminListVo> buildAdminPage(IPage<AppointmentOrder> pagedOrders) {
        Page<AppointmentAdminListVo> page =
                new Page<>(pagedOrders.getCurrent(), pagedOrders.getSize(), pagedOrders.getTotal());
        List<AppointmentOrder> orders = pagedOrders.getRecords();
        if (orders == null || orders.isEmpty()) {
            page.setRecords(List.of());
            return page;
        }
        List<AppointmentOrder> orders =
                appointmentOrderMapper.selectList(
                        buildOrderQuery(
                                visitedUserName,
                                visitedDeptId,
                                accessArea,
                                localUnit,
                                visitDateStart,
                                visitDateEnd,
                                visitReasonCode,
                                visitorOrderIds));
        if (orders.isEmpty()) {
            return List.of();
        }
        List<Long> orderIds = orders.stream().map(AppointmentOrder::getId).filter(Objects::nonNull).toList();
        Map<Long, List<AppointmentVisitor>> visitorRowsMap = loadVisitorRows(orderIds);
        Map<Long, ApprovalInstance> approvalInstanceMap = loadApprovalInstanceMap(orderIds);
        Map<Long, String> deptNameMap = loadDeptNameMap(orders);
        Map<String, String> reasonNameMap = loadReasonNameMap(orders);
        List<AppointmentAdminListVo> result = new ArrayList<>();
        AdminPageData pageData = loadAdminPageData(orders);
        List<AppointmentAdminListVo> records = new ArrayList<>();
        for (AppointmentOrder order : orders) {
            AppointmentAdminListVo vo =
            records.add(
                    toAdminListVo(
                            order,
                            deptNameMap.get(order.getVisitedDeptId()),
                            reasonNameMap,
                            visitorRowsMap.get(order.getId()),
                            approvalInstanceMap.get(order.getId()));
            if (matchesDisplayStatus(vo, displayStatus) && matchesApprovalStatus(vo, approvalStatus)) {
                result.add(vo);
            }
                            pageData.deptNameMap().get(order.getVisitedDeptId()),
                            pageData.reasonNameMap(),
                            pageData.visitorRowsMap().get(order.getId()),
                            pageData.approvalInstanceMap().get(order.getId())));
        }
        return result;
        page.setRecords(records);
        return page;
    }
    private LambdaQueryWrapper<AppointmentOrder> buildOrderQuery(
            String visitedUserName,
            Long visitedDeptId,
            String accessArea,
            String localUnit,
            LocalDate visitDateStart,
            LocalDate visitDateEnd,
            String visitReasonCode,
            Set<Long> visitorOrderIds) {
        LambdaQueryWrapper<AppointmentOrder> q = new LambdaQueryWrapper<>();
        q.eq(AppointmentOrder::getDelFlag, 0);
        q.like(StringUtils.hasText(visitedUserName), AppointmentOrder::getVisitedUserName, trim(visitedUserName));
        q.eq(visitedDeptId != null, AppointmentOrder::getVisitedDeptId, visitedDeptId);
        q.like(StringUtils.hasText(accessArea), AppointmentOrder::getPassAccessAreaNames, trim(accessArea));
        q.like(StringUtils.hasText(localUnit), AppointmentOrder::getPassLocalUnitNames, trim(localUnit));
        q.eq(StringUtils.hasText(visitReasonCode), AppointmentOrder::getVisitReasonCode, trim(visitReasonCode));
        q.le(visitDateEnd != null, AppointmentOrder::getVisitStartDate, visitDateEnd);
        q.ge(visitDateStart != null, AppointmentOrder::getVisitEndDate, visitDateStart);
        if (visitorOrderIds != null) {
            q.in(AppointmentOrder::getId, visitorOrderIds);
        }
        q.orderByDesc(AppointmentOrder::getCreateTime).orderByDesc(AppointmentOrder::getId);
        return q;
    }
    private Set<Long> findOrderIdsByVisitorKeyword(String visitorKeyword) {
        String keyword = trimToNull(visitorKeyword);
        if (!StringUtils.hasText(keyword)) {
            return null;
        }
        List<AppointmentVisitor> rows =
                appointmentVisitorMapper.selectList(
                        new LambdaQueryWrapper<AppointmentVisitor>()
                                .eq(AppointmentVisitor::getDelFlag, 0)
                                .like(AppointmentVisitor::getName, keyword)
                                .select(AppointmentVisitor::getOrderId));
        return rows.stream()
                .map(AppointmentVisitor::getOrderId)
                .filter(Objects::nonNull)
                .collect(Collectors.toCollection(LinkedHashSet::new));
    private AdminPageData loadAdminPageData(List<AppointmentOrder> orders) {
        List<Long> orderIds = orders.stream().map(AppointmentOrder::getId).filter(Objects::nonNull).toList();
        return new AdminPageData(
                loadVisitorRows(orderIds),
                loadApprovalInstanceMap(orderIds),
                loadDeptNameMap(orders),
                loadReasonNameMap(orders));
    }
    private Map<Long, MpVisitor> loadVisitorMap(List<AppointmentVisitor> rows) {
@@ -359,6 +288,27 @@
            result.put(entry.getKey(), joined);
        }
        return result;
    }
    private String loadOrderPlateText(Long orderId) {
        if (orderId == null) {
            return null;
        }
        List<AppointmentVehicle> rows =
                appointmentVehicleMapper.selectList(
                        new LambdaQueryWrapper<AppointmentVehicle>()
                                .eq(AppointmentVehicle::getDelFlag, 0)
                                .eq(AppointmentVehicle::getOrderId, orderId)
                                .orderByAsc(AppointmentVehicle::getId));
        if (rows == null || rows.isEmpty()) {
            return null;
        }
        return rows.stream()
                .map(AppointmentVehicle::getPlateNo)
                .filter(StringUtils::hasText)
                .map(String::trim)
                .distinct()
                .collect(Collectors.joining("、"));
    }
    private Map<Long, List<AppointmentVisitor>> loadVisitorRows(List<Long> orderIds) {
@@ -927,4 +877,10 @@
        }
        return null;
    }
    private record AdminPageData(
            Map<Long, List<AppointmentVisitor>> visitorRowsMap,
            Map<Long, ApprovalInstance> approvalInstanceMap,
            Map<Long, String> deptNameMap,
            Map<String, String> reasonNameMap) {}
}