Bang Hu
2 天以前 2b0b64182263d922b946ec898070e59b602382dc
src/main/java/com/webmanage/service/impl/OrderInfoServiceImpl.java
@@ -186,7 +186,7 @@
        Page<OrderInfo> page = new Page<>(queryDTO.getPageNum(), queryDTO.getPageSize());
        // 基于workFlowType查询流程实例ID集合
        List<String> workFlowIds = fetchWorkflowProcessInstanceIds(
        List<Object> workFlowsList = fetchWorkflowProcessInstanceIds(
            queryDTO.getWorkFlowType(),
            queryDTO.getUserId(),
            queryDTO.getDepartmentId(),
@@ -196,7 +196,7 @@
        );
        // 如果没有任何流程ID,直接返回空分页
        if (workFlowIds == null || workFlowIds.isEmpty()) {
        if (workFlowsList == null || workFlowsList.isEmpty()) {
            return new PageResult<OrderDetailVO>(
                java.util.Collections.emptyList(),
                0L,
@@ -206,7 +206,23 @@
            );
        }
        List<String> workFlowIds = workFlowsList.stream()
                 .filter(item -> item instanceof Map)
                 .map(item -> (Map<?, ?>) item)
                 .map(m -> m.get("processInstanceId"))
                 .filter(Objects::nonNull)
                 .map(Object::toString)
                 .collect(Collectors.toList());
        log.info("从工作流服务获取的原始数据: {}", workFlowsList);
        log.info("提取的工作流ID列表: {}", workFlowIds);
        Map<String,String> workFlowIdAndTaskIdMap = workFlowsList.stream()
                .filter(item -> item instanceof Map)
                .map(item -> (Map<?, ?>) item).collect(Collectors.toMap(m -> m.get("processInstanceId").toString(), m -> m.get("taskId").toString(),(k1,k2) -> k2));
        // 执行分页查询
        log.info("执行待审批订单查询,工作流ID列表: {}, 订单状态: {}, 产品名称: {}", workFlowIds, queryDTO.getOrderStatus(), queryDTO.getProductName());
        IPage<OrderInfo> result = baseMapper.selectPendingApprovalOrderPage(
            page, queryDTO.getOrderStatus(), queryDTO.getProductName(), queryDTO.getProviderName(),
            queryDTO.getOrderId(),
@@ -214,6 +230,7 @@
            queryDTO.getApplyTimeEnd() != null ? queryDTO.getApplyTimeEnd().toString() : null,
            queryDTO.getOrderBy(), queryDTO.getOrderDirection(), workFlowIds
        );
        log.info("查询结果总数: {}, 当前页记录数: {}", result.getTotal(), result.getRecords().size());
        // 将订单与详情联表封装到VO
        List<OrderDetailVO> voList = result.getRecords().stream().map(order -> {
@@ -226,6 +243,7 @@
                return item;
            }).collect(java.util.stream.Collectors.toList());
            vo.setOrderDetails(items);
            vo.setTaskId(workFlowIdAndTaskIdMap.get(vo.getWorkflowId()));
            return vo;
        }).collect(java.util.stream.Collectors.toList());
@@ -240,19 +258,19 @@
    }
    @Override
    public PageResult<OrderInfo> getPendingApprovalOrderPageWithProductConditions(OrderQueryDTO queryDTO) {
    public PageResult<OrderDetailVO> getPendingApprovalOrderPageWithProductConditions(OrderQueryDTO queryDTO) {
        // 根据产品条件查询产品ID列表
        List<String> productIds = null;
        if (StringUtils.hasText(queryDTO.getIndustryId()) || StringUtils.hasText(queryDTO.getUnitProjectId()) ||
        if (StringUtils.hasText(queryDTO.getIndustryId()) || queryDTO.getUnitProjectId() != null ||
            StringUtils.hasText(queryDTO.getProductTypeId()) || StringUtils.hasText(queryDTO.getProductSubTypeId())) {
            productIds = reportResultSubmissionMapper.selectProductIdsByConditions(
                queryDTO.getIndustryId(), queryDTO.getUnitProjectId(),
                queryDTO.getIndustryId(), queryDTO.getUnitProjectId(), queryDTO.getImportantDistrictId(),
                queryDTO.getProductTypeId(), queryDTO.getProductSubTypeId()
            );
            
            // 如果没有找到匹配的产品,直接返回空结果
            if (CollectionUtils.isEmpty(productIds)) {
                return new PageResult<OrderInfo>(
                return new PageResult<OrderDetailVO>(
                    java.util.Collections.emptyList(),
                    0L,
                    queryDTO.getPageNum().longValue(),
@@ -267,7 +285,7 @@
        // 执行分页查询
        // 基于workFlowType查询流程实例ID集合
        List<String> workFlowIds = fetchWorkflowProcessInstanceIds(
        List<?> workFlowList = fetchWorkflowProcessInstanceIds(
            queryDTO.getWorkFlowType(),
            queryDTO.getUserId(),
            queryDTO.getDepartmentId(),
@@ -275,17 +293,29 @@
            queryDTO.getPageNum(),
            queryDTO.getPageSize()
        );
        // 如果没有任何流程ID,直接返回空分页
        if (workFlowIds == null || workFlowIds.isEmpty()) {
            return new PageResult<OrderInfo>(
                java.util.Collections.emptyList(),
                0L,
                queryDTO.getPageNum().longValue(),
                queryDTO.getPageSize().longValue(),
                0L
        if (workFlowList == null || workFlowList.isEmpty()) {
            return new PageResult<OrderDetailVO>(
                    java.util.Collections.emptyList(),
                    0L,
                    queryDTO.getPageNum().longValue(),
                    queryDTO.getPageSize().longValue(),
                    0L
            );
        }
        List<String> workFlowIds = workFlowList.stream()
                        .filter(item -> item instanceof Map)
                        .map(item -> (Map<?, ?>) item)
                        .map(m -> m.get("processInstanceId"))
                        .filter(Objects::nonNull)
                        .map(Object::toString)
                        .collect(Collectors.toList());
        Map<String,String> workFlowIdAndTaskIdMap = workFlowList.stream()
                .filter(item -> item instanceof Map)
                .map(item -> (Map<?, ?>) item).collect(Collectors.toMap(m -> m.get("processInstanceId").toString(), m -> m.get("taskId").toString(),(k1,k2) -> k2));
        IPage<OrderInfo> result = baseMapper.selectPendingApprovalOrderPageWithProductConditions(
            page, queryDTO.getOrderStatus(), queryDTO.getProductName(), queryDTO.getProviderName(),
@@ -294,10 +324,24 @@
            queryDTO.getApplyTimeEnd() != null ? queryDTO.getApplyTimeEnd().toString() : null,
            queryDTO.getOrderBy(), queryDTO.getOrderDirection(), productIds, workFlowIds
        );
        // 将订单与详情联表封装到VO
        List<OrderDetailVO> voList = result.getRecords().stream().map(order -> {
            OrderDetailVO vo = new OrderDetailVO();
            BeanUtils.copyProperties(order, vo);
            List<OrderDetail> details = orderDetailMapper.selectByOrderId(order.getOrderId());
            List<OrderDetailItemVO> items = details.stream().map(d -> {
                OrderDetailItemVO item = new OrderDetailItemVO();
                BeanUtils.copyProperties(d, item);
                return item;
            }).collect(java.util.stream.Collectors.toList());
            vo.setOrderDetails(items);
            vo.setTaskId(workFlowIdAndTaskIdMap.get(vo.getWorkflowId()));
            return vo;
        }).collect(java.util.stream.Collectors.toList());
        // 构建返回结果
        return new PageResult<OrderInfo>(
            result.getRecords(),
        return new PageResult<OrderDetailVO>(
            voList,
            result.getTotal(),
            queryDTO.getPageNum().longValue(),
            queryDTO.getPageSize().longValue(),
@@ -314,10 +358,10 @@
        // 根据产品条件查询产品ID列表
        List<String> productIds = null;
        if (StringUtils.hasText(queryDTO.getIndustryId()) || StringUtils.hasText(queryDTO.getUnitProjectId()) ||
        if (StringUtils.hasText(queryDTO.getIndustryId())  || queryDTO.getUnitProjectId() != null ||
            StringUtils.hasText(queryDTO.getProductTypeId()) || StringUtils.hasText(queryDTO.getProductSubTypeId())) {
            productIds = reportResultSubmissionMapper.selectProductIdsByConditions(
                queryDTO.getIndustryId(), queryDTO.getUnitProjectId(),
                queryDTO.getIndustryId(), queryDTO.getUnitProjectId(), queryDTO.getImportantDistrictId(),
                queryDTO.getProductTypeId(), queryDTO.getProductSubTypeId()
            );
            
@@ -381,10 +425,10 @@
        // 根据产品条件查询产品ID列表
        List<String> productIds = null;
        if (StringUtils.hasText(queryDTO.getIndustryId()) || StringUtils.hasText(queryDTO.getUnitProjectId()) ||
        if (StringUtils.hasText(queryDTO.getIndustryId()) || queryDTO.getUnitProjectId()!= null ||
            StringUtils.hasText(queryDTO.getProductTypeId()) || StringUtils.hasText(queryDTO.getProductSubTypeId())) {
            productIds = reportResultSubmissionMapper.selectProductIdsByConditions(
                queryDTO.getIndustryId(), queryDTO.getUnitProjectId(),
                queryDTO.getIndustryId(), queryDTO.getUnitProjectId(), queryDTO.getImportantDistrictId(),
                queryDTO.getProductTypeId(), queryDTO.getProductSubTypeId()
            );
            
@@ -596,7 +640,7 @@
    @Transactional(rollbackFor = Exception.class)
    public Long uploadOrderAttachment(String orderId, String fileName, String originalName, 
                                    String fileType, Long fileSize, String fileUrl, 
                                    String bucketName, String objectName, Long uploadUserId,
                                    String bucketName, String objectName, String uploadUserId,
                                    String uploadUserName, String attachmentType, String description) {
        // 参数校验
        if (!StringUtils.hasText(orderId)) {
@@ -638,7 +682,7 @@
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean addOrderEvaluation(String orderId, Long evaluatorId, String evaluatorName,
    public boolean addOrderEvaluation(String orderId, String evaluatorId, String evaluatorName,
                                   String evaluatorType, String content, Integer rating, 
                                   Integer serviceRating, Integer qualityRating, Integer deliveryRating, 
                                   Boolean isAnonymous) {
@@ -942,31 +986,51 @@
            }
        }
        // 更新订单状态(通过 -> 下一个;驳回 -> 上一个)
        // 先调用工作流,再依据结果决定是否流转订单状态
        String currentStatus = orderInfo.getOrderStatus();
        if (!StringUtils.hasText(currentStatus)) {
            throw new BusinessException("订单当前状态为空");
        }
        boolean isReject = orderApprovalDTO.getApprovalResult().contains("驳回");
        String targetStatus = isReject ? getPreviousOrderStatus(currentStatus) : getNextOrderStatus(currentStatus);
        if (targetStatus == null) {
            throw new BusinessException((isReject ? "已是初始状态,无法回退" : "已是最终状态,无法继续流转"));
        }
        orderInfo.setOrderStatus(targetStatus);
        orderInfo.setUpdatedAt(LocalDateTime.now());
        int updated = this.baseMapper.updateById(orderInfo);
        if (updated <= 0) {
            throw new BusinessException("更新订单状态失败");
        }
        log.info("订单状态更新成功,订单ID: {}, 从 {} 更新为 {}", orderInfo.getOrderId(), currentStatus, targetStatus);
        // 根据审批结果调用提交或驳回接口
        String comment = orderApprovalDTO.getApprovalResult().contains("驳回") ? "审核驳回" : "审核通过";
        if ("审核驳回".equals(comment)) {
            rejectWorkflowTask(orderInfo.getTaskId(), String.valueOf(orderApprovalDTO.getApproverId()), comment);
        String comment = isReject ? "审核驳回" : "审核通过";
        boolean workflowEnded = false;
        if (isReject) {
            // 驳回:调用工作流驳回,并将订单状态回退到上一个状态
            rejectWorkflowTask(orderApprovalDTO.getTaskId(), String.valueOf(orderApprovalDTO.getApproverId()), orderApprovalDTO.getApprovalOpinion());
            String previousStatus = getPreviousOrderStatus(currentStatus);
            if (previousStatus == null) {
                throw new BusinessException("已是初始状态,无法回退");
            }
            orderInfo.setOrderStatus(previousStatus);
            orderInfo.setUpdatedAt(LocalDateTime.now());
            int updated = this.baseMapper.updateById(orderInfo);
            if (updated <= 0) {
                throw new BusinessException("更新订单状态失败");
            }
            log.info("订单状态回退成功,订单ID: {}, 从 {} 回退为 {}", orderInfo.getOrderId(), currentStatus, previousStatus);
        } else {
            completeWorkflowTask(orderInfo.getTaskId(), String.valueOf(orderApprovalDTO.getApproverId()), comment);
            // 通过:调用完成任务,并读取工作流是否结束
            workflowEnded = completeWorkflowTask(orderApprovalDTO.getTaskId(), String.valueOf(orderApprovalDTO.getApproverId()), orderApprovalDTO.getApprovalOpinion());
            // 按需流转订单状态:仅当是通过且工作流已结束时,推进到下一个状态
            if (workflowEnded) {
                String targetStatus = getNextOrderStatus(currentStatus);
            if (targetStatus == null) {
                        throw new BusinessException("已是最终状态,无法继续流转");
            }
            orderInfo.setOrderStatus(targetStatus);
            orderInfo.setUpdatedAt(LocalDateTime.now());
            int updated = this.baseMapper.updateById(orderInfo);
            if (updated <= 0) {
                throw new BusinessException("更新订单状态失败");
            }
            log.info("订单状态更新成功,订单ID: {}, 从 {} 更新为 {}", orderInfo.getOrderId(), currentStatus, targetStatus);
            } else {
                log.info("未推进订单状态,原因:isReject={}, workflowEnded={}", isReject, workflowEnded);
            }
        }
        log.info("审批记录添加成功,订单ID: {}, 审批类型: {}, 审批结果: {}, 审批人: {}, 审批意见: {}", 
@@ -1261,46 +1325,50 @@
        try {
            // 1. 删除订单附件(包括MinIO文件和数据库记录)
            log.info("开始删除订单附件,订单ID: {}", orderId);
            List<OrderAttachment> attachments = orderAttachmentMapper.selectByOrderId(orderId);
            for (OrderAttachment attachment : attachments) {
                try {
                    // 删除MinIO中的文件
                    if (StringUtils.hasText(attachment.getObjectName())) {
                        log.info("删除MinIO文件,对象名称: {}", attachment.getObjectName());
                        minioService.deleteFile(attachment.getObjectName());
                    }
                    // 删除数据库记录
                    orderAttachmentMapper.deleteById(attachment.getId());
                    log.info("删除附件记录成功,附件ID: {}", attachment.getId());
                } catch (Exception e) {
                    log.error("删除附件失败,附件ID: {}, 错误: {}", attachment.getId(), e.getMessage());
                    // 继续删除其他附件,不中断整个流程
                }
            }
//            List<OrderAttachment> attachments = orderAttachmentMapper.selectByOrderId(orderId);
//            for (OrderAttachment attachment : attachments) {
//                try {
//                    // 删除MinIO中的文件
//                    if (StringUtils.hasText(attachment.getObjectName())) {
//                        log.info("删除MinIO文件,对象名称: {}", attachment.getObjectName());
//                        minioService.deleteFile(attachment.getObjectName());
//                    }
//                    // 删除数据库记录
//                    orderAttachmentMapper.deleteById(attachment.getId());
//                    log.info("删除附件记录成功,附件ID: {}", attachment.getId());
//                } catch (Exception e) {
//                    log.error("删除附件失败,附件ID: {}, 错误: {}", attachment.getId(), e.getMessage());
//                    // 继续删除其他附件,不中断整个流程
//                }
//            }
            // 2. 逻辑删除订单详情
            log.info("开始逻辑删除订单详情,订单ID: {}", orderId);
            // log.info("开始逻辑删除订单详情,订单ID: {}", orderId);
            // 先查询订单详情列表,然后逐个逻辑删除
            List<OrderDetail> orderDetails = orderDetailMapper.selectByOrderId(orderId);
            int detailDeleted = 0;
            for (OrderDetail detail : orderDetails) {
                int result = orderDetailMapper.deleteById(detail.getId());
                if (result > 0) {
                    detailDeleted++;
                }
            }
            log.info("逻辑删除订单详情完成,影响行数: {}", detailDeleted);
//            List<OrderDetail> orderDetails = orderDetailMapper.selectByOrderId(orderId);
//            int detailDeleted = 0;
//            for (OrderDetail detail : orderDetails) {
//                int result = orderDetailMapper.deleteById(detail.getId());
//                if (result > 0) {
//                    detailDeleted++;
//                }
//            }
//            log.info("逻辑删除订单详情完成,影响行数: {}", detailDeleted);
            // 3. 删除订单信息(逻辑删除)
            log.info("开始删除订单信息,订单ID: {}", orderId);
            int orderDeleted = this.baseMapper.deleteById(orderId);
            log.info("删除订单信息完成,影响行数: {}", orderDeleted);
//            log.info("开始删除订单信息,订单ID: {}", orderId);
//            int orderDeleted = this.baseMapper.deleteById(orderId);
//            log.info("删除订单信息完成,影响行数: {}", orderDeleted);
            // 更新订单状态为已完成
            orderInfo.setOrderStatus("已取消");
            orderInfo.setUpdatedAt(LocalDateTime.now());
            int orderDeleted = this.baseMapper.updateById(orderInfo);
            if (orderDeleted > 0) {
                log.info("订单取消成功,订单ID: {}", orderId);
                return true;
            } else {
                log.error("删除订单信息失败,影响行数为0,订单ID: {}", orderId);
                log.error("更新订单信息失败,影响行数为0,订单ID: {}", orderId);
                throw new BusinessException("删除订单信息失败");
            }
        } catch (Exception e) {
@@ -1443,7 +1511,7 @@
     * @param userId 用户ID
     * @param comment 审批意见(如:审核通过)
     */
    private void completeWorkflowTask(String taskId, String userId, String comment) {
    private boolean completeWorkflowTask(String taskId, String userId, String comment) {
        try {
            String url = workflowProperties.getProcess().getBaseUrl() + workflowProperties.getProcess().getCompleteUrl();
            Map<String, Object> params = new HashMap<>();
@@ -1472,7 +1540,15 @@
                if (data == null) {
                    throw new BusinessException("工作流完成任务失败,返回数据为空");
                }
                log.info("完成工作流任务成功,processinstId: {}", data.get("processinstId"));
                Object isEndedObj = data.get("isEnded");
                boolean isEnded = false;
                if (isEndedObj instanceof Boolean) {
                    isEnded = (Boolean) isEndedObj;
                } else if (isEndedObj != null) {
                    isEnded = "true".equalsIgnoreCase(String.valueOf(isEndedObj));
                }
                log.info("完成工作流任务成功,processinstId: {}, isEnded: {}", data.get("processinstId"), isEnded);
                return isEnded;
            } else {
                throw new BusinessException("工作流完成任务接口调用失败,HTTP状态: " + response.getStatusCode());
            }
@@ -1528,7 +1604,7 @@
     * 按照workFlowType查询流程实例ID集合
     * workFlowType: 0=代办,1=已办
     */
    private List<String> fetchWorkflowProcessInstanceIds(Integer workFlowType, String userId, String depId,String businessKey,Integer pageIndex, Integer pageSize) {
    private List<Object> fetchWorkflowProcessInstanceIds(Integer workFlowType, String userId, String depId,String businessKey,Integer pageIndex, Integer pageSize) {
        try {
            if (workFlowType == null) {
                return java.util.Collections.emptyList();
@@ -1572,28 +1648,30 @@
                if (!(dataObj instanceof java.util.List)) {
                    return java.util.Collections.emptyList();
                }
                java.util.List<?> list = (java.util.List<?>) dataObj;
                return list.stream()
                        .filter(item -> item instanceof Map)
                        .map(item -> (Map<?, ?>) item)
                        .map(m -> m.get("processInstanceId"))
                        .filter(Objects::nonNull)
                        .map(Object::toString)
                        .collect(Collectors.toList());
                java.util.List<Object> list = (java.util.List<Object>) dataObj;
                return list;
//                        list.stream()
//                        .filter(item -> item instanceof Map)
//                        .map(item -> (Map<?, ?>) item)
//                        .map(m -> m.get("processInstanceId"))
//                        .filter(Objects::nonNull)
//                        .map(Object::toString)
//                        .collect(Collectors.toList());
            }else {
                if (!(dataObj instanceof Map)) {
                    return java.util.Collections.emptyList();
                }
                Map<?,?> map = (Map<?,?>) dataObj;
                Object dataObj1 = ((Map<?, ?>) dataObj).get("list");
                java.util.List<?> list = (java.util.List<?>) dataObj1;
                return list.stream()
                        .filter(item -> item instanceof Map)
                        .map(item -> (Map<?, ?>) item)
                        .map(m -> m.get("processInstanceId"))
                        .filter(Objects::nonNull)
                        .map(Object::toString)
                        .collect(Collectors.toList());
                java.util.List<Object> list = (java.util.List<Object>) dataObj1;
                return list;
//                        list.stream()
//                        .filter(item -> item instanceof Map)
//                        .map(item -> (Map<?, ?>) item)
//                        .map(m -> m.get("processInstanceId"))
//                        .filter(Objects::nonNull)
//                        .map(Object::toString)
//                        .collect(Collectors.toList());
            }
        } catch (Exception e) {