1
0
Переглянути джерело

Merge branch 'feature/商品图案批量导入210906' into featrue/图片批量上传和批量上架0907

qng 3 роки тому
батько
коміт
7f86180348

+ 5 - 0
kmall-admin/pom.xml

@@ -32,6 +32,11 @@
             <artifactId>kmall-api</artifactId>
             <version>${kmall-version}</version>
         </dependency>
+        <dependency>
+            <groupId>org.apache.ant</groupId>
+            <artifactId>ant</artifactId>
+            <version>1.9.7</version>
+        </dependency>
 
     </dependencies>
 

+ 228 - 7
kmall-admin/src/main/java/com/kmall/admin/controller/GoodsController.java

@@ -1,28 +1,36 @@
 package com.kmall.admin.controller;
 
+import com.alibaba.fastjson.JSON;
 import com.kmall.admin.dto.GoodsDetailsDto;
 import com.kmall.admin.dto.GoodsDto;
 import com.kmall.admin.entity.GoodsEntity;
 import com.kmall.admin.entity.GoodsGalleryEntity;
-import com.kmall.admin.entity.StoreEntity;
-import com.kmall.admin.service.GoodsGalleryService;
-import com.kmall.admin.service.GoodsService;
-import com.kmall.admin.service.OfflineCartService;
-import com.kmall.admin.service.StoreService;
+import com.kmall.admin.entity.SysOssEntity;
+import com.kmall.admin.service.*;
 import com.kmall.admin.utils.ParamUtils;
 import com.kmall.admin.utils.ShiroUtils;
+import com.kmall.api.cache.UserTokenCache;
 import com.kmall.common.constant.Dict;
 import com.kmall.common.constant.JxlsXmlTemplateName;
 import com.kmall.admin.fromcomm.entity.SysUserEntity;
+import com.kmall.common.fileserver.util.FileManager;
 import com.kmall.common.utils.*;
 import com.kmall.common.utils.excel.ExcelUtil;
-import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.fileupload.FileItem;
+import org.apache.commons.fileupload.FileItemFactory;
+import org.apache.commons.fileupload.disk.DiskFileItemFactory;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
 import org.apache.shiro.authz.annotation.RequiresPermissions;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
 
+import java.io.*;
 import java.util.*;
+import org.apache.tools.zip.ZipEntry;
+import org.apache.tools.zip.ZipFile;
+import org.springframework.web.multipart.commons.CommonsMultipartFile;
 
 /**
  * Controller
@@ -34,6 +42,8 @@ import java.util.*;
 @RestController
 @RequestMapping("goods")
 public class GoodsController {
+
+    private static Log logger = LogFactory.getLog(UserTokenCache.class);
     @Autowired
     private GoodsService goodsService;
     @Autowired
@@ -44,7 +54,8 @@ public class GoodsController {
     private ExcelUtil excelUtil;
     @Autowired
     private StoreService storeService;
-
+    @Autowired
+    private SysOssService sysOssService;
     /**
      * 查看列表
      */
@@ -300,6 +311,216 @@ public class GoodsController {
         return R.ok().put("goodsDetails", goods);
     }
 
+    @RequestMapping("/generalGoodsImgUploadByZip")
+    @ResponseBody
+    public R batchAddImgByZip(@RequestParam("file") MultipartFile file) throws IOException {
+        //上传文件
+        batchAdd(file,2);
+        return R.ok();
+    }
+
+    @RequestMapping("/generalGoodsImgUpload")
+    @ResponseBody
+    public R batchAddImg(@RequestParam("file") MultipartFile file) throws IOException {
+        //上传文件
+        batchAdd(file,1);
+        return R.ok();
+    }
+
+    private Map<String, Object> batchAdd(MultipartFile file, int type) throws IOException {
+        /*
+         *创建临时文件夹
+         * 解压文件
+         */
+        String fileName = file.getOriginalFilename();
+        String path = "/data/project/img/";
+        File dir = new File(path);
+        dir.mkdirs();
+        String filePath = "/data/project/img2/";
+        File fileDir = new File(filePath);
+        fileDir.mkdirs();
+        File saveFile = new File(fileDir, fileName);//将压缩包解析到指定位置
+        List<String>list = new ArrayList<>();
+
+        try {
+            file.transferTo(saveFile);
+            String newFilePath = filePath + fileName;
+            File zipFile = new File(newFilePath);
+            unZipFiles(zipFile, path,list,type);//解压文件,获取文件路径
+        } catch (IOException e) {
+            e.printStackTrace();
+            System.out.println("解压执行失败");
+            throw e;
+        }
+
+
+        logger.info(JSON.toJSONString(list));
+        //程序结束时,删除临时文件
+        deleteFiles(filePath);//删除压缩包文件夹
+        deleteFiles(path);//删除解压文件夹**
+
+        Map<String, Object> jsonMap = new HashMap<String, Object>();
+        jsonMap.put("ret",list);
+        return jsonMap;
+    }
 
+    public void deleteFiles(String filePath) {
+        File file = new File(filePath);
+        if ((!file.exists()) || (!file.isDirectory())) {
+            System.out.println("file not exist");
+            return;
+        }
+        String[] tempList = file.list();
+        File temp = null;
+        for (int i = 0; i < tempList.length; i++) {
+            if (filePath.endsWith(File.separator)) {
+                temp = new File(filePath + tempList[i]);
+            }
+            else {
+                temp = new File(filePath + File.separator + tempList[i]);
+            }
+            if (temp.isFile()) {
+                temp.delete();
+            }
+            if (temp.isDirectory()) {
+                this.deleteFiles(filePath + "/" + tempList[i]);
+            }
+        }
+        // 空文件的删除
+        file.delete();
+    }
+
+    public void unZipFiles(File srcFile, String destDirPath, List<String> list, int type) throws RuntimeException {
+        long start = System.currentTimeMillis();
+        // 判断源文件是否存在
+        if (!srcFile.exists()) {
+            throw new RuntimeException(srcFile.getPath() + "所指文件不存在");
+        }
+        // 开始解压
+        ZipFile zipFile = null;
+        try {
+            zipFile = new ZipFile(srcFile);
+        } catch (IOException e) {
+            throw new RRException("zip文件解压出错", e);
+        }
+        zipFile.getEncoding();
+        Enumeration<?> entries = zipFile.getEntries();
+        List<ZipEntry> entryList = new ArrayList<>();
+        while (entries.hasMoreElements()) {
+            ZipEntry entry = (ZipEntry) entries.nextElement();
+            logger.info("解压" + entry.getName());
+            entryList.add(entry);
+            // 如果是文件夹,就创建个文件夹
+        }
+        if(null==entryList){
+            throw new RRException("文件夹内无图片信息,请检查后重试");
+        }
+        if(entryList.size()>30){
+            throw new RRException("最多上传30张图片");
+        }
+        try {
+            for(ZipEntry entry : entryList){
+                if (entry.isDirectory()) {
+                    String dirPath = destDirPath + "/" + entry.getName();
+                    File dir = new File(dirPath);
+                    dir.mkdirs();
+                } else {
+                    // 如果是文件,就先创建一个文件,然后用io流把内容copy过去
+                    File targetFile = new File(destDirPath + "/" + entry.getName());
+                    // 保证这个文件的父文件夹必须要存在
+
+                    if(!targetFile.getParentFile().exists()){
+
+                    }
+                    targetFile.createNewFile();
+                    // 将压缩文件内容写入到这个文件中
+                    InputStream is = zipFile.getInputStream(entry);
+                    FileOutputStream fos = new FileOutputStream(targetFile);
+                    int len;
+                    byte[] buf = new byte[1024];
+                    while ((len = is.read(buf)) != -1) {
+                        fos.write(buf, 0, len);
+                    }
+
+                    MultipartFile mulFileByPath = getMulFileByPath(destDirPath + "/" + entry.getName());
+                    //上传文件
+                    String url = FileManager.upload(mulFileByPath);
+                    list.add(url);
+                    if(type == 1){
+                        String sku = entry.getName().split("\\.")[0];
+                        if (null==sku||"".equals(sku)) {
+                            throw new RRException("文件名为:" + sku + "的商品命名格式不正确,请检查!");
+                        }
+                        GoodsEntity goodsEntity = goodsService.queryBySku(sku);
+                        goodsEntity.setPrimaryPicUrl(url);
+                        goodsEntity.setListPicUrl(url);
+                        goodsService.updateForImgUrl(goodsEntity);
+                    }else if(type == 2){
+                        String barCode = entry.getName().split("/")[1];
+                        GoodsEntity goodsEntity = goodsService.queryByBarcode(barCode);
+                        goodsEntity.setPrimaryPicUrl(url);
+                        goodsEntity.setListPicUrl(url);
+                        goodsService.updateForImgUrl(goodsEntity);
+                    }
+                    //保存文件信息
+                    SysOssEntity ossEntity = new SysOssEntity();
+                    ossEntity.setUrl(url);
+                    ossEntity.setCreateDate(new Date());
+                    sysOssService.save(ossEntity);
+                    // 关流顺序,先打开的后关闭
+                    fos.close();
+                    is.close();
+                }
+            }
+            long end = System.currentTimeMillis();
+            System.out.println("解压完成,耗时:" + (end - start) +" ms");
+        } catch (Exception e) {
+            throw new RuntimeException("unzip error from ZipUtils", e);
+        } finally {
+            if(zipFile != null){
+                try {
+                    zipFile.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+
+    private static MultipartFile getMulFileByPath(String picPath) {
+        FileItem fileItem = createFileItem(picPath);
+        MultipartFile mfile = new CommonsMultipartFile(fileItem);
+        return mfile;
+    }
+
+    private static FileItem createFileItem(String filePath)
+    {
+        FileItemFactory factory = new DiskFileItemFactory(16, null);
+        String textFieldName = "textField";
+        int num = filePath.lastIndexOf(".");
+        String extFile = filePath.substring(num);
+        FileItem item = factory.createItem(textFieldName, "text/plain", true,
+                "MyFileName" + extFile);
+        File newfile = new File(filePath);
+        int bytesRead = 0;
+        byte[] buffer = new byte[8192];
+        try
+        {
+            FileInputStream fis = new FileInputStream(newfile);
+            OutputStream os = item.getOutputStream();
+            while ((bytesRead = fis.read(buffer, 0, 8192))
+                    != -1)
+            {
+                os.write(buffer, 0, bytesRead);
+            }
+            os.close();
+            fis.close();
+        }
+        catch (IOException e)
+        {
+            e.printStackTrace();
+        }
+        return item;
+    }
 
 }

+ 4 - 0
kmall-admin/src/main/java/com/kmall/admin/dao/GoodsDao.java

@@ -31,4 +31,8 @@ public interface GoodsDao extends BaseDao<GoodsEntity> {
     GoodsEntity queryObjectByStoreId(@Param("id") Long id, @Param("storeId") Long storeId);
 
     GoodsEntity queryGoodsByGoodsSnAndStoreId(@Param("goodsSn") String goodsSn, @Param("storeId") Long storeId);
+
+    GoodsEntity queryByBarcode(String barCode);
+
+    GoodsEntity queryBySku(String sku);
 }

+ 16 - 0
kmall-admin/src/main/java/com/kmall/admin/service/GoodsService.java

@@ -131,4 +131,20 @@ public interface GoodsService {
      * @return
      */
     GoodsDetailsDto queryGoodsDetailsByProdBarcode(String prodBarcode);
+
+    /**
+     * 根据条形码查询商品
+     * @param barCode
+     * @return
+     */
+    GoodsEntity queryByBarcode(String barCode);
+
+    /**
+     * 根据sku查询商品
+     * @param sku
+     * @return
+     */
+    GoodsEntity queryBySku(String sku);
+
+    void updateForImgUrl(GoodsEntity goodsEntity);
 }

+ 31 - 0
kmall-admin/src/main/java/com/kmall/admin/service/impl/GoodsServiceImpl.java

@@ -1073,4 +1073,35 @@ public class GoodsServiceImpl implements GoodsService {
     public GoodsEntity queryObjectBySn(String goodsSn) {
         return goodsDao.queryObjectBySn(goodsSn);
     }
+
+
+
+    /**
+     * 根据条形码查询商品
+     *
+     * @param barCode
+     * @return
+     */
+    @Override
+    public GoodsEntity queryByBarcode(String barCode) {
+        return goodsDao.queryByBarcode(barCode);
+    }
+
+    /**
+     * 根据sku查询商品
+     *
+     * @param sku
+     * @return
+     */
+    @Override
+    public GoodsEntity queryBySku(String sku) {
+        return goodsDao.queryBySku(sku);
+    }
+
+    @Transactional
+    @Override
+    public void updateForImgUrl(GoodsEntity goodsEntity){
+        // 修改商品
+        goodsDao.update(goodsEntity);
+    }
 }

+ 13 - 0
kmall-admin/src/main/resources/mybatis/mapper/GoodsDao.xml

@@ -580,4 +580,17 @@
     <select id="queryMaxId" resultType="java.lang.Long" parameterType="map">
         SELECT MAX(id) FROM mall_goods
     </select>
+
+    <select id="queryByBarcode" resultType="com.kmall.admin.entity.GoodsEntity">
+        select *
+        from mall_goods
+        where prod_barcode = #{barCode}
+    </select>
+
+    <select id="queryBySku" resultType="com.kmall.admin.entity.GoodsEntity">
+        select *
+        from mall_goods
+        where sku = #{sku}
+    </select>
+
 </mapper>

+ 17 - 0
kmall-admin/src/main/webapp/WEB-INF/page/shop/goods.html

@@ -138,11 +138,28 @@
                         <i-button type="ghost" icon="ios-cloud-upload-outline">普货商品导入</i-button>
                     </Upload>
                 </i-col>
+                <i-col style="display: inline-grid;">
+                    <Upload :show-upload-list="false" :on-success="uploadExcelSuccess" :on-error="uploadExcelError" :on-format-error="uploadExcelFormatError"
+                            :on-progress="uploadExcelProgress"
+                            :format="['xls','xlsx','zip']"
+                            action="../goods/generalGoodsImgUpload">
+                        <i-button type="ghost" icon="ios-cloud-upload-outline">商品图片批量导入</i-button>
+                    </Upload>
+                </i-col>
+<!--                <i-col style="display: inline-grid;">-->
+<!--                    <Upload :show-upload-list="false" :on-success="uploadExcelSuccess" :on-error="uploadExcelError" :on-format-error="uploadExcelFormatError"-->
+<!--                            :on-progress="uploadExcelProgress"-->
+<!--                            :format="['xls','xlsx','zip']"-->
+<!--                            action="../goods/generalGoodsImgUploadByZip">-->
+<!--                        <i-button type="ghost" icon="ios-cloud-upload-outline">商品图片(文件夹)批量导入</i-button>-->
+<!--                    </Upload>-->
+<!--                </i-col>-->
                 #end
                 #if($shiro.hasPermission("goods:down"))
                 &nbsp;&nbsp;&nbsp;&nbsp;
                 <a href="../statics/file/goods_export_yyyy_mm_dd_v1.0.0.xls">商品模板下载</a>&nbsp;&nbsp;&nbsp;&nbsp;
                 <a href="../statics/file/general_goods_export_yyyy_mm_dd_v1.0.0.xls">普货商品模板下载</a>
+                <a href="../statics/file/goods_img.zip">商品导入示例下载</a>
                 #end
             </div>
         </Row>

+ 13 - 0
kmall-admin/src/main/webapp/js/shop/goods.js

@@ -106,6 +106,7 @@ $(function () {
 });
 
 var ztree;
+var exportMsg;
 
 var setting = {
     data: {
@@ -592,6 +593,18 @@ var vm = new Vue({
                 desc: '文件 ' + file.name + ' 格式不正确,请上传 xls 或 xlsx 格式的文件。'
             });
         },
+        uploadExcelProgress:function(event, file, fileList){
+            console.log("上传中")
+            console.log(event)
+            console.log(file)
+            console.log(fileList)
+            console.log("上传中")
+            exportMsg = this.$Message.loading({
+                content: 'Loading...',
+                duration: 0
+            });
+            setTimeout(exportMsg,1000);
+        },
         handleRemove(file) {
             // 从 upload 实例删除数据
             const fileList = vm.uploadList;

BIN
kmall-admin/src/main/webapp/statics/file/goods_img.zip