6 次代碼提交 e347f3de3c ... 73aa9fe335

作者 SHA1 備註 提交日期
  superb 73aa9fe335 修改冲突 修改Swagger注解文件描述 1 年之前
  superb f523a42179 根据token下载文件模块完成 1 年之前
  wuheng 4e256aac9e Merge branch 'wheng' of wuheng/eas-system into master 1 年之前
  wuheng 397dbfae9b post delete 1 年之前
  wuheng a2e27375c0 Merge branch 'superb' of wuheng/eas-system into master 1 年之前
  wuheng 568ef45e6a 处理签到 1 年之前

+ 73 - 0
common/src/main/java/com/koobietech/eas/common/constant/ArchiveFileType.java

@@ -0,0 +1,73 @@
+package com.koobietech.eas.common.constant;
+
+
+public enum ArchiveFileType {
+    //OFFICE 文件
+    DOC(".doc", 11, "application/msword"),
+    XLS(".xls", 12, "application/vnd.ms-excel"),
+    PPT(".ppt", 13, "application/vnd.ms-powerpoint"),
+    XLSX(".xlsx", 14, "application/vnd.openxmlformats-office, document.spreadsheetml.sheet"),
+    DOCX(".docx", 15, "application/vnd.openxmlformats-office, document.wordprocessingml.document"),
+    PDF(".pdf", 16, "application/pdf"),
+    //文本文件
+    TXT(".txt", 21, "text/plain"),
+    HTML(".html", 22, "text/html"),
+    CSS(".css", 23, "text/css"),
+    JS(".js", 24, "application/x-javascript"),
+    //媒体文件
+    JPG(".jpg", 31, "image/jpeg"),
+    JPEG(".jpeg", 36, "image/jpeg"),
+    GIF(".gif", 32, "image/gif"),
+    MP4(".mp4", 33, "video/mp4"),
+    MP3(".mp3", 34, "audio/mp3"),
+    PNG(".png", 35, "image/png"),
+    //压缩文件
+    GZ(".gz", 41, "application/x-gzip"),
+    ZIP(".zip", 42, "application/zip"),
+    RAR(".rar", 43, "application/x-rar-compressed"),
+    //其他文件
+    FILE(".file", 51, "application/octet-stream");
+
+    private final String suffix;
+    private final int value;
+    private final String contentType;
+
+    ArchiveFileType(String suffix, int value, String contentType) {
+        this.suffix = suffix;
+        this.value = value;
+        this.contentType = contentType;
+    }
+
+    public static String getSuffix(int fileTypeCode) {
+        for (FileType fileType : FileType.values()) {
+            if (fileType.getValue() == fileTypeCode) {
+                return fileType.getSuffix();
+            }
+        }
+        return null;
+    }
+
+    public String getSuffix() {
+        return suffix;
+    }
+
+    public static String getContentType(String suffix) {
+        //根据后缀名获取文件类型
+        for (ArchiveFileType fileType : ArchiveFileType.values()) {
+            if (fileType.getSuffix().equalsIgnoreCase(suffix)) {
+                return fileType.getContentType();
+            }
+        }
+        return null;
+    }
+
+    public String getContentType() {
+        return contentType;
+    }
+
+
+    public int getValue() {
+        return value;
+    }
+}
+

+ 1 - 0
common/src/main/java/com/koobietech/eas/common/constant/FileType.java

@@ -55,4 +55,5 @@ public enum FileType {
     public int getValue() {
         return value;
     }
+
 }

+ 25 - 0
common/src/main/java/com/koobietech/eas/common/utils/PasswordManager.java

@@ -7,7 +7,10 @@ import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Component;
 
 
+import javax.crypto.Cipher;
+import javax.crypto.spec.SecretKeySpec;
 import java.nio.charset.StandardCharsets;
+import java.util.Base64;
 
 /**
  * @author lc
@@ -33,5 +36,27 @@ public class PasswordManager {
         return decryptPassword;
     }
 
+    public String archiveEncryptPassword(String data) {
+        SecureUtil.disableBouncyCastle();
+        AES aes = new AES(passwordSignKey.getBytes(StandardCharsets.UTF_8));
+        String encryptStr;
+        try {
+            encryptStr = aes.encryptHex(data);
+        } catch (Exception e) {
+            throw new EasException("AES加密错误", e);
+        }
+        return encryptStr;
+    }
 
+    public String archiveDecryptPassword(String encryptedData) {
+        SecureUtil.disableBouncyCastle();
+        AES aes = new AES(passwordSignKey.getBytes(StandardCharsets.UTF_8));
+        String decryptedStr;
+        try {
+            decryptedStr = aes.decryptStr(encryptedData);
+        } catch (Exception e) {
+            throw new EasException("AES解密错误", e);
+        }
+        return decryptedStr;
+    }
 }

+ 5 - 2
controller/src/main/java/com/koobietech/eas/controller/EasArcTlsAttendanceController.java

@@ -8,10 +8,12 @@ import com.koobietech.eas.mbg.model.EasArcTlsAttendance;
 import com.koobietech.eas.mbg.model.EasEduClassroom;
 import com.koobietech.eas.service.EasArcTlsAttendanceService;
 import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
 import org.springframework.web.bind.annotation.*;
 
 import javax.annotation.Resource;
 
+@Tag(name = "签到模块")
 @RestController
 @RequestMapping("/attendance")
 public class EasArcTlsAttendanceController {
@@ -20,7 +22,7 @@ public class EasArcTlsAttendanceController {
     private EasArcTlsAttendanceService easArcTlsAttendanceService;
 
     @GetMapping("/getStudentList")
-    @Operation(summary = "获取学生列表", description = "签到的时候会根据班级来获取学生列表(class_id)")
+    @Operation(summary = "获取学生列表", description = "签到的时候会根据课表ID来获取学生列表(scheduleId)")
     public JsonResult getStudentList(@RequestParam Long scheduleId) {
         return JsonResult.data(easArcTlsAttendanceService.getStudentList(scheduleId));
     }
@@ -54,8 +56,9 @@ public class EasArcTlsAttendanceController {
     }
 
 
+
     @DeleteMapping("/delete")
-    @Operation(summary = "删除签到记录", description = "删除签到记录数据根据时间和学员ID")
+    @Operation(summary = "删除签到记录", description = "删除签到记录数据根据时间和学员student_number")
     public JsonResult delete(@RequestBody EasArcTlsAttendance attendance) {
         Boolean ret = easArcTlsAttendanceService.delete(attendance);
         if (ret) {

+ 41 - 0
controller/src/main/java/com/koobietech/eas/controller/EasArchiveFileDownload.java

@@ -0,0 +1,41 @@
+package com.koobietech.eas.controller;
+
+import com.koobietech.eas.common.result.JsonResult;
+import com.koobietech.eas.service.EasArchiveFileDownloadService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletResponse;
+
+@Tag(name = "下载文件模块")
+@RestController
+public class EasArchiveFileDownload {
+
+    @Resource
+    EasArchiveFileDownloadService easArchiveFileDownloadService;
+
+    @GetMapping("/getArchiveFile")
+    @Operation(summary = "获取下载token", description = "前端传入archiveId,后端返回下载token")
+    public JsonResult getFile(Integer archiveId) {
+
+        String archiveToken = easArchiveFileDownloadService.getArchiveToken(archiveId);
+
+        return JsonResult.data(archiveToken);
+    }
+
+    @GetMapping("/getFileByToken")
+    @Operation(summary = "获取文件流", description = "前端把token传入请求头,后端返回文件流")
+    public void getFileByToken(@RequestParam String archiveToken, HttpServletResponse response) {
+
+        //加if判断,如果返回的是false,说明token已经过期,返回null
+        easArchiveFileDownloadService.downloadFileByToken(archiveToken, response);
+    }
+
+
+
+
+}

+ 4 - 1
controller/src/main/java/com/koobietech/eas/controller/EasStuProfileController.java

@@ -4,11 +4,14 @@ package com.koobietech.eas.controller;
 import com.koobietech.eas.common.result.JsonResult;
 import com.koobietech.eas.mbg.model.EasArcTlsStudents;
 import com.koobietech.eas.service.EasStuProfileService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
 import org.springframework.web.bind.annotation.*;
 
 import javax.annotation.Resource;
 import java.io.FileNotFoundException;
 
+@Tag(name = "学生档案下载模块")
 @RestController
 public class EasStuProfileController {
 
@@ -16,7 +19,7 @@ public class EasStuProfileController {
     private EasStuProfileService easStuProfileService;
 
     @PostMapping("/StuProfileDownload")
-
+    @Operation(summary = "保存学生档案为word文档到本地或者服务器中", description = "根据学生档案信息和管理员ID保存学生档案为word文档到本地或者服务器中,注意manager_id要传在url中")
     public JsonResult StuProfileDownload(@RequestBody EasArcTlsStudents easArcTlsStudents, @RequestParam Integer manager_id) throws FileNotFoundException {
         //StuProfileDownload返回值是boolean,这里用JsonResult包装一下 加上if判断
         if (easStuProfileService.StuProfileDownload(easArcTlsStudents, manager_id)) {

+ 4 - 0
service/pom.xml

@@ -56,6 +56,10 @@
             <version>1.3.0</version>
             <scope>compile</scope>
         </dependency>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>javax.servlet-api</artifactId>
+        </dependency>
     </dependencies>
 
     <parent>

+ 7 - 0
service/src/main/java/com/koobietech/eas/service/ArchiveRedisService.java

@@ -0,0 +1,7 @@
+package com.koobietech.eas.service;
+
+public interface ArchiveRedisService {
+    void saveArchiveToken(String token, String filePath);
+
+    String getFilePathByToken(String token);
+}

+ 11 - 0
service/src/main/java/com/koobietech/eas/service/EasArchiveFileDownloadService.java

@@ -0,0 +1,11 @@
+package com.koobietech.eas.service;
+
+import javax.servlet.http.HttpServletResponse;
+
+public interface EasArchiveFileDownloadService {
+    String getArchiveToken(Integer archiveId);
+
+    String getFilePathByToken(String archiveToken);
+
+    boolean downloadFileByToken(String archiveToken, HttpServletResponse response);
+}

+ 31 - 0
service/src/main/java/com/koobietech/eas/service/impl/ArchiveRedisServiceImpl.java

@@ -0,0 +1,31 @@
+package com.koobietech.eas.service.impl;
+
+import com.koobietech.eas.common.exception.EasException;
+import com.koobietech.eas.common.service.RedisService;
+import com.koobietech.eas.service.ArchiveRedisService;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+
+
+@Service
+public class ArchiveRedisServiceImpl implements ArchiveRedisService {
+    @Resource
+    private RedisService redisService;
+
+    private final int ARCHIVE_EXPIRE_TIME = 60*3;
+
+    @Override
+    public void saveArchiveToken(String token, String filePath) {
+        //将token和filePath存入redis,时间设置成三分钟
+        redisService.set(token, filePath, ARCHIVE_EXPIRE_TIME);
+    }
+
+    @Override
+    public String getFilePathByToken(String token) {
+        // 如果取出的值为空,说明token已经过期,返回null
+        // 如果取出的值不为空,说明token没有过期,返回v值
+        return (String) redisService.get(token);
+    }
+
+}

+ 4 - 1
service/src/main/java/com/koobietech/eas/service/impl/EasArcTlsScoresServiceImpl.java

@@ -137,15 +137,18 @@ public class EasArcTlsScoresServiceImpl implements EasArcTlsScoresService {
         try {
             List<EasArcTlsScoresPojo> score = ExcelImportUtil.importExcel(
                     inputStream, EasArcTlsScoresPojo.class, params);
+            EasArcTlsScores easArcTlsScores = null;
             for ( EasArcTlsScoresPojo easArcTlsScoresPojo : score) {
                 if ( easArcTlsScoresPojo.getScore() == null
                         || easArcTlsScoresPojo.getScore().equals("") ) {
                     continue;
                 }
                 easArcTlsScoresPojo.setCreateTime(new Date());
-                EasArcTlsScores easArcTlsScores = new EasArcTlsScores();
+                easArcTlsScores = new EasArcTlsScores();
                 BeanUtil.copyProperties(easArcTlsScoresPojo, easArcTlsScores);
                 easArcTlsScoresMapper.insert(easArcTlsScores);
+            }
+            if ( Objects.nonNull(easArcTlsScores) ) {
                 saveStudentScoreArchive(easArcTlsScores);
             }
         } catch (FileNotFoundException e) {

+ 139 - 0
service/src/main/java/com/koobietech/eas/service/impl/EasArchiveFileDownloadServiceImpl.java

@@ -0,0 +1,139 @@
+package com.koobietech.eas.service.impl;
+
+import cn.hutool.core.lang.UUID;
+import com.koobietech.eas.common.constant.ArchiveFileType;
+import com.koobietech.eas.common.exception.EasException;
+import com.koobietech.eas.common.utils.PasswordManager;
+import com.koobietech.eas.mbg.mapper.EasArcArchivesMapper;
+import com.koobietech.eas.mbg.model.EasArcArchives;
+import com.koobietech.eas.service.ArchiveRedisService;
+import com.koobietech.eas.service.EasArchiveFileDownloadService;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletResponse;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+@Service
+public class EasArchiveFileDownloadServiceImpl implements EasArchiveFileDownloadService {
+    @Resource
+    private PasswordManager passwordManager;
+
+    @Resource
+    private ArchiveRedisService archiveRedisService;
+
+    @Resource
+    private EasArcArchivesMapper archivesMapper;
+
+
+    @Override
+    public String getArchiveToken(Integer archiveId) {
+        //在getArchiveToken中,使用UUID随机生成字符串作为k键,
+        // 为了保证每次生成的字符串不同,在生成的时候加上时间戳
+        // 使用根据id查询到的所需文件在本机上的地址file_path作为v值
+        // 存入redis,时间设置成三分钟
+        // 获取当前时间戳
+        long timestamp = System.currentTimeMillis();
+        // 使用UUID生成一个唯一标识
+        String uniqueId = UUID.randomUUID().toString();
+        // 将用户传入的ID与时间戳和唯一标识拼接起来
+        String token = archiveId + "_" + timestamp + "_" + uniqueId;
+        System.out.println("生成的file token 拼接版:"+token);
+        EasArcArchives easArcArchives = archivesMapper.selectByPrimaryKey(archiveId);
+        // 获取文件路径
+        String filePath = easArcArchives.getFilePath();
+
+        archiveRedisService.saveArchiveToken(token,filePath);
+        // 将token返回给用户
+        String archiveToken = passwordManager.archiveEncryptPassword(token);
+        System.out.println("加密生成的file token 加密版:"+archiveToken);
+        return archiveToken;
+
+    }
+
+    @Override
+    public String getFilePathByToken(String archiveToken) {
+        //在getFilePathByToken中,使用token作为k键,从redis中取出v值
+        // 如果取出的值为空,说明token已经过期,返回null
+        // 如果取出的值不为空,说明token没有过期,返回v值
+        String token = passwordManager.archiveDecryptPassword(archiveToken);
+        System.out.println("解密后的file token:"+token);
+        return archiveRedisService.getFilePathByToken(token);
+    }
+
+
+
+    @Override
+    public boolean downloadFileByToken(String archiveToken, HttpServletResponse response) {
+        //加入判断
+
+        String filePath = getFilePathByToken(archiveToken);
+
+        //加一个判断,如果filePath为空,说明token已经过期,抛出异常
+        if (filePath == null) {
+            throw new EasException("获取文件超时,请重新获取token", 4003);
+        }
+        String fileExtension = getFileExtension(filePath);
+        String archiveFileType = ArchiveFileType.getContentType(fileExtension);
+
+
+        if (archiveFileType != null) {
+            response.addHeader("Content-Type", archiveFileType);
+            response.addHeader("Content-Disposition", "attachment; filename=" + getFileSaveName(filePath) );
+        } else {
+            throw new EasException("文件类型未知", 4000);
+        }
+
+        try (OutputStream outputStream = response.getOutputStream();
+             FileInputStream fileInputStream = new FileInputStream(filePath)) {
+            byte[] buffer = new byte[1024];
+            int bytesRead;
+            while ((bytesRead = fileInputStream.read(buffer)) != -1) {
+                outputStream.write(buffer, 0, bytesRead);
+            }
+            outputStream.flush();
+        } catch (IOException e) {
+            throw new EasException("文件传输失败", 4001);
+        }
+
+        return true;
+    }
+
+    private String getFileExtension(String filePath) {
+        // 获取文件后缀名逻辑,请根据实际情况实现
+        if (filePath == null || filePath.isEmpty()) {
+            return "";
+        }
+
+        int dotIndex = filePath.lastIndexOf(".");
+        if (dotIndex == -1 || dotIndex == filePath.length() - 1) {
+            return "";
+        }
+
+        String extension = filePath.substring(dotIndex);
+        System.out.println("文件后缀名:" + extension);
+
+        return extension;
+    }
+
+    private String getFileSaveName(String filePath) {
+        // 获取文件后缀名逻辑,请根据实际情况实现
+        if (filePath == null || filePath.isEmpty()) {
+            return "";
+        }
+
+        int dotIndex = filePath.lastIndexOf(File.separator );
+        if (dotIndex == -1 || dotIndex == filePath.length() - 1) {
+            return "";
+        }
+
+        String filename = filePath.substring(dotIndex + 1);
+        System.out.println("文件名:" + filename);
+
+        return filename;
+    }
+
+}