longz
2026-04-21 c4db0a4526f61758272c92396aa788d84f098102
backend/src/main/java/com/sinata/appointment/service/AppointmentApplicationService.java
@@ -1,6 +1,8 @@
package com.sinata.appointment.service;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -87,19 +89,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,53 +117,44 @@
            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,
        try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
            ExcelWriter writer = EasyExcel.write(bos, AppointmentAdminExportRow.class).build();
            WriteSheet sheet = EasyExcel.writerSheet("预约记录").build();
            long pageNo = 1L;
            long pageSize = 200L;
            while (true) {
                Page<AppointmentOrder> orderPage = new Page<>(pageNo, pageSize);
                IPage<AppointmentOrder> pagedOrders =
                        appointmentOrderMapper.pageAdminOrders(
                                orderPage,
                                trimToNull(visitedUserName),
                                visitedDeptId,
                                accessArea,
                                localUnit,
                                trimToNull(accessArea),
                                trimToNull(localUnit),
                                visitDateStart,
                                visitDateEnd,
                                visitReasonCode,
                                visitorOrderIds));
        if (orders.isEmpty()) {
            return writeExportRows(List.of());
                                trimToNull(displayStatus),
                                trimToNull(approvalStatus),
                                trimToNull(visitorKeyword),
                                trimToNull(visitReasonCode));
                List<AppointmentOrder> orders = pagedOrders.getRecords();
                if (orders == null || orders.isEmpty()) {
                    break;
        }
        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);
                AdminPageData pageData = loadAdminPageData(orders);
                List<AppointmentAdminExportRow> rows =
                        buildExportRows(
                                orders,
                                pageData.visitorRowsMap(),
                                pageData.approvalInstanceMap(),
                                pageData.reasonNameMap());
                writer.write(rows, sheet);
                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);
            writer.finish();
            return bos.toByteArray();
        } catch (Exception e) {
            return new byte[0];
@@ -215,99 +210,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) {
@@ -927,4 +860,10 @@
        }
        return null;
    }
    private record AdminPageData(
            Map<Long, List<AppointmentVisitor>> visitorRowsMap,
            Map<Long, ApprovalInstance> approvalInstanceMap,
            Map<Long, String> deptNameMap,
            Map<String, String> reasonNameMap) {}
}