yq 3 роки тому
батько
коміт
7edb5b3683

+ 1 - 1
src/main/java/com/usky/dxtop/MysqlGenerator.java

@@ -43,7 +43,7 @@
 //        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
 //        // strategy.setTablePrefix("t_"); // 表名前缀
 //        strategy.setEntityLombokModel(true); //使用lombok
-//        strategy.setInclude("company");  // 逆向工程使用的表   如果要生成多个,这里可以传入String[]
+//        strategy.setInclude("sys_file");  // 逆向工程使用的表   如果要生成多个,这里可以传入String[]
 //        mpg.setStrategy(strategy);
 //
 //        //5、执行

+ 56 - 11
src/main/java/com/usky/dxtop/common/utils/file/FileUtils.java

@@ -1,20 +1,17 @@
 package com.usky.dxtop.common.utils.file;
 
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.UnsupportedEncodingException;
-import java.net.URLEncoder;
-import java.nio.charset.StandardCharsets;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
 import com.usky.dxtop.common.utils.StringUtils;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.ArrayUtils;
 
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.*;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+
 
 /**
  * 文件处理工具类
@@ -240,4 +237,52 @@ public class FileUtils
             return false;
         }
     }
+
+
+    /**
+     * 下载远程文件并保存到本地
+     * @param remoteFilePath 远程文件路径
+     * @param localFilePath 本地文件路径(带文件名)
+     */
+    public static void downloadFile(String remoteFilePath, String localFilePath)
+    {
+        URL urlfile = null;
+        HttpURLConnection httpUrl = null;
+        BufferedInputStream bis = null;
+        BufferedOutputStream bos = null;
+        File f = new File(localFilePath);
+        try
+        {
+            urlfile = new URL(remoteFilePath);
+            httpUrl = (HttpURLConnection)urlfile.openConnection();
+            httpUrl.connect();
+            bis = new BufferedInputStream(httpUrl.getInputStream());
+            bos = new BufferedOutputStream(new FileOutputStream(f));
+            int len = 2048;
+            byte[] b = new byte[len];
+            while ((len = bis.read(b)) != -1)
+            {
+                bos.write(b, 0, len);
+            }
+            bos.flush();
+            bis.close();
+            httpUrl.disconnect();
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+        }
+        finally
+        {
+            try
+            {
+                bis.close();
+                bos.close();
+            }
+            catch (IOException e)
+            {
+                e.printStackTrace();
+            }
+        }
+    }
 }

+ 18 - 0
src/main/java/com/usky/dxtop/mapper/SysFileMapper.java

@@ -0,0 +1,18 @@
+package com.usky.dxtop.mapper;
+
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.usky.dxtop.model.SysFile;
+
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author yq
+ * @since 2021-10-09
+ */
+public interface SysFileMapper extends BaseMapper<SysFile> {
+
+}

+ 117 - 0
src/main/java/com/usky/dxtop/model/SysFile.java

@@ -0,0 +1,117 @@
+package com.usky.dxtop.model;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * <p>
+ * 
+ * </p>
+ *
+ * @author yq
+ * @since 2021-10-09
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+public class SysFile implements Serializable {
+
+    private static final long serialVersionUID=1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    /**
+     * 文件批次(一次上传多个文件)
+     */
+    private String batchNo;
+    /**
+     * 文件类型
+     */
+    private String fileType;
+
+    /**
+     * 原文件名
+     */
+    private String oriName;
+
+    /**
+     * url
+     */
+    private String url;
+
+    /**
+     * 业务类型
+     */
+    private String businessType;
+
+    /**
+     * 文件权限
+     */
+    private String fileAcl;
+
+    /**
+     * 文件大小
+     */
+    private Integer fileSize;
+
+    /**
+     * 失效时间
+     */
+    private Date expriceAt;
+
+    /**
+     * 0未生效1已生效
+     */
+    private Integer activeFlag;
+
+    /**
+     * 0未删除1已删除
+     */
+    private Integer delFlag;
+
+    /**
+     * 创建者
+     */
+    private String createBy;
+
+    /**
+     * 创建时间
+     */
+    private Date createTime;
+
+    /**
+     * 更新者
+     */
+    private String updateBy;
+
+    /**
+     * 更新时间
+     */
+    private Date updateTime;
+
+
+    @TableField(exist = false)
+    private List<MultipartFile> files;
+
+    @TableField(exist = false)
+    private List<String> urls;
+
+    @TableField(exist = false)
+    private Boolean success;
+
+    @TableField(exist = false)
+    private String message;
+
+    @TableField(exist = false)
+    private String uploadType;
+}

+ 102 - 0
src/main/java/com/usky/dxtop/service/SysFileService.java

@@ -0,0 +1,102 @@
+package com.usky.dxtop.service;
+
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.usky.dxtop.model.SysFile;
+import com.usky.dxtop.service.vo.SysFileQueryRequest;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * <p>
+ *  服务类
+ * </p>
+ *
+ * @author yq
+ * @since 2021-10-09
+ */
+public interface SysFileService extends IService<SysFile> {
+
+    /**
+     * 添加文件到sysfile
+     * 可以同时长传多个文件. 但相比V2,不能够指定key. key随机生成.
+     * @param sysFile
+     * @return
+     */
+    List<SysFile> addFile(SysFile sysFile);
+
+    /**
+     * 添加multipart file
+     * @param m
+     * @param sysFile
+     * @return
+     */
+    SysFile uploadMultipartFile(MultipartFile m, SysFile sysFile);
+
+    /**
+     * 添加链接
+     * @param url
+     * @param sysFile
+     * @return
+     */
+    SysFile addExternalLink(String url, SysFile sysFile);
+
+
+    /**
+     * 生成新的batchNo
+     * @return
+     */
+    String generateBatchNo();
+
+    /**
+     * 确认文件生效
+     * @param batchNo
+     * @param fileIds
+     * @return
+     */
+    Boolean active(String batchNo, List<String> fileIds);
+
+    /**
+     * 获取文件
+     * @param sysFileRequest
+     * @return
+     */
+    List<SysFile> getFile(SysFileQueryRequest sysFileRequest);
+
+
+    /**
+     * 根据时间获取失效文件
+     *
+     * @param date
+     * @return
+     */
+    List<SysFile> getFileByExpireAt(Date date);
+
+
+    /**
+     * 批量删除文件(更新文件删除状态)
+     *
+     * @param sysFiles
+     * @return
+     */
+    Integer deleteFiles(List<SysFile> sysFiles);
+
+    /**
+     * 通过batchNo删除
+     *
+     * @param batchNo
+     * @return
+     */
+    Integer removeByBatchNo(String batchNo);
+
+
+    /**
+     * 清理垃圾文件.
+     *
+     * @param fileList
+     * @return
+     */
+    Integer clearFiles(List<SysFile> fileList);
+}

+ 170 - 0
src/main/java/com/usky/dxtop/service/impl/SysFileServiceImpl.java

@@ -0,0 +1,170 @@
+package com.usky.dxtop.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.usky.dxtop.common.config.DxConfig;
+import com.usky.dxtop.common.exception.CustomException;
+import com.usky.dxtop.common.utils.StringUtils;
+import com.usky.dxtop.common.utils.file.FileTypeUtils;
+import com.usky.dxtop.common.utils.file.FileUploadUtils;
+import com.usky.dxtop.common.utils.file.FileUtils;
+import com.usky.dxtop.common.utils.uuid.IdUtils;
+import com.usky.dxtop.mapper.SysFileMapper;
+import com.usky.dxtop.model.SysFile;
+import com.usky.dxtop.service.SysFileService;
+import com.usky.dxtop.service.vo.SysFileQueryRequest;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.Date;
+import java.util.List;
+
+import static java.util.stream.Collectors.toList;
+
+/**
+ * <p>
+ *  服务实现类
+ * </p>
+ *
+ * @author yq
+ * @since 2021-10-09
+ */
+@Slf4j
+@Service
+public class SysFileServiceImpl extends ServiceImpl<SysFileMapper, SysFile> implements SysFileService {
+
+    private static final String FILE = "file";
+
+    private static final String URL = "url";
+
+    @Override
+    public List<SysFile> addFile(SysFile sysFile) {
+        if (StringUtils.isNotBlank(sysFile.getUploadType())) {
+            sysFile.setUploadType(FILE);
+        }
+        sysFile.setSuccess(true);
+        switch (sysFile.getUploadType()) {
+            case FILE:
+                return sysFile.getFiles().stream().map(m -> this.uploadMultipartFile(m, sysFile)).collect(toList());
+            case URL:
+                return sysFile.getUrls().stream().map(m -> this.addExternalLink(m, sysFile)).collect(toList());
+            default:
+                break;
+        }
+        return null;
+    }
+
+    @Override
+    public SysFile uploadMultipartFile(MultipartFile m, SysFile sysFile) {
+        try {
+            // 上传文件路径
+            String filePath = DxConfig.getUploadPath();
+            // 上传并返回新文件名称
+            String fileName = FileUploadUtils.upload(filePath, m);
+            sysFile.setOriName(m.getOriginalFilename());
+            sysFile.setFileSize(Integer.parseInt(String.valueOf(m.getSize())));
+            sysFile.setFileType(m.getContentType());
+            sysFile.setUrl(String.format("%s%s", filePath, fileName));
+        } catch (Exception e) {
+            sysFile.setSuccess(false);
+            sysFile.setMessage(e.getMessage());
+        }
+        this.save(sysFile);
+        return sysFile;
+    }
+
+    @Override
+    public SysFile addExternalLink(String url, SysFile sysFile) {
+        try {
+            String filePath = DxConfig.getUploadPath();
+            String format = String.format("%s%s.%s", filePath, System.currentTimeMillis() + "", FileTypeUtils.getFileType(url));
+            FileUtils.downloadFile(url,format);
+        }catch (Exception e){
+            sysFile.setSuccess(false);
+            sysFile.setMessage(e.getMessage());
+        }
+        this.save(sysFile);
+        return sysFile;
+    }
+
+    @Override
+    public String generateBatchNo() {
+        return IdUtils.randomUUID();
+    }
+
+    @Override
+    @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
+    public Boolean active(String batchNo, List<String> fileIds) {
+        if (CollectionUtils.isEmpty(fileIds)) {
+            return false;
+        }
+        LambdaUpdateWrapper<SysFile> updateWrapper = Wrappers.lambdaUpdate();
+        updateWrapper.set(SysFile::getActiveFlag,1)
+                .eq(SysFile::getBatchNo,batchNo)
+                .in(SysFile::getFiles,fileIds);
+        return this.update(updateWrapper);
+    }
+
+    @Override
+    public List<SysFile> getFile(SysFileQueryRequest req) {
+        if(StringUtils.isBlank(req.getBatchNo()) && CollectionUtils.isEmpty(req.getIds())){
+            throw new CustomException("批次或者文件编号不能为空");
+        }
+        LambdaQueryWrapper<SysFile> queryWrapper = Wrappers.lambdaQuery();
+        queryWrapper.eq(StringUtils.isNotBlank(req.getBatchNo()), SysFile::getBatchNo, req.getBatchNo())
+                .eq(SysFile::getActiveFlag, 1)
+                .in(!CollectionUtils.isEmpty(req.getIds()), SysFile::getId, req.getIds());
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public List<SysFile> getFileByExpireAt(Date date) {
+        LambdaQueryWrapper<SysFile> queryWrapper = Wrappers.lambdaQuery();
+        queryWrapper.eq(SysFile::getDelFlag, 0)
+                .and(wrapper -> wrapper.eq(SysFile::getActiveFlag, 0)
+                        .or()
+                        .eq(SysFile::getActiveFlag, 1))
+        .between(SysFile::getCreateTime,0,date);
+        return this.list(queryWrapper);
+    }
+
+    @Override
+    public Integer deleteFiles(List<SysFile> sysFiles) {
+        Date now = new Date();
+        sysFiles = sysFiles.stream().peek(s -> {
+            s.setDelFlag(1);
+            s.setActiveFlag(0);
+            s.setExpriceAt(now);
+        }).collect(toList());
+        return updateBatchById(sysFiles) ? sysFiles.size() : 0;
+    }
+
+    @Override
+    public Integer removeByBatchNo(String batchNo) {
+        LambdaQueryWrapper<SysFile> queryWrapper = Wrappers.lambdaQuery();
+        queryWrapper.eq(SysFile::getBatchNo, batchNo);
+        List<SysFile> sysFileList = list(queryWrapper);
+        return this.deleteFiles(sysFileList);
+    }
+
+    @Override
+    public Integer clearFiles(List<SysFile> fileList) {
+        if (CollectionUtils.isEmpty(fileList)){
+            return 0;
+        }
+        fileList.forEach(sysFile -> {
+            try {
+                FileUtils.deleteFile(sysFile.getUrl());
+            }catch (Exception e){
+                log.error("删除文件失败:"+e);
+            }
+        });
+        return this.deleteFiles(fileList);
+    }
+}

+ 31 - 0
src/main/java/com/usky/dxtop/service/job/FileJob.java

@@ -0,0 +1,31 @@
+package com.usky.dxtop.service.job;
+
+import com.usky.dxtop.model.SysFile;
+import com.usky.dxtop.service.SysFileService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * @author yq
+ * @date 2021/10/9 13:34
+ */
+@Component
+@Slf4j
+public class FileJob {
+    @Autowired
+    private SysFileService fileService;
+
+    private void deleteInvalidFile(String start) {
+        List<SysFile> sysFileList = fileService.getFileByExpireAt(new Date());
+        if (CollectionUtils.isEmpty(sysFileList)) {
+            return;
+        }
+        Integer integer = fileService.clearFiles(sysFileList);
+        log.info("删除的file条数=:" + integer);
+    }
+}

+ 19 - 0
src/main/java/com/usky/dxtop/service/vo/SysFileQueryRequest.java

@@ -0,0 +1,19 @@
+package com.usky.dxtop.service.vo;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author yq
+ * @date 2021/10/9 10:40
+ */
+@Data
+public class SysFileQueryRequest {
+
+    private String batchNo;
+
+    private Integer activeFlag;
+
+    private List<Long> ids;
+}

+ 1 - 0
src/main/resources/application-dev.properties

@@ -92,6 +92,7 @@ dx.copyrightYear: 2021
 dx.demoEnabled: true
 dx.addressEnabled: false
 dx.captchaType: math
+dx.profile: C:/Users/pc/Desktop/
 
 # mq
 spring.rabbitmq.host=124.71.174.104

+ 1 - 0
src/main/resources/application-prod.properties

@@ -92,6 +92,7 @@ dx.copyrightYear: 2021
 dx.demoEnabled: true
 dx.addressEnabled: false
 dx.captchaType: math
+dx.profile: /usr/local/service/dxtop/dxfile/
 
 # mq
 spring.rabbitmq.host=124.71.174.104

+ 23 - 0
src/main/resources/mapper/SysFileMapper.xml

@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.usky.dxtop.mapper.SysFileMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.usky.dxtop.model.SysFile">
+        <id column="id" property="id" />
+        <result column="file_type" property="fileType" />
+        <result column="ori_name" property="oriName" />
+        <result column="url" property="url" />
+        <result column="business_type" property="businessType" />
+        <result column="file_acl" property="fileAcl" />
+        <result column="file_size" property="fileSize" />
+        <result column="exprice_at" property="expriceAt" />
+        <result column="active_flag" property="activeFlag" />
+        <result column="del_flag" property="delFlag" />
+        <result column="create_by" property="createBy" />
+        <result column="create_time" property="createTime" />
+        <result column="update_by" property="updateBy" />
+        <result column="update_time" property="updateTime" />
+    </resultMap>
+
+</mapper>