deason vor 2 Wochen
Ursprung
Commit
17948115cd

+ 150 - 0
src/main/java/cn/com/qmth/examcloud/tool/service/export_student_photo/DownloadStudentPhoto.java

@@ -0,0 +1,150 @@
+package cn.com.qmth.examcloud.tool.service.export_student_photo;
+
+import ch.qos.logback.classic.LoggerContext;
+import cn.com.qmth.examcloud.tool.service.export_student_photo.vo.StudentInfo;
+import cn.com.qmth.examcloud.tool.utils.FileHelper;
+import cn.com.qmth.examcloud.tool.utils.HttpHelper;
+import cn.com.qmth.examcloud.tool.utils.SignUtils;
+import cn.com.qmth.examcloud.tool.vo.SignRequest;
+import com.alibaba.excel.EasyExcel;
+import com.alibaba.excel.context.AnalysisContext;
+import com.alibaba.excel.event.AnalysisEventListener;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class DownloadStudentPhoto {
+
+    private final static Logger log = LoggerFactory.getLogger(DownloadStudentPhoto.class);
+
+    public static void main(String[] args) {
+        LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
+        loggerContext.getLogger("cn").setLevel(ch.qos.logback.classic.Level.INFO);
+        loggerContext.getLogger("com").setLevel(ch.qos.logback.classic.Level.INFO);
+        loggerContext.getLogger("org").setLevel(ch.qos.logback.classic.Level.INFO);
+
+        SignRequest signReq = new SignRequest();
+        // signReq.setServerUrl("https://www.exam-cloud.cn");
+        // signReq.setServerUrl("http://192.168.10.41:8007");
+        signReq.setServerUrl("http://192.168.10.39:8007");
+        signReq.setRootOrgId(0L);
+        signReq.setAppId("11");
+        signReq.setSecretKey("123456");
+
+        String exportDir = "D:/home/data/todo";
+        List<StudentInfo> students = loadStudentFromExcel(signReq, exportDir + "/students.xlsx");
+        downloadImages(students, exportDir);
+    }
+
+    private static void downloadImages(List<StudentInfo> students, String exportDir) {
+        long startTime = System.currentTimeMillis();
+        AtomicInteger finishAc = new AtomicInteger(), successAc = new AtomicInteger(), failAc = new AtomicInteger();
+        ExecutorService executorService = Executors.newFixedThreadPool(10);
+
+        final int totalCount = students.size();
+        for (StudentInfo student : students) {
+            executorService.execute(() -> {
+                String photoSuffix = FileHelper.getFileSuffix(student.getPhotoUrl());
+                String savePhotoPath = String.format("%s/images/%s%s", exportDir, student.getIdentityNumber(), photoSuffix);
+
+                try {
+                    if (new File(savePhotoPath).exists()) {
+                        log.debug("【图片下载】已处理!{} {}", savePhotoPath, student.getPhotoUrl());
+                    } else {
+                        FileHelper.saveImageToFile(student.getPhotoUrl(), savePhotoPath);
+                    }
+                    successAc.incrementAndGet();
+                } catch (Exception e) {
+                    log.error("【图片下载】 {} err:{}", student.getPhotoUrl(), e.getMessage());
+                    failAc.incrementAndGet();
+                }
+
+                int finishCount = finishAc.incrementAndGet();
+                if (finishCount % 100 == 0) {
+                    float finishRate = finishCount * 100f / totalCount;
+                    long cost = Math.max((System.currentTimeMillis() - startTime) / 1000, 1);
+                    float speed = (float) finishCount / cost;
+                    log.info("【图片下载】总数:{} 成功数:{} 失败数:{} 进度:{}% 速度:约{}个每秒 已耗时:{}秒",
+                            totalCount, successAc.get(), failAc.get(), finishRate, speed, cost);
+                }
+            });
+        }
+
+        executorService.shutdown();
+        while (!executorService.isTerminated()) {
+            // ignore
+        }
+
+        log.info("【图片下载】已执行完成!");
+    }
+
+    private static List<StudentInfo> loadStudentFromExcel(SignRequest signReq, String dataFilePath) {
+        long startTime = System.currentTimeMillis();
+        List<StudentInfo> list = new ArrayList<>();
+        try {
+            EasyExcel.read(dataFilePath, StudentInfo.class, new AnalysisEventListener<StudentInfo>() {
+                        @Override
+                        public void invoke(StudentInfo data, AnalysisContext analysisContext) {
+                            list.add(data);
+                        }
+
+                        @Override
+                        public void doAfterAllAnalysed(AnalysisContext analysisContext) {
+                            // ignore
+                        }
+                    }
+            ).sheet().doRead();
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+            throw new RuntimeException("Excel内容解析错误,请使用标准模板!");
+        }
+
+        int noPhotoCount = 0;
+        List<StudentInfo> hasPhotoStudents = new ArrayList<>();
+        for (StudentInfo student : list) {
+            String photoUrl = getPhotoUrl(signReq, student.getIdentityNumber());
+            if (StringUtils.isEmpty(photoUrl)) {
+                noPhotoCount++;
+                continue;
+            }
+
+            // System.out.println(photoUrl);
+            student.setPhotoUrl(photoUrl);
+            hasPhotoStudents.add(student);
+        }
+
+        long cost = System.currentTimeMillis() - startTime;
+        log.info("【获取学生照片】总数:{} 有底照数:{} 无底照数:{} 耗时:{}ms", list.size(), hasPhotoStudents.size(), noPhotoCount, cost);
+        return hasPhotoStudents;
+    }
+
+    private static String getPhotoUrl(SignRequest signReq, String identityNumber) {
+        long timestamp = System.currentTimeMillis();
+        String accessToken = SignUtils.accessToken(signReq.getRootOrgId(), signReq.getAppId(), signReq.getSecretKey(), timestamp);
+
+        Map<String, String> headers = new HashMap<>();
+        headers.put("rootOrgId", String.valueOf(signReq.getRootOrgId()));
+        headers.put("appId", signReq.getAppId());
+        headers.put("access_token", accessToken);
+        headers.put("timestamp", String.valueOf(timestamp));
+
+        // String url = signReq.getServerUrl() + "/api/exchange/outer/face/getPhotoUrl?rootOrgId=" + signReq.getRootOrgId() + "&studentCode=" + studentCode;
+        String url = signReq.getServerUrl() + "/api/exchange/outer/face/getPhotoUrl?rootOrgId=" + signReq.getRootOrgId() + "&identityNumber=" + identityNumber;
+        try {
+            return HttpHelper.post(url, headers, null);
+        } catch (Exception e) {
+            log.error(e.getMessage());
+            return null;
+        }
+    }
+
+}

+ 20 - 0
src/main/java/cn/com/qmth/examcloud/tool/service/export_student_photo/vo/StudentInfo.java

@@ -0,0 +1,20 @@
+package cn.com.qmth.examcloud.tool.service.export_student_photo.vo;
+
+import com.alibaba.excel.annotation.ExcelProperty;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.io.Serializable;
+
+@Setter
+@Getter
+public class StudentInfo implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ExcelProperty(value = "身份证号", index = 0)
+    private String identityNumber;
+
+    private String photoUrl;
+
+}

+ 24 - 0
src/main/java/cn/com/qmth/examcloud/tool/vo/SignRequest.java

@@ -0,0 +1,24 @@
+package cn.com.qmth.examcloud.tool.vo;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import java.io.Serializable;
+
+@Getter
+@Setter
+public class SignRequest implements Serializable {
+
+    private static final long serialVersionUID = 6987632754151817204L;
+
+    private String serverUrl;
+
+    private Long rootOrgId;
+
+    private String appId;
+
+    private String secretKey;
+
+    private long timestamp;
+
+}

+ 5 - 6
src/test/java/cn/com/qmth/examcloud/tool/UploadTest.java

@@ -22,10 +22,9 @@ public class UploadTest {
     public void init() throws Exception {
         // Configurator.setRootLevel(Level.INFO);
         LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
-        ch.qos.logback.classic.Logger logger = loggerContext.getLogger("org.apache");
-        logger.setLevel(ch.qos.logback.classic.Level.INFO);
-        ch.qos.logback.classic.Logger logger2 = loggerContext.getLogger("com.aliyun");
-        logger2.setLevel(ch.qos.logback.classic.Level.INFO);
+        loggerContext.getLogger("cn").setLevel(ch.qos.logback.classic.Level.INFO);
+        loggerContext.getLogger("com").setLevel(ch.qos.logback.classic.Level.INFO);
+        loggerContext.getLogger("org").setLevel(ch.qos.logback.classic.Level.INFO);
     }
 
     @Test
@@ -62,7 +61,7 @@ public class UploadTest {
                     float finishRate = finishCount * 100f / totalCount;
                     long cost = Math.max((System.currentTimeMillis() - startTime) / 1000, 1);
                     float speed = (float) finishCount / cost;
-                    log.info("【图片上传】 总数:{} 成功数:{} 失败数:{} 进度:{}% 速度:约{}个每秒 已耗时:{}秒",
+                    log.info("【图片上传】总数:{} 成功数:{} 失败数:{} 进度:{}% 速度:约{}个每秒 已耗时:{}秒",
                             totalCount, successAc.get(), failAc.get(), finishRate, speed, cost);
                 }
             });
@@ -73,7 +72,7 @@ public class UploadTest {
             // ignore
         }
 
-        log.info("文件上传已完成!");
+        log.info("【图片上传】已执行完成!");
     }
 
 }