guomengjiao před 4 měsíci
rodič
revize
0bba315a4a

+ 7 - 80
ruoyi-admin/src/main/java/com/ruoyi/web/controller/shop/order/ShopOrderController.java

@@ -21,16 +21,9 @@ import com.ruoyi.common.core.validate.QueryGroup;
 import com.ruoyi.common.enums.BusinessType;
 import com.ruoyi.common.enums.FilePathSplicingType;
 import com.ruoyi.common.enums.order.OrderType;
-import com.ruoyi.common.exception.ServiceException;
+import com.ruoyi.common.excel.ExcelResult;
 import com.ruoyi.common.filepathsplicing.FilePathSplicing;
-import com.ruoyi.common.utils.importverify.ImportVerifyHandler;
 import com.ruoyi.common.utils.poi.ExcelUtil;
-import com.ruoyi.common.utils.poi.ImportUtil;
-import com.ruoyi.message.domain.bo.MessageBo;
-import com.ruoyi.message.enums.MessageType;
-import com.ruoyi.message.enums.ModelType;
-import com.ruoyi.message.service.ISendPrivateMessageMsgService;
-import com.ruoyi.shop.order.domain.ShopOrderPackage;
 import com.ruoyi.shop.order.domain.bo.BusinessCountBo;
 import com.ruoyi.shop.order.domain.bo.ShopOrderBo;
 import com.ruoyi.shop.order.domain.bo.ShopOrderBusinessRemarkBo;
@@ -39,20 +32,16 @@ import com.ruoyi.shop.order.enums.CancellationMethod;
 import com.ruoyi.shop.order.enums.ShippingMethod;
 import com.ruoyi.shop.order.enums.ShippingStatus;
 import com.ruoyi.shop.order.enums.TransactionStatus;
-import com.ruoyi.shop.order.service.IShopOrderPackageService;
 import com.ruoyi.shop.order.service.IShopOrderService;
-import com.ruoyi.shop.order.service.mqproduct.IShopOrderMqProductService;
+import com.ruoyi.shop.order.service.ShopOrderWaitShipImportListener;
 import com.ruoyi.shop.rights.service.ISaleRightsOrderService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import io.swagger.annotations.ApiParam;
-import jodd.util.StringUtil;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
-import org.apache.commons.lang3.StringUtils;
 import org.apache.poi.ss.usermodel.Workbook;
 import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
-import org.springframework.util.CollectionUtils;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
@@ -64,7 +53,8 @@ import java.io.IOException;
 import java.math.BigDecimal;
 import java.net.URLEncoder;
 import java.util.*;
-import java.util.concurrent.*;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
 import java.util.stream.Collectors;
 
 /**
@@ -85,11 +75,6 @@ public class ShopOrderController extends BaseController {
     private final ISaleRightsOrderService rightsOrderService;
     private final IBusinessService iBusinessService;
     private final ThreadPoolTaskExecutor threadPoolTaskExecutor;
-    private final ImportVerifyHandler importVerifyHandler;
-    private final ThreadPoolExecutor executor;
-    private final IShopOrderPackageService shopOrderPackageService;
-    private final IShopOrderMqProductService shopOrderMqProductService;
-    private final ISendPrivateMessageMsgService sendPrivateMessageMsgService;
 
     /**
      * 平台分页查询订单列表
@@ -598,73 +583,15 @@ public class ShopOrderController extends BaseController {
     /**
      * 导入设置好的发货订单文件,批量发货
      * @param multipartFile
-     * @param response
      * @return
      * @throws Exception
      */
     @PostMapping("/import_ship")
-    public R importUser(@RequestParam("file") MultipartFile multipartFile, HttpServletResponse response) throws Exception {
+    public R<Void> importShip(@RequestParam("file") MultipartFile multipartFile) throws Exception {
         Long businessId = getBusinessId(true);
         //获得excel中的数据
-        Map<String, Object> map = ImportUtil.importExcel(1, 1, ShopOrderWaitShipVo.class, importVerifyHandler, multipartFile, true);
-        List<ShopOrderWaitShipVo> importList = (List<ShopOrderWaitShipVo>) map.get("success");
-        // 创建 Future 集合,用来存储 Future 实例
-        List<Future<ShopOrderWaitShipVo>> futureList = new ArrayList<>();
-        if (!CollectionUtils.isEmpty(importList)) {
-            if (importList.size() > 0) {
-                importList.forEach(importRow -> {
-                    if (StringUtils.isNotEmpty(importRow.getLogisticCode())) {
-                        //批量导入数据库
-                        Future<ShopOrderWaitShipVo> future = executor.submit(new Callable<ShopOrderWaitShipVo>() {
-                            @Override
-                            public ShopOrderWaitShipVo call() throws Exception {
-                                if (StringUtils.isEmpty(importRow.getLogisticCode())) {
-                                    importRow.setErrorMsg("运单号没有填");
-                                    return importRow;
-                                }
-                                try {
-                                    ShopOrderPackage shopOrderPackage = shopOrderPackageService.expressShipForImport(businessId, importRow);
-                                    try
-                                    {
-                                        // 发送自动收货消息
-                                        shopOrderMqProductService.orderPackageReceivingMqProductSend(shopOrderPackage.getPackageId());
-                                        // 发送物流消息
-                                        sendPrivateMessageMsgService.send(new MessageBo(MessageType.LOGISTICS_MESSAGE,
-                                            ModelType.LOGISTICS, shopOrderPackage.getPackageId()));
-                                    }
-                                    catch (Exception e)
-                                    {
-                                        log.error("MQ发送自动收货消息失败", e);
-                                    }
-                                } catch (Exception ex) {
-                                    importRow.setErrorMsg(ex.getMessage());
-                                    return importRow;
-                                }
-                                return null;
-                            }
-                        });
-                        futureList.add(future);
-                    }
-                });
-                List<ShopOrderWaitShipVo> resultList = new ArrayList<>();
-                for (Future<ShopOrderWaitShipVo> future : futureList) {
-                    // 获取每一个线程的返回结果,如果该线程未完成,会阻塞
-                    ShopOrderWaitShipVo vo = future.get(30, TimeUnit.SECONDS);
-                    if (vo != null) {
-                        resultList.add(vo);
-                    }
-                }
-                StringBuffer sbf = new StringBuffer();
-                resultList.forEach(e ->
-                {
-                    sbf.append("第" + (e.getRowNum() + 1) + "行存在错误:" + e.getErrorMsg()+"");
-                });
-                if (StringUtil.isNotEmpty(sbf.toString())) {
-                    throw new ServiceException(sbf.toString());
-                }
-            }
-        }
-        return R.ok();
+        ExcelResult<ShopOrderWaitShipVo> result = ExcelUtil.importExcel(multipartFile.getInputStream(), ShopOrderWaitShipVo.class, new ShopOrderWaitShipImportListener(businessId));
+        return R.ok(result.getAnalysis());
     }
 
     /**

+ 0 - 44
ruoyi-common/src/main/java/com/ruoyi/common/utils/importverify/BaseImportDto.java

@@ -1,44 +0,0 @@
-/**
- * Copyright (c) 2016-2019 人人开源 All rights reserved.
- * <p>
- * https://www.renren.io
- * <p>
- * 版权所有,侵权必究!
- */
-
-package com.ruoyi.common.utils.importverify;
-
-import cn.afterturn.easypoi.handler.inter.IExcelDataModel;
-import cn.afterturn.easypoi.handler.inter.IExcelModel;
-import lombok.Data;
-
-
-/**
- * 系统日志
- *
- * @author Mark sunlightcs@gmail.com
- */
-@Data
-public class BaseImportDto implements IExcelDataModel, IExcelModel {
-
-
-    @Override
-    public Integer getRowNum() {
-        return null;
-    }
-
-    @Override
-    public void setRowNum(Integer rowNum) {
-
-    }
-
-    @Override
-    public String getErrorMsg() {
-        return null;
-    }
-
-    @Override
-    public void setErrorMsg(String errorMsg) {
-
-    }
-}

+ 0 - 45
ruoyi-common/src/main/java/com/ruoyi/common/utils/importverify/ImportVerifyHandler.java

@@ -1,45 +0,0 @@
-package com.ruoyi.common.utils.importverify;
-
-import cn.afterturn.easypoi.excel.entity.result.ExcelVerifyHandlerResult;
-import cn.afterturn.easypoi.handler.inter.IExcelVerifyHandler;
-import org.springframework.stereotype.Component;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.StringJoiner;
-
-@Component
-public class ImportVerifyHandler implements IExcelVerifyHandler<BaseImportDto> {
-
-    private final ThreadLocal<List<BaseImportDto>> threadLocal = new ThreadLocal<>();
-
-    @Override
-    public ExcelVerifyHandlerResult verifyHandler(BaseImportDto inputEntity) {
-        StringJoiner joiner = new StringJoiner(",");
-
-        List<BaseImportDto> threadLocalVal = threadLocal.get();
-        if (threadLocalVal == null) {
-            threadLocalVal = new ArrayList<>();
-        }
-
-        for (BaseImportDto dto:threadLocalVal) {
-            if (dto.equals(inputEntity)) {
-                int lineNumber = dto.getRowNum() + 1;
-                joiner.add("数据与第" + lineNumber + "行重复");
-                break;
-            }
-        }
-
-        // 添加本行数据对象到ThreadLocal中
-        threadLocalVal.add(inputEntity);
-        threadLocal.set(threadLocalVal);
-        if (joiner.length() != 0) {
-            return new ExcelVerifyHandlerResult(false, joiner.toString());
-        }
-        return new ExcelVerifyHandlerResult(true);
-    }
-
-    public ThreadLocal<List<BaseImportDto>> getThreadLocal() {
-        return threadLocal;
-    }
-}

+ 0 - 26
ruoyi-framework/src/main/java/com/ruoyi/framework/config/properties/ThreadConfig.java

@@ -1,26 +0,0 @@
-package com.ruoyi.framework.config.properties;
-
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-import java.util.concurrent.Executors;
-import java.util.concurrent.LinkedBlockingDeque;
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
-
-/**
- * 线程池
- */
-@Configuration
-public class ThreadConfig {
-    @Bean
-    public ThreadPoolExecutor threadPoolExecutor(ThreadPoolProperties poolProperties) {
-        return new ThreadPoolExecutor(poolProperties.getCorePoolSize(),
-                poolProperties.getMaxPoolSize(),
-                poolProperties.getKeepAliveSeconds(),
-                TimeUnit.SECONDS,
-                new LinkedBlockingDeque<>(poolProperties.getQueueCapacity()),
-                Executors.defaultThreadFactory(),
-                new ThreadPoolExecutor.AbortPolicy());
-    }
-}

+ 2 - 4
ruoyi-shop/src/main/java/com/ruoyi/shop/order/domain/vo/ShopOrderWaitShipVo.java

@@ -2,20 +2,18 @@ package com.ruoyi.shop.order.domain.vo;
 
 import cn.afterturn.easypoi.excel.annotation.Excel;
 import cn.afterturn.easypoi.excel.annotation.ExcelTarget;
-import cn.afterturn.easypoi.handler.inter.IExcelDataModel;
-import cn.afterturn.easypoi.handler.inter.IExcelModel;
 import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
 import com.alibaba.excel.annotation.ExcelProperty;
 import com.ruoyi.common.annotation.ExcelDictFormat;
 import com.ruoyi.common.convert.ExcelDateTimeConvert;
 import com.ruoyi.common.convert.ExcelEnumConvert;
-import com.ruoyi.common.utils.importverify.BaseImportDto;
 import com.ruoyi.shop.order.enums.PaymentStatus;
 import com.ruoyi.shop.order.enums.SellerMark;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 
+import java.io.Serializable;
 import java.math.BigDecimal;
 import java.util.Date;
 import java.util.List;
@@ -31,7 +29,7 @@ import java.util.List;
 @ApiModel("代发货视图对象")
 @ExcelTarget("ShopOrderWaitShipVo")
 @ExcelIgnoreUnannotated
-public class ShopOrderWaitShipVo extends BaseImportDto implements IExcelDataModel, IExcelModel {
+public class ShopOrderWaitShipVo implements Serializable {
 
     private static final long serialVersionUID = 1L;
 

+ 89 - 0
ruoyi-shop/src/main/java/com/ruoyi/shop/order/service/ShopOrderWaitShipImportListener.java

@@ -0,0 +1,89 @@
+package com.ruoyi.shop.order.service;
+
+import com.alibaba.excel.context.AnalysisContext;
+import com.alibaba.excel.event.AnalysisEventListener;
+import com.ruoyi.common.excel.ExcelListener;
+import com.ruoyi.common.excel.ExcelResult;
+import com.ruoyi.common.exception.ServiceException;
+import com.ruoyi.common.utils.spring.SpringUtils;
+import com.ruoyi.message.domain.bo.MessageBo;
+import com.ruoyi.message.enums.MessageType;
+import com.ruoyi.message.enums.ModelType;
+import com.ruoyi.message.service.ISendPrivateMessageMsgService;
+import com.ruoyi.shop.order.domain.ShopOrderPackage;
+import com.ruoyi.shop.order.domain.vo.ShopOrderWaitShipVo;
+import com.ruoyi.shop.order.service.mqproduct.IShopOrderMqProductService;
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.List;
+
+@Slf4j
+public class ShopOrderWaitShipImportListener extends AnalysisEventListener<ShopOrderWaitShipVo> implements ExcelListener<ShopOrderWaitShipVo> {
+    private final Long businessId;
+    private final IShopOrderPackageService shopOrderPackageService;
+    private final IShopOrderMqProductService shopOrderMqProductService;
+    private final ISendPrivateMessageMsgService sendPrivateMessageMsgService;
+    private int successNum = 0;
+    private int failureNum = 0;
+    private final StringBuilder successMsg = new StringBuilder();
+    private final StringBuilder failureMsg = new StringBuilder();
+
+    public ShopOrderWaitShipImportListener(Long businessId) {
+        this.businessId = businessId;
+        shopOrderPackageService = SpringUtils.getBean(IShopOrderPackageService.class);
+        shopOrderMqProductService = SpringUtils.getBean(IShopOrderMqProductService.class);
+        sendPrivateMessageMsgService = SpringUtils.getBean(ISendPrivateMessageMsgService.class);
+    }
+
+    @Override
+    public ExcelResult<ShopOrderWaitShipVo> getExcelResult() {
+        return new ExcelResult<ShopOrderWaitShipVo>() {
+            @Override
+            public String getAnalysis() {
+                if (failureNum > 0) {
+                    failureMsg.insert(0, "很抱歉,导入失败!共 " + failureNum + " 条数据格式不正确,错误如下:");
+                    throw new ServiceException(failureMsg.toString());
+                } else {
+                    successMsg.insert(0, "恭喜您,数据已全部导入成功!共 " + successNum + " 条,数据如下:");
+                }
+                return successMsg.toString();
+            }
+            @Override
+            public List<ShopOrderWaitShipVo> getList() {
+                return null;
+            }
+            @Override
+            public List<String> getErrorList() {
+                return null;
+            }
+        };
+    }
+
+    @Override
+    public void invoke(ShopOrderWaitShipVo shopOrderWaitShipVo, AnalysisContext analysisContext) {
+        ShopOrderPackage shopOrderPackage = shopOrderPackageService.expressShipForImport(businessId, shopOrderWaitShipVo);
+        try {
+            try {
+                // 发送自动收货消息
+                shopOrderMqProductService.orderPackageReceivingMqProductSend(shopOrderPackage.getPackageId());
+                // 发送物流消息
+                sendPrivateMessageMsgService.send(new MessageBo(MessageType.LOGISTICS_MESSAGE,
+                    ModelType.LOGISTICS, shopOrderPackage.getPackageId()));
+            } catch (Exception e) {
+                log.error("MQ发送自动收货消息失败", e);
+            }
+            successNum++;
+            successMsg.append("<br/>").append(successNum).append("、订单 ").append(shopOrderWaitShipVo.getOrderNo()).append(" 发货成功");
+        } catch (Exception e) {
+            failureNum++;
+            String msg = "<br/>" + failureNum + "、订单 " + shopOrderWaitShipVo.getOrderNo() + " 导入发货失败:";
+            failureMsg.append(msg).append(e.getMessage());
+            log.error(msg, e);
+        }
+    }
+
+    @Override
+    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
+
+    }
+}

+ 6 - 0
ruoyi-shop/src/main/java/com/ruoyi/shop/order/service/impl/ShopOrderPackageServiceImpl.java

@@ -792,6 +792,12 @@ public class ShopOrderPackageServiceImpl implements IShopOrderPackageService {
     @Override
     public ShopOrderPackage expressShipForImport(Long businessId, ShopOrderWaitShipVo importRow) {
         ShopOrder order = shopOrderService.loadByBusinessIdAndOrderNo(businessId, importRow.getOrderNo(), true);
+        if (StringUtils.isEmpty(importRow.getExpressName())) {
+            throw new ServiceException("物流公司名称不能为空");
+        }
+        if (StringUtils.isEmpty(importRow.getLogisticCode())) {
+            throw new ServiceException("物流单号不能为空");
+        }
         ShopShipExpressBo expressBo = new ShopShipExpressBo();
         expressBo.setOrderId(order.getOrderId());
         ExpressCompany expressCompany = expressCompanyService.loadByName(importRow.getExpressName());