package com.webmanage.service.impl; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.webmanage.common.BusinessException; import com.webmanage.common.PageResult; import com.webmanage.dto.CreateOrderDTO; import com.webmanage.dto.CreateOrderItemDTO; import com.webmanage.dto.FileCheckDTO; import com.webmanage.dto.OrderApprovalDTO; import com.webmanage.dto.OrderQueryDTO; import com.webmanage.dto.UpdateOrderDetailDTO; import com.webmanage.entity.OrderApproval; import com.webmanage.entity.OrderAttachment; import com.webmanage.entity.OrderDetail; import com.webmanage.entity.OrderEvaluation; import com.webmanage.entity.OrderInfo; import com.webmanage.mapper.OrderApprovalMapper; import com.webmanage.mapper.OrderAttachmentMapper; import com.webmanage.mapper.OrderDetailMapper; import com.webmanage.mapper.OrderEvaluationMapper; import com.webmanage.mapper.OrderInfoMapper; import com.webmanage.service.OrderInfoService; import com.webmanage.service.OrderNoService; import com.webmanage.service.MinioService; import com.webmanage.vo.OrderAttachmentVO; import com.webmanage.vo.OrderDetailItemVO; import com.webmanage.vo.OrderDetailVO; import com.webmanage.vo.OrderEvaluationVO; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.BeanUtils; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; import javax.annotation.Resource; import java.math.BigDecimal; import java.time.LocalDateTime; import java.util.List; import java.util.stream.Collectors; /** * 订单信息Service实现类 */ @Slf4j @Service public class OrderInfoServiceImpl extends ServiceImpl implements OrderInfoService { @Resource private OrderDetailMapper orderDetailMapper; @Resource private OrderAttachmentMapper orderAttachmentMapper; @Resource private OrderEvaluationMapper orderEvaluationMapper; @Resource private OrderApprovalMapper orderApprovalMapper; @Resource private OrderNoService orderNoService; @Resource private MinioService minioService; @Override public PageResult getBuyerOrderPage(OrderQueryDTO queryDTO) { // 参数校验 if (queryDTO.getUserId() == null) { throw new BusinessException("用户ID不能为空"); } // 创建分页对象 Page page = new Page<>(queryDTO.getPageNum(), queryDTO.getPageSize()); // 执行分页查询 IPage result = baseMapper.selectBuyerOrderPage( page, queryDTO.getUserId(), queryDTO.getUnitId(), queryDTO.getOrderStatus(), queryDTO.getPaymentStatus(), queryDTO.getPaymentType(), queryDTO.getProductName(), queryDTO.getProviderName(), queryDTO.getOrderId(), queryDTO.getApplyTimeStart() != null ? queryDTO.getApplyTimeStart().toString() : null, queryDTO.getApplyTimeEnd() != null ? queryDTO.getApplyTimeEnd().toString() : null, queryDTO.getCreateTimeStart() != null ? queryDTO.getCreateTimeStart().toString() : null, queryDTO.getCreateTimeEnd() != null ? queryDTO.getCreateTimeEnd().toString() : null, queryDTO.getOrderBy(), queryDTO.getOrderDirection() ); // 构建返回结果 return new PageResult( result.getRecords(), result.getTotal(), queryDTO.getPageNum().longValue(), queryDTO.getPageSize().longValue(), result.getPages() ); } @Override public PageResult getSellerOrderPage(OrderQueryDTO queryDTO) { // 参数校验 if (queryDTO.getProviderId() == null) { throw new BusinessException("提供者ID不能为空"); } // 创建分页对象 Page page = new Page<>(queryDTO.getPageNum(), queryDTO.getPageSize()); // 执行分页查询 IPage result = baseMapper.selectSellerOrderPage( page, queryDTO.getProviderId(), queryDTO.getOrderStatus(), queryDTO.getPaymentStatus(), queryDTO.getProductName(), queryDTO.getOrderId(), queryDTO.getApplyTimeStart() != null ? queryDTO.getApplyTimeStart().toString() : null, queryDTO.getApplyTimeEnd() != null ? queryDTO.getApplyTimeEnd().toString() : null, queryDTO.getCreateTimeStart() != null ? queryDTO.getCreateTimeStart().toString() : null, queryDTO.getCreateTimeEnd() != null ? queryDTO.getCreateTimeEnd().toString() : null, queryDTO.getOrderBy(), queryDTO.getOrderDirection() ); // 构建返回结果 return new PageResult( result.getRecords(), result.getTotal(), queryDTO.getPageNum().longValue(), queryDTO.getPageSize().longValue(), result.getPages() ); } @Override public PageResult getPendingApprovalOrderPage(OrderQueryDTO queryDTO) { // 创建分页对象 Page page = new Page<>(queryDTO.getPageNum(), queryDTO.getPageSize()); // 执行分页查询 IPage result = baseMapper.selectPendingApprovalOrderPage( page, queryDTO.getOrderStatus(), queryDTO.getProductName(), queryDTO.getProviderName(), queryDTO.getOrderId(), queryDTO.getApplyTimeStart() != null ? queryDTO.getApplyTimeStart().toString() : null, queryDTO.getApplyTimeEnd() != null ? queryDTO.getApplyTimeEnd().toString() : null, queryDTO.getOrderBy(), queryDTO.getOrderDirection() ); // 构建返回结果 return new PageResult( result.getRecords(), result.getTotal(), queryDTO.getPageNum().longValue(), queryDTO.getPageSize().longValue(), result.getPages() ); } @Override public OrderDetailVO getOrderDetail(String orderId) { // 参数校验 if (!StringUtils.hasText(orderId)) { throw new BusinessException("订单ID不能为空"); } // 查询订单基本信息 OrderInfo orderInfo = this.getById(orderId); if (orderInfo == null) { throw new BusinessException("订单不存在"); } // 构建订单详情VO OrderDetailVO orderDetailVO = new OrderDetailVO(); BeanUtils.copyProperties(orderInfo, orderDetailVO); // 查询订单详情列表 List orderDetails = orderDetailMapper.selectByOrderId(orderId); List orderDetailItemVOs = orderDetails.stream().map(detail -> { OrderDetailItemVO itemVO = new OrderDetailItemVO(); BeanUtils.copyProperties(detail, itemVO); return itemVO; }).collect(Collectors.toList()); orderDetailVO.setOrderDetails(orderDetailItemVOs); // 查询订单附件列表 List attachments = orderAttachmentMapper.selectByOrderId(orderId); List attachmentVOs = attachments.stream().map(attachment -> { OrderAttachmentVO attachmentVO = new OrderAttachmentVO(); BeanUtils.copyProperties(attachment, attachmentVO); return attachmentVO; }).collect(Collectors.toList()); orderDetailVO.setAttachments(attachmentVOs); // 查询订单评价 OrderEvaluation evaluation = orderEvaluationMapper.selectByOrderId(orderId); if (evaluation != null) { OrderEvaluationVO evaluationVO = new OrderEvaluationVO(); BeanUtils.copyProperties(evaluation, evaluationVO); orderDetailVO.setEvaluation(evaluationVO); } return orderDetailVO; } @Override @Transactional(rollbackFor = Exception.class) public OrderInfo createOrder(CreateOrderDTO createOrderDTO) { if (createOrderDTO == null || CollectionUtils.isEmpty(createOrderDTO.getItems())) { throw new BusinessException("订单信息不完整"); } // 生成订单编号 String orderId = orderNoService.generateOrderNo(); // 计算总金额 BigDecimal totalAmount = BigDecimal.ZERO; for (CreateOrderItemDTO item : createOrderDTO.getItems()) { BigDecimal unitPrice = item.getUnitPrice(); Integer quantity = item.getQuantity(); if (unitPrice == null || quantity == null || quantity <= 0) { throw new BusinessException("明细项单价或数量不合法"); } BigDecimal lineAmount = unitPrice.multiply(BigDecimal.valueOf(quantity)); totalAmount = totalAmount.add(lineAmount); } // 保存订单头 OrderInfo orderInfo = new OrderInfo(); orderInfo.setOrderId(orderId); orderInfo.setProductId(createOrderDTO.getItems().get(0).getProductId()); orderInfo.setProductName(createOrderDTO.getProductName()); orderInfo.setProviderId(createOrderDTO.getProviderId()); orderInfo.setProviderName(createOrderDTO.getProviderName()); orderInfo.setUserId(createOrderDTO.getUserId()); orderInfo.setUnitId(createOrderDTO.getUnitId()); orderInfo.setApplyTime(LocalDateTime.now()); // 根据订单明细中是否包含协议价格类型来决定初始状态 String initialStatus = determineInitialOrderStatus(createOrderDTO.getItems()); orderInfo.setOrderStatus(initialStatus); orderInfo.setTotalAmount(createOrderDTO.getTotalAmount() != null ? createOrderDTO.getTotalAmount() : totalAmount); orderInfo.setPaymentType(createOrderDTO.getPaymentType()); orderInfo.setPaymentStatus("未支付"); orderInfo.setBuyerRemarks(createOrderDTO.getBuyerRemarks()); orderInfo.setCreatedAt(LocalDateTime.now()); orderInfo.setUpdatedAt(LocalDateTime.now()); int inserted = this.baseMapper.insert(orderInfo); if (inserted <= 0) { throw new BusinessException("保存订单失败"); } // 保存订单明细 for (CreateOrderItemDTO item : createOrderDTO.getItems()) { OrderDetail detail = new OrderDetail(); detail.setOrderId(orderId); detail.setPricingId(item.getPricingId()); detail.setProductId(item.getProductId()); detail.setSuiteName(item.getSuiteName()); detail.setSalesForm(item.getSalesForm()); detail.setCustomerType(item.getCustomerType()); detail.setAccountLimit(item.getAccountLimit()); detail.setConcurrentNodes(item.getConcurrentNodes()); detail.setPriceType(item.getPriceType()); detail.setPriceUnit(item.getPriceUnit()); detail.setUnitPrice(item.getUnitPrice()); detail.setQuantity(item.getQuantity()); detail.setDuration(item.getDuration()); BigDecimal lineAmount = item.getUnitPrice().multiply(BigDecimal.valueOf(item.getQuantity())); detail.setTotalPrice(item.getTotalPrice() != null ? item.getTotalPrice() : lineAmount); detail.setProviderId(item.getProviderId()); detail.setProviderName(item.getProviderName()); detail.setRemarks(item.getRemarks()); detail.setCreatedAt(LocalDateTime.now()); detail.setUpdatedAt(LocalDateTime.now()); orderDetailMapper.insert(detail); } return orderInfo; } @Override @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 uploadUserName, String attachmentType, String description) { // 参数校验 if (!StringUtils.hasText(orderId)) { throw new BusinessException("订单ID不能为空"); } if (!StringUtils.hasText(fileName)) { throw new BusinessException("文件名不能为空"); } // 检查订单是否存在 OrderInfo orderInfo = this.getById(orderId); if (orderInfo == null) { throw new BusinessException("订单不存在"); } // 创建订单附件 OrderAttachment attachment = new OrderAttachment(); attachment.setOrderId(orderId); attachment.setFileName(fileName); attachment.setOriginalName(originalName); attachment.setFileType(fileType); attachment.setFileSize(fileSize); attachment.setFileUrl(fileUrl); attachment.setBucketName(bucketName); attachment.setObjectName(objectName); attachment.setUploadUserId(uploadUserId); attachment.setUploadUserName(uploadUserName); attachment.setAttachmentType(attachmentType); attachment.setDescription(description); // 保存附件并返回附件ID int result = orderAttachmentMapper.insert(attachment); if (result > 0) { return attachment.getId(); } else { throw new BusinessException("保存附件失败"); } } @Override @Transactional(rollbackFor = Exception.class) public boolean addOrderEvaluation(String orderId, Long evaluatorId, String evaluatorName, String evaluatorType, String content, Integer rating, Integer serviceRating, Integer qualityRating, Integer deliveryRating, Boolean isAnonymous) { // 参数校验 if (!StringUtils.hasText(orderId)) { throw new BusinessException("订单ID不能为空"); } if (evaluatorId == null) { throw new BusinessException("评价人ID不能为空"); } if (!StringUtils.hasText(content)) { throw new BusinessException("评价内容不能为空"); } if (rating == null || rating < 1 || rating > 5) { throw new BusinessException("评分必须在1-5之间"); } // 检查订单是否存在 OrderInfo orderInfo = this.getById(orderId); if (orderInfo == null) { throw new BusinessException("订单不存在"); } // 检查是否已经评价过 OrderEvaluation existingEvaluation = orderEvaluationMapper.selectByOrderId(orderId); if (existingEvaluation != null) { throw new BusinessException("该订单已经评价过了"); } // 创建订单评价 OrderEvaluation evaluation = new OrderEvaluation(); evaluation.setOrderId(orderId); evaluation.setEvaluatorId(evaluatorId); evaluation.setEvaluatorName(evaluatorName); evaluation.setEvaluatorType(evaluatorType); evaluation.setContent(content); evaluation.setRating(rating); evaluation.setServiceRating(serviceRating); evaluation.setQualityRating(qualityRating); evaluation.setDeliveryRating(deliveryRating); evaluation.setIsAnonymous(isAnonymous != null ? isAnonymous : false); // 保存评价 return orderEvaluationMapper.insert(evaluation) > 0; } @Override @Transactional(rollbackFor = Exception.class) public boolean confirmTransaction(String orderId, Long userId) { // 参数校验 if (!StringUtils.hasText(orderId)) { throw new BusinessException("订单ID不能为空"); } if (userId == null) { throw new BusinessException("用户ID不能为空"); } // 查询订单信息 OrderInfo orderInfo = this.getById(orderId); if (orderInfo == null) { throw new BusinessException("订单不存在"); } // 检查订单状态 if (!"待交易确认".equals(orderInfo.getOrderStatus())) { throw new BusinessException("订单状态不正确,无法确认交易"); } // 检查用户权限 if (!userId.equals(orderInfo.getUserId())) { throw new BusinessException("无权限操作此订单"); } // 更新订单状态 orderInfo.setOrderStatus("已完成"); orderInfo.setUpdatedAt(LocalDateTime.now()); // 如果是积分交易,需要扣除积分 if ("积分".equals(orderInfo.getPaymentType())) { // TODO: 实现积分扣除逻辑 log.info("积分交易确认,订单ID: {}, 需要扣除积分", orderId); } // 保存订单 return this.updateById(orderInfo); } @Override @Transactional(rollbackFor = Exception.class) public boolean replyEvaluation(Long evaluationId, String replyContent, Long replyUserId) { // 参数校验 if (evaluationId == null) { throw new BusinessException("评价ID不能为空"); } if (!StringUtils.hasText(replyContent)) { throw new BusinessException("回复内容不能为空"); } if (replyUserId == null) { throw new BusinessException("回复用户ID不能为空"); } // 查询评价信息 OrderEvaluation evaluation = orderEvaluationMapper.selectById(evaluationId); if (evaluation == null) { throw new BusinessException("评价不存在"); } // 更新回复信息 evaluation.setReplyContent(replyContent); evaluation.setReplyUserId(replyUserId); evaluation.setReplyTime(LocalDateTime.now()); evaluation.setUpdatedAt(LocalDateTime.now()); // 保存评价 return orderEvaluationMapper.updateById(evaluation) > 0; } @Override @Transactional(rollbackFor = Exception.class) public boolean updateOrderDetail(UpdateOrderDetailDTO updateOrderDetailDTO) { // 参数校验 if (updateOrderDetailDTO == null) { throw new BusinessException("更新参数不能为空"); } if (!StringUtils.hasText(updateOrderDetailDTO.getOrderId())) { throw new BusinessException("订单ID不能为空"); } if (!StringUtils.hasText(updateOrderDetailDTO.getOrderStatus())) { throw new BusinessException("订单状态不能为空"); } if (CollectionUtils.isEmpty(updateOrderDetailDTO.getOrderDetails())) { throw new BusinessException("订单详情列表不能为空"); } // 查询订单信息 OrderInfo orderInfo = this.getById(updateOrderDetailDTO.getOrderId()); if (orderInfo == null) { throw new BusinessException("订单不存在"); } // 更新订单状态 orderInfo.setOrderStatus(updateOrderDetailDTO.getOrderStatus()); orderInfo.setUpdatedAt(LocalDateTime.now()); int orderUpdated = this.baseMapper.updateById(orderInfo); if (orderUpdated <= 0) { throw new BusinessException("更新订单状态失败"); } // 更新订单详情备注 for (UpdateOrderDetailDTO.UpdateOrderDetailItemDTO itemDTO : updateOrderDetailDTO.getOrderDetails()) { if (itemDTO.getId() == null) { continue; } OrderDetail orderDetail = orderDetailMapper.selectById(itemDTO.getId()); if (orderDetail == null) { log.warn("订单详情不存在,ID: {}", itemDTO.getId()); continue; } // 更新备注 orderDetail.setRemarks(itemDTO.getRemarks()); orderDetail.setUpdatedAt(LocalDateTime.now()); int detailUpdated = orderDetailMapper.updateById(orderDetail); if (detailUpdated <= 0) { log.warn("更新订单详情失败,ID: {}", itemDTO.getId()); } } return true; } @Override @Transactional(rollbackFor = Exception.class) public boolean checkFiles(FileCheckDTO fileCheckDTO) { // 参数校验 if (fileCheckDTO == null) { throw new BusinessException("文件核查参数不能为空"); } if (!StringUtils.hasText(fileCheckDTO.getOrderId())) { throw new BusinessException("订单ID不能为空"); } if (fileCheckDTO.getIsApprove() == null) { throw new BusinessException("审批结果不能为空"); } if (fileCheckDTO.getApproverId() == null) { throw new BusinessException("审批人ID不能为空"); } if (!StringUtils.hasText(fileCheckDTO.getApproverName())) { throw new BusinessException("审批人姓名不能为空"); } // 查询订单信息 OrderInfo orderInfo = this.getById(fileCheckDTO.getOrderId()); if (orderInfo == null) { throw new BusinessException("订单不存在"); } // 检查订单状态是否为"待授权" if (!"待授权".equals(orderInfo.getOrderStatus())) { throw new BusinessException("订单状态不正确,当前状态为:" + orderInfo.getOrderStatus()); } // 更新订单状态 if (fileCheckDTO.getIsApprove()) { // 通过:更新为"待交易确认" orderInfo.setOrderStatus("待交易确认"); } else { // 驳回:更新为"待上传文件"(需要重新上传) orderInfo.setOrderStatus("待上传文件"); } orderInfo.setUpdatedAt(LocalDateTime.now()); // 保存订单 int updated = this.baseMapper.updateById(orderInfo); if (updated <= 0) { throw new BusinessException("更新订单状态失败"); } log.info("文件核查完成,订单ID: {}, 审批结果: {}, 审批人: {}, 审批意见: {}", fileCheckDTO.getOrderId(), fileCheckDTO.getIsApprove() ? "通过" : "驳回", fileCheckDTO.getApproverName(), fileCheckDTO.getApprovalOpinion()); return true; } @Override @Transactional(rollbackFor = Exception.class) public boolean approveOrder(OrderApprovalDTO orderApprovalDTO) { // 参数校验 if (orderApprovalDTO == null) { throw new BusinessException("审批参数不能为空"); } if (!StringUtils.hasText(orderApprovalDTO.getOrderId())) { throw new BusinessException("订单ID不能为空"); } if (!StringUtils.hasText(orderApprovalDTO.getApprovalOpinion())) { throw new BusinessException("审批意见不能为空"); } if (orderApprovalDTO.getApproverId() == null) { throw new BusinessException("审批人ID不能为空"); } if (!StringUtils.hasText(orderApprovalDTO.getApproverName())) { throw new BusinessException("审批人姓名不能为空"); } if (!StringUtils.hasText(orderApprovalDTO.getApprovalType())) { throw new BusinessException("审批类型不能为空"); } if (!StringUtils.hasText(orderApprovalDTO.getApprovalResult())) { throw new BusinessException("审批结果不能为空"); } // 查询订单信息 OrderInfo orderInfo = this.getById(orderApprovalDTO.getOrderId()); if (orderInfo == null) { throw new BusinessException("订单不存在"); } // 创建审批记录 OrderApproval orderApproval = new OrderApproval(); orderApproval.setOrderId(orderApprovalDTO.getOrderId()); orderApproval.setApprovalStep("审批授权"); orderApproval.setApprovalType(orderApprovalDTO.getApprovalType()); orderApproval.setApprovalResult(orderApprovalDTO.getApprovalResult()); orderApproval.setApproverId(orderApprovalDTO.getApproverId()); orderApproval.setApproverName(orderApprovalDTO.getApproverName()); orderApproval.setApprovalOpinion(orderApprovalDTO.getApprovalOpinion()); orderApproval.setApprovalTime(LocalDateTime.now()); // 插入审批记录 int insertResult = orderApprovalMapper.insert(orderApproval); if (insertResult <= 0) { throw new BusinessException("插入审批记录失败"); } log.info("审批记录添加成功,订单ID: {}, 审批类型: {}, 审批结果: {}, 审批人: {}, 审批意见: {}", orderApprovalDTO.getOrderId(), orderApprovalDTO.getApprovalType(), orderApprovalDTO.getApprovalResult(), orderApprovalDTO.getApproverName(), orderApprovalDTO.getApprovalOpinion()); return true; } @Override @Transactional(rollbackFor = Exception.class) public boolean updateOrderStatusToNext(String orderId) { // 参数校验 if (!StringUtils.hasText(orderId)) { throw new BusinessException("订单ID不能为空"); } // 查询订单信息 OrderInfo orderInfo = this.getById(orderId); if (orderInfo == null) { throw new BusinessException("订单不存在"); } // 获取当前状态 String currentStatus = orderInfo.getOrderStatus(); if (!StringUtils.hasText(currentStatus)) { throw new BusinessException("订单当前状态为空"); } // 获取下一个状态 String nextStatus = getNextOrderStatus(currentStatus); if (nextStatus == null) { throw new BusinessException("当前状态 " + currentStatus + " 已是最终状态,无法继续流转"); } // 更新订单状态 orderInfo.setOrderStatus(nextStatus); orderInfo.setUpdatedAt(LocalDateTime.now()); int updated = this.baseMapper.updateById(orderInfo); if (updated <= 0) { throw new BusinessException("更新订单状态失败"); } log.info("订单状态更新成功,订单ID: {}, 从 {} 更新为 {}", orderId, currentStatus, nextStatus); return true; } @Override @Transactional(rollbackFor = Exception.class) public boolean updateOrderStatusToPrevious(String orderId) { // 参数校验 if (!StringUtils.hasText(orderId)) { throw new BusinessException("订单ID不能为空"); } // 查询订单信息 OrderInfo orderInfo = this.getById(orderId); if (orderInfo == null) { throw new BusinessException("订单不存在"); } // 获取当前状态 String currentStatus = orderInfo.getOrderStatus(); if (!StringUtils.hasText(currentStatus)) { throw new BusinessException("订单当前状态为空"); } // 获取上一个状态 String previousStatus = getPreviousOrderStatus(currentStatus); if (previousStatus == null) { throw new BusinessException("当前状态 " + currentStatus + " 已是初始状态,无法回退"); } // 更新订单状态 orderInfo.setOrderStatus(previousStatus); orderInfo.setUpdatedAt(LocalDateTime.now()); int updated = this.baseMapper.updateById(orderInfo); if (updated <= 0) { throw new BusinessException("更新订单状态失败"); } log.info("订单状态更新成功,订单ID: {}, 从 {} 回退为 {}", orderId, currentStatus, previousStatus); return true; } /** * 根据订单明细确定初始订单状态 * @param items 订单明细列表 * @return 初始状态 */ private String determineInitialOrderStatus(List items) { // 检查是否有价格类型为"协议"的明细项 boolean hasAgreementPrice = items.stream() .anyMatch(item -> "协议".equals(item.getPriceType())); // 如果有协议价格,从"待上传文件"开始,否则从"待授权"开始 String initialStatus = hasAgreementPrice ? "待上传文件" : "待授权"; log.info("订单初始状态确定为: {}, 是否包含协议价格: {}", initialStatus, hasAgreementPrice); return initialStatus; } /** * 获取下一个订单状态 * @param currentStatus 当前状态 * @return 下一个状态,如果是最终状态则返回null */ private String getNextOrderStatus(String currentStatus) { switch (currentStatus) { case "待上传文件": return "待授权"; case "待授权": return "待交易确认"; case "待交易确认": return "已完成"; case "已完成": return "已评价"; case "已评价": return null; // 最终状态 default: throw new BusinessException("未知的订单状态:" + currentStatus); } } /** * 获取上一个订单状态 * @param currentStatus 当前状态 * @return 上一个状态,如果是初始状态则返回null */ private String getPreviousOrderStatus(String currentStatus) { switch (currentStatus) { case "待上传文件": return null; // 初始状态 case "待授权": return "待上传文件"; case "待交易确认": return "待授权"; case "已完成": return "待交易确认"; case "已评价": return "已完成"; default: throw new BusinessException("未知的订单状态:" + currentStatus); } } @Override public boolean hasAgreementPriceType(String orderId) { // 参数校验 if (!StringUtils.hasText(orderId)) { throw new BusinessException("订单ID不能为空"); } // 查询订单详情,检查是否有价格类型为"协议"的子订单 QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.eq("order_id", orderId); queryWrapper.eq("price_type", "协议"); queryWrapper.eq("deleted", 0); List agreementDetails = orderDetailMapper.selectList(queryWrapper); boolean hasAgreement = !CollectionUtils.isEmpty(agreementDetails); log.info("检查订单协议类型,订单ID: {}, 是否包含协议类型: {}", orderId, hasAgreement); return hasAgreement; } @Override @Transactional(rollbackFor = Exception.class) public boolean updateOrderDetailRemarksOnly(UpdateOrderDetailDTO.UpdateOrderDetailRemarksOnlyDTO updateOrderDetailDTO) { // 参数校验 if (updateOrderDetailDTO == null) { throw new BusinessException("更新参数不能为空"); } if (!StringUtils.hasText(updateOrderDetailDTO.getOrderId())) { throw new BusinessException("订单ID不能为空"); } if (CollectionUtils.isEmpty(updateOrderDetailDTO.getOrderDetails())) { throw new BusinessException("订单详情列表不能为空"); } // 查询订单信息(验证订单存在) OrderInfo orderInfo = this.getById(updateOrderDetailDTO.getOrderId()); if (orderInfo == null) { throw new BusinessException("订单不存在"); } // 只更新订单详情备注,不更新订单状态 for (UpdateOrderDetailDTO.UpdateOrderDetailItemDTO itemDTO : updateOrderDetailDTO.getOrderDetails()) { if (itemDTO.getId() == null) { continue; } OrderDetail orderDetail = orderDetailMapper.selectById(itemDTO.getId()); if (orderDetail == null) { log.warn("订单详情不存在,ID: {}", itemDTO.getId()); continue; } // 更新备注 orderDetail.setRemarks(itemDTO.getRemarks()); orderDetail.setUpdatedAt(LocalDateTime.now()); int detailUpdated = orderDetailMapper.updateById(orderDetail); if (detailUpdated <= 0) { log.warn("更新订单详情失败,ID: {}", itemDTO.getId()); } } log.info("订单详情备注更新成功,订单ID: {}", updateOrderDetailDTO.getOrderId()); return true; } @Override @Transactional(rollbackFor = Exception.class) public boolean deleteOrderAttachment(Long attachmentId) { // 参数校验 if (attachmentId == null) { throw new BusinessException("附件ID不能为空"); } log.info("开始删除订单附件,附件ID: {}", attachmentId); // 查询附件信息 OrderAttachment attachment = orderAttachmentMapper.selectById(attachmentId); if (attachment == null) { log.error("附件不存在,附件ID: {}", attachmentId); throw new BusinessException("附件不存在"); } log.info("查询到附件信息: ID={}, 文件名={}, 对象名称={}, 当前删除状态={}", attachment.getId(), attachment.getFileName(), attachment.getObjectName(), attachment.getDeleted()); try { // 1. 删除MinIO中的文件 if (StringUtils.hasText(attachment.getObjectName())) { log.info("开始删除MinIO文件,对象名称: {}", attachment.getObjectName()); minioService.deleteFile(attachment.getObjectName()); log.info("MinIO文件删除成功,对象名称: {}", attachment.getObjectName()); } else { log.warn("附件对象名称为空,跳过MinIO文件删除"); } // 2. 删除数据库中的附件记录(逻辑删除) log.info("开始逻辑删除数据库记录,附件ID: {}", attachmentId); // 使用MyBatis-Plus的逻辑删除方法 int result = orderAttachmentMapper.deleteById(attachmentId); log.info("数据库逻辑删除结果: 影响行数={}", result); if (result > 0) { log.info("订单附件删除成功,附件ID: {}, 文件名: {}", attachmentId, attachment.getFileName()); return true; } else { log.error("数据库更新失败,影响行数为0,附件ID: {}", attachmentId); throw new BusinessException("删除附件记录失败"); } } catch (Exception e) { log.error("删除订单附件失败,附件ID: {}", attachmentId, e); throw new BusinessException("删除订单附件失败:" + e.getMessage()); } } @Override @Transactional(rollbackFor = Exception.class) public boolean cancelOrder(String orderId) { // 参数校验 if (!StringUtils.hasText(orderId)) { throw new BusinessException("订单ID不能为空"); } log.info("开始取消订单,订单ID: {}", orderId); // 查询订单信息 OrderInfo orderInfo = this.getById(orderId); if (orderInfo == null) { throw new BusinessException("订单不存在"); } // 检查订单状态,只有"已完成"状态前的订单才能取消 String currentStatus = orderInfo.getOrderStatus(); if ("已完成".equals(currentStatus) || "已评价".equals(currentStatus)) { throw new BusinessException("已完成或已评价的订单不能取消"); } try { // 1. 删除订单附件(包括MinIO文件和数据库记录) log.info("开始删除订单附件,订单ID: {}", orderId); List 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); // 先查询订单详情列表,然后逐个逻辑删除 List 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); if (orderDeleted > 0) { log.info("订单取消成功,订单ID: {}", orderId); return true; } else { log.error("删除订单信息失败,影响行数为0,订单ID: {}", orderId); throw new BusinessException("删除订单信息失败"); } } catch (Exception e) { log.error("取消订单失败,订单ID: {}", orderId, e); throw new BusinessException("取消订单失败:" + e.getMessage()); } } }