Browse Source

06/07 xiexiang

xiexiang 2 năm trước cách đây
mục cha
commit
14a0678c28
39 tập tin đã thay đổi với 5311 bổ sung0 xóa
  1. 8 0
      src/main/java/com/example/fms/common/core/Convert.java
  2. 22 0
      src/main/java/com/example/fms/common/core/base/RedisConf.java
  3. 28 0
      src/main/java/com/example/fms/common/model/BaseVO.java
  4. 12 0
      src/main/java/com/example/fms/common/model/dto/CommonData.java
  5. 14 0
      src/main/java/com/example/fms/common/model/dto/ProjectFieldOrderDTO.java
  6. 48 0
      src/main/java/com/example/fms/common/model/dto/SystemFileDTO.java
  7. 57 0
      src/main/java/com/example/fms/common/model/dto/SystemFileUpdateDTO.java
  8. 17 0
      src/main/java/com/example/fms/common/model/dto/UploadFileDTO.java
  9. 19 0
      src/main/java/com/example/fms/common/model/vo/ConfigSettingVO.java
  10. 175 0
      src/main/java/com/example/fms/common/model/vo/PersonnelVO.java
  11. 67 0
      src/main/java/com/example/fms/common/model/vo/SystemFileVO.java
  12. 147 0
      src/main/java/com/example/fms/common/utils/BackupUtils.java
  13. 172 0
      src/main/java/com/example/fms/common/utils/CacheUtils.java
  14. 667 0
      src/main/java/com/example/fms/common/utils/DateUtils.java
  15. 58 0
      src/main/java/com/example/fms/common/utils/ExcuteConfigUtils.java
  16. 321 0
      src/main/java/com/example/fms/common/utils/FileUtils.java
  17. 342 0
      src/main/java/com/example/fms/common/utils/JsonUtils.java
  18. 1325 0
      src/main/java/com/example/fms/common/utils/RedisUtil.java
  19. 117 0
      src/main/java/com/example/fms/common/utils/Response.java
  20. 56 0
      src/main/java/com/example/fms/common/utils/ResponseEnum.java
  21. 22 0
      src/main/java/com/example/fms/common/utils/SFTP.java
  22. 45 0
      src/main/java/com/example/fms/common/utils/SecurityUtils/LoginUtils.java
  23. 131 0
      src/main/java/com/example/fms/common/utils/SpringUtils.java
  24. 508 0
      src/main/java/com/example/fms/common/utils/StringUtils.java
  25. 18 0
      src/main/java/com/example/fms/common/utils/ThrowException.java
  26. 34 0
      src/main/java/com/example/fms/controller/FileMangerController.java
  27. 67 0
      src/main/java/com/example/fms/domain/AbstractPictureFile.java
  28. 71 0
      src/main/java/com/example/fms/domain/InstructionFile.java
  29. 61 0
      src/main/java/com/example/fms/domain/OtherFile.java
  30. 67 0
      src/main/java/com/example/fms/domain/SystemFile.java
  31. 13 0
      src/main/java/com/example/fms/exception/XiaoShiException.java
  32. 50 0
      src/main/java/com/example/fms/mapper/SystemFileMapper.java
  33. 68 0
      src/main/java/com/example/fms/service/FileFactoryService.java
  34. 21 0
      src/main/java/com/example/fms/service/IFileManagerService.java
  35. 48 0
      src/main/java/com/example/fms/service/ISystemFileService.java
  36. 147 0
      src/main/java/com/example/fms/service/SftpService.java
  37. 51 0
      src/main/java/com/example/fms/service/impl/FileManagerServiceImpl.java
  38. 142 0
      src/main/java/com/example/fms/service/impl/SystemFileServiceImpl.java
  39. 75 0
      src/main/resources/mapper/SystemFileMapper.xml

+ 8 - 0
src/main/java/com/example/fms/common/core/Convert.java

@@ -0,0 +1,8 @@
+package com.example.fms.common.core;
+
+/**
+ * @Author xiexiang
+ * @Date 2023/6/1
+ */
+public class Convert {
+}

+ 22 - 0
src/main/java/com/example/fms/common/core/base/RedisConf.java

@@ -0,0 +1,22 @@
+package com.example.fms.common.core.base;
+
+/**
+ * Redis常量类
+ *
+ * @Author xiexiang
+ * @Date 2023/6/1
+ */
+public class RedisConf {
+
+    public static final String SYMBOL_COLON = ":";
+    public static final String SYMBOL_LINE = "-";
+    public final static String COMMON_DATA = "common-data";
+    public final static String LOGIN_USER = "login-user";
+    public final static String VERIFY_CODE = "verify-code";
+    public final static String SELECT_PATENT = "select-patent";
+    public final static String ANALYSIS_COUNT = "analysis-count";
+    public final static String AREA_LIST = "area-list";
+    public final static String USER_FIELD = "user-field";
+    public final static String FIELD_ORDER = "field-order";
+    public final static String USER_IMPORT = "user-import";
+}

+ 28 - 0
src/main/java/com/example/fms/common/model/BaseVO.java

@@ -0,0 +1,28 @@
+package com.example.fms.common.model;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+/**
+ * @Author xiexiang
+ * @Date 2023/5/31
+ */
+@Data
+@Accessors(chain = true)
+public class BaseVO {
+    /**
+     * 每页条数
+     */
+    private Integer size;
+
+    /**
+     * 当前页数
+     */
+    private Integer current;
+
+    /**
+     * 数据总数
+     */
+    private Integer total;
+
+}

+ 12 - 0
src/main/java/com/example/fms/common/model/dto/CommonData.java

@@ -0,0 +1,12 @@
+package com.example.fms.common.model.dto;
+
+import lombok.Data;
+
+/**
+ * @Author xiexiang
+ * @Date 2023/6/1
+ */
+@Data
+public class CommonData {
+
+}

+ 14 - 0
src/main/java/com/example/fms/common/model/dto/ProjectFieldOrderDTO.java

@@ -0,0 +1,14 @@
+package com.example.fms.common.model.dto;
+
+import lombok.Data;
+
+/**
+ * @Author xiexiang
+ * @Date 2023/6/1
+ */
+@Data
+public class ProjectFieldOrderDTO {
+    private Integer id;
+    private Integer order;
+}
+

+ 48 - 0
src/main/java/com/example/fms/common/model/dto/SystemFileDTO.java

@@ -0,0 +1,48 @@
+package com.example.fms.common.model.dto;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.util.Date;
+
+/**
+ * 系统文件新增DTO
+ *
+ * @Author xiexiang
+ * @Date 2023/6/1
+ */
+@Accessors(chain = true)
+@Data
+public class SystemFileDTO {
+
+    /**
+     * 唯一标识id
+     */
+    private String GUID;
+
+    /**
+     * 文件路径
+     */
+    private String filePath;
+
+    /**
+     * 文件名称
+     */
+    private String fileName;
+
+    /**
+     * 原始名称
+     */
+    private String originalName;
+
+    /**
+     * 文件大小
+     */
+    private String fileLength;
+
+    /**
+     * 是否删除
+     */
+    private Integer isDelete;
+
+}

+ 57 - 0
src/main/java/com/example/fms/common/model/dto/SystemFileUpdateDTO.java

@@ -0,0 +1,57 @@
+package com.example.fms.common.model.dto;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.util.Date;
+
+/**
+ * 系统文件更新dto
+ *
+ * @Author xiexiang
+ * @Date 2023/6/1
+ */
+@Accessors(chain = true)
+@Data
+public class SystemFileUpdateDTO {
+    /**
+     * 主键id
+     */
+    private Integer id;
+
+    /**
+     * 唯一标识id
+     */
+    private String GUID;
+
+    /**
+     * 文件路径
+     */
+    private String filePath;
+
+    /**
+     * 文件名称
+     */
+    private String fileName;
+
+    /**
+     * 原始名称
+     */
+    private String originalName;
+
+    /**
+     * 文件大小
+     */
+    private String fileLength;
+
+    /**
+     * 更新时间
+     */
+    private Date updateTime;
+
+    /**
+     * 是否删除
+     */
+    private Integer isDelete;
+
+}

+ 17 - 0
src/main/java/com/example/fms/common/model/dto/UploadFileDTO.java

@@ -0,0 +1,17 @@
+package com.example.fms.common.model.dto;
+
+import lombok.Data;
+
+/**
+ * @Author xiexiang
+ * @Date 2023/5/31
+ */
+@Data
+public class UploadFileDTO {
+    private String name;
+    private String fileName;
+    private String path;
+    private String extName;
+    private Long fileSize;
+}
+

+ 19 - 0
src/main/java/com/example/fms/common/model/vo/ConfigSettingVO.java

@@ -0,0 +1,19 @@
+package com.example.fms.common.model.vo;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+/**
+ * @Author xiexiang
+ * @Date 2023/6/6
+ */
+@Data
+@Accessors(chain = true)
+public class ConfigSettingVO {
+    private Integer sourceId;
+    private String sourceName;
+    private String name;
+    private Integer id;
+    private String userName;
+    private String password;
+}

+ 175 - 0
src/main/java/com/example/fms/common/model/vo/PersonnelVO.java

@@ -0,0 +1,175 @@
+package com.example.fms.common.model.vo;
+
+import com.example.fms.common.model.BaseVO;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.util.List;
+
+/**
+ * @Author xiexiang
+ * @Date 2023/6/1
+ */
+
+@Data
+@Accessors(chain = true)
+public class PersonnelVO extends BaseVO {
+    /**
+     * ID
+     */
+    private Integer id;
+
+    /**
+     * Front:姓名
+     * Back:人员名称
+     */
+    private String name;
+
+    /**
+     * Front:性别
+     * Back:人员性别
+     */
+    private Integer gender;
+
+    /**
+     * Front:邮箱
+     * Back:人员邮箱
+     */
+    private String email;
+
+    /**
+     * Front:联系方式
+     * Back:人员联系电话
+     */
+    private String mobile;
+
+    /**
+     * Front:所属租户
+     * Back:租户ID
+     */
+    private Integer tenant;
+
+    /**
+     * Front:状态
+     * Back:人员账号状态(1启用0停用)
+     */
+    private Integer state;
+
+    /**
+     * Front:账号
+     * Back:人员账号
+     */
+    private String username;
+
+    /**
+     * Front:密码
+     * Back:人员密码
+     */
+    private String password;
+
+    /**
+     * Front:备注
+     * Back:人员描述
+     */
+    private String remark;
+
+    /**
+     * Front:QQ号
+     * Back:人员QQ号
+     */
+    private String qqNumber;
+    /**
+     * Front:
+     * Back:负责部门List
+     */
+    private List<Integer> dutyDeparts;
+    /**
+     * Front:微信号
+     * Back:人员微信号
+     */
+    private String wechat;
+
+    /**
+     * Front:钉钉号
+     * Back:人员钉钉号
+     */
+    private String nail;
+
+    /**
+     * Front:
+     * Back:租户名称
+     */
+    private String tenantName;
+
+    /**
+     * Front:
+     * Back:租户ID
+     */
+    private Integer tenantId;
+
+    /**
+     * 登陆成功后生成的Token
+     */
+    private String token;
+
+    /**
+     * 角色List
+     */
+    private List<PerRole> rList;
+
+    /**
+     * 部门职位List
+     */
+    private List<DP> dpList;
+    /**
+     * 角色类型(是否为管理角色)
+     */
+    private Integer roleType;
+
+    /**
+     * 剔除的人员Id
+     */
+    private List<Integer> notInPersonIds;
+    /**
+     * 租户类型
+     */
+    private String tenantType;
+    /**
+     * 部门职位绑定关系
+     */
+    @Data
+    public static class DP {
+        /**
+         * 部门名称
+         */
+        private String departmentName;
+        /**
+         * 部门ID
+         */
+        private Integer departmentId;
+        /**
+         * 职位名称
+         */
+        private String positionName;
+        /**
+         * 职位ID
+         */
+        private Integer positionId;
+    }
+
+    /**
+     * 角色信息
+     */
+    @Data
+    public static class PerRole {
+        /**
+         * 角色名称
+         */
+        private String roleName;
+        /**
+         * 角色ID
+         */
+        private Integer roleId;
+    }
+
+}

+ 67 - 0
src/main/java/com/example/fms/common/model/vo/SystemFileVO.java

@@ -0,0 +1,67 @@
+package com.example.fms.common.model.vo;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.util.Date;
+
+/**
+ * 查询系统文件返回VO
+ *
+ * @Author xiexiang
+ * @Date 2023/6/1
+ */
+@Accessors(chain = true)
+@Data
+public class SystemFileVO {
+    /**
+     * 主键id
+     */
+    private Integer id;
+
+    /**
+     * 唯一标识id
+     */
+    private String GUID;
+
+    /**
+     * 文件路径
+     */
+    private String filePath;
+
+    /**
+     * 文件名称
+     */
+    private String fileName;
+
+    /**
+     * 原始名称
+     */
+    private String originalName;
+
+    /**
+     * 文件大小
+     */
+    private String fileLength;
+
+    /**
+     * 创建人id
+     */
+    private Integer createId;
+
+    /**
+     * 更新时间
+     */
+    private Date updateTime;
+
+    /**
+     * 创建时间
+     */
+    private Date createTime;
+
+    /**
+     * 是否删除
+     */
+    private Integer isDelete;
+
+}

+ 147 - 0
src/main/java/com/example/fms/common/utils/BackupUtils.java

@@ -0,0 +1,147 @@
+package com.example.fms.common.utils;
+
+import cn.hutool.core.io.FileUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.boot.system.ApplicationHome;
+import org.yaml.snakeyaml.Yaml;
+
+import java.io.File;
+import java.io.InputStream;
+/**
+ * @Author xiexiang
+ * @Date 2023/5/31
+ */
+@Slf4j
+public class BackupUtils {
+
+    private final static String BACKUP_CONFIG = "backup-config.yml";
+
+    private static Backup getBackupConfig() {
+        try {
+            ApplicationHome ah = new ApplicationHome(BackupUtils.class);
+            File file = ah.getSource();
+            String rootPath = file.getParentFile().toString() + FileUtils.FILE_SEPARATOR + BACKUP_CONFIG;
+            Yaml yaml = new Yaml();
+            InputStream in = FileUtil.getInputStream(rootPath);
+            Backup backup = yaml.loadAs(in, Backup.class);
+            if (in != null) {
+                in.close();
+            }
+            return backup;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    public static void main(String[] args) {
+        System.out.println(getBackupConfig());
+    }
+
+    public void run() {
+        Backup backup = getBackupConfig();
+        if (backup == null) {
+            log.info("数据库备份配置文件不存在");
+            return;
+        }
+        log.info("数据库备份配置文件:{}", backup);
+        if (backup.isEnable()) {
+            String path = FileUtils.getStaticPath(FileUtils.BACKUP_FILE);
+            String fileName = DateUtils.getNowTimeFormat(DateUtils.YYYYMMDDHHMMSS) + ".sql";
+            try {
+                String cmd = String.format("mysqldump --skip-opt -h%s -P%s -u%s -p%s %s > %s", backup.getHost(), backup.getPort(), backup.getUsername(), backup.getPassword(), backup.getDb(), path + FileUtils.FILE_SEPARATOR + fileName);
+                String[] command;
+                if (backup.getOs() == 0) {
+                    command = new String[]{"cmd", "/c", String.valueOf(cmd)};
+                } else {
+                    command = new String[]{"/bin/sh", "-c", String.valueOf(cmd)};
+                }
+                Runtime.getRuntime().exec(command);
+                log.info("备份数据库成功");
+            } catch (Exception e) {
+                e.printStackTrace();
+                log.error("备份数据库失败");
+            }
+        }
+    }
+
+    public static class Backup {
+        private String host;
+        private String port;
+        private String db;
+        private String username;
+        private String password;
+        private int os;
+        private boolean enable;
+
+        @Override
+        public String toString() {
+            return "Backup{" +
+                    "host='" + host + '\'' +
+                    ", port='" + port + '\'' +
+                    ", db='" + db + '\'' +
+                    ", username='" + username + '\'' +
+                    ", password='" + password + '\'' +
+                    ", os=" + os +
+                    ", enable=" + enable +
+                    '}';
+        }
+
+        public boolean isEnable() {
+            return enable;
+        }
+
+        public void setEnable(boolean enable) {
+            this.enable = enable;
+        }
+
+        public String getHost() {
+            return host;
+        }
+
+        public void setHost(String host) {
+            this.host = host;
+        }
+
+        public String getPort() {
+            return port;
+        }
+
+        public void setPort(String port) {
+            this.port = port;
+        }
+
+        public String getDb() {
+            return db;
+        }
+
+        public void setDb(String db) {
+            this.db = db;
+        }
+
+        public String getUsername() {
+            return username;
+        }
+
+        public void setUsername(String username) {
+            this.username = username;
+        }
+
+        public String getPassword() {
+            return password;
+        }
+
+        public void setPassword(String password) {
+            this.password = password;
+        }
+
+        public int getOs() {
+            return os;
+        }
+
+        public void setOs(int os) {
+            this.os = os;
+        }
+    }
+
+}

+ 172 - 0
src/main/java/com/example/fms/common/utils/CacheUtils.java

@@ -0,0 +1,172 @@
+package com.example.fms.common.utils;
+
+import cn.dev33.satoken.exception.NotLoginException;
+import cn.hutool.core.lang.tree.Tree;
+import cn.hutool.core.util.IdUtil;
+import cn.hutool.crypto.SecureUtil;
+import com.example.fms.common.core.base.RedisConf;
+import com.example.fms.common.model.dto.CommonData;
+import com.example.fms.common.model.dto.ProjectFieldOrderDTO;
+import com.example.fms.common.model.vo.PersonnelVO;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * @Author xiexiang
+ * @Date 2023/6/1
+ */
+@Component
+public class CacheUtils {
+
+    @Resource
+    private RedisUtil redisUtil;
+
+    public void setCommonData(CommonData commonData) {
+        redisUtil.set(RedisConf.COMMON_DATA, JsonUtils.objectToJson(commonData));
+    }
+
+    public CommonData getCommonData() {
+        String json = redisUtil.get(RedisConf.COMMON_DATA);
+        if (StringUtils.isEmpty(json)) {
+            return null;
+        } else {
+            return JsonUtils.jsonToPojo(json, CommonData.class);
+        }
+    }
+
+    //    public void setLoginUser(User user) {
+//        redisUtil.set(RedisConf.LOGIN_USER + RedisConf.SYMBOL_COLON + user.getId(), JsonUtils.objectToJson(user));
+//    }
+//
+    public PersonnelVO getLoginUser(Object userId) {
+        String json = redisUtil.get(RedisConf.LOGIN_USER + RedisConf.SYMBOL_COLON + userId);
+        if (StringUtils.isEmpty(json)) {
+            throw new NotLoginException("无数据", "user", "");
+        } else {
+            return com.alibaba.fastjson2.JSONObject.parseObject(json, PersonnelVO.class);
+        }
+    }
+
+    public PersonnelVO getLoginUserPersonnel(Object userId) {
+        String json = redisUtil.get(RedisConf.LOGIN_USER + RedisConf.SYMBOL_COLON + userId);
+        if (StringUtils.isEmpty(json)) {
+            throw new NotLoginException("无数据", "user", "");
+        } else {
+            return com.alibaba.fastjson2.JSONObject.parseObject(json, PersonnelVO.class);
+        }
+    }
+
+    public String getSelectPatentIds(String patentKey) {
+        return redisUtil.get(RedisConf.SELECT_PATENT + RedisConf.SYMBOL_COLON + patentKey);
+    }
+
+    public Integer getSelectPatentNum(String patentKey) {
+        String ids = getSelectPatentIds(patentKey);
+        if (StringUtils.isEmpty(ids)) {
+            return 0;
+        }
+        return StringUtils.changeStringToInteger(ids, ",").size();
+    }
+
+//    public void setAnalysisCountV2(String patentKey, Integer field, Integer expand, String value, String ids) {
+//        String md5 = SecureUtil.md5(field + RedisConf.SYMBOL_COLON + expand + RedisConf.SYMBOL_COLON + patentKey);
+//        String key = RedisConf.ANALYSIS_COUNT + RedisConf.SYMBOL_COLON + md5;
+//        if (StringUtils.isNotEmpty(value) && StringUtils.isNotEmpty(ids)) {
+//            redisUtil.hPut(key, value, ids);
+//            redisUtil.expire(key, 7200, TimeUnit.SECONDS);
+//        }
+//    }
+//
+//    public Object getAnalysisCountIdsV2(String patentKey, Integer field, Integer expand, String name) {
+//        String md5 = SecureUtil.md5(field + RedisConf.SYMBOL_COLON + expand + RedisConf.SYMBOL_COLON + patentKey);
+//        String key = RedisConf.ANALYSIS_COUNT + RedisConf.SYMBOL_COLON + md5;
+//        return redisUtil.hGet(key, name);
+//    }
+//
+//    public List<AnalysisItemResultDTO> getAnalysisCountV2(String patentKey, Integer field, Integer expand) {
+//        List<AnalysisItemResultDTO> resultList = new ArrayList<>();
+//        String md5 = SecureUtil.md5(field + RedisConf.SYMBOL_COLON + expand + RedisConf.SYMBOL_COLON + patentKey);
+//        String key = RedisConf.ANALYSIS_COUNT + RedisConf.SYMBOL_COLON + md5;
+//        Map<Object, Object> result = redisUtil.hGetAll(key);
+//        for (Object name : result.keySet()) {
+//            Object value = result.get(name);
+//            if (StringUtils.isNotNull(value)) {
+//                List<Integer> ids = StringUtils.changeStringToInteger(value.toString(), ",");
+//                AnalysisItemResultDTO analysisItemResultDTO = new AnalysisItemResultDTO();
+//                analysisItemResultDTO.setIds(value.toString());
+//                analysisItemResultDTO.setName(name.toString());
+//                analysisItemResultDTO.setCount(ids.size());
+//                resultList.add(analysisItemResultDTO);
+//            }
+//        }
+//        return resultList;
+//    }
+
+    public List<Tree> setAreaTreeList(List<Tree<Integer>> treeList) {
+        redisUtil.set(RedisConf.COMMON_DATA + RedisConf.SYMBOL_COLON + RedisConf.AREA_LIST, JsonUtils.objectToJson(treeList));
+        return this.getAreaTreeList();
+    }
+
+    public List<Tree> getAreaTreeList() {
+        String json = redisUtil.get(RedisConf.COMMON_DATA + RedisConf.SYMBOL_COLON + RedisConf.AREA_LIST);
+        if (StringUtils.isNotEmpty(json)) {
+            return JsonUtils.jsonToList(json, Tree.class);
+        }
+        return null;
+    }
+
+    public String setSelectPatentIds(List<Integer> patentIds) {
+        String uuid = IdUtil.simpleUUID();
+        redisUtil.setEx(RedisConf.SELECT_PATENT + RedisConf.SYMBOL_COLON + uuid, StringUtils.join(patentIds, ","), 43200, TimeUnit.SECONDS);
+        return uuid;
+    }
+
+    public void deleteUserSystemFieldSetting(Integer projectId, String type, String view, Integer userId) {
+        String key = SecureUtil.md5(projectId + RedisConf.SYMBOL_COLON + type + RedisConf.SYMBOL_COLON + view + RedisConf.SYMBOL_COLON + userId);
+        redisUtil.delete(RedisConf.USER_FIELD + RedisConf.SYMBOL_COLON + key);
+    }
+
+//    public void setUserSystemFieldSetting(Integer projectId, String type, String view, Integer userId, List<PatentField> defaultField) {
+//        String key = SecureUtil.md5(projectId + RedisConf.SYMBOL_COLON + type + RedisConf.SYMBOL_COLON + view + RedisConf.SYMBOL_COLON + userId);
+//        redisUtil.set(RedisConf.USER_FIELD + RedisConf.SYMBOL_COLON + key, JsonUtils.objectToJson(defaultField));
+//    }
+
+//    public List<PatentField> getUserSystemFieldSetting(Integer projectId, String type, String view, Integer userId) {
+//        String key = SecureUtil.md5(projectId + RedisConf.SYMBOL_COLON + type + RedisConf.SYMBOL_COLON + view + RedisConf.SYMBOL_COLON + userId);
+//        String json = redisUtil.get(RedisConf.USER_FIELD + RedisConf.SYMBOL_COLON + key);
+//        if (StringUtils.isNotEmpty(json)) {
+//            return JsonUtils.jsonToList(json, PatentField.class);
+//        }
+//        return new ArrayList<>();
+//    }
+
+    public List<ProjectFieldOrderDTO> getProjectFieldOrder(Integer projectId, Integer userId) {
+        String key = SecureUtil.md5(projectId + RedisConf.SYMBOL_COLON + userId);
+        String json = redisUtil.get(RedisConf.FIELD_ORDER + RedisConf.SYMBOL_COLON + key);
+        if (StringUtils.isNotEmpty(json)) {
+            return JsonUtils.jsonToList(json, ProjectFieldOrderDTO.class);
+        }
+        return new ArrayList<>();
+    }
+
+    public void setProjectFieldOrder(Integer projectId, Integer userId, List<ProjectFieldOrderDTO> data) {
+        String key = SecureUtil.md5(projectId + RedisConf.SYMBOL_COLON + userId);
+        redisUtil.set(RedisConf.FIELD_ORDER + RedisConf.SYMBOL_COLON + key, JsonUtils.objectToJson(data));
+    }
+
+    public void setUserImportId(Integer userId, Integer importId) {
+        redisUtil.set(RedisConf.USER_IMPORT + RedisConf.SYMBOL_COLON + userId, String.valueOf(importId));
+    }
+
+    public String getUserImportId(Integer userId) {
+        return redisUtil.get(RedisConf.USER_IMPORT + RedisConf.SYMBOL_COLON + userId);
+    }
+
+    public void deleteUserImport(Integer userId) {
+        redisUtil.delete(RedisConf.USER_IMPORT + RedisConf.SYMBOL_COLON + userId);
+    }
+}

+ 667 - 0
src/main/java/com/example/fms/common/utils/DateUtils.java

@@ -0,0 +1,667 @@
+package com.example.fms.common.utils;
+
+import cn.hutool.core.date.DateTime;
+import cn.hutool.core.date.DateUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.lang.management.ManagementFactory;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.*;
+import java.util.regex.Pattern;
+
+/**
+ * @Author xiexiang
+ * @Date 2023/5/31
+ */
+public class DateUtils {
+
+    public static final String START_TIME = " 00:00:00";
+    public static final String END_TIME = " 23:59:59";
+    public final static String FORMAT_STRING = "yyyy-MM-dd HH:mm:ss";
+    public final static String[] REPLACE_STRING = new String[]{"GMT+0800", "GMT+08:00"};
+    public final static String SPLIT_STRING = "(中国标准时间)";
+    public static Logger log = LoggerFactory.getLogger(DateUtils.class);
+    public static String YYYY = "yyyy";
+    public static String YYYY_MM = "yyyy-MM";
+    public static String YYYY_MM_DD = "yyyy-MM-dd";
+    public static String YYYYMMDDHHMMSS = "yyyyMMddHHmmss";
+    public static String YYYYMMDD = "yyyyMMdd";
+    public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
+    private static String[] parsePatterns = {
+            "yyyy-MM-dd", "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM",
+            "yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm", "yyyy/MM",
+            "yyyy.MM.dd", "yyyy.MM.dd HH:mm:ss", "yyyy.MM.dd HH:mm", "yyyy.MM"};
+
+    public static String getDateSourceName(Date startTime, Date endTime, Integer offset, Integer index) {
+        String ret = null;
+        switch (offset) {
+            //月份
+            case -1:
+                ret = DateUtil.format(startTime, "yyyy-MM");
+                break;
+            //季度
+            case -3:
+                ret = String.format("%s-Q%s", DateUtil.format(startTime, "yyyy"), (index % 4) + 1);
+                break;
+            //半年
+            case -6:
+                ret = String.format("%s-%s", DateUtil.format(startTime, "yyyy"), index % 2 == 0 ? "H1" : "H2");
+                break;
+            //1年
+            case -12:
+                ret = DateUtil.format(startTime, "yyyy");
+                break;
+            //2年,3年,5年
+            case -24:
+            case -36:
+            case -60:
+                ret = String.format("%s-%s", DateUtil.format(DateUtil.offsetMonth(endTime, offset / 12 * -1), "yyyy"), DateUtil.format(startTime, "yyyy"));
+                break;
+        }
+        return ret;
+    }
+
+    private DateUtils() {
+    }
+
+    public static Integer getWeek(String beginDateStr, String endDateStr, String date) {
+        DateTime beginDate = DateUtil.parseDate(beginDateStr);
+        DateTime endDate = DateUtil.parseDate(endDateStr);
+        DateTime currentDate = DateUtil.parseDate(date);
+        int week = 1;
+        if (DateUtil.isIn(currentDate, beginDate, endDate)) {
+            Date endDateOfWeek = DateUtil.endOfWeek(beginDate);
+            while (!DateUtil.isIn(currentDate, beginDate, endDateOfWeek)) {
+                ++week;
+                endDateOfWeek = DateUtil.endOfWeek(DateUtil.offsetDay(endDateOfWeek, 1));
+            }
+            return week;
+        }
+        return -1;
+    }
+
+    public static boolean belongCalendar(Date nowTime, Date beginTime, Date endTime) {
+        Calendar date = Calendar.getInstance();
+        date.setTime(nowTime);
+        Calendar begin = Calendar.getInstance();
+        begin.setTime(beginTime);
+        Calendar end = Calendar.getInstance();
+        end.setTime(endTime);
+        return date.after(begin) && date.before(end);
+    }
+
+    /**
+     * 获取现在的时间 yyyy-MM-dd HH:mm:ss
+     */
+    public static String getNowTime() {
+        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        Date date = new Date(System.currentTimeMillis());
+        return format.format(date);
+    }
+
+    /**
+     * 获取当前Date型日期
+     *
+     * @return Date() 当前日期
+     */
+    public static Date getNowDate() {
+        return new Date();
+    }
+
+    public static Integer getDateTime() {
+        return (int) (new Date().getTime() / 1000);
+    }
+
+    public static Integer getDateTime(String date) {
+        int dateTime = 0;
+        if (date.contains("/")) {
+            dateTime = Math.toIntExact(strToDateTime(date, parsePatterns[4]).getTime() / 1000);
+        } else if (date.contains("-")) {
+            dateTime = Math.toIntExact(strToDateTime(date, YYYY_MM_DD).getTime() / 1000);
+        }
+        return dateTime;
+    }
+
+    /**
+     * @author 陌溪
+     * @date 2018年6月14日
+     */
+    public static String getNowTimeFormat(String format) {
+        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
+        Date date = new Date(System.currentTimeMillis());
+        return simpleDateFormat.format(date);
+    }
+
+
+    public static Date str2Date(String dateString) {
+        try {
+            dateString = dateString.split(Pattern.quote(SPLIT_STRING))[0].replace(REPLACE_STRING[0], REPLACE_STRING[1]);
+            SimpleDateFormat sf1 = new SimpleDateFormat("E MMM dd yyyy HH:mm:ss z", Locale.US);
+            return sf1.parse(dateString);
+        } catch (Exception e) {
+            throw new RuntimeException("时间转化格式错误" + "[dateString=" + dateString + "]" + "[FORMAT_STRING=" + FORMAT_STRING + "]");
+        }
+    }
+
+    public static Date strToDate(String dateString) {
+        try {
+            SimpleDateFormat sf1;
+            if (dateString.contains("-")) {
+                sf1 = new SimpleDateFormat("yyyy-MM-dd");
+            } else if (dateString.contains("//")) {
+                sf1 = new SimpleDateFormat("yyyy/MM/dd");
+            } else if (dateString.contains(":")) {
+                sf1 = new SimpleDateFormat("yyyy:MM:dd");
+            } else if (dateString.contains(".")) {
+                sf1 = new SimpleDateFormat("yyyy.MM.dd");
+            } else {
+                sf1 = new SimpleDateFormat("yyyyMMdd");
+            }
+
+            return sf1.parse(dateString);
+        } catch (Exception e) {
+            throw new RuntimeException("时间转化格式错误" + "[dateString=" + dateString + "]" + "[FORMAT_STRING=" + FORMAT_STRING + "]");
+        }
+    }
+
+    /**
+     * 获取今天开始的时间
+     */
+    public static String getToDayStartTime() {
+        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
+        Date date = new Date(System.currentTimeMillis());
+        return format.format(date);
+    }
+
+    /**
+     * 获取今天结束的时间
+     */
+    public static String getToDayEndTime() {
+        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd 23:59:59");
+        Date date = new Date(System.currentTimeMillis());
+        return format.format(date);
+    }
+
+    /**
+     * 获取昨天开始的时间
+     */
+    public static String getYesterdayStartTime() {
+        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
+        Date date = new Date(System.currentTimeMillis() - 24 * 60 * 60 * 1000L);
+        return format.format(date);
+    }
+
+    /**
+     * 获取昨天结束的时间
+     */
+    public static String getYesterdayEndTime() {
+        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd 23:59:59");
+        Date date = new Date(System.currentTimeMillis() - 24 * 60 * 60 * 1000L);
+        return format.format(date);
+    }
+
+    /**
+     * 获取某天开始的时间
+     */
+    public static String getOneDayStartTime(String oneDay) {
+        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
+        Date date = new Date(oneDay);
+        return format.format(oneDay);
+    }
+
+    /**
+     * 获取某天开始的日期
+     */
+    public static String getOneDayStartTime(Date oneDay) {
+        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
+        return format.format(oneDay);
+    }
+
+    /**
+     * 获取某天结束的时间
+     */
+    public static String getOneDayEndTime(String oneDay) {
+        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
+        Date date = new Date(oneDay);
+        return format.format(date);
+    }
+
+    /**
+     * 获取某天结束的日期
+     */
+    public static String getOneDayEndTime(Date oneDay) {
+        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
+        return format.format(oneDay);
+    }
+
+    /**
+     * 获取本周开始的时间
+     */
+    public static Date getWeekStartTime() {
+        //获得本周一0点时间
+        Calendar cal = Calendar.getInstance();
+        cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
+        cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
+        return cal.getTime();
+    }
+
+    /**
+     * 将 String 转换成 Date
+     */
+    public static Date strToDateTime(String dateTime) {
+        Date date = null;
+        try {
+            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+            date = format.parse(dateTime);
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+        return date;
+    }
+
+    /**
+     * 将 String 转换成 Date (转换格式可传入)
+     */
+    public static Date strToDateTime(String dateTime, String fmt) {
+        Date date = null;
+        try {
+            SimpleDateFormat format = new SimpleDateFormat(fmt);
+            date = format.parse(dateTime);
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+        return date;
+    }
+
+    /**
+     * 将 Date 转换成时间戳
+     */
+    public static Long dateToStamp(String s) throws ParseException {
+        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        Date date = simpleDateFormat.parse(s);
+        return date.getTime();
+    }
+
+    /**
+     * 将 Date 转换成 String
+     */
+    public static String dateTimeToStr(Date dateTime) {
+        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        return format.format(dateTime);
+    }
+
+    public static String dateTimeToStr(Date dateTime, String fmt) {
+
+        SimpleDateFormat format = new SimpleDateFormat(fmt);
+        return format.format(dateTime);
+    }
+
+    /**
+     * 获取本周开始的时间的字符串
+     */
+    public static String getWeekStartTimeStr() {
+        //获得本周一0点时间
+        Calendar cal = Calendar.getInstance();
+        cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
+        cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
+        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
+        return format.format(cal.getTime());
+    }
+
+    /**
+     * 获取本周结束的时间
+     */
+    public static Date getWeekEndTime() {
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(getWeekStartTime());
+        cal.add(Calendar.DAY_OF_WEEK, 7);
+        return cal.getTime();
+    }
+
+    /**
+     * 获取本周结束的时间的字符串
+     */
+    public static String getWeekEndTimeStr() {
+        Calendar cal = Calendar.getInstance();
+        cal.setTime(getWeekStartTime());
+        cal.add(Calendar.DAY_OF_WEEK, 7);
+        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd 23:59:59");
+        return format.format(cal.getTime());
+    }
+
+    /**
+     * 获取上周开始的时间的字符串
+     */
+    public static String getLastWeekStartTimeStr() {
+        int weeks = -1;
+        int mondayPlus = getMondayPlus();
+        GregorianCalendar currentDate = new GregorianCalendar();
+        currentDate.add(GregorianCalendar.DATE, mondayPlus + 7 * weeks);
+        Date monday = currentDate.getTime();
+        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
+        return format.format(monday);
+    }
+
+    /**
+     * 获取本月开始的时间
+     */
+    public static Date getMonthStartTime() {
+        Calendar cal = Calendar.getInstance();
+        cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
+        cal.set(Calendar.DAY_OF_MONTH, cal.getActualMinimum(Calendar.DAY_OF_MONTH));
+        return cal.getTime();
+    }
+
+    /**
+     * 获取本月开始的时间的字符串
+     */
+    public static String getMonthStartTimeStr() {
+        Calendar cal = Calendar.getInstance();
+        cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
+        cal.set(Calendar.DAY_OF_MONTH, cal.getActualMinimum(Calendar.DAY_OF_MONTH));
+        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd 23:59:59");
+        return format.format(cal.getTime());
+    }
+
+    /**
+     * 获取本月结束的时间
+     */
+    public static Date getMonthEndTime() {
+        Calendar cal = Calendar.getInstance();
+        cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
+        cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
+        cal.set(Calendar.HOUR_OF_DAY, 24);
+        return cal.getTime();
+    }
+
+    /**
+     * 获取本月结束的时间的字符串
+     */
+    public static String getMonthEndTimeStr() {
+        Calendar cal = Calendar.getInstance();
+        cal.set(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH), 0, 0, 0);
+        cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
+        cal.set(Calendar.HOUR_OF_DAY, 24);
+        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd 23:59:59");
+        return format.format(cal.getTime());
+    }
+
+    /**
+     * 获取当月的 天数
+     */
+    public static int getCurrentMonthDay() {
+        Calendar a = Calendar.getInstance();
+        a.set(Calendar.DATE, 1);
+        a.roll(Calendar.DATE, -1);
+        return a.get(Calendar.DATE);
+    }
+
+    /**
+     * 得到二个日期间的间隔天数
+     */
+    public static int getDayByTwoDay(String date1, String date2) {
+        SimpleDateFormat myFormatter = new SimpleDateFormat("yyyy-MM-dd");
+        long day;
+        try {
+            Date date = myFormatter.parse(date1);
+            Date myDate = myFormatter.parse(date2);
+            day = (date.getTime() - myDate.getTime()) / (24 * 60 * 60 * 1000);
+        } catch (Exception e) {
+            return 0;
+        }
+        return (int) day;
+    }
+
+    /**
+     * 得到两个日期相差的秒数
+     */
+    public static int getSecondByTwoDay(Date lastDate, Date date) {
+        long second;
+        try {
+            second = (lastDate.getTime() - date.getTime()) / 1000;
+        } catch (Exception e) {
+            return 0;
+        }
+        return (int) second;
+    }
+
+    /**
+     * 判断某个日期属于本周的第几天 (星期一代表第一天)
+     */
+    public static int getDaysByWeek(String dateTime) throws ParseException {
+        Calendar cal = Calendar.getInstance();
+        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
+        Date date = dateFormat.parse(dateTime);
+        cal.setTime(date);
+        int day = cal.get(Calendar.DAY_OF_WEEK);
+        day = day - 1;
+        if (day == 0) {
+            day = 7;
+        }
+        return day;
+    }
+
+    /**
+     * 判断某个日期属于本月的第几天
+     */
+    public static int getDaysByMonth(String dateTime) throws ParseException {
+        Calendar cal = Calendar.getInstance();
+        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
+        Date date = dateFormat.parse(dateTime);
+        cal.setTime(date);
+        return cal.get(Calendar.DAY_OF_MONTH);
+    }
+
+    /**
+     * 根据年 月 获取对应的月份 天数
+     */
+    public static int getDaysByYearMonth(int year, int month) {
+        Calendar a = Calendar.getInstance();
+        a.set(Calendar.YEAR, year);
+        a.set(Calendar.MONTH, month - 1);
+        a.set(Calendar.DATE, 1);
+        a.roll(Calendar.DATE, -1);
+        return a.get(Calendar.DATE);
+    }
+
+
+    /**
+     * 获取当前的年
+     */
+    public static Integer getYears() {
+        Calendar calendar = new GregorianCalendar(TimeZone
+                .getDefault());
+        return calendar.get(Calendar.YEAR);
+    }
+
+    /**
+     * 获取当前的月
+     */
+    public static Integer getMonth() {
+        Calendar calendar = new GregorianCalendar(TimeZone
+                .getDefault());
+        return calendar.get(Calendar.MONTH) + 1;
+    }
+
+    /**
+     * 获取当前天
+     */
+    public static Integer getDay() {
+        Calendar calendar = new GregorianCalendar(TimeZone
+                .getDefault());
+        return calendar.get(Calendar.DAY_OF_MONTH);
+    }
+
+    /**
+     * wx支付的过期时间
+     */
+    public static String getTime(double hour) {
+        long time = (long) (System.currentTimeMillis() + hour * 60 * 60 * 1000L);
+        Date date = new Date(time);
+        SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
+        return format.format(date);
+    }
+
+    /**
+     * 获得当前日期与本周日相差的天数
+     */
+    private static int getMondayPlus() {
+        Calendar cd = Calendar.getInstance();
+        // 获得今天是一周的第几天,星期日是第一天,星期二是第二天......
+        // 因为按中国礼拜一作为第一天所以这里减1
+        int dayOfWeek = cd.get(Calendar.DAY_OF_WEEK) - 1;
+        if (dayOfWeek == 1) {
+            return 0;
+        } else {
+            return 1 - dayOfWeek;
+        }
+    }
+
+    /**
+     * 获取几天之后的日期
+     *
+     * @param date yyyy-MM-dd HH:mm:ss
+     * @param day  加减的天数
+     */
+    public static Date getDate(String date, int day) {
+        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        Calendar cal = Calendar.getInstance();
+        Date beforeDate;
+        try {
+            beforeDate = format.parse(date);
+            cal.setTime(beforeDate);
+            cal.add(Calendar.DAY_OF_MONTH, day);
+            return cal.getTime();
+        } catch (ParseException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    /**
+     * 获取某个日期 在加上 秒数的时间
+     *
+     * @param beforeDate yyyy-MM-dd HH:mm:ss
+     * @param timeSecond 加减的秒数
+     */
+    public static String getDateStr(Date beforeDate, Long timeSecond) {
+        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+        try {
+            // 返回毫秒数 + 添加的毫秒数
+            Long time = beforeDate.getTime() + timeSecond * 1000;
+            return format.format(time);
+        } catch (Exception e) {
+            log.error(e.getMessage());
+        }
+        return "";
+    }
+
+    /**
+     * 把date转换成字符串
+     */
+    public static String formatDate(Date date, String code) {
+        SimpleDateFormat format = new SimpleDateFormat(code);
+        return format.format(date);
+    }
+
+    public static String formatDate(Integer timestamp, String code) {
+        if (timestamp == null || timestamp == 0) {
+            return "";
+        }
+        return formatDate(new Date(timestamp * 1000L), code);
+    }
+
+    /**
+     * 获取过去N天内的日期数组
+     *
+     * @param intervals intervals天内
+     * @param formatStr 格式化字符串   yyyy-MM-dd
+     * @return 日期数组
+     */
+    public static ArrayList<String> getDaysByN(int intervals, String formatStr) {
+        ArrayList<String> pastDaysList = new ArrayList<>();
+        for (int i = intervals - 1; i >= 0; i--) {
+            pastDaysList.add(getPastDate(i, formatStr));
+        }
+        return pastDaysList;
+    }
+
+    /**
+     * 获取过去第几天的日期
+     */
+    public static String getPastDate(int past, String formatStr) {
+        Calendar calendar = Calendar.getInstance();
+        calendar.set(Calendar.DAY_OF_YEAR, calendar.get(Calendar.DAY_OF_YEAR) - past);
+        Date today = calendar.getTime();
+        SimpleDateFormat format = new SimpleDateFormat(formatStr);
+        return format.format(today);
+    }
+
+    /**
+     * 获取某个时间段内所有日期
+     */
+    public static List<String> getDayBetweenDates(String begin, String end) {
+        Date dBegin = strToDateTime(begin);
+        Date dEnd = strToDateTime(end);
+        List<String> lDate = new ArrayList<>();
+        SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd");
+        lDate.add(sd.format(dBegin));
+        Calendar calBegin = Calendar.getInstance();
+        // 使用给定的 Date 设置此 Calendar 的时间
+        calBegin.setTime(dBegin);
+        Calendar calEnd = Calendar.getInstance();
+        // 使用给定的 Date 设置此 Calendar 的时间
+        calEnd.setTime(dEnd);
+        // 测试此日期是否在指定日期之后
+        while (dEnd.after(calBegin.getTime())) {
+            // 根据日历的规则,为给定的日历字段添加或减去指定的时间量
+            calBegin.add(Calendar.DAY_OF_MONTH, 1);
+            lDate.add(sd.format(calBegin.getTime()));
+        }
+        return lDate;
+    }
+
+    /**
+     * 获取服务器启动时间
+     */
+    public static Date getServerStartDate() {
+        long time = ManagementFactory.getRuntimeMXBean().getStartTime();
+        return new Date(time);
+    }
+
+    /**
+     * 计算两个时间差
+     */
+    public static String getDatePoor(Date endDate, Date nowDate) {
+        long nd = 1000 * 24 * 60 * 60;
+        long nh = 1000 * 60 * 60;
+        long nm = 1000 * 60;
+        // 获得两个时间的毫秒时间差异
+        long diff = endDate.getTime() - nowDate.getTime();
+        // 计算差多少天
+        long day = diff / nd;
+        // 计算差多少小时
+        long hour = diff % nd / nh;
+        // 计算差多少分钟
+        long min = diff % nd % nh / nm;
+        return day + "天" + hour + "小时" + min + "分钟";
+    }
+
+    public static long getTimeDiff(Date date) {
+        long NTime = date.getTime();
+        long OTime = getNowDate().getTime();
+        return (NTime - OTime) / 1000 / 60;
+    }
+
+    public static Date setDateHourAndMinute(Date date, int hour, int minute) {
+        Calendar calendar = Calendar.getInstance();
+        calendar.setTime(date);
+        calendar.set(Calendar.HOUR_OF_DAY, hour);
+        calendar.set(Calendar.MINUTE, minute);
+        calendar.set(Calendar.SECOND, 0);
+        return calendar.getTime();
+    }
+}
+

+ 58 - 0
src/main/java/com/example/fms/common/utils/ExcuteConfigUtils.java

@@ -0,0 +1,58 @@
+package com.example.fms.common.utils;
+
+import com.alibaba.fastjson.JSONArray;
+import com.example.fms.common.model.vo.ConfigSettingVO;
+import org.springframework.boot.system.ApplicationHome;
+import org.springframework.stereotype.Service;
+
+import java.io.*;
+import java.nio.charset.StandardCharsets;
+import java.util.List;
+
+/**
+ * 解析配置utils
+ *
+ * @Author xiexiang
+ * @Date 2023/6/2
+ */
+@Service
+public class ExcuteConfigUtils {
+
+    //解析配置utils
+    public static String excuteConfigJson() {
+        ApplicationHome ah = new ApplicationHome(BackupUtils.class);
+        File file = ah.getSource();
+        String settingFilePath = ah + FileUtils.FILE_SEPARATOR + "configSetting.json";
+        BufferedReader reader = null;
+        StringBuilder last = new StringBuilder();
+        InputStreamReader inputStreamReader;
+        try (FileInputStream fileInputStream = new FileInputStream(settingFilePath)) {
+            inputStreamReader = new InputStreamReader(fileInputStream, StandardCharsets.UTF_8);
+
+            reader = new BufferedReader(inputStreamReader);
+            String tempString;
+            while ((tempString = reader.readLine()) != null) {
+                last.append(tempString);
+            }
+            reader.close();
+        } catch (IOException e) {
+            e.printStackTrace();
+        } finally {
+            if (reader != null) {
+                try {
+                    reader.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+        return last.toString();
+    }
+
+    //解析配置utils
+    public static List<ConfigSettingVO> excuteConfigVO() {
+        String config = ExcuteConfigUtils.excuteConfigJson();
+        List<ConfigSettingVO> configSettingVOList = JSONArray.parseArray(config,ConfigSettingVO.class);
+        return configSettingVOList;
+    }
+}

+ 321 - 0
src/main/java/com/example/fms/common/utils/FileUtils.java

@@ -0,0 +1,321 @@
+package com.example.fms.common.utils;
+
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.util.IdUtil;
+
+import com.example.fms.common.model.dto.SystemFileDTO;
+import com.example.fms.common.model.dto.UploadFileDTO;
+import org.apache.commons.fileupload.FileItem;
+import org.apache.commons.fileupload.disk.DiskFileItemFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.system.ApplicationHome;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.web.multipart.commons.CommonsMultipartFile;
+
+import java.io.*;
+import java.net.URL;
+
+@Service
+public class FileUtils {
+
+    public static final String FILE_SEPARATOR = System.getProperty("file.separator");
+    public static final String COMMON_FILE = "file";
+    public static final String BACKUP_FILE = "backup";
+    @Autowired
+    private FileUtils fileUtils;
+
+    public static String getStaticPath(String fileName) {
+        //ApplicationHome类 返回target目录层级
+        ApplicationHome ah = new ApplicationHome(FileUtils.class);
+        //获取 applicationHome 内的路径 ...\target\classes 到这一层级下
+        File file = ah.getSource();
+        //获取 file的parentFile 即最后一级之前的所有层级路径(包括盘符) 这里能获得到的最终层级为  ...\target 后续用FILE_SEPARATOR(系统路径分割通配符 即 "\") 以及fileName拼接生成存放文件的目录层级 即为根目录 root
+        String rootPath = file.getParentFile().toString() + FILE_SEPARATOR + fileName;
+        //根据上方生成的根目录路径 生成对应文件夹 没有就新建
+        File root = new File(rootPath);
+        if (!root.exists()) {
+            root.mkdir();
+        }
+        //返回的最终形式为 盘符:\项目层级\target\file
+        return rootPath;
+    }
+
+    public UploadFileDTO uploadFile(MultipartFile file) {
+        UploadFileDTO fileDTO = new UploadFileDTO();
+        //以下操作为 先取得传入文件的完整文件名 (文件名 + 后缀) 然后用FileUtil分别取出 文件名 和 不带 "." 的后缀 然后将这些内容装配进 实体中
+        //file.getOriginFilename 获取源文件
+        //FileUtil.getPrefix 返回主文件名
+        fileDTO.setName(FileUtil.getPrefix(file.getOriginalFilename()));
+        //FileUtil.extName 获取文件的扩展名(后缀名),扩展名不带 "."
+        fileDTO.setExtName(FileUtil.extName(file.getOriginalFilename()));
+        //获取目录名 用时间作为目录名称
+        String directoryName = this.getDirectoryName();
+        //用IdUtil生成的UUID 与实体中的 extName(后缀名) 拼接后作为文件名 simpleUUID与randomUUID的区别是 simpleUUID 没有 "-"
+        String fileName = IdUtil.simpleUUID() + "." + fileDTO.getExtName();
+        //将完整文件名进行装配
+        fileDTO.setFileName(fileName);
+        //生成存储文件的路径
+        String savePath = this.getSavePath(directoryName);
+        //根据生成存储文件的路径 生成对应文件夹 没有就新建
+        File directory = new File(savePath);
+        if (!directory.exists()) {
+            directory.mkdir();
+        }
+        this.saveFile(file, savePath + fileName);
+        fileDTO.setPath(FILE_SEPARATOR + directoryName + FILE_SEPARATOR + fileName);
+        fileDTO.setFileSize(file.getSize());
+        return fileDTO;
+    }
+
+    public SystemFileDTO getFileInfo(MultipartFile file){
+        SystemFileDTO systemFileDTO = new SystemFileDTO();
+        //以下操作为 先取得传入文件的完整文件名 (文件名 + 后缀) 然后用FileUtil分别取出 文件名 和 不带 "." 的后缀 然后将这些内容装配进 实体中
+        //file.getOriginFilename 获取源文件
+        //FileUtil.getPrefix 返回主文件名
+        systemFileDTO.setFileName(FileUtil.getPrefix(file.getOriginalFilename()));
+
+        return systemFileDTO;
+    }
+
+    public String createDirectory() {
+        String directoryName = this.getDirectoryName();
+        String savePath = this.getSavePath(directoryName);
+        File directory = new File(savePath);
+        if (!directory.exists()) {
+            directory.mkdir();
+        }
+        return directoryName;
+    }
+
+    public void saveFile(MultipartFile file, String path) {
+        try {
+            file.transferTo(new File(path));
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public String getTempPath(String fileName) {
+        String tempPath = getStaticPath(COMMON_FILE) + FILE_SEPARATOR + "temp";
+        File file = new File(tempPath);
+        if (!file.exists()) {
+            file.mkdir();
+        }
+        return tempPath + FILE_SEPARATOR + fileName;
+    }
+
+    public String getSavePath(String directoryName) {
+        return getStaticPath(COMMON_FILE) + FILE_SEPARATOR + directoryName + FILE_SEPARATOR;
+    }
+
+    public String getDirectory(String fileName) {
+        return FILE_SEPARATOR + this.createDirectory() + FILE_SEPARATOR + fileName;
+    }
+
+    public String getDirectory2(String directoryName) {
+        return FILE_SEPARATOR + directoryName + FILE_SEPARATOR;
+    }
+
+    public String getSystemPath(String url) {
+        return getStaticPath(COMMON_FILE) + FILE_SEPARATOR + url;
+    }
+
+    public String getSystemPath() {
+        return getStaticPath(COMMON_FILE);
+    }
+
+    public String getPath(String url) {
+        return getStaticPath(COMMON_FILE) + url;
+    }
+
+
+    public static MultipartFile fileToMultipartFile(File file) {
+        DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory(16, null);
+        FileItem item = diskFileItemFactory.createItem(file.getName(), "text/plain", true, file.getName());
+        int bytesRead = 0;
+        byte[] buffer = new byte[8192];
+        try {
+            FileInputStream fis = new FileInputStream(file);
+            OutputStream os = item.getOutputStream();
+            int len = 8192;
+            while ((bytesRead = fis.read(buffer, 0, len)) != -1) {
+                os.write(buffer, 0, bytesRead);
+            }
+            os.close();
+            fis.close();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return (MultipartFile) new CommonsMultipartFile(item);
+    }
+
+    public static File getFile(String url, String type) throws Exception {
+        //读取图片类型
+        String fileName = url.substring(url.lastIndexOf("."), url.length());
+        File file = null;
+
+        URL urlfile;
+        InputStream inStream = null;
+        OutputStream os = null;
+        try {
+            file = File.createTempFile("new_url", type);
+            //获取文件
+            urlfile = new URL(url);
+            inStream = urlfile.openStream();
+            os = new FileOutputStream(file);
+
+            int bytesRead = 0;
+            byte[] buffer = new byte[8192];
+            while ((bytesRead = inStream.read(buffer, 0, 8192)) != -1) {
+                os.write(buffer, 0, bytesRead);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            try {
+                if (null != os) {
+                    os.close();
+                }
+                if (null != inStream) {
+                    inStream.close();
+                }
+
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+
+        return file;
+    }
+
+    public static File urlToFile(String fileUrl) {
+        String path = System.getProperty("user.dir");
+        File tmpFile = new File(path, "tmp");
+        if (!tmpFile.exists()) {
+            tmpFile.mkdirs();
+        }
+        return urlToFile(fileUrl, tmpFile);
+    }
+
+    /**
+     * @param fileUrl 资源地址
+     * @param tmpFile 临时文件
+     * @Description: 网络资源转file, 用完以后必须删除该临时文件
+     * @return: 返回值
+     */
+    public static File urlToFile(String fileUrl, File tmpFile) {
+        String fileName = fileUrl.substring(fileUrl.lastIndexOf("/"));
+        FileOutputStream downloadFile = null;
+        InputStream openStream = null;
+        File savedFile = null;
+        try {
+            savedFile = new File(tmpFile.getAbsolutePath() + fileName);
+            URL url = new URL(fileUrl);
+            java.net.HttpURLConnection connection = (java.net.HttpURLConnection) url.openConnection();
+            openStream = connection.getInputStream();
+            int index;
+            byte[] bytes = new byte[1024];
+            downloadFile = new FileOutputStream(savedFile);
+            while ((index = openStream.read(bytes)) != -1) {
+                downloadFile.write(bytes, 0, index);
+                downloadFile.flush();
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            try {
+                if (openStream != null) {
+                    openStream.close();
+                }
+                if (downloadFile != null) {
+                    downloadFile.close();
+                }
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+        return savedFile;
+    }
+
+    public static MultipartFile urlToMultipartFile(String url, String type) throws Exception {
+        File file = FileUtils.getFile(url, type);
+        DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory(16, null);
+        FileItem item = diskFileItemFactory.createItem(file.getName(), "text/plain", true, file.getName());
+        int bytesRead = 0;
+        byte[] buffer = new byte[8192];
+        try {
+            FileInputStream fis = new FileInputStream(file);
+            OutputStream os = item.getOutputStream();
+            int len = 8192;
+            while ((bytesRead = fis.read(buffer, 0, len)) != -1) {
+                os.write(buffer, 0, bytesRead);
+            }
+            os.close();
+            fis.close();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        return (MultipartFile) new CommonsMultipartFile(item);
+    }
+
+
+    public UploadFileDTO uploadToLocal(String url, String type) throws Exception {
+        MultipartFile file = FileUtils.urlToMultipartFile(url, type);
+        UploadFileDTO fileDTO = fileUtils.uploadFile(file);
+        return fileDTO;
+
+    }
+
+    public static String readerMethod() throws IOException {
+        String ah = FileUtils.getStaticPath("setting.json");
+        File file = new File(ah);
+        FileReader fileReader = new FileReader(file);
+        Reader reader = new InputStreamReader(new FileInputStream(file), "Utf-8");
+        int ch = 0;
+        StringBuffer sb = new StringBuffer();
+        while ((ch = reader.read()) != -1) {
+            sb.append((char) ch);
+        }
+        fileReader.close();
+        reader.close();
+        String jsonStr = sb.toString();
+        return jsonStr;
+    }
+    public static File multipartFileToFile(MultipartFile file) throws Exception {
+        File toFile = null;
+        if (file.equals("") || file.getSize() <= 0) {
+            file = null;
+        } else {
+            InputStream ins = null;
+            ins = file.getInputStream();
+            toFile = new File(file.getOriginalFilename());
+            inputStreamToFile(ins, toFile);
+            ins.close();
+        }
+        return toFile;
+    }
+
+    //获取流文件
+    private static void inputStreamToFile(InputStream ins, File file) {
+        try {
+            OutputStream os = new FileOutputStream(file);
+            int bytesRead = 0;
+            byte[] buffer = new byte[8192];
+            while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {
+                os.write(buffer, 0, bytesRead);
+            }
+            os.close();
+            ins.close();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public String getDirectoryName() {
+        return DateUtils.getNowTimeFormat("yyyyMMdd");
+    }
+
+
+}
+

+ 342 - 0
src/main/java/com/example/fms/common/utils/JsonUtils.java

@@ -0,0 +1,342 @@
+package com.example.fms.common.utils;
+
+import com.alibaba.fastjson.JSONObject;
+import com.fasterxml.jackson.databind.JavaType;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonSyntaxException;
+import com.google.gson.reflect.TypeToken;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+/**
+ * json解析的工具类
+ */
+public class JsonUtils {
+
+    // 定义jackson对象
+    private static final ObjectMapper MAPPER = new ObjectMapper();
+    public static Logger log = LoggerFactory.getLogger(JsonUtils.class);
+
+    /**
+     * 把对象转换为json数据
+     *
+     * @param obj
+     * @return 2018年5月7日  下午5:27:16
+     */
+    public static String objectToJson(Object obj) {
+        Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
+        try {
+            String json = gson.toJson(obj);
+            return json;
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    /**
+     * 将Object转换成Map
+     *
+     * @param obj
+     * @return
+     */
+    public static Map<String, Object> objectToMap(Object obj) {
+
+        try {
+            Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
+            String json = gson.toJson(obj);
+            return jsonToMap(json);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    /**
+     * 将Object类型的map转换成String类型
+     *
+     * @param map
+     * @return
+     */
+    public static Map<String, String> mapToMap(Map<String, Object> map) {
+        Map<String, String> returnMap = new HashMap<>();
+        for (String key : map.keySet()) {
+            returnMap.put(key, String.valueOf(map.get(key)));
+        }
+        return returnMap;
+    }
+
+    /**
+     * 任意类型转换成Map
+     * @return
+     */
+    public static Map<String, String> object2Map(Object obj) {
+        Map<String, String> hashMap = new HashMap();
+        try {
+            Class c = obj.getClass();
+            Method m[] = c.getDeclaredMethods();
+            for (int i = 0; i < m.length; i++) {
+                if (m[i].getName().indexOf("get")==0) {
+                    // 得到Map的key
+                    String suffixKey = m[i].getName().substring(4);
+                    String prefixKey = m[i].getName().substring(3,4).toLowerCase();
+                    hashMap.put(prefixKey + suffixKey, String.valueOf(m[i].invoke(obj, new Object[0])));
+                }
+            }
+        } catch (Throwable e) {
+            log.error(e.getMessage());
+        }
+        return hashMap;
+    }
+
+
+    /**
+     * 把json字符串转化为对象
+     *
+     * @param jsonString
+     * @param clazz
+     * @return
+     */
+    public static Object jsonToObject(String jsonString, Class<?> clazz) {
+
+        Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
+        Object obj = null;
+        try {
+            obj = gson.fromJson(jsonString, clazz);
+        } catch (JsonSyntaxException e) {
+            e.printStackTrace();
+        }
+        return obj;
+    }
+
+    /**
+     * josn转arrayList
+     *
+     * @param jsonArray
+     * @return
+     */
+    public static ArrayList<?> jsonArrayToArrayList(String jsonArray) {
+
+        Gson gson = new GsonBuilder()
+                .excludeFieldsWithModifiers(Modifier.FINAL, Modifier.TRANSIENT, Modifier.STATIC)
+                .setDateFormat("yyyy-MM-dd HH:mm:ss")
+                .serializeNulls()
+                .create();
+        ArrayList<?> list = null;
+        try {
+            Type listType = new TypeToken<ArrayList<?>>() {
+            }.getType();
+
+            list = gson.fromJson(jsonArray, listType);
+        } catch (JsonSyntaxException e) {
+            e.printStackTrace();
+        }
+        return list;
+    }
+
+    /**
+     * JSON 转 ArrayList
+     */
+    public static ArrayList<?> jsonArrayToArrayList(String jsonArray, Class<?> clazz) {
+
+        Gson gson = new GsonBuilder()
+                .excludeFieldsWithModifiers(Modifier.FINAL, Modifier.TRANSIENT, Modifier.STATIC)
+                .setDateFormat("yyyy-MM-dd HH:mm:ss")
+                .serializeNulls()
+                .create();
+        ArrayList<?> list = null;
+        try {
+
+            list = (ArrayList<?>) gson.fromJson(jsonArray, clazz);
+        } catch (JsonSyntaxException e) {
+            e.printStackTrace();
+        }
+        return list;
+    }
+
+    /**
+     * 把json转换为map类型的数据
+     *
+     * @param json
+     * @return
+     */
+    public static Map<String, Object> jsonToMap(String json) {
+
+        Gson gson = new GsonBuilder()
+                .excludeFieldsWithModifiers(Modifier.FINAL, Modifier.TRANSIENT, Modifier.STATIC)
+                .setDateFormat("yyyy-MM-dd HH:mm:ss")
+                .serializeNulls()
+                .create();
+        Map<String, Object> map = null;
+        try {
+            Type type = new TypeToken<Map<String, Object>>() {
+            }.getType();
+
+            map = gson.fromJson(json, type);
+        } catch (JsonSyntaxException e) {
+            e.printStackTrace();
+        }
+        return map;
+    }
+
+    /**
+     * 将Json转换成Map<String, ?>
+     *
+     * @param json
+     * @param clazz
+     * @return
+     */
+    public static Map<String, ?> jsonToMap(String json, Class<?> clazz) {
+
+        Gson gson = new GsonBuilder()
+                .excludeFieldsWithModifiers(Modifier.FINAL, Modifier.TRANSIENT, Modifier.STATIC)
+                .setDateFormat("yyyy-MM-dd HH:mm:ss")
+                .serializeNulls()
+                .create();
+        Map<String, ?> map = null;
+        try {
+            Type type = new TypeToken<Map<String, ?>>() {
+            }.getType();
+
+            map = gson.fromJson(json, type);
+        } catch (JsonSyntaxException e) {
+            e.printStackTrace();
+        }
+        return map;
+    }
+
+    /**
+     * 将map转换成pojo
+     *
+     * @param map
+     * @param beanType
+     * @param <T>
+     * @return
+     */
+    public static <T> T mapToPojo(Map<String, Object> map, Class<T> beanType) {
+
+        Gson gson = new GsonBuilder()
+                .excludeFieldsWithModifiers(Modifier.FINAL, Modifier.TRANSIENT, Modifier.STATIC)
+                .setDateFormat("yyyy-MM-dd HH:mm:ss")
+                .serializeNulls()
+                .create();
+
+        JsonElement jsonElement = gson.toJsonTree(map);
+        T pojo = gson.fromJson(jsonElement, beanType);
+
+        return pojo;
+    }
+
+    /**
+     * 将json结果集转化为对象
+     *
+     * @param jsonData
+     * @param beanType
+     * @param <T>
+     * @return
+     */
+    public static <T> T jsonToPojo(String jsonData, Class<T> beanType) {
+        try {
+            T t = MAPPER.readValue(jsonData, beanType);
+            return t;
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    /**
+     * 将json数据转换成pojo对象list
+     *
+     * @param jsonData
+     * @param beanType
+     * @return
+     */
+    public static <T> List<T> jsonToList(String jsonData, Class<T> beanType) {
+        JavaType javaType = MAPPER.getTypeFactory().constructParametricType(List.class, beanType);
+        try {
+            List<T> list = MAPPER.readValue(jsonData, javaType);
+            return list;
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+
+    /**
+     * 将任意pojo转化成map
+     *
+     * @param t pojo对象
+     * @return
+     */
+    public static <T> Map<String, Object> pojoToMap(T t) {
+        Map<String, Object> result = new HashMap<String, Object>();
+        Method[] methods = t.getClass().getMethods();
+        try {
+            for (Method method : methods) {
+                Class<?>[] paramClass = method.getParameterTypes();
+                // 如果方法带参数,则跳过
+                if (paramClass.length > 0) {
+                    continue;
+                }
+                String methodName = method.getName();
+                if (methodName.startsWith("get")) {
+                    Object value = method.invoke(t);
+                    result.put(methodName, value);
+                }
+            }
+        } catch (IllegalArgumentException e) {
+            e.printStackTrace();
+        } catch (IllegalAccessException e) {
+            e.printStackTrace();
+        } catch (InvocationTargetException e) {
+            e.printStackTrace();
+        } catch (SecurityException e) {
+            e.printStackTrace();
+        }
+        return result;
+    }
+
+
+    /**
+     * 将二叉树json对象转为sql where后的条件语句
+     *liRJ
+     * @param jsonObject jsaonObject
+     * @return
+     */
+    public static String reSql(JSONObject jsonObject){
+        String str1 = "";
+        String str2 = "";
+        JSONObject jsonLeft =jsonObject.getJSONObject("left");
+        JSONObject jsonRight =jsonObject.getJSONObject("right");
+        if(jsonLeft.containsKey("left")){
+            str1 = reSql(jsonLeft);
+        }
+        else{
+            str1 = jsonLeft.get("field").toString()+jsonLeft.get("opr").toString()+jsonLeft.get("value").toString();
+        }
+        if(jsonRight.containsKey("right")){
+            str2= reSql( jsonRight);
+        }
+        else{
+            str2 =jsonRight.get("field").toString()+jsonRight.get("opr").toString()+jsonRight.get("value").toString();
+        }
+        String sql ="("+ str1+") "+ jsonObject.get("logicOpr")+" ("+str2+")";
+
+        return sql;
+    };
+
+
+}

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1325 - 0
src/main/java/com/example/fms/common/utils/RedisUtil.java


+ 117 - 0
src/main/java/com/example/fms/common/utils/Response.java

@@ -0,0 +1,117 @@
+package com.example.fms.common.utils;
+
+import com.example.fms.common.model.BaseVO;
+
+/**
+ * @Author xiexiang
+ * @Date 2023/5/31
+ */
+public class Response {
+
+    private Integer code;
+    private Object data;
+    private String message;
+    private Object pageColumn;
+
+    public static String success() {
+        Response response = new Response();
+        response.setResultEnum(ResponseEnum.SUCCESS);
+        return JsonUtils.objectToJson(response);
+    }
+
+    public static String success(Object data) {
+        Response response = new Response();
+        response.setResultEnum(ResponseEnum.SUCCESS);
+        response.setData(data);
+        return JsonUtils.objectToJson(response);
+    }
+
+    public static String success(Object data, BaseVO baseVO) {
+        Response response = new Response();
+        response.setResultEnum(ResponseEnum.SUCCESS);
+        response.setData(data);
+        response.setPageColumn(baseVO);
+        return JsonUtils.objectToJson(response);
+    }
+
+    public static String websocket(Object data, ResponseEnum responseEnum) {
+        Response response = new Response();
+        response.setResultEnum(responseEnum);
+        response.setData(data);
+        return JsonUtils.objectToJson(response);
+    }
+
+    public static String error() {
+        Response response = new Response();
+        response.setData(Boolean.FALSE);
+        response.setResultEnum(ResponseEnum.ERROR);
+        return JsonUtils.objectToJson(response);
+    }
+
+    public static String error(String message) {
+        Response response = new Response();
+        response.setCode(ResponseEnum.ERROR.getCode());
+        response.setData(Boolean.FALSE);
+        response.setMessage(message);
+        return JsonUtils.objectToJson(response);
+    }
+
+    public static String error(Object data, String message) {
+        Response response = new Response();
+        response.setCode(ResponseEnum.ERROR.getCode());
+        response.setData(data);
+        response.setMessage(message);
+        return JsonUtils.objectToJson(response);
+    }
+
+    public static String error(ResponseEnum responseEnum) {
+        Response response = new Response();
+        response.setResultEnum(responseEnum);
+        return JsonUtils.objectToJson(response);
+    }
+
+    public Response(Integer code, String message) {
+        this.code = code;
+        this.message = message;
+    }
+
+    public Response() {
+    }
+
+    public Object getData() {
+        return data;
+    }
+
+    public void setData(Object data) {
+        this.data = data;
+    }
+
+    public Object getPageColumn() {
+        return pageColumn;
+    }
+
+    public void setPageColumn(Object pageColumn) {
+        this.pageColumn = pageColumn;
+    }
+
+    public Integer getCode() {
+        return code;
+    }
+
+    public void setCode(Integer code) {
+        this.code = code;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+
+    private void setResultEnum(ResponseEnum responseEnum) {
+        this.code = responseEnum.getCode();
+        this.message = responseEnum.getMessage();
+    }
+}

+ 56 - 0
src/main/java/com/example/fms/common/utils/ResponseEnum.java

@@ -0,0 +1,56 @@
+package com.example.fms.common.utils;
+
+/**
+ * @Author xiexiang
+ * @Date 2023/5/31
+ */
+public enum ResponseEnum {
+
+    SUCCESS(200, "请求成功"),
+    WEB_SOCKET_SUCCESS(2, "WebSocket请求成功"),
+    BATCH_UPLOAD_INSTRUCTION_TASK_SUCCESS(900, "WebSocket请求成功"),
+    PROJECT_IMPORT_TASK_SUCCESS(901, "WebSocket请求成功"),
+    PROJECT_EXPORT_TASK_SUCCESS(902, "WebSocket请求成功"),
+    PATENT_IMPORT_TASK_SUCCESS(903, "WebSocket请求成功"),
+    PATENT_EXPORT_TASK_SUCCESS(904, "WebSocket请求成功"),
+    UNAUTHORIZED(401, "未登录"),
+    NOT_PERMISSION(402, "无操作权限"),
+    FORBIDDEN(403, "拒绝访问"),
+    USERNAME_ERROR(0, "用户名不存在"),
+    PASSWORD_ERROR(0, "密码错误"),
+    VERIFY_CODE_ERROR(0, "验证码错误"),
+    QUERY_CACHE_ERROR(0, "专利检索缓存失效,请重试"),
+    BATCH_UPLOAD_INSTRUCTION_TASK_ERROR(800, "导入说明书失败"),
+    PROJECT_EXPORT_TASK_ERROR(802, "专题库数据导出失败"),
+    PATENT_IMPORT_TASK_ERROR(803, "专利导入专利失败"),
+    PATENT_EXPORT_TASK_ERROR(804, "专利导出专利失败"),
+    SYSTEM_ERROR(500, "系统异常"),
+    ERROR(0, "请求失败"),
+    TENANT_STATUS_ERROR(805,"该用户的租户未启用"),
+    PERSONNEL_STATUS_ERROR(806,"该用户未启用");
+
+
+    private Integer code;
+    private String message;
+
+    ResponseEnum(Integer code, String message) {
+        this.code = code;
+        this.message = message;
+    }
+
+    public Integer getCode() {
+        return code;
+    }
+
+    public void setCode(Integer code) {
+        this.code = code;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+
+    public void setMessage(String message) {
+        this.message = message;
+    }
+}

+ 22 - 0
src/main/java/com/example/fms/common/utils/SFTP.java

@@ -0,0 +1,22 @@
+package com.example.fms.common.utils;
+
+import com.jcraft.jsch.Channel;
+import com.jcraft.jsch.ChannelSftp;
+import com.jcraft.jsch.Session;
+import lombok.Data;
+
+/**
+ * @Author xiexiang
+ * @Date 2023/6/7
+ */
+@Data
+public class SFTP {
+    //会话
+    private Session session;
+
+    //连接通道
+    private Channel channel;
+
+    //sftp操作类
+    private ChannelSftp sftp;
+}

+ 45 - 0
src/main/java/com/example/fms/common/utils/SecurityUtils/LoginUtils.java

@@ -0,0 +1,45 @@
+package com.example.fms.common.utils.SecurityUtils;
+
+import com.example.fms.common.utils.RedisUtil;
+import com.example.fms.common.utils.StringUtils;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestAttributes;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * @Author xiexiang
+ * @Date 2023/6/1
+ */
+@Component
+public class LoginUtils {
+    @Resource
+    private RedisUtil redisUtil;
+
+    public static String getToken() {
+        RequestAttributes ra = RequestContextHolder.getRequestAttributes();
+        ServletRequestAttributes sra = (ServletRequestAttributes) ra;
+        HttpServletRequest httpRequest = Objects.requireNonNull(sra).getRequest();
+        String tem = httpRequest.getHeader("Cookie");
+        List<String> lst = StringUtils.changeStringToString(tem, ";");
+        final String[] token = {null};
+        lst.forEach(item -> {
+            if (item.contains("token")) {
+                token[0] = item;
+            }
+        });
+        return token[0].replaceAll(" ", "");
+    }
+
+    public Integer getId() {
+        String oriToken = LoginUtils.getToken();
+        String q = "token:login:" + oriToken.replace("=", ":");
+        String IdS = redisUtil.get(q);
+        return Integer.parseInt(IdS);
+    }
+}

+ 131 - 0
src/main/java/com/example/fms/common/utils/SpringUtils.java

@@ -0,0 +1,131 @@
+package com.example.fms.common.utils;
+
+import org.springframework.aop.framework.AopContext;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.NoSuchBeanDefinitionException;
+import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.stereotype.Component;
+
+
+/**
+ * spring工具类 方便在非spring管理环境中获取bean
+ */
+@Component
+public final class SpringUtils implements BeanFactoryPostProcessor, ApplicationContextAware {
+    /**
+     * Spring应用上下文环境
+     */
+    private static ConfigurableListableBeanFactory beanFactory;
+
+    private static ApplicationContext applicationContext;
+
+    @Override
+    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
+        SpringUtils.beanFactory = beanFactory;
+    }
+
+    @Override
+    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+        SpringUtils.applicationContext = applicationContext;
+    }
+
+    /**
+     * 获取对象
+     *
+     * @param name
+     * @return Object 一个以所给名字注册的bean的实例
+     * @throws BeansException
+     */
+    @SuppressWarnings("unchecked")
+    public static <T> T getBean(String name) throws BeansException {
+        return (T) beanFactory.getBean(name);
+    }
+
+    /**
+     * 获取类型为requiredType的对象
+     *
+     * @param clz
+     * @return
+     * @throws BeansException
+     */
+    public static <T> T getBean(Class<T> clz) throws BeansException {
+        T result = (T) beanFactory.getBean(clz);
+        return result;
+    }
+
+    /**
+     * 如果BeanFactory包含一个与所给名称匹配的bean定义,则返回true
+     *
+     * @param name
+     * @return boolean
+     */
+    public static boolean containsBean(String name) {
+        return beanFactory.containsBean(name);
+    }
+
+    /**
+     * 判断以给定名字注册的bean定义是一个singleton还是一个prototype。 如果与给定名字相应的bean定义没有被找到,将会抛出一个异常(NoSuchBeanDefinitionException)
+     *
+     * @param name
+     * @return boolean
+     * @throws NoSuchBeanDefinitionException
+     */
+    public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException {
+        return beanFactory.isSingleton(name);
+    }
+
+    /**
+     * @param name
+     * @return Class 注册对象的类型
+     * @throws NoSuchBeanDefinitionException
+     */
+    public static Class<?> getType(String name) throws NoSuchBeanDefinitionException {
+        return beanFactory.getType(name);
+    }
+
+    /**
+     * 如果给定的bean名字在bean定义中有别名,则返回这些别名
+     *
+     * @param name
+     * @return
+     * @throws NoSuchBeanDefinitionException
+     */
+    public static String[] getAliases(String name) throws NoSuchBeanDefinitionException {
+        return beanFactory.getAliases(name);
+    }
+
+    /**
+     * 获取aop代理对象
+     *
+     * @param invoker
+     * @return
+     */
+    @SuppressWarnings("unchecked")
+    public static <T> T getAopProxy(T invoker) {
+        return (T) AopContext.currentProxy();
+    }
+
+    /**
+     * 获取当前的环境配置,无配置返回null
+     *
+     * @return 当前的环境配置
+     */
+    public static String[] getActiveProfiles() {
+        return applicationContext.getEnvironment().getActiveProfiles();
+    }
+
+    /**
+     * 获取当前的环境配置,当有多个环境配置时,只获取第一个
+     *
+     * @return 当前的环境配置
+     */
+    public static String getActiveProfile() {
+        final String[] activeProfiles = getActiveProfiles();
+        return StringUtils.isNotNull(activeProfiles) ? activeProfiles[0] : null;
+    }
+}
+
+

+ 508 - 0
src/main/java/com/example/fms/common/utils/StringUtils.java

@@ -0,0 +1,508 @@
+package com.example.fms.common.utils;
+
+import lombok.extern.slf4j.Slf4j;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.UUID;
+
+/**
+ * @Author xiexiang
+ * @Date 2023/6/1
+ */
+@Slf4j
+public class StringUtils {
+
+    private final static int NUM_32 = 32;
+    //集群号
+    private static int machineId = 1;
+    /** 下划线 */
+    private static final char SEPARATOR = '_';
+
+    /**
+     * 下划线转驼峰命名
+     */
+    public static String toUnderScoreCase(String str) {
+        if (str == null) {
+            return null;
+        }
+        StringBuilder sb = new StringBuilder();
+        // 前置字符是否大写
+        boolean preCharIsUpperCase = true;
+        // 当前字符是否大写
+        boolean curreCharIsUpperCase = true;
+        // 下一字符是否大写
+        boolean nexteCharIsUpperCase = true;
+        for (int i = 0; i < str.length(); i++) {
+            char c = str.charAt(i);
+            if (i > 0) {
+                preCharIsUpperCase = Character.isUpperCase(str.charAt(i - 1));
+            } else {
+                preCharIsUpperCase = false;
+            }
+
+            curreCharIsUpperCase = Character.isUpperCase(c);
+
+            if (i < (str.length() - 1)) {
+                nexteCharIsUpperCase = Character.isUpperCase(str.charAt(i + 1));
+            }
+
+            if (preCharIsUpperCase && curreCharIsUpperCase && !nexteCharIsUpperCase) {
+                sb.append(SEPARATOR);
+            } else if ((i != 0 && !preCharIsUpperCase) && curreCharIsUpperCase) {
+                sb.append(SEPARATOR);
+            }
+            sb.append(Character.toLowerCase(c));
+        }
+
+        return sb.toString();
+    }
+
+    /**
+     * * 判断一个对象是否非空
+     *
+     * @param object Object
+     * @return true:非空 false:空
+     */
+    public static boolean isNotNull(Object object) {
+        return !isNull(object);
+    }
+
+    public static boolean isNull(Object object) {
+        return object == null;
+    }
+
+
+    /**
+     * 把String 转换为 long
+     *
+     * @param str
+     * @param defaultData
+     * @return
+     */
+    public static long getLong(String str, Long defaultData) {
+        Long lnum = defaultData;
+
+        if (isEmpty(str)) {
+            return lnum;
+        }
+        try {
+            lnum = Long.valueOf(str.trim()).longValue();
+        } catch (NumberFormatException e) {
+            log.warn("把String 转换为 long======== " + str);
+        }
+        return lnum;
+
+    }
+
+    /**
+     * 转换成Boolean类型
+     *
+     * @param str
+     * @param defaultData
+     * @return
+     */
+    public static Boolean getBoolean(String str, Boolean defaultData) {
+        Boolean lnum = defaultData;
+
+        if (isEmpty(str)) {
+            return lnum;
+        }
+        try {
+            lnum = Boolean.valueOf(str.trim()).booleanValue();
+        } catch (NumberFormatException e) {
+            log.warn("把String 转换为 long======== " + str);
+        }
+        return lnum;
+
+    }
+
+    /**
+     * 把String转换成int数据
+     *
+     * @param str
+     * @param defaultData
+     * @return
+     */
+    public static int getInt(String str, Integer defaultData) {
+        int inum = defaultData;
+        if (isEmpty(str)) {
+            return inum;
+        }
+        try {
+            inum = Integer.valueOf(str.trim()).intValue();
+        } catch (NumberFormatException e) {
+            log.warn("把String转换成int数据========== " + str);
+        }
+        return inum;
+    }
+
+    /**
+     * 把String转换成double数据
+     *
+     * @param str
+     * @param defaultData
+     * @return
+     */
+    public static double getDouble(String str, Double defaultData) {
+        double dnum = defaultData;
+        if (isEmpty(str)) {
+            return dnum;
+        }
+        try {
+            dnum = Double.valueOf(str.trim()).doubleValue();
+        } catch (NumberFormatException e) {
+            log.error("把String转换成double数据: {}", str);
+        }
+        return dnum;
+    }
+
+    /**
+     * 把String转换成float数据
+     *
+     * @param str
+     * @param defaultData
+     * @return
+     */
+    public static float getFloat(String str, Float defaultData) {
+        float dnum = defaultData;
+        if (isEmpty(str)) {
+            return dnum;
+        }
+        try {
+            dnum = Float.valueOf(str.trim()).floatValue();
+        } catch (NumberFormatException e) {
+            log.error("把String转换成float数据: {}", str);
+        }
+        return dnum;
+    }
+
+    /**
+     * 判断字符串是否为空
+     *
+     * @param s
+     * @return
+     */
+    public static Boolean isEmpty(String s) {
+        if (s == null || s.length() <= 0) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * 判断字符串是否为空
+     *
+     * @param str
+     * @return
+     */
+    public static boolean isNotEmpty(String str) {
+        return !StringUtils.isEmpty(str);
+    }
+
+    /**
+     * 按code截取字符串
+     *
+     * @return
+     */
+    public static String[] split(String str, String code) {
+        String[] split;
+        if (isEmpty(str)) {
+            split = null;
+        } else {
+            split = str.split(code);
+        }
+        return split;
+    }
+
+    /**
+     * 把字符串按code 转换为List<Long>
+     *
+     * @param str
+     * @return
+     */
+    public static List<Long> changeStringToLong(String str, String code) {
+        String[] split = split(str, code);
+        List<Long> lnums = new ArrayList<>();
+        for (String s : split) {
+            if (!isEmpty(s)) {
+                long lnum = getLong(s, 0L);
+                lnums.add(lnum);
+            }
+
+        }
+        return lnums;
+    }
+
+    /**
+     * 把字符串按code 转换为List<String>
+     *
+     * @param str
+     * @return
+     */
+    public static List<String> changeStringToString(String str, String code) {
+        String[] split = split(str, code);
+        List<String> lnums = new ArrayList<>();
+        if(split==null){
+            return lnums;
+        }
+        for (String s : split) {
+            //long lnum = getLong(s, 0l);
+            lnums.add(s);
+        }
+        return lnums;
+    }
+
+    /**
+     * 把字符串按code 转换为List<Long>
+     *
+     * @param str
+     * @return
+     */
+    public static List<Integer> changeStringToInteger(String str, String code) {
+        if (isEmpty(str)) {
+            return new ArrayList<>();
+        }
+        String[] split = split(str, code);
+        List<Integer> inums = new ArrayList<>();
+        for (String s : split) {
+            int inum = getInt(s, 0);
+            inums.add(inum);
+        }
+        return inums;
+    }
+
+
+    /**
+     * 生成唯一订单号
+     *
+     * @return
+     */
+    public static String getOrderNumberByUUID() {
+
+        int hashCodeV = UUID.randomUUID().toString().hashCode();
+        //有可能是负数
+        if (hashCodeV < 0) {
+            hashCodeV = -hashCodeV;
+        }
+        String orderNumber = machineId + String.format("%015d", hashCodeV);
+        return orderNumber;
+    }
+
+    /**
+     * 生成唯一商户退款单号
+     *
+     * @return
+     */
+    public static String getOutRefundNoByUUID() {
+
+        int hashCodeV = UUID.randomUUID().toString().hashCode();
+        //有可能是负数
+        if (hashCodeV < 0) {
+            hashCodeV = -hashCodeV;
+        }
+        String out_refund_no = "BACK" + machineId + String.format("%015d", hashCodeV);
+        return out_refund_no;
+
+    }
+
+    /**
+     * 获取UUID,去掉了-
+     *
+     * @return
+     */
+    public static String getUUID() {
+        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
+        log.debug("获取32位的UUID的调试日志-->>" + uuid);
+        return uuid;
+    }
+
+    /**
+     * 获取雪花UID
+     *
+     * @return
+     */
+//    public static Long getSnowflakeId() {
+//        SnowflakeIdWorker snowflakeIdWorker = new SnowflakeIdWorker(0, 0);
+//        return snowflakeIdWorker.nextId();
+//    }
+
+    /**
+     * list小于0的数据就过滤了
+     * 把list的数组变成1,3,4,5,6
+     *
+     * @param list
+     * @param code
+     * @return
+     */
+    public static String listToString(List<Long> list, String code) {
+        String s = "";
+        if (list == null || list.size() <= 0) {
+            return s;
+        }
+        for (Long l : list) {
+            if (l.longValue() > 0) {
+                s = s + l + code;
+            }
+        }
+        return s;
+    }
+
+    /**
+     * 按code把list的数组转换成字符串
+     *
+     * @param list
+     * @param code
+     * @return
+     */
+    public static String listTranformString(List<String> list, String code) {
+        String s = "";
+        if (list == null || list.size() <= 0) {
+            return s;
+        }
+        s = String.join(code, list);
+        return s;
+    }
+
+    /**
+     * 判断是否为非空字符串
+     *
+     * @param str
+     * @return
+     */
+    public static boolean isNotBlank(String str) {
+        return !StringUtils.isBlank(str);
+    }
+
+    /**
+     * 校验uid列表,检查里面元素是否满足限定长度为32
+     *
+     * @param collection
+     * @return
+     */
+    public static boolean checkUidList(Collection<String> collection) {
+        if (collection.size() == 0) {
+            return false;
+        }
+        for (String uid : collection) {
+            if (uid.trim().length() != NUM_32) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * 判断是否为空字符串
+     *
+     * @param str
+     * @return
+     */
+    public static boolean isBlank(String str) {
+        int strLen;
+        if (str == null || (strLen = str.length()) == 0) {
+            return true;
+        }
+        for (int i = 0; i < strLen; i++) {
+            if ((Character.isWhitespace(str.charAt(i)) == false)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * 判断一个字符串是否为数字
+     *
+     * @param str
+     * @return
+     */
+    public static boolean isNumeric(String str) {
+        try {
+            //把字符串强制转换为数字
+            Integer.valueOf(str);
+            //如果是数字,返回True
+            return true;
+        } catch (Exception e) {
+            //如果抛出异常,返回False
+            return false;
+        }
+    }
+
+    /**
+     * 某个子串是否在字符串内
+     *
+     * @param str
+     * @param searchChar
+     * @return
+     */
+    public static boolean contains(String str, String searchChar) {
+        if (isEmpty(str)) {
+            return false;
+        }
+        return str.indexOf(searchChar) >= 0;
+    }
+
+    /**
+     * 切割字符串
+     *
+     * @param str
+     * @param start
+     * @return
+     */
+    public static String substring(String str, int start) {
+        if (str == null) {
+            return null;
+        }
+        // handle negatives, which means last n characters
+        if (start < 0) {
+            start = str.length() + start;
+        }
+        if (start < 0) {
+            start = 0;
+        }
+        if (start > str.length()) {
+            return "";
+        }
+        return str.substring(start);
+    }
+
+    /**
+     * 判断评论是否为垃圾评论(仅通过单一字符重复出现来判断,以后可以扩展更多的检测方法)
+     *
+     * @param content
+     * @return
+     */
+    public static Boolean isCommentSpam(String content) {
+        if (content == null) {
+            return true;
+        }
+        char[] chars = content.toCharArray();
+        // 最大重复次数
+        Integer maxCount = 4;
+        for (int a = 0; a < chars.length; a++) {
+            Integer count = 1;
+            for (int b = a; b < chars.length - 1; b++) {
+                if (chars[b + 1] == chars[b]) {
+                    count++;
+                    // 判断字符重复的次数是否大于阈值
+                    if (count >= maxCount) {
+                        return true;
+                    }
+                    continue;
+                } else {
+                    break;
+                }
+            }
+        }
+        return false;
+    }
+
+    public static <T> String join(List<T> list, String separator) {
+        return org.apache.commons.lang3.StringUtils.join(list, separator);
+    }
+    public static <T> String join(String[] list, String separator) {
+        return org.apache.commons.lang3.StringUtils.join(list, separator);
+    }
+}

+ 18 - 0
src/main/java/com/example/fms/common/utils/ThrowException.java

@@ -0,0 +1,18 @@
+package com.example.fms.common.utils;
+
+import com.example.fms.exception.XiaoShiException;
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * @Author xiexiang
+ * @Date 2023/5/31
+ */
+@Slf4j
+public class ThrowException {
+
+    public static void throwXiaoShiException(String message) {
+        log.info("{}", message);
+        throw new XiaoShiException(message);
+    }
+
+}

+ 34 - 0
src/main/java/com/example/fms/controller/FileMangerController.java

@@ -0,0 +1,34 @@
+package com.example.fms.controller;
+
+import com.example.fms.common.utils.Response;
+import com.example.fms.service.IFileManagerService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.List;
+
+/**
+ * @Author xiexiang
+ * @Date 2023/6/6
+ */
+@Tag(name = "操作模块")
+@Slf4j
+@RestController
+@RequiredArgsConstructor
+@RequestMapping("/fileManager")
+public class FileMangerController {
+    private final IFileManagerService fileManagerService;
+
+    @PostMapping("/uploadSystemFile")
+    @Operation(summary = "上传文件报告")
+    public String upload(List<MultipartFile> files, Integer sourceId) {
+        fileManagerService.add(files, sourceId);
+        return Response.success("上传系统文件成功");
+    }
+}

+ 67 - 0
src/main/java/com/example/fms/domain/AbstractPictureFile.java

@@ -0,0 +1,67 @@
+package com.example.fms.domain;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.util.Date;
+
+/**
+ * 摘要附图文档
+ *
+ * @Author xiexiang
+ * @Date 2023/5/31
+ */
+@Accessors(chain = true)
+@Data
+public class AbstractPictureFile {
+    /**
+     * 主键id
+     */
+    private Integer id;
+
+    /**
+     * 文件路径
+     */
+    private String filePath;
+
+    /**
+     * 文件类型
+     */
+    private String fileType;
+
+    /**
+     * 文件名称
+     */
+    private String fileName;
+
+    /**
+     * 文件大小
+     */
+    private String fileLength;
+
+    /**
+     * 创建时间
+     */
+    private Date createTime;
+
+    /**
+     * 创建人id
+     */
+    private Integer createId;
+
+    /**
+     * 是否删除
+     */
+    private Integer isDelete;
+
+    /**
+     * 专利号
+     */
+    private String patentNo;
+
+    /**
+     * 更新时间
+     */
+    private Date updateTime;
+
+}

+ 71 - 0
src/main/java/com/example/fms/domain/InstructionFile.java

@@ -0,0 +1,71 @@
+package com.example.fms.domain;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.util.Date;
+
+/**
+ * 说明书文档
+ *
+ * @Author xiexiang
+ * @Date 2023/5/31
+ */
+@Accessors(chain = true)
+@Data
+public class InstructionFile {
+    /**
+     * 主键id
+     */
+    private Integer id;
+
+    /**
+     * 文件路径
+     */
+    private String filePath;
+
+    /**
+     * 文件类型
+     */
+    private String fileType;
+
+    /**
+     * 文件名称
+     */
+    private String fileName;
+
+    /**
+     * 文件大小
+     */
+    private String fileLength;
+
+    /**
+     * 创建时间
+     */
+    private Date createTime;
+
+    /**
+     * 创建人id
+     */
+    private Integer createId;
+
+    /**
+     * 是否删除
+     */
+    private Integer isDelete;
+
+    /**
+     * 专利号
+     */
+    private String patentNo;
+
+    /**
+     * 更新时间
+     */
+    private Date updateTime;
+
+    /**
+     * 文档类型
+     */
+    private Integer type;
+}

+ 61 - 0
src/main/java/com/example/fms/domain/OtherFile.java

@@ -0,0 +1,61 @@
+package com.example.fms.domain;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.util.Date;
+
+/**
+ * 其他类型文档
+ *
+ * @Author xiexiang
+ * @Date 2023/5/31
+ */
+@Accessors(chain = true)
+@Data
+public class OtherFile {
+    /**
+     * 主键id
+     */
+    private Integer id;
+
+    /**
+     * 文件路径
+     */
+    private String filePath;
+
+    /**
+     * 文件类型
+     */
+    private String fileType;
+
+    /**
+     * 文件名称
+     */
+    private String fileName;
+
+    /**
+     * 文件大小
+     */
+    private String fileLength;
+
+    /**
+     * 创建时间
+     */
+    private Date createTime;
+
+    /**
+     * 创建人id
+     */
+    private Integer createId;
+
+    /**
+     * 是否删除
+     */
+    private Integer isDelete;
+
+    /**
+     * 更新时间
+     */
+    private Date updateTime;
+}

+ 67 - 0
src/main/java/com/example/fms/domain/SystemFile.java

@@ -0,0 +1,67 @@
+package com.example.fms.domain;
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import java.util.Date;
+
+/**
+ * 系统文件实体类
+ *
+ * @Author xiexiang
+ * @Date 2023/6/1
+ */
+@Accessors(chain = true)
+@Data
+public class SystemFile {
+    /**
+     * 主键id
+     */
+    private Integer id;
+
+    /**
+     * 唯一标识id
+     */
+    private String GUID;
+
+    /**
+     * 文件路径
+     */
+    private String filePath;
+
+    /**
+     * 文件名称
+     */
+    private String fileName;
+
+    /**
+     * 原始名称
+     */
+    private String originalName;
+
+    /**
+     * 文件大小
+     */
+    private String fileLength;
+
+    /**
+     * 创建人id
+     */
+    private Integer createId;
+
+    /**
+     * 更新时间
+     */
+    private Date updateTime;
+
+    /**
+     * 创建时间
+     */
+    private Date createTime;
+
+    /**
+     * 是否删除
+     */
+    private Integer isDelete;
+
+}

+ 13 - 0
src/main/java/com/example/fms/exception/XiaoShiException.java

@@ -0,0 +1,13 @@
+package com.example.fms.exception;
+
+/**
+ * @Author xiexiang
+ * @Date 2023/5/31
+ */
+public class XiaoShiException extends RuntimeException {
+
+    public XiaoShiException(String message) {
+        super(message);
+    }
+
+}

+ 50 - 0
src/main/java/com/example/fms/mapper/SystemFileMapper.java

@@ -0,0 +1,50 @@
+package com.example.fms.mapper;
+
+import com.example.fms.common.model.vo.SystemFileVO;
+import com.example.fms.domain.SystemFile;
+import org.apache.ibatis.annotations.Mapper;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+/**
+ * 系统文件的Mapper层接口
+ *
+ * @Author xiexiang
+ * @Date 2023/6/1
+ */
+@Repository
+@Mapper
+public interface SystemFileMapper {
+    /**
+     * 新增系统文件
+     *
+     * @param systemFile
+     * @return 受影响的行数
+     */
+    int add(SystemFile systemFile);
+
+    /**
+     * 更新系统文件
+     *
+     * @param systemFile
+     * @return
+     */
+    int update(SystemFile systemFile);
+
+    /**
+     * 查询系统文件
+     *
+     * @param id
+     * @return
+     */
+    SystemFileVO query(Integer id);
+
+    /**
+     * 删除系统文件
+     *
+     * @param ids
+     * @return
+     */
+    int delete(List<Integer> ids);
+}

+ 68 - 0
src/main/java/com/example/fms/service/FileFactoryService.java

@@ -0,0 +1,68 @@
+package com.example.fms.service;
+
+import com.example.fms.common.model.dto.SystemFileDTO;
+import com.example.fms.common.model.vo.ConfigSettingVO;
+import com.example.fms.common.utils.ExcuteConfigUtils;
+import com.example.fms.common.utils.FileUtils;
+import com.example.fms.exception.XiaoShiException;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.*;
+
+/**
+ * 上传文件工厂类
+ *
+ * @Author xiexiang
+ * @Date 2023/6/2
+ */
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class FileFactoryService {
+ private final FileUtils fileUtils;
+    //上传方法
+    public List<SystemFileDTO> uploadFiles(List<MultipartFile> files, Integer sourceId){
+        if(files != null && files.size() != 0) {
+            //调用解析配置方法,获取配置信息
+            List<ConfigSettingVO> configSettingVOS = ExcuteConfigUtils.excuteConfigVO();
+            ConfigSettingVO configSettingVO = configSettingVOS.stream().filter(item -> item.getSourceId().equals(sourceId)).findFirst().orElse(null);
+            if (configSettingVO == null) {
+                return null;
+            }
+            String sourceName = configSettingVO.getSourceName();
+            if (sourceName.equals("OSS")) {
+                return this.uploadToOSS(files, configSettingVO);
+            } else if (sourceName.equals("FSS")) {
+                return this.uploadToFSS(files, configSettingVO);
+            }
+            return null;
+        }
+        throw new XiaoShiException("传入文件为空");
+    }
+
+    public List<SystemFileDTO> uploadToOSS(List<MultipartFile> files, ConfigSettingVO configSettingVO){
+        return null;
+    }
+
+    public List<SystemFileDTO> uploadToFSS(List<MultipartFile> files, ConfigSettingVO configSettingVO){
+        List<SystemFileDTO> systemFileDTOS = new ArrayList<>();
+        for(MultipartFile file:files){
+            try {
+                String directoryName = fileUtils.getDirectoryName();
+                SystemFileDTO systemFileDTO = SftpService.upload("/file/"+directoryName, file, configSettingVO);
+                systemFileDTO.setOriginalName(file.getOriginalFilename());
+                systemFileDTO.setFilePath("/file/" + directoryName + "/" + systemFileDTO.getFileName());
+                systemFileDTOS.add(systemFileDTO);
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+        return systemFileDTOS;
+    }
+
+
+}

+ 21 - 0
src/main/java/com/example/fms/service/IFileManagerService.java

@@ -0,0 +1,21 @@
+package com.example.fms.service;
+
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.List;
+
+/**
+ * @Author xiexiang
+ * @Date 2023/6/7
+ */
+public interface IFileManagerService {
+    /**
+     * 上传系统文件
+     *
+     * @param files
+     * @param sourceId
+     */
+    @Transactional
+    void add(List<MultipartFile> files, Integer sourceId);
+}

+ 48 - 0
src/main/java/com/example/fms/service/ISystemFileService.java

@@ -0,0 +1,48 @@
+package com.example.fms.service;
+
+import com.example.fms.common.model.dto.SystemFileDTO;
+import com.example.fms.common.model.dto.SystemFileUpdateDTO;
+import com.example.fms.common.model.vo.SystemFileVO;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+
+/**
+ * @Author xiexiang
+ * @Date 2023/6/1
+ */
+public interface ISystemFileService {
+
+    /**
+     * 新增系统文件
+     *
+     * @param systemFiles
+     */
+    @Transactional
+    void add(List<SystemFileDTO> systemFiles);
+
+    /**
+     * 更新系统文件
+     *
+     * @param systemFiles
+     */
+    @Transactional
+    void update(List<SystemFileUpdateDTO> systemFiles);
+
+    /**
+     * 查询系统文件
+     *
+     * @param id
+     * @return
+     */
+    SystemFileVO query(Integer id);
+
+    /**
+     * 删除系统文件
+     *
+     * @param ids
+     * @return
+     */
+    @Transactional
+    void delete(List<Integer> ids, Integer type);
+}

+ 147 - 0
src/main/java/com/example/fms/service/SftpService.java

@@ -0,0 +1,147 @@
+package com.example.fms.service;
+
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.util.IdUtil;
+import com.example.fms.common.model.dto.SystemFileDTO;
+import com.example.fms.common.model.vo.ConfigSettingVO;
+import com.example.fms.common.utils.FileUtils;
+import com.example.fms.common.utils.SFTP;
+import com.jcraft.jsch.*;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.util.List;
+import java.util.Properties;
+
+/**
+ * sftp配置
+ *
+ * @Author xiexiang
+ * @Date 2023/6/7
+ */
+@Service
+public class SftpService {
+    public static void getConnect(SFTP s, ConfigSettingVO configSettingVO) throws Exception {
+        //** 密钥的密码  */
+//      String privateKey ="key";
+//        /** 密钥文件路径  */
+//      String passphrase ="path";
+        //主机
+        String host = configSettingVO.getName();
+        //端口
+        int port = 22;
+        //用户名
+        String username = configSettingVO.getUserName();
+        //密码
+        String password = configSettingVO.getPassword();
+        //会话初始化
+        Session session = null;
+        //连接通道初始化
+        Channel channel = null;
+        //sftp操作类初始化
+        ChannelSftp sftp = null;
+        JSch jsch = new JSch();
+        //设置密钥和密码
+        //支持密钥的方式登陆,只需在jsch.getSession之前设置一下密钥的相关信息
+//      if (privateKey != null && !"".equals(privateKey)) {
+//             if (passphrase != null && "".equals(passphrase)) {
+//              //设置带口令的密钥
+//                 jsch.addIdentity(privateKey, passphrase);
+//             } else {
+//              //设置不带口令的密钥
+//                 jsch.addIdentity(privateKey);
+//             }
+//      }
+        session = jsch.getSession(username, host, port);
+        session.setPassword(password);
+        Properties config = new Properties();
+        config.put("StrictHostKeyChecking", "no"); // 不验证 HostKey
+        session.setConfig(config);
+        try {
+            session.connect();
+        } catch (Exception e) {
+            if (session.isConnected())
+                session.disconnect();
+        }
+        channel = session.openChannel("sftp");
+        try {
+            channel.connect();
+        } catch (Exception e) {
+            if (channel.isConnected())
+                channel.disconnect();
+        }
+        sftp = (ChannelSftp) channel;
+        s.setChannel(channel);
+        s.setSession(session);
+        s.setSftp(sftp);
+    }
+    /*断开连接*/
+    public static void disConn(Session session,Channel channel,ChannelSftp sftp)throws Exception{
+        if(null != sftp){
+            sftp.disconnect();
+            sftp.exit();
+            sftp = null;
+        }
+        if(null != channel){
+            channel.disconnect();
+            channel = null;
+        }
+        if(null != session){
+            session.disconnect();
+            session = null;
+        }
+    }
+
+    /**
+     * 上传文件
+     * @param directory 上传的目录-相对于SFPT设置的用户访问目录,
+     * 为空则在SFTP设置的根目录进行创建文件(除设置了服务器全磁盘访问)
+     * @param multipartFile 要上传的文件
+     * @param configSettingVO 配置的信息
+     * @return systemFileDTO
+     */
+    public static SystemFileDTO upload(String directory, MultipartFile multipartFile, ConfigSettingVO configSettingVO) throws Exception {
+        SystemFileDTO systemFileDTO = new SystemFileDTO();
+        SFTP s=new SFTP();
+        //建立连接
+        getConnect(s, configSettingVO);
+        Session session = s.getSession();
+        Channel channel = s.getChannel();
+        //sftp操作类
+        ChannelSftp sftp = s.getSftp();
+        try {
+            try{
+                //进入目录
+                sftp.cd(directory);
+            }catch(SftpException sException){
+                //指定上传路径不存在
+                if(sftp.SSH_FX_NO_SUCH_FILE == sException.id){
+                    //创建目录
+                    sftp.mkdir(directory);
+                    //进入目录
+                    sftp.cd(directory);
+                }
+            }
+            //将传入的multipartFile转为所需要的file
+            File file = FileUtils.multipartFileToFile(multipartFile);
+            //定义文件名随机生成
+            String fileName = IdUtil.simpleUUID();
+            //重命名
+            file = FileUtil.rename(file, fileName, true, true);
+            InputStream in= new FileInputStream(file);
+            sftp.put(in, file.getName());
+            in.close();
+            systemFileDTO.setFileName(fileName);
+            systemFileDTO.setFileLength(Long.toString(file.length()));
+            systemFileDTO.setIsDelete(0);
+        } catch (Exception e) {
+            throw new Exception(e.getMessage(),e);
+        } finally {
+            disConn(session, channel, sftp);
+        }
+        return systemFileDTO;
+    }
+}

+ 51 - 0
src/main/java/com/example/fms/service/impl/FileManagerServiceImpl.java

@@ -0,0 +1,51 @@
+package com.example.fms.service.impl;
+
+import com.example.fms.common.model.dto.SystemFileDTO;
+import com.example.fms.exception.XiaoShiException;
+import com.example.fms.service.FileFactoryService;
+import com.example.fms.service.IFileManagerService;
+import com.example.fms.service.ISystemFileService;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.List;
+
+/**
+ * service层实现类
+ *
+ * @Author xiexiang
+ * @Date 2023/6/7
+ */
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class FileManagerServiceImpl implements IFileManagerService {
+    private final FileFactoryService fileFactoryService;
+    private final ISystemFileService systemFileService;
+
+    @Override
+    public void add(List<MultipartFile> files, Integer sourceId){
+        if(files != null && files.size() != 0){
+            //1.获取文件上传到服务器,调用FileFactory的uploadFile
+            List<SystemFileDTO> systemFileDTOS = fileFactoryService.uploadFiles(files, sourceId);
+            //2.根据上传后的返回实体类信息,将实体类信息入库,调用systemFileService add
+            if(systemFileDTOS != null && systemFileDTOS.size() != 0 ) {
+                systemFileService.add(systemFileDTOS);
+            }
+            else {
+                throw new XiaoShiException("入表信息为空");
+            }
+        }
+        else {
+            throw new XiaoShiException("上传文件为空");
+        }
+    }
+
+    //取系统文件
+
+    //删除系统文件
+
+    //系统文件是否存在
+}

+ 142 - 0
src/main/java/com/example/fms/service/impl/SystemFileServiceImpl.java

@@ -0,0 +1,142 @@
+package com.example.fms.service.impl;
+
+import com.example.fms.common.model.dto.SystemFileDTO;
+import com.example.fms.common.model.dto.SystemFileUpdateDTO;
+import com.example.fms.common.model.vo.PersonnelVO;
+import com.example.fms.common.model.vo.SystemFileVO;
+import com.example.fms.common.utils.CacheUtils;
+import com.example.fms.common.utils.SecurityUtils.LoginUtils;
+import com.example.fms.domain.SystemFile;
+import com.example.fms.exception.XiaoShiException;
+import com.example.fms.mapper.SystemFileMapper;
+import com.example.fms.service.ISystemFileService;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeanUtils;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 系统文件的Service层实现类
+ *
+ * @Author xiexiang
+ * @Date 2023/6/1
+ */
+@Slf4j
+@Service
+@RequiredArgsConstructor
+public class SystemFileServiceImpl implements ISystemFileService {
+    private final SystemFileMapper systemFileMapper;
+    private final CacheUtils cacheUtils;
+    private final LoginUtils loginUtils;
+
+    /**
+     * 新增系统文件(批量)
+     *
+     * @param systemFiles
+     */
+    @Override
+    public void add(List<SystemFileDTO> systemFiles){
+        //判断传入列表不为空
+        if(systemFiles != null && systemFiles.size() > 0){
+            SystemFile systemFile = new SystemFile();
+            //遍历传入列表
+            for(int i = 0; i < systemFiles.size(); i++){
+                //取集合中的dto对象,并赋值给实体类
+                SystemFileDTO systemFileDTO = systemFiles.get(i);
+                BeanUtils.copyProperties(systemFileDTO, systemFile);
+//                //获取当前登陆人的信息
+//                PersonnelVO personnelVO = cacheUtils.getLoginUser(loginUtils.getId());
+//                //给实体类赋值登陆人id
+//                systemFile.setCreateId(personnelVO.getId());
+                //插入数据
+                int row = systemFileMapper.add(systemFile);
+                //判断正确性
+                if(row != 1){
+                    String mes = "新增系统文件第" + i + "条失败";
+                    log.info("新增失败,{}", mes);
+                    throw new XiaoShiException(mes);
+                }
+            }log.info("新增系统文件成功");
+        }
+    }
+
+    /**
+     * 更新系统文件(批量)
+     * @param systemFiles
+     */
+    @Override
+    public void update(List<SystemFileUpdateDTO> systemFiles){
+        //判断传入对象不为空
+        if(systemFiles != null && systemFiles.size() > 0){
+            SystemFile systemFile = new SystemFile();
+            //遍历传入列表
+            for(int i = 0; i < systemFiles.size(); i++){
+                //取集合中的dto对象,并赋值给实体类
+                SystemFileUpdateDTO systemFileUpdateDTO = systemFiles.get(i);
+                BeanUtils.copyProperties(systemFileUpdateDTO, systemFile);
+                //数据入表
+                int row = systemFileMapper.update(systemFile);
+                //判断正确性
+                if(row != 1){
+                    String mes = "更新系统文件第" + i + "条失败";
+                    log.info("更新失败,{}", mes);
+                    throw new XiaoShiException(mes);
+                }
+            }log.info("更新系统文件成功");
+        }
+    }
+
+    /**
+     * 查询系统文件
+     *
+     * @param id
+     * @return
+     */
+    @Override
+    public SystemFileVO query(Integer id){
+        //id不为空且id不等于0
+        if(id != null && id != 0){
+            return systemFileMapper.query(id);
+        } else {
+            String mes = "传入id不可以为空";
+            throw new XiaoShiException(mes);
+        }
+    }
+
+
+    @Override
+    public void delete(List<Integer> ids, Integer type){
+        //有逻辑删除和物理删除两种,需要进行判定
+        //首先判断传入的需要删除的id集合不能为空
+        if(ids != null && ids.size() > 0){
+            //tpye不为空,数值为1,物理删除
+            if(type != null && type.equals(1)){
+                int rows = systemFileMapper.delete(ids);
+                if(rows != ids.size()){
+                    throw new XiaoShiException("删除错误");
+                }
+            }
+            //type不为空,数值为0,逻辑删除
+            if(type != null && type.equals(0)){
+                //遍历传入id集合
+                for(int i = 0; i < ids.size(); i++){
+                    //根据id查询出表中这一笔数据,并将isDelete设置为1
+                    SystemFileVO systemFileVO = systemFileMapper.query(ids.get(i));
+                    systemFileVO.setIsDelete(1);
+                    //新建集合用于装载更新数据
+                    List<SystemFileUpdateDTO> tombstone = new ArrayList<>();
+                    //将查询出来的vo赋值给dto
+                    SystemFileUpdateDTO systemFileUpdateDTO = new SystemFileUpdateDTO();
+                    BeanUtils.copyProperties(systemFileVO, systemFileUpdateDTO);
+                    tombstone.add(systemFileUpdateDTO);
+                    this.update(tombstone);
+                }
+            }
+            //type为空,或者为除了0,1之外的数值
+            throw new XiaoShiException("传入类型错误");
+        }
+    }
+}

+ 75 - 0
src/main/resources/mapper/SystemFileMapper.xml

@@ -0,0 +1,75 @@
+<?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.example.fms.mapper.SystemFileMapper">
+    <!--新增系统文件-->
+    <!--int add(SystemFile systemFile);-->
+    <insert id="add" useGeneratedKeys="true" keyProperty="id">
+        INSERT INTO SYSTEM_FILE(GUID, FILE_PATH, FILE_NAME, ORIGINAL_NAME, FILE_LENGTH, CREATE_ID, UPDATE_TIME, IS_DELETE)
+        VALUES (#{GUID}, #{filePath}, #{fileName}, #{originalName}, #{fileLength},#{createId}, #{updateTime}, #{isDelete})
+    </insert>
+
+
+    <!--更新系统文件-->
+    <!--int update(SystemFile systemFile);-->
+    <update id="update">
+        UPDATE SYSTEM_FILE
+        <set>
+            <if test="GUID != null">
+                GUID = #{GUID},
+            </if>
+            <if test="filePath != null">
+                FILE_PATH = #{filePath},
+            </if>
+            <if test="fileName != null">
+                FILE_NAME = #{fileName},
+            </if>
+            <if test="originalName != null">
+                ORIGINAL_NAME = #{originalName},
+            </if>
+            <if test="fileLength != null">
+                FILE_LENGTH = #{fileLength},
+            </if>
+            <if test="updateTime != null">
+                UPDATE_TIME = #{updateTime},
+            </if>
+            <if test="isDelete != null">
+                IS_DELETE = #{isDelete},
+            </if>
+        </set>
+        WHERE ID = #{id}
+    </update>
+
+    <!--查询系统文件-->
+    <!--SystemFileVO query(Integer id);-->
+    <select id="query" resultMap="queryMap">
+        SELECT ID, GUID, FILE_PATH, FILE_NAME, ORIGINAL_NAME, FILE_LENGTH, CREATE_ID, UPDATE_TIME, CREATE_TIME, IS_DELETE
+        FROM SYSTEM_FILE
+        WHERE ID = #{id}
+        ORDER BY CREATE_TIME DESC
+    </select>
+
+    <resultMap id="queryMap" type="com.example.fms.common.model.vo.SystemFileVO">
+        <id column="ID" property="id"/>
+        <result column="GUID" property="GUID"/>
+        <result column="FILE_PATH" property="filePath"/>
+        <result column="FILE_NAME" property="fileName"/>
+        <result column="ORIGINAL_NAME" property="originalName"/>
+        <result column="FILE_LENGTH" property="fileLength"/>
+        <result column="CREATE_ID" property="createId"/>
+        <result column="UPDATE_TIME" property="updateTime"/>
+        <result column="CREATE_TIME" property="createTime"/>
+        <result column="IS_DELETE" property="isDelete"/>
+    </resultMap>
+
+    <!--根据ids删除数据-->
+    <!--int delete(List<Integer> ids);-->
+    <delete id="delete" parameterType="java.util.List">
+        DELETE
+        FROM SYSTEM_FILE
+        WHERE ID IN
+        <foreach collection="ids" item="id" index="index" open="(" close=")" separator=",">
+            #{id}
+        </foreach>
+    </delete>
+</mapper>