package cn.lili.modules.order.order.serviceimpl; import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.date.DateUtil; import cn.hutool.core.io.IoUtil; import cn.hutool.core.text.CharSequenceUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONUtil; import cn.hutool.poi.excel.ExcelReader; import cn.hutool.poi.excel.ExcelUtil; import cn.hutool.poi.excel.ExcelWriter; import cn.lili.common.enums.ClientTypeEnum; import cn.lili.common.enums.PromotionTypeEnum; import cn.lili.common.enums.ResultCode; import cn.lili.common.event.TransactionCommitSendMQEvent; import cn.lili.common.exception.ServiceException; import cn.lili.common.properties.RocketmqCustomProperties; import cn.lili.common.security.OperationalJudgment; import cn.lili.common.security.context.UserContext; import cn.lili.common.security.enums.UserEnums; import cn.lili.common.utils.CurrencyUtil; import cn.lili.common.utils.SnowFlake; import cn.lili.modules.goods.entity.dto.GoodsCompleteMessage; import cn.lili.modules.member.entity.dto.MemberAddressDTO; import cn.lili.modules.order.cart.entity.dto.TradeDTO; import cn.lili.modules.order.cart.entity.enums.DeliveryMethodEnum; import cn.lili.modules.order.order.aop.OrderLogPoint; import cn.lili.modules.order.order.entity.dos.*; import cn.lili.modules.order.order.entity.dto.*; import cn.lili.modules.order.order.entity.enums.*; import cn.lili.modules.order.order.entity.vo.OrderDetailVO; import cn.lili.modules.order.order.entity.vo.OrderSimpleVO; import cn.lili.modules.order.order.entity.vo.OrderVO; import cn.lili.modules.order.order.entity.vo.PaymentLog; import cn.lili.modules.order.order.mapper.OrderMapper; import cn.lili.modules.order.order.service.*; import cn.lili.modules.order.trade.entity.dos.OrderLog; import cn.lili.modules.order.trade.service.OrderLogService; import cn.lili.modules.payment.entity.enums.PaymentMethodEnum; import cn.lili.modules.promotion.entity.dos.Pintuan; import cn.lili.modules.promotion.service.PintuanService; import cn.lili.modules.store.entity.dto.StoreDeliverGoodsAddressDTO; import cn.lili.modules.store.service.StoreDetailService; import cn.lili.modules.system.aspect.annotation.SystemLogPoint; import cn.lili.modules.system.entity.dos.Logistics; import cn.lili.modules.system.entity.dos.Setting; import cn.lili.modules.system.entity.dto.OrderSetting; import cn.lili.modules.system.entity.enums.SettingEnum; import cn.lili.modules.system.entity.vo.Traces; import cn.lili.modules.system.service.LogisticsService; import cn.lili.modules.system.service.SettingService; import cn.lili.mybatis.util.PageUtil; import cn.lili.rocketmq.RocketmqSendCallbackBuilder; import cn.lili.rocketmq.tags.GoodsTagsEnum; import cn.lili.rocketmq.tags.OrderTagsEnum; import cn.lili.trigger.enums.DelayTypeEnums; import cn.lili.trigger.interfaces.TimeTrigger; import cn.lili.trigger.message.PintuanOrderMessage; import cn.lili.trigger.model.TimeExecuteConstant; import cn.lili.trigger.model.TimeTriggerMsg; import cn.lili.trigger.util.DelayQueueTools; import com.baomidou.mybatisplus.core.conditions.Wrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import lombok.extern.slf4j.Slf4j; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.util.CellRangeAddressList; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.apache.rocketmq.spring.core.RocketMQTemplate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationEventPublisher; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; import java.io.InputStream; import java.net.URLEncoder; import java.util.*; import java.util.stream.Collectors; /** * 子订单业务层实现 * * @author Chopper * @since 2020/11/17 7:38 下午 */ @Service @Slf4j public class OrderServiceImpl extends ServiceImpl implements OrderService { private static final String ORDER_SN_COLUMN = "order_sn"; /** * 延时任务 */ @Autowired private TimeTrigger timeTrigger; /** * 发票 */ @Autowired private ReceiptService receiptService; /** * 订单货物 */ @Autowired private OrderItemService orderItemService; /** * 物流公司 */ @Autowired private LogisticsService logisticsService; /** * 订单日志 */ @Autowired private OrderLogService orderLogService; /** * RocketMQ */ @Autowired private RocketMQTemplate rocketMQTemplate; /** * RocketMQ配置 */ @Autowired private RocketmqCustomProperties rocketmqCustomProperties; /** * 订单流水 */ @Autowired private StoreFlowService storeFlowService; /** * 拼团 */ @Autowired private PintuanService pintuanService; @Autowired private TradeService tradeService; @Autowired private ApplicationEventPublisher applicationEventPublisher; @Autowired private StoreDetailService storeDetailService; /** * 订单包裹 */ @Autowired private OrderPackageService orderPackageService; /** * 订单包裹货物 */ @Autowired private OrderPackageItemService orderPackageItemService; @Autowired private SettingService settingService; @Override @Transactional(rollbackFor = Exception.class) public void intoDB(TradeDTO tradeDTO) { //检查TradeDTO信息 checkTradeDTO(tradeDTO); //存放购物车,即业务中的订单 List orders = new ArrayList<>(tradeDTO.getCartList().size()); //存放自订单/订单日志 List orderItems = new ArrayList<>(); List orderLogs = new ArrayList<>(); //订单集合 List orderVOS = new ArrayList<>(); //循环购物车 tradeDTO.getCartList().forEach(item -> { //当前购物车订单子项 List currentOrderItems = new ArrayList<>(); Order order = new Order(item, tradeDTO); //构建orderVO对象 OrderVO orderVO = new OrderVO(); BeanUtil.copyProperties(order, orderVO); //持久化DO orders.add(order); String message = "订单[" + item.getSn() + "]创建"; //记录日志 orderLogs.add(new OrderLog(item.getSn(), UserContext.getCurrentUser().getId(), UserContext.getCurrentUser().getRole().getRole(), UserContext.getCurrentUser().getUsername(), message)); item.getCheckedSkuList().forEach( sku -> { orderItems.add(new OrderItem(sku, item, tradeDTO)); currentOrderItems.add(new OrderItem(sku, item, tradeDTO)); } ); //写入子订单信息 orderVO.setOrderItems(currentOrderItems); //orderVO 记录 orderVOS.add(orderVO); }); tradeDTO.setOrderVO(orderVOS); //批量保存订单 this.saveBatch(orders); //批量保存 子订单 orderItemService.saveBatch(orderItems); //批量记录订单操作日志 orderLogService.saveBatch(orderLogs); } @Override public IPage queryByParams(OrderSearchParams orderSearchParams) { QueryWrapper queryWrapper = orderSearchParams.queryWrapper(); queryWrapper.groupBy("o.id"); queryWrapper.orderByDesc("o.id"); return this.baseMapper.queryByParams(PageUtil.initPage(orderSearchParams), queryWrapper); } /** * 订单信息 * * @param orderSearchParams 查询参数 * @return 订单信息 */ @Override public List queryListByParams(OrderSearchParams orderSearchParams) { return this.baseMapper.queryListByParams(orderSearchParams.queryWrapper()); } /** * 根据促销查询订单 * * @param orderPromotionType 订单类型 * @param payStatus 支付状态 * @param parentOrderSn 依赖订单编号 * @param orderSn 订单编号 * @return 订单信息 */ @Override public List queryListByPromotion(String orderPromotionType, String payStatus, String parentOrderSn, String orderSn) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); //查找团长订单和已和当前拼团订单拼团的订单 queryWrapper.eq(Order::getOrderPromotionType, orderPromotionType) .eq(Order::getPayStatus, payStatus) .and(i -> i.eq(Order::getParentOrderSn, parentOrderSn).or(j -> j.eq(Order::getSn, orderSn))); return this.list(queryWrapper); } /** * 根据促销查询订单 * * @param orderPromotionType 订单类型 * @param payStatus 支付状态 * @param parentOrderSn 依赖订单编号 * @param orderSn 订单编号 * @return 订单信息 */ @Override public long queryCountByPromotion(String orderPromotionType, String payStatus, String parentOrderSn, String orderSn) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); //查找团长订单和已和当前拼团订单拼团的订单 queryWrapper.eq(Order::getOrderPromotionType, orderPromotionType) .eq(Order::getPayStatus, payStatus) .and(i -> i.eq(Order::getParentOrderSn, parentOrderSn).or(j -> j.eq(Order::getSn, orderSn))); return this.count(queryWrapper); } /** * 父级拼团订单 * * @param pintuanId 拼团id * @return 拼团订单信息 */ @Override public List queryListByPromotion(String pintuanId) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(Order::getOrderPromotionType, PromotionTypeEnum.PINTUAN.name()); queryWrapper.eq(Order::getPromotionId, pintuanId); queryWrapper.nested(i -> i.eq(Order::getPayStatus, PayStatusEnum.PAID.name()).or(j -> j.eq(Order::getOrderStatus, OrderStatusEnum.PAID.name()))); queryWrapper.ne(Order::getOrderStatus, OrderStatusEnum.CANCELLED.name()); return this.list(queryWrapper); } @Override public void queryExportOrder(HttpServletResponse response, OrderSearchParams orderSearchParams) { XSSFWorkbook workbook = initOrderExportData(this.baseMapper.queryExportOrder(orderSearchParams.queryWrapper())); try { // 设置响应头 String fileName = URLEncoder.encode("订单列表", "UTF-8"); response.setContentType("application/vnd.ms-excel;charset=UTF-8"); response.setHeader("Content-Disposition", "attachment;filename=" + fileName + ".xlsx"); ServletOutputStream out = response.getOutputStream(); workbook.write(out); } catch (Exception e) { e.printStackTrace(); } finally { try { workbook.close(); } catch (Exception e) { e.printStackTrace(); } } } @Override public OrderDetailVO queryDetail(String orderSn) { Order order = this.getBySn(orderSn); if (order == null) { throw new ServiceException(ResultCode.ORDER_NOT_EXIST); } //查询订单项信息 List orderItems = orderItemService.getByOrderSn(orderSn); //查询订单日志信息 List orderLogs = orderLogService.getOrderLog(orderSn); //查询发票信息 Receipt receipt = receiptService.getByOrderSn(orderSn); //查询订单和自订单,然后写入vo返回 return new OrderDetailVO(order, orderItems, orderLogs, receipt); } @Override @OrderLogPoint(description = "'订单['+#orderSn+']取消,原因为:'+#reason", orderSn = "#orderSn") @Transactional(rollbackFor = Exception.class) public Order cancel(String orderSn, String reason) { Order order = OperationalJudgment.judgment(this.getBySn(orderSn)); //如果订单促销类型不为空&&订单是拼团订单,并且订单未成团,则抛出异常 if (OrderPromotionTypeEnum.PINTUAN.name().equals(order.getOrderPromotionType()) && !CharSequenceUtil.equalsAny(order.getOrderStatus(), OrderStatusEnum.TAKE.name(), OrderStatusEnum.UNDELIVERED.name(), OrderStatusEnum.STAY_PICKED_UP.name())) { throw new ServiceException(ResultCode.ORDER_CAN_NOT_CANCEL); } if (CharSequenceUtil.equalsAny(order.getOrderStatus(), OrderStatusEnum.UNDELIVERED.name(), OrderStatusEnum.UNPAID.name(), OrderStatusEnum.STAY_PICKED_UP.name(), OrderStatusEnum.PAID.name(), OrderStatusEnum.TAKE.name())) { order.setOrderStatus(OrderStatusEnum.CANCELLED.name()); order.setCancelReason(reason); //修改订单 this.updateById(order); //生成店铺退款流水 storeFlowService.orderCancel(orderSn); //发送消息 orderStatusMessage(order); return order; } else { throw new ServiceException(ResultCode.ORDER_CAN_NOT_CANCEL); } } @Override @OrderLogPoint(description = "'订单['+#orderSn+']系统取消,原因为:'+#reason", orderSn = "#orderSn") @Transactional(rollbackFor = Exception.class) public void systemCancel(String orderSn, String reason, Boolean refundMoney) { Order order = this.getBySn(orderSn); order.setOrderStatus(OrderStatusEnum.CANCELLED.name()); order.setCancelReason(reason); this.updateById(order); if (refundMoney) { //生成店铺退款流水 storeFlowService.orderCancel(orderSn); orderStatusMessage(order); } } /** * 获取订单 * * @param orderSn 订单编号 * @return 订单详情 */ @Override public Order getBySn(String orderSn) { return this.getOne(new LambdaQueryWrapper().eq(Order::getSn, orderSn)); } @Override @Transactional(rollbackFor = Exception.class) public void payOrder(String orderSn, String paymentMethod, String receivableNo) { Order order = this.getBySn(orderSn); //如果订单已支付,就不能再次进行支付 if (order.getPayStatus().equals(PayStatusEnum.PAID.name())) { log.error("订单[ {} ]检测到重复付款,请处理", orderSn); throw new ServiceException(ResultCode.PAY_DOUBLE_ERROR); } //修改订单状态 order.setPaymentTime(new Date()); order.setPaymentMethod(paymentMethod); order.setPayStatus(PayStatusEnum.PAID.name()); order.setOrderStatus(OrderStatusEnum.PAID.name()); order.setReceivableNo(receivableNo); order.setCanReturn(!PaymentMethodEnum.BANK_TRANSFER.name().equals(order.getPaymentMethod())); this.updateById(order); //记录店铺订单支付流水 storeFlowService.payOrder(orderSn); //发送订单已付款消息 OrderMessage orderMessage = new OrderMessage(); orderMessage.setOrderSn(order.getSn()); orderMessage.setPaymentMethod(paymentMethod); orderMessage.setNewStatus(OrderStatusEnum.PAID); this.sendUpdateStatusMessage(orderMessage); String message = "订单付款,付款方式[" + PaymentMethodEnum.valueOf(paymentMethod).paymentName() + "]"; OrderLog orderLog = new OrderLog(orderSn, "-1", UserEnums.SYSTEM.getRole(), "系统操作", message); orderLogService.save(orderLog); } @Override @OrderLogPoint(description = "'库存确认'", orderSn = "#orderSn") @Transactional(rollbackFor = Exception.class) public void afterOrderConfirm(String orderSn) { Order order = this.getBySn(orderSn); //判断是否为拼团订单,进行特殊处理 //判断订单类型进行不同的订单确认操作 if (OrderPromotionTypeEnum.PINTUAN.name().equals(order.getOrderPromotionType())) { String parentOrderSn = CharSequenceUtil.isEmpty(order.getParentOrderSn()) ? orderSn : order.getParentOrderSn(); this.checkPintuanOrder(order.getPromotionId(), parentOrderSn); } else { //判断订单类型 if (order.getOrderType().equals(OrderTypeEnum.NORMAL.name())) { normalOrderConfirm(orderSn); } else { virtualOrderConfirm(orderSn); } } } @Override @SystemLogPoint(description = "修改订单", customerLog = "'订单[' + #orderSn + ']收货信息修改,修改为'+#memberAddressDTO.consigneeDetail") @Transactional(rollbackFor = Exception.class) public Order updateConsignee(String orderSn, MemberAddressDTO memberAddressDTO) { Order order = OperationalJudgment.judgment(this.getBySn(orderSn)); //要记录之前的收货地址,所以需要以代码方式进行调用 不采用注解 String message = "订单[" + orderSn + "]收货信息修改,由[" + order.getConsigneeDetail() + "]修改为[" + memberAddressDTO.getConsigneeDetail() + "]"; //记录订单操作日志 BeanUtil.copyProperties(memberAddressDTO, order); this.updateById(order); OrderLog orderLog = new OrderLog(orderSn, UserContext.getCurrentUser().getId(), UserContext.getCurrentUser().getRole().getRole(), UserContext.getCurrentUser().getUsername(), message); orderLogService.save(orderLog); return order; } @Override @OrderLogPoint(description = "'订单['+#orderSn+']发货,发货单号['+#logisticsNo+']'", orderSn = "#orderSn") @Transactional(rollbackFor = Exception.class) public Order delivery(String orderSn, String logisticsNo, String logisticsId) { Order order = OperationalJudgment.judgment(this.getBySn(orderSn)); //如果订单未发货,并且订单状态值等于待发货 if (order.getDeliverStatus().equals(DeliverStatusEnum.UNDELIVERED.name()) && order.getOrderStatus().equals(OrderStatusEnum.UNDELIVERED.name())) { //获取对应物流 Logistics logistics = logisticsService.getById(logisticsId); if (logistics == null) { throw new ServiceException(ResultCode.ORDER_LOGISTICS_ERROR); } //写入物流信息 order.setLogisticsCode(logistics.getId()); order.setLogisticsName(logistics.getName()); order.setLogisticsNo(logisticsNo); order.setLogisticsTime(new Date()); order.setDeliverStatus(DeliverStatusEnum.DELIVERED.name()); this.updateById(order); //修改订单状态为已发送 this.updateStatus(orderSn, OrderStatusEnum.DELIVERED); //修改订单货物可以进行售后、投诉 orderItemService.update(new UpdateWrapper().eq(ORDER_SN_COLUMN, orderSn) .set("after_sale_status", OrderItemAfterSaleStatusEnum.NOT_APPLIED) .set("complain_status", OrderComplaintStatusEnum.NO_APPLY)); //发送订单状态改变消息 OrderMessage orderMessage = new OrderMessage(); orderMessage.setNewStatus(OrderStatusEnum.DELIVERED); orderMessage.setOrderSn(order.getSn()); this.sendUpdateStatusMessage(orderMessage); } else { throw new ServiceException(ResultCode.ORDER_DELIVER_ERROR); } return order; } @Override @Transactional(rollbackFor = Exception.class) public Order shunFengDelivery(String orderSn) { OrderDetailVO orderDetailVO = this.queryDetail(orderSn); String logisticsNo = logisticsService.sfCreateOrder(orderDetailVO); Logistics logistics = logisticsService.getOne(new LambdaQueryWrapper().eq(Logistics::getCode, "SF")); return delivery(orderSn, logisticsNo, logistics.getId()); } @Override public Traces getTraces(String orderSn) { //获取订单信息 Order order = this.getBySn(orderSn); //获取踪迹信息 return logisticsService.getLogisticTrack(order.getLogisticsCode(), order.getLogisticsNo(), order.getConsigneeMobile()); } @Override public Traces getMapTraces(String orderSn) { //获取订单信息 Order order = this.getBySn(orderSn); //获取店家信息 StoreDeliverGoodsAddressDTO storeDeliverGoodsAddressDTO = storeDetailService.getStoreDeliverGoodsAddressDto(order.getStoreId()); String from = storeDeliverGoodsAddressDTO.getSalesConsignorAddressPath().substring(0, storeDeliverGoodsAddressDTO.getSalesConsignorAddressPath().indexOf(",") - 1); String to = order.getConsigneeAddressPath().substring(0, order.getConsigneeAddressPath().indexOf(",") - 1); //获取踪迹信息 return logisticsService.getLogisticMapTrack(order.getLogisticsCode(), order.getLogisticsNo(), order.getConsigneeMobile(), from, to); } @Override @OrderLogPoint(description = "'订单['+#orderSn+']核销,核销码['+#verificationCode+']'", orderSn = "#orderSn") @Transactional(rollbackFor = Exception.class) public Order take(String orderSn, String verificationCode) { //获取订单信息 Order order = this.getBySn(orderSn); //检测虚拟订单信息 checkVerificationOrder(order, verificationCode); order.setOrderStatus(OrderStatusEnum.COMPLETED.name()); //订单完成 this.complete(orderSn); return order; } @Override public Order take(String verificationCode) { String storeId = OperationalJudgment.judgment(UserContext.getCurrentUser()).getStoreId(); Order order = this.getOne(new LambdaQueryWrapper().eq(Order::getVerificationCode, verificationCode).eq(Order::getStoreId, storeId)); if (order == null) { throw new ServiceException(ResultCode.ORDER_NOT_EXIST); } order.setOrderStatus(OrderStatusEnum.COMPLETED.name()); //订单完成 this.complete(order.getSn()); return order; } @Override public Order getOrderByVerificationCode(String verificationCode) { String storeId = Objects.requireNonNull(UserContext.getCurrentUser()).getStoreId(); Order order = this.getOne(new LambdaQueryWrapper() .in(Order::getOrderStatus, OrderStatusEnum.TAKE.name(), OrderStatusEnum.STAY_PICKED_UP.name()) .eq(Order::getStoreId, storeId) .eq(Order::getVerificationCode, verificationCode)); if (order == null) { throw new ServiceException(ResultCode.ORDER_TAKE_ERROR); } return order; } @Override @OrderLogPoint(description = "'订单['+#orderSn+']完成'", orderSn = "#orderSn") @Transactional(rollbackFor = Exception.class) public void complete(String orderSn) { //是否可以查询到订单 Order order = OperationalJudgment.judgment(this.getBySn(orderSn)); complete(order, orderSn); } @Override @OrderLogPoint(description = "'订单['+#orderSn+']完成'", orderSn = "#orderSn") @Transactional(rollbackFor = Exception.class) public void systemComplete(String orderSn) { Order order = this.getBySn(orderSn); complete(order, orderSn); } /** * 完成订单方法封装 * * @param order 订单 * @param orderSn 订单编号 */ @Transactional(rollbackFor = Exception.class) public void complete(Order order, String orderSn) {//修改订单状态为完成 this.updateStatus(orderSn, OrderStatusEnum.COMPLETED); //修改订单货物可以进行评价 orderItemService.update(new UpdateWrapper().eq(ORDER_SN_COLUMN, orderSn) .set("comment_status", CommentStatusEnum.UNFINISHED)); this.update(new LambdaUpdateWrapper().eq(Order::getSn, orderSn).set(Order::getCompleteTime, new Date())); //修改订单投诉状态 updateOrderComplainStatus(orderSn); //发送订单状态改变消息 OrderMessage orderMessage = new OrderMessage(); orderMessage.setNewStatus(OrderStatusEnum.COMPLETED); orderMessage.setOrderSn(order.getSn()); this.sendUpdateStatusMessage(orderMessage); //发送当前商品购买完成的信息(用于更新商品数据) List orderItems = orderItemService.getByOrderSn(orderSn); List goodsCompleteMessageList = new ArrayList<>(); for (OrderItem orderItem : orderItems) { GoodsCompleteMessage goodsCompleteMessage = new GoodsCompleteMessage(); goodsCompleteMessage.setGoodsId(orderItem.getGoodsId()); goodsCompleteMessage.setSkuId(orderItem.getSkuId()); goodsCompleteMessage.setBuyNum(orderItem.getNum()); goodsCompleteMessage.setMemberId(order.getMemberId()); goodsCompleteMessageList.add(goodsCompleteMessage); } //发送商品购买消息 if (!goodsCompleteMessageList.isEmpty()) { String destination = rocketmqCustomProperties.getGoodsTopic() + ":" + GoodsTagsEnum.BUY_GOODS_COMPLETE.name(); //发送订单变更mq消息 rocketMQTemplate.asyncSend(destination, JSONUtil.toJsonStr(goodsCompleteMessageList), RocketmqSendCallbackBuilder.commonCallback()); } } @Override public List getByTradeSn(String tradeSn) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); return this.list(queryWrapper.eq(Order::getTradeSn, tradeSn)); } @Override @Transactional(rollbackFor = Exception.class) public void sendUpdateStatusMessage(OrderMessage orderMessage) { applicationEventPublisher.publishEvent(new TransactionCommitSendMQEvent("发送订单变更mq消息", rocketmqCustomProperties.getOrderTopic(), OrderTagsEnum.STATUS_CHANGE.name(), JSONUtil.toJsonStr(orderMessage))); } @Override @Transactional(rollbackFor = Exception.class) public void deleteOrder(String sn) { Order order = this.getBySn(sn); if (order == null) { log.error("订单号为" + sn + "的订单不存在!"); throw new ServiceException(); } LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>(); updateWrapper.eq(Order::getSn, sn).set(Order::getDeleteFlag, true); this.update(updateWrapper); LambdaUpdateWrapper orderItemLambdaUpdateWrapper = new LambdaUpdateWrapper<>(); orderItemLambdaUpdateWrapper.eq(OrderItem::getOrderSn, sn).set(OrderItem::getDeleteFlag, true); this.orderItemService.update(orderItemLambdaUpdateWrapper); } @Override public Boolean invoice(String sn) { //根据订单号查询发票信息 Receipt receipt = receiptService.getByOrderSn(sn); //校验发票信息是否存在 if (receipt != null) { receipt.setReceiptStatus(1); return receiptService.updateById(receipt); } throw new ServiceException(ResultCode.USER_RECEIPT_NOT_EXIST); } /** * 自动成团订单处理 * * @param pintuanId 拼团活动id * @param parentOrderSn 拼团订单sn */ @Override @Transactional(rollbackFor = Exception.class) public void agglomeratePintuanOrder(String pintuanId, String parentOrderSn) { //获取拼团配置 Pintuan pintuan = pintuanService.getById(pintuanId); List list = this.getPintuanOrder(pintuanId, parentOrderSn); if (Boolean.TRUE.equals(pintuan.getFictitious()) && pintuan.getRequiredNum() > list.size()) { //如果开启虚拟成团且当前订单数量不足成团数量,则认为拼团成功 this.pintuanOrderSuccess(list); } else if (Boolean.FALSE.equals(pintuan.getFictitious()) && pintuan.getRequiredNum() > list.size()) { //如果未开启虚拟成团且当前订单数量不足成团数量,则认为拼团失败 this.pintuanOrderFailed(parentOrderSn); } } @Override public void getBatchDeliverList(HttpServletResponse response, List logisticsName) { ExcelWriter writer = ExcelUtil.getWriter(); //Excel 头部 ArrayList rows = new ArrayList<>(); rows.add("订单编号"); rows.add("物流公司"); rows.add("物流编号"); writer.writeHeadRow(rows); //存放下拉列表 ----店铺已选择物流公司列表 String[] logiList = logisticsName.toArray(new String[]{}); CellRangeAddressList cellRangeAddressList = new CellRangeAddressList(1, 200, 1, 1); writer.addSelect(cellRangeAddressList, logiList); ServletOutputStream out = null; try { //设置公共属性,列表名称 response.setContentType("application/vnd.ms-excel;charset=utf-8"); response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("批量发货导入模板", "UTF8") + ".xls"); out = response.getOutputStream(); writer.flush(out, true); } catch (Exception e) { log.error("获取待发货订单编号列表错误", e); } finally { writer.close(); IoUtil.close(out); } } @Override @Transactional(rollbackFor = Exception.class) public void batchDeliver(MultipartFile files) { InputStream inputStream; List orderBatchDeliverDTOList = new ArrayList<>(); try { inputStream = files.getInputStream(); //2.应用HUtool ExcelUtil获取ExcelReader指定输入流和sheet ExcelReader excelReader = ExcelUtil.getReader(inputStream); //可以加上表头验证 //3.读取第二行到最后一行数据 List> read = excelReader.read(1, excelReader.getRowCount()); for (List objects : read) { OrderBatchDeliverDTO orderBatchDeliverDTO = new OrderBatchDeliverDTO(); orderBatchDeliverDTO.setOrderSn(objects.get(0).toString()); orderBatchDeliverDTO.setLogisticsName(objects.get(1).toString()); orderBatchDeliverDTO.setLogisticsNo(objects.get(2).toString()); orderBatchDeliverDTOList.add(orderBatchDeliverDTO); } } catch (Exception e) { throw new ServiceException(ResultCode.ORDER_BATCH_DELIVER_ERROR); } //循环检查是否符合规范 checkBatchDeliver(orderBatchDeliverDTOList); //订单批量发货 for (OrderBatchDeliverDTO orderBatchDeliverDTO : orderBatchDeliverDTOList) { this.delivery(orderBatchDeliverDTO.getOrderSn(), orderBatchDeliverDTO.getLogisticsNo(), orderBatchDeliverDTO.getLogisticsId()); } } @Override public Double getPaymentTotal(String orderSn) { Order order = this.getBySn(orderSn); Trade trade = tradeService.getBySn(order.getTradeSn()); //如果交易不为空,则返回交易的金额,否则返回订单金额 if (CharSequenceUtil.isNotEmpty(trade.getPayStatus()) && trade.getPayStatus().equals(PayStatusEnum.PAID.name())) { return trade.getFlowPrice(); } return order.getFlowPrice(); } @Override public IPage queryPaymentLogs(IPage page, Wrapper queryWrapper) { return baseMapper.queryPaymentLogs(page, queryWrapper); } /** * 循环检查批量发货订单列表 * * @param list 待发货订单列表 */ private void checkBatchDeliver(List list) { List logistics = logisticsService.list(); for (OrderBatchDeliverDTO orderBatchDeliverDTO : list) { //查看订单号是否存在-是否是当前店铺的订单 Order order = this.getOne(new LambdaQueryWrapper() .eq(Order::getStoreId, UserContext.getCurrentUser().getStoreId()) .eq(Order::getSn, orderBatchDeliverDTO.getOrderSn())); if (order == null) { throw new ServiceException("订单编号:'" + orderBatchDeliverDTO.getOrderSn() + " '不存在"); } else if (!order.getOrderStatus().equals(OrderStatusEnum.UNDELIVERED.name())) { throw new ServiceException("订单编号:'" + orderBatchDeliverDTO.getOrderSn() + " '不能发货"); } //获取物流公司 logistics.forEach(item -> { if (item.getName().equals(orderBatchDeliverDTO.getLogisticsName())) { orderBatchDeliverDTO.setLogisticsId(item.getId()); } }); if (CharSequenceUtil.isEmpty(orderBatchDeliverDTO.getLogisticsId())) { throw new ServiceException("物流公司:'" + orderBatchDeliverDTO.getLogisticsName() + " '不存在"); } } } /** * 检查是否开始虚拟成团 * * @param pintuanId 拼团活动id * @param requiredNum 成团人数 * @param fictitious 是否开启成团 * @return 是否成功 */ @Override @Transactional(rollbackFor = Exception.class) public boolean checkFictitiousOrder(String pintuanId, Integer requiredNum, Boolean fictitious) { Map> collect = this.queryListByPromotion(pintuanId) .stream().collect(Collectors.groupingBy(Order::getParentOrderSn)); for (Map.Entry> entry : collect.entrySet()) { //是否开启虚拟成团 if (Boolean.FALSE.equals(fictitious) && CharSequenceUtil.isNotEmpty(entry.getKey()) && entry.getValue().size() < requiredNum) { //如果未开启虚拟成团且已参团人数小于成团人数,则自动取消订单 String reason = "拼团活动结束订单未付款,系统自动取消订单"; if (CharSequenceUtil.isNotEmpty(entry.getKey())) { this.systemCancel(entry.getKey(), reason, true); } else { for (Order order : entry.getValue()) { if (!CharSequenceUtil.equalsAny(order.getOrderStatus(), OrderStatusEnum.COMPLETED.name(), OrderStatusEnum.DELIVERED.name(), OrderStatusEnum.TAKE.name(), OrderStatusEnum.STAY_PICKED_UP.name())) { this.systemCancel(order.getSn(), reason, true); } } } } else if (Boolean.TRUE.equals(fictitious)) { this.fictitiousPintuan(entry, requiredNum); } } return false; } @Override public Order partDelivery(PartDeliveryParamsDTO partDeliveryParamsDTO) { String logisticsId = partDeliveryParamsDTO.getLogisticsId(); String orderSn = partDeliveryParamsDTO.getOrderSn(); String invoiceNumber = partDeliveryParamsDTO.getLogisticsNo(); //获取对应物流 Logistics logistics = logisticsService.getById(logisticsId); if (logistics == null) { throw new ServiceException(ResultCode.ORDER_LOGISTICS_ERROR); } Order order = OperationalJudgment.judgment(this.getBySn(orderSn)); List orderItemList = orderItemService.getByOrderSn(orderSn); OrderPackage orderPackage = new OrderPackage(); orderPackage.setPackageNo(SnowFlake.createStr("OP")); orderPackage.setOrderSn(orderSn); orderPackage.setLogisticsNo(invoiceNumber); orderPackage.setLogisticsCode(logistics.getCode()); orderPackage.setLogisticsName(logistics.getName()); orderPackage.setStatus("1"); orderPackage.setConsigneeMobile(order.getConsigneeMobile()); orderPackageService.save(orderPackage); List orderLogList = new ArrayList<>(); for (PartDeliveryDTO partDeliveryDTO : partDeliveryParamsDTO.getPartDeliveryDTOList()) { for (OrderItem orderItem : orderItemList) { //寻找订单货物进行判断 if (partDeliveryDTO.getOrderItemId().equals(orderItem.getId())) { if ((partDeliveryDTO.getDeliveryNum() + orderItem.getDeliverNumber()) > orderItem.getNum()) { throw new ServiceException("发货数量不正确!"); } orderItem.setDeliverNumber((partDeliveryDTO.getDeliveryNum() + orderItem.getDeliverNumber())); // 记录分包裹中每个item子单的具体发货信息 OrderPackageItem orderPackageItem = new OrderPackageItem(); orderPackageItem.setOrderSn(orderSn); orderPackageItem.setPackageNo(orderPackage.getPackageNo()); orderPackageItem.setOrderItemSn(orderItem.getSn()); orderPackageItem.setDeliverNumber(partDeliveryDTO.getDeliveryNum()); orderPackageItem.setLogisticsTime(new Date()); orderPackageItem.setGoodsName(orderItem.getGoodsName()); orderPackageItem.setThumbnail(orderItem.getImage()); orderPackageItemService.save(orderPackageItem); OrderLog orderLog = new OrderLog(orderSn, UserContext.getCurrentUser().getId(), UserContext.getCurrentUser().getRole().getRole(), UserContext.getCurrentUser().getUsername(), "订单 [ " + orderSn + " ]商品" + " [ " + orderItem.getGoodsName() + " ]发货,发货数量: [ " + partDeliveryDTO.getDeliveryNum() + " ],发货单号[ " + invoiceNumber + " ]"); orderLogList.add(orderLog); } } } //修改订单货物 orderItemService.updateBatchById(orderItemList); orderLogService.saveBatch(orderLogList); //判断订单货物是否全部发货完毕 Boolean delivery = true; for (OrderItem orderItem : orderItemList) { if (orderItem.getDeliverNumber() < orderItem.getNum()) { delivery = false; break; } } //是否全部发货 if (delivery) { return delivery(orderSn, invoiceNumber, logisticsId); } return order; } @Override public Order updateSellerRemark(String orderSn, String sellerRemark) { Order order = this.getBySn(orderSn); order.setSellerRemark(sellerRemark); this.updateById(order); return order; } /** * 虚拟成团 * * @param entry 订单列表 * @param requiredNum 必须参团人数 */ @Transactional(rollbackFor = Exception.class) public void fictitiousPintuan(Map.Entry> entry, Integer requiredNum) { Map> listMap = entry.getValue().stream().collect(Collectors.groupingBy(Order::getPayStatus)); //未付款订单 List unpaidOrders = listMap.get(PayStatusEnum.UNPAID.name()); //未付款订单自动取消 if (unpaidOrders != null && !unpaidOrders.isEmpty()) { for (Order unpaidOrder : unpaidOrders) { this.systemCancel(unpaidOrder.getSn(), "拼团活动结束订单未付款,系统自动取消订单", false); } } List paidOrders = listMap.get(PayStatusEnum.PAID.name()); //如待参团人数大于0,并已开启虚拟成团 if (!paidOrders.isEmpty()) { //待参团人数 int waitNum = requiredNum - paidOrders.size(); //添加虚拟成团 for (int i = 0; i < waitNum; i++) { Order order = new Order(); BeanUtil.copyProperties(paidOrders.get(0), order, "id", "sn"); order.setSn(SnowFlake.createStr("G")); order.setParentOrderSn(paidOrders.get(0).getParentOrderSn()); order.setMemberId("-1"); order.setMemberName("参团人员"); order.setDeleteFlag(true); this.save(order); paidOrders.add(order); } for (Order paidOrder : paidOrders) { if (!CharSequenceUtil.equalsAny(paidOrder.getOrderStatus(), OrderStatusEnum.COMPLETED.name(), OrderStatusEnum.DELIVERED.name(), OrderStatusEnum.TAKE.name(), OrderStatusEnum.STAY_PICKED_UP.name())) { if (OrderTypeEnum.NORMAL.name().equals(paidOrder.getOrderType())) { paidOrder.setOrderStatus(OrderStatusEnum.UNDELIVERED.name()); } else if (OrderTypeEnum.VIRTUAL.name().equals(paidOrder.getOrderType())) { paidOrder.setOrderStatus(OrderStatusEnum.TAKE.name()); } this.updateById(paidOrder); orderStatusMessage(paidOrder); } } } } /** * 订单状态变更消息 * * @param order 订单信息 */ @Transactional(rollbackFor = Exception.class) public void orderStatusMessage(Order order) { OrderMessage orderMessage = new OrderMessage(); orderMessage.setOrderSn(order.getSn()); orderMessage.setNewStatus(OrderStatusEnum.valueOf(order.getOrderStatus())); this.sendUpdateStatusMessage(orderMessage); } // /** // * 生成店铺退款流水 // * // * @param order 订单信息 // */ // private void generatorStoreRefundFlow(Order order) { // // 判断订单是否是付款 // if (!PayStatusEnum.PAID.name().equals((order.getPayStatus()))) { // return; // } // List items = orderItemService.getByOrderSn(order.getSn()); // List storeFlows = new ArrayList<>(); // for (OrderItem item : items) { // StoreFlow storeFlow = new StoreFlow(order, item, FlowTypeEnum.REFUND); // storeFlows.add(storeFlow); // } // storeFlowService.saveBatch(storeFlows); // } /** * 此方法只提供内部调用,调用前应该做好权限处理 * 修改订单状态 * * @param orderSn 订单编号 * @param orderStatus 订单状态 */ private void updateStatus(String orderSn, OrderStatusEnum orderStatus) { this.baseMapper.updateStatus(orderStatus.name(), orderSn); } /** * 检测拼团订单内容 * 此方法用与订单确认 * 判断拼团是否达到人数进行下一步处理 * * @param pintuanId 拼团活动ID * @param parentOrderSn 拼团父订单编号 */ @Transactional(rollbackFor = Exception.class) public void checkPintuanOrder(String pintuanId, String parentOrderSn) { //获取拼团配置 Pintuan pintuan = pintuanService.getById(pintuanId); List list = this.getPintuanOrder(pintuanId, parentOrderSn); int count = list.size(); if (count == 1) { //如果为开团订单,则发布一个24小时的延时任务,时间到达后,如果未成团则自动结束(未开启虚拟成团的情况下) PintuanOrderMessage pintuanOrderMessage = new PintuanOrderMessage(); //开团结束时间 long startTime = DateUtil.offsetHour(new Date(), 24).getTime(); if (DateUtil.compare(DateUtil.offsetHour(pintuan.getStartTime(), 24), pintuan.getEndTime()) > 0) { startTime = pintuan.getEndTime().getTime(); } pintuanOrderMessage.setOrderSn(parentOrderSn); pintuanOrderMessage.setPintuanId(pintuanId); TimeTriggerMsg timeTriggerMsg = new TimeTriggerMsg(TimeExecuteConstant.PROMOTION_EXECUTOR, startTime, pintuanOrderMessage, DelayQueueTools.wrapperUniqueKey(DelayTypeEnums.PINTUAN_ORDER, (pintuanId + parentOrderSn)), rocketmqCustomProperties.getPromotionTopic()); this.timeTrigger.addDelay(timeTriggerMsg); } //拼团所需人数,小于等于 参团后的人数,则说明成团,所有订单成团 if (pintuan.getRequiredNum() <= count) { this.pintuanOrderSuccess(list); } } /** * 根据拼团活动id和拼团订单sn获取所有当前与当前拼团订单sn相关的订单 * * @param pintuanId 拼团活动id * @param parentOrderSn 拼团订单sn * @return 所有当前与当前拼团订单sn相关的订单 */ private List getPintuanOrder(String pintuanId, String parentOrderSn) { //寻找拼团的所有订单 LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(Order::getPromotionId, pintuanId) .eq(Order::getOrderPromotionType, OrderPromotionTypeEnum.PINTUAN.name()) .eq(Order::getPayStatus, PayStatusEnum.PAID.name()); //拼团sn=开团订单sn 或者 参团订单的开团订单sn queryWrapper.and(i -> i.eq(Order::getSn, parentOrderSn) .or(j -> j.eq(Order::getParentOrderSn, parentOrderSn))); queryWrapper.ne(Order::getOrderStatus, OrderStatusEnum.CANCELLED.name()); //参团后的订单数(人数) return this.list(queryWrapper); } /** * 根据提供的拼团订单列表更新拼团状态为拼团成功 * 循环订单列表根据不同的订单类型进行确认订单 * * @param orderList 需要更新拼团状态为成功的拼团订单列表 */ @Transactional(rollbackFor = Exception.class) public void pintuanOrderSuccess(List orderList) { for (Order order : orderList) { if (order.getOrderType().equals(OrderTypeEnum.VIRTUAL.name())) { this.virtualOrderConfirm(order.getSn()); } else if (order.getOrderType().equals(OrderTypeEnum.NORMAL.name())) { this.normalOrderConfirm(order.getSn()); } } } /** * 根据提供的拼团订单列表更新拼团状态为拼团失败 * * @param parentOrderSn 拼团订单sn */ private void pintuanOrderFailed(String parentOrderSn) { List list = this.list(new LambdaQueryWrapper().eq(Order::getParentOrderSn, parentOrderSn).or().eq(Order::getSn, parentOrderSn)); for (Order order : list) { try { this.systemCancel(order.getSn(), "拼团人数不足,拼团失败!", true); } catch (Exception e) { log.error("拼团订单取消失败", e); } } } /** * 检查交易信息 * * @param tradeDTO 交易DTO */ private void checkTradeDTO(TradeDTO tradeDTO) { //检测是否为拼团订单 if (tradeDTO.getParentOrderSn() != null) { //判断用户不能参与自己发起的拼团活动 Order parentOrder = this.getBySn(tradeDTO.getParentOrderSn()); if (parentOrder.getMemberId().equals(UserContext.getCurrentUser().getId())) { throw new ServiceException(ResultCode.PINTUAN_JOIN_ERROR); } } } /** * 普通商品订单确认 * 修改订单状态为待发货 * 发送订单状态变更消息 * * @param orderSn 订单编号 */ @Transactional(rollbackFor = Exception.class) public void normalOrderConfirm(String orderSn) { OrderStatusEnum orderStatusEnum = null; Order order = this.getBySn(orderSn); if (DeliveryMethodEnum.SELF_PICK_UP.name().equals(order.getDeliveryMethod())) { orderStatusEnum = OrderStatusEnum.STAY_PICKED_UP; } else if (DeliveryMethodEnum.LOGISTICS.name().equals(order.getDeliveryMethod())) { orderStatusEnum = OrderStatusEnum.UNDELIVERED; } //修改订单 this.update(new LambdaUpdateWrapper() .eq(Order::getSn, orderSn) .set(Order::getOrderStatus, orderStatusEnum.name())); //修改订单 OrderMessage orderMessage = new OrderMessage(); orderMessage.setNewStatus(orderStatusEnum); orderMessage.setOrderSn(orderSn); this.sendUpdateStatusMessage(orderMessage); } /** * 虚拟商品订单确认 * 修改订单状态为待核验 * 发送订单状态变更消息 * * @param orderSn 订单编号 */ @Transactional(rollbackFor = Exception.class) public void virtualOrderConfirm(String orderSn) { //修改订单 this.update(new LambdaUpdateWrapper() .eq(Order::getSn, orderSn) .set(Order::getOrderStatus, OrderStatusEnum.TAKE.name())); OrderMessage orderMessage = new OrderMessage(); orderMessage.setNewStatus(OrderStatusEnum.TAKE); orderMessage.setOrderSn(orderSn); this.sendUpdateStatusMessage(orderMessage); } /** * 检测虚拟订单信息 * * @param order 订单 * @param verificationCode 验证码 */ private void checkVerificationOrder(Order order, String verificationCode) { //判断查询是否可以查询到订单 if (order == null) { throw new ServiceException(ResultCode.ORDER_NOT_EXIST); } //判断是否为虚拟订单 或 自提订单 if (!order.getOrderType().equals(OrderTypeEnum.VIRTUAL.name()) && !order.getDeliveryMethod().equals(DeliveryMethodEnum.SELF_PICK_UP.name())) { throw new ServiceException(ResultCode.ORDER_TAKE_ERROR); } //判断虚拟订单状态 或 待自提 if (!order.getOrderStatus().equals(OrderStatusEnum.TAKE.name()) && !order.getOrderStatus().equals(OrderStatusEnum.STAY_PICKED_UP.name())) { throw new ServiceException(ResultCode.ORDER_TAKE_ERROR); } //判断验证码是否正确 if (!verificationCode.equals(order.getVerificationCode())) { throw new ServiceException(ResultCode.ORDER_TAKE_ERROR); } } /** * 根据订单设置修改订单投诉状态 * * @param orderSn */ private void updateOrderComplainStatus(String orderSn) { Setting setting = settingService.get(SettingEnum.ORDER_SETTING.name()); //订单设置 OrderSetting orderSetting = JSONUtil.toBean(setting.getSettingValue(), OrderSetting.class); if (orderSetting == null) { return; } //设置投诉天数大于0 则走每日定时任务处理,=0 则即可关闭订单的投诉状态 if (orderSetting.getCloseComplaint() > 0) { return; } //关闭订单投诉状态 LambdaUpdateWrapper lambdaUpdateWrapper = new LambdaUpdateWrapper() .eq(OrderItem::getOrderSn, orderSn) .set(OrderItem::getComplainStatus, OrderComplaintStatusEnum.EXPIRED.name()); orderItemService.update(lambdaUpdateWrapper); } /** * 初始化填充订单导出数据 * * @param orderExportDTOList 导出的订单数据 * @return 订单导出列表 */ private XSSFWorkbook initOrderExportData(List orderExportDTOList) { List orderExportDetailDTOList = new ArrayList<>(); for (OrderExportDTO orderExportDTO : orderExportDTOList) { OrderExportDetailDTO orderExportDetailDTO = new OrderExportDetailDTO(); BeanUtil.copyProperties(orderExportDTO, orderExportDetailDTO); //金额 PriceDetailDTO priceDetailDTO = JSONUtil.toBean(orderExportDTO.getPriceDetail(), PriceDetailDTO.class); orderExportDetailDTO.setFreightPrice(priceDetailDTO.getFreightPrice()); orderExportDetailDTO.setDiscountPrice(CurrencyUtil.add(priceDetailDTO.getDiscountPrice(), priceDetailDTO.getCouponPrice())); orderExportDetailDTO.setUpdatePrice(priceDetailDTO.getUpdatePrice()); orderExportDetailDTO.setStoreMarketingCost(priceDetailDTO.getSiteCouponCommission()); orderExportDetailDTO.setSiteMarketingCost(CurrencyUtil.sub(orderExportDetailDTO.getDiscountPrice(), orderExportDetailDTO.getStoreMarketingCost())); //地址 if (StrUtil.isNotBlank(orderExportDTO.getConsigneeAddressPath())) { String[] receiveAddress = orderExportDTO.getConsigneeAddressPath().split(","); orderExportDetailDTO.setProvince(receiveAddress[0]); orderExportDetailDTO.setCity(receiveAddress.length > 1 ?receiveAddress[1]:""); orderExportDetailDTO.setDistrict(receiveAddress.length > 2 ? receiveAddress[2] : ""); orderExportDetailDTO.setStreet(receiveAddress.length > 3 ? receiveAddress[3] : ""); } //状态 orderExportDetailDTO.setOrderStatus(OrderStatusEnum.valueOf(orderExportDTO.getOrderStatus()).description()); orderExportDetailDTO.setPaymentMethod(CharSequenceUtil.isNotBlank(orderExportDTO.getPaymentMethod()) ? PaymentMethodEnum.valueOf(orderExportDTO.getPaymentMethod()).paymentName() : ""); orderExportDetailDTO.setClientType(ClientTypeEnum.valueOf(orderExportDTO.getClientType()).value()); orderExportDetailDTO.setOrderType(orderExportDTO.getOrderType().equals(OrderTypeEnum.NORMAL.name()) ? "普通订单" : "虚拟订单"); orderExportDetailDTO.setAfterSaleStatus(OrderItemAfterSaleStatusEnum.valueOf(orderExportDTO.getAfterSaleStatus()).description()); //时间 orderExportDetailDTO.setCreateTime(DateUtil.formatDateTime(orderExportDTO.getCreateTime())); orderExportDetailDTO.setPaymentTime(DateUtil.formatDateTime(orderExportDTO.getPaymentTime())); orderExportDetailDTO.setLogisticsTime(DateUtil.formatDateTime(orderExportDTO.getLogisticsTime())); orderExportDetailDTO.setCompleteTime(DateUtil.formatDateTime(orderExportDTO.getCompleteTime())); orderExportDetailDTOList.add(orderExportDetailDTO); } XSSFWorkbook workbook = new XSSFWorkbook(); Sheet sheet = workbook.createSheet("订单列表"); // 创建表头 Row header = sheet.createRow(0); String[] headers = {"主订单编号", "子订单编号", "选购商品", "商品数量", "商品ID", "商品单价", "订单应付金额", "运费", "优惠总金额", "平台优惠", "商家优惠", "商家改价", "支付方式", "收件人", "收件人手机号", "省", "市", "区", "街道", "详细地址", "买家留言", "订单提交时间", "支付完成时间", "来源", "订单状态", "订单类型", "售后状态", "取消原因", "发货时间", "完成时间", "店铺"}; for (int i = 0; i < headers.length; i++) { Cell cell = header.createCell(i); cell.setCellValue(headers[i]); } // 填充数据 for (int i = 0; i < orderExportDetailDTOList.size(); i++) { OrderExportDetailDTO dto = orderExportDetailDTOList.get(i); Row row = sheet.createRow(i + 1); row.createCell(0).setCellValue(dto.getOrderSn()); row.createCell(1).setCellValue(dto.getOrderItemSn()); row.createCell(2).setCellValue(dto.getGoodsName()); row.createCell(3).setCellValue(dto.getNum()); row.createCell(4).setCellValue(dto.getGoodsId()); row.createCell(5).setCellValue(dto.getUnitPrice()!=null?dto.getUnitPrice():0); row.createCell(6).setCellValue(dto.getFlowPrice()!=null?dto.getFlowPrice():0); row.createCell(7).setCellValue(dto.getFreightPrice()!=null?dto.getFreightPrice():0); row.createCell(8).setCellValue(dto.getDiscountPrice()!=null?dto.getDiscountPrice():0); row.createCell(9).setCellValue(dto.getSiteMarketingCost()!=null?dto.getSiteMarketingCost():0); row.createCell(10).setCellValue(dto.getStoreMarketingCost()!=null?dto.getStoreMarketingCost():0); row.createCell(11).setCellValue(dto.getUpdatePrice()!=null?dto.getUpdatePrice():0); row.createCell(12).setCellValue(dto.getPaymentMethod()); row.createCell(13).setCellValue(dto.getConsigneeName()); row.createCell(14).setCellValue(dto.getConsigneeMobile()); row.createCell(15).setCellValue(dto.getProvince()); row.createCell(16).setCellValue(dto.getCity()); row.createCell(17).setCellValue(dto.getDistrict()); row.createCell(18).setCellValue(dto.getStreet()); row.createCell(19).setCellValue(dto.getConsigneeDetail()); row.createCell(20).setCellValue(dto.getRemark()); row.createCell(21).setCellValue(dto.getCreateTime()); row.createCell(22).setCellValue(dto.getPaymentTime()); row.createCell(23).setCellValue(dto.getClientType()); row.createCell(24).setCellValue(dto.getOrderStatus()); row.createCell(25).setCellValue(dto.getOrderType()); row.createCell(26).setCellValue(dto.getAfterSaleStatus()); row.createCell(27).setCellValue(dto.getCancelReason()); row.createCell(28).setCellValue(dto.getLogisticsTime()); row.createCell(29).setCellValue(dto.getCompleteTime()); row.createCell(30).setCellValue(dto.getStoreName()); } //修改列宽 // sheet.setColumnWidth(0, 30 * 256); // sheet.setColumnWidth(1, 30 * 256); // sheet.setColumnWidth(2, 30 * 256); // sheet.setColumnWidth(3, 8 * 256); // sheet.setColumnWidth(4, 20 * 256); // sheet.setColumnWidth(5, 10 * 256); // sheet.setColumnWidth(6, 10 * 256); // sheet.setColumnWidth(7, 10 * 256); // sheet.setColumnWidth(8, 10 * 256); // sheet.setColumnWidth(9, 10 * 256); // sheet.setColumnWidth(10, 10 * 256); // sheet.setColumnWidth(11, 10 * 256); // sheet.setColumnWidth(12, 10 * 256); // sheet.setColumnWidth(13, 10 * 256); // sheet.setColumnWidth(14, 16 * 256); // sheet.setColumnWidth(15, 10 * 256); // sheet.setColumnWidth(16, 10 * 256); // sheet.setColumnWidth(17, 10 * 256); // sheet.setColumnWidth(18, 10 * 256); // sheet.setColumnWidth(19, 30 * 256); // sheet.setColumnWidth(20, 20 * 256); // sheet.setColumnWidth(21, 20 * 256); // sheet.setColumnWidth(22, 20 * 256); // sheet.setColumnWidth(23, 10 * 256); // sheet.setColumnWidth(24, 10 * 256); // sheet.setColumnWidth(25, 10 * 256); // sheet.setColumnWidth(26, 10 * 256); // sheet.setColumnWidth(27, 20 * 256); // sheet.setColumnWidth(28, 20 * 256); // sheet.setColumnWidth(29, 20 * 256); // sheet.setColumnWidth(30, 20 * 256); return workbook; } }