xiatian hai 6 meses
pai
achega
9481de7f6b
Modificáronse 43 ficheiros con 1567 adicións e 1161 borrados
  1. 0 35
      src/main/java/cn/com/qmth/Application.java
  2. 0 77
      src/main/java/cn/com/qmth/SpringContextHolder.java
  3. 164 0
      src/main/java/cn/com/qmth/im/Calculator.java
  4. 2 1
      src/main/java/cn/com/qmth/im/ClearProp.java
  5. 34 0
      src/main/java/cn/com/qmth/im/ConsumerDto.java
  6. 32 32
      src/main/java/cn/com/qmth/im/Course.java
  7. 35 35
      src/main/java/cn/com/qmth/im/CourseDto.java
  8. 1 1
      src/main/java/cn/com/qmth/im/DateUtil.java
  9. 50 0
      src/main/java/cn/com/qmth/im/DeleteQuestionConsumer.java
  10. 22 0
      src/main/java/cn/com/qmth/im/DeleteQuestionDto.java
  11. 87 0
      src/main/java/cn/com/qmth/im/DeleteQuestionProducer.java
  12. 1 1
      src/main/java/cn/com/qmth/im/FileUtil.java
  13. 1 1
      src/main/java/cn/com/qmth/im/FormFilePart.java
  14. 1 1
      src/main/java/cn/com/qmth/im/HttpMethod.java
  15. 2 2
      src/main/java/cn/com/qmth/im/JsonUtil.java
  16. 103 0
      src/main/java/cn/com/qmth/im/MyConsumer.java
  17. 116 0
      src/main/java/cn/com/qmth/im/MyProducer.java
  18. 64 64
      src/main/java/cn/com/qmth/im/NoPaperException.java
  19. 1 1
      src/main/java/cn/com/qmth/im/OKHttpUtil.java
  20. 35 0
      src/main/java/cn/com/qmth/im/QuestionId.java
  21. 1 1
      src/main/java/cn/com/qmth/im/ReWriteExcel.java
  22. 64 64
      src/main/java/cn/com/qmth/im/SSLSocketClient.java
  23. 87 0
      src/main/java/cn/com/qmth/im/StatusException.java
  24. 48 48
      src/main/java/cn/com/qmth/im/Temp.java
  25. 0 35
      src/main/java/cn/com/qmth/importpaper/ConsumerDto.java
  26. 0 93
      src/main/java/cn/com/qmth/importpaper/DeleteImportPaperQuestion.java
  27. 0 41
      src/main/java/cn/com/qmth/importpaper/ImportPaperByCourse.java
  28. 0 95
      src/main/java/cn/com/qmth/importpaper/MyConsumer.java
  29. 0 110
      src/main/java/cn/com/qmth/importpaper/MyProducer.java
  30. 0 15
      src/main/java/cn/com/qmth/importpaper/Param.java
  31. 0 19
      src/main/java/cn/com/qmth/importpaper/QuestionId.java
  32. 147 93
      src/main/java/cn/com/qmth/multithread/Basket.java
  33. 79 55
      src/main/java/cn/com/qmth/multithread/Consumer.java
  34. 1 0
      src/main/java/cn/com/qmth/multithread/EndObject.java
  35. 0 30
      src/main/java/cn/com/qmth/multithread/Kv.java
  36. 17 0
      src/main/java/cn/com/qmth/multithread/ProcessCount.java
  37. 166 130
      src/main/java/cn/com/qmth/multithread/Producer.java
  38. 0 80
      src/main/java/cn/com/qmth/multithread/StatusException.java
  39. 22 0
      src/main/java/cn/com/qmth/param/Param.java
  40. 102 0
      src/main/java/cn/com/qmth/run/DeleteImportPaperQuestion.java
  41. 30 0
      src/main/java/cn/com/qmth/run/DeleteQuestionMulti.java
  42. 45 0
      src/main/java/cn/com/qmth/run/ImportPaperByCourse.java
  43. 7 1
      src/main/java/cn/com/qmth/run/ImportPropByCourse.java

+ 0 - 35
src/main/java/cn/com/qmth/Application.java

@@ -1,35 +0,0 @@
-/*
- * *************************************************
- * Copyright (c) 2018 QMTH. All Rights Reserved.
- * Created by Deason on 2018-07-16 15:00:21.
- * *************************************************
- */
-
-package cn.com.qmth;
-
-import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.SpringBootApplication;
-import org.springframework.boot.autoconfigure.domain.EntityScan;
-import org.springframework.context.annotation.ComponentScan;
-import org.springframework.scheduling.annotation.EnableAsync;
-
-@EnableAsync
-@SpringBootApplication
-@ComponentScan(basePackages = {"cn.com.qmth"})
-@EntityScan(basePackages = {"cn.com.qmth"})
-public class Application {
-
-    static {
-        String runtimeLevel = System.getProperty("log.commonLevel");
-        if (null == runtimeLevel) {
-            System.setProperty("log.commonLevel", "INFO");
-        }
-        System.setProperty("hibernate.dialect.storage_engine", "innodb");
-    }
-
-    public static void main(String[] args) {
-        //SpringApplication.run(ApiApplication.class, args);
-    	SpringApplication.run(Application.class, args);
-    }
-
-}

+ 0 - 77
src/main/java/cn/com/qmth/SpringContextHolder.java

@@ -1,77 +0,0 @@
-package cn.com.qmth;
-
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.ApplicationContextAware;
-import org.springframework.core.ResolvableType;
-import org.springframework.stereotype.Component;
-
-/**
- * spring context holder.
- *
- * @author 
- * @date 2018年7月10日
- * @Copyright (c) 2018-? http://qmth.com.cn All Rights Reserved.
- */
-@Component
-public class SpringContextHolder implements ApplicationContextAware {
-
-	private static ApplicationContext ctx = null;
-
-	@Override
-	public void setApplicationContext(ApplicationContext ctx) {
-		SpringContextHolder.ctx = ctx;
-	}
-
-	public static ApplicationContext getApplicationContext() {
-		return ctx;
-	}
-
-	public static Object getBean(String name) {
-		return ctx.getBean(name);
-	}
-
-	public static <T> T getBean(String name, Class<T> requiredType) {
-		return ctx.getBean(name, requiredType);
-	}
-
-	public static <T> T getBean(Class<T> requiredType) {
-		return ctx.getBean(requiredType);
-	}
-
-	public static Object getBean(String name, Object... args) {
-		return ctx.getBean(name, args);
-	}
-
-	public static <T> T getBean(Class<T> requiredType, Object... args) {
-		return ctx.getBean(requiredType, args);
-	}
-
-	public static boolean containsBean(String name) {
-		return ctx.containsBean(name);
-	}
-
-	public static boolean isSingleton(String name) {
-		return ctx.isSingleton(name);
-	}
-
-	public static boolean isPrototype(String name) {
-		return ctx.isPrototype(name);
-	}
-
-	public static boolean isTypeMatch(String name, ResolvableType typeToMatch) {
-		return ctx.isTypeMatch(name, typeToMatch);
-	}
-
-	public static boolean isTypeMatch(String name, Class<?> typeToMatch) {
-		return ctx.isTypeMatch(name, typeToMatch);
-	}
-
-	public static Class<?> getType(String name) {
-		return ctx.getType(name);
-	}
-
-	public static String[] getAliases(String name) {
-		return ctx.getAliases(name);
-	}
-
-}

+ 164 - 0
src/main/java/cn/com/qmth/im/Calculator.java

@@ -0,0 +1,164 @@
+package cn.com.qmth.im;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+import org.apache.commons.collections4.CollectionUtils;
+
+/**
+ * 计算器
+ *
+ * @author
+ * @date 2019年7月30日
+ * @Copyright (c) 2018-? http://qmth.com.cn All Rights Reserved.
+ */
+public class Calculator {
+
+    public static Double percentageDouble(Integer v1, Integer v2, Integer len) {
+        if (v1 == null || v2 == null || v2 == 0) {
+            return null;
+        }
+        BigDecimal b1 = BigDecimal.valueOf(v1);
+        BigDecimal b2 = BigDecimal.valueOf(v2);
+        BigDecimal b3 = BigDecimal.valueOf(100);
+        return b1.multiply(b3).divide(b2, len, BigDecimal.ROUND_HALF_UP).doubleValue();
+
+    }
+
+    /**
+     * 加法 保留两位小数
+     * 
+     * @param v1
+     * @param v2
+     * @return
+     */
+    public static double add(double v1, double v2) {
+        return add(v1, v2, 2);
+
+    }
+
+    /**
+     * 加法 保留指定位小数
+     * 
+     * @param v1
+     * @param v2
+     * @param len
+     * @return
+     */
+    public static double add(double v1, double v2, int len) {
+        BigDecimal b1 = new BigDecimal(v1);
+        BigDecimal b2 = new BigDecimal(v2);
+        return b1.add(b2).setScale(len, BigDecimal.ROUND_HALF_UP).doubleValue();
+
+    }
+
+    /**
+     * 加法 保留指定位小数
+     * 
+     * @param ds
+     * @param len
+     * @return
+     */
+    public static double add(List<Double> ds, int len) {
+        if (CollectionUtils.isEmpty(ds)) {
+            return 0;
+        }
+        BigDecimal ret = new BigDecimal(0.0);
+        for (Double d : ds) {
+            if (d != null) {
+                ret = ret.add(new BigDecimal(d));
+            }
+        }
+        return ret.setScale(len, BigDecimal.ROUND_HALF_UP).doubleValue();
+
+    }
+
+    /**
+     * 减法 保留两位小数
+     * 
+     * @param v1
+     * @param v2
+     * @return
+     */
+    public static double subtract(double v1, double v2) {
+        return subtract(v1, v2, 2);
+
+    }
+
+    /**
+     * 减法 保留指定位小数
+     * 
+     * @param v1
+     * @param v2
+     * @param len
+     * @return
+     */
+    public static double subtract(double v1, double v2, int len) {
+        BigDecimal b1 = new BigDecimal(v1);
+        BigDecimal b2 = new BigDecimal(v2);
+        return b1.subtract(b2).setScale(len, BigDecimal.ROUND_HALF_UP).doubleValue();
+
+    }
+
+    /**
+     * 乘法 保留两位小数
+     * 
+     * @param v1
+     * @param v2
+     * @return
+     */
+    public static double multiply(double v1, double v2) {
+        return multiply(v1, v2, 2);
+
+    }
+
+    /**
+     * 乘法 保留指定位小数
+     * 
+     * @param v1
+     * @param v2
+     * @param len
+     * @return
+     */
+    public static double multiply(double v1, double v2, int len) {
+        BigDecimal b1 = new BigDecimal(v1);
+        BigDecimal b2 = new BigDecimal(v2);
+        return b1.multiply(b2).setScale(len, BigDecimal.ROUND_HALF_UP).doubleValue();
+
+    }
+
+    /**
+     * 除法 保留两位小数
+     * 
+     * @param v1
+     * @param v2
+     * @param len
+     * @return
+     */
+    public static double divide(double v1, double v2) {
+        return divide(v1, v2, 2);
+    }
+
+    /**
+     * 除法 保留指定位小数
+     * 
+     * @param v1
+     * @param v2
+     * @param len
+     * @return
+     */
+    public static double divide(double v1, double v2, int len) {
+        BigDecimal b1 = new BigDecimal(v1);
+        BigDecimal b2 = new BigDecimal(v2);
+        return b1.divide(b2, len, BigDecimal.ROUND_HALF_UP).doubleValue();
+    }
+
+    public static String divide2String(Double v1, Double v2, int len) {
+        if (v1 == null || v2 == null || v2 == 0) {
+            return "-";
+        }
+        BigDecimal b1 = new BigDecimal(v1);
+        BigDecimal b2 = new BigDecimal(v2);
+        return String.valueOf(b1.divide(b2, len, BigDecimal.ROUND_HALF_UP).doubleValue());
+    }
+}

+ 2 - 1
src/main/java/cn/com/qmth/importpaper/ClearProp.java → src/main/java/cn/com/qmth/im/ClearProp.java

@@ -1,4 +1,4 @@
-package cn.com.qmth.importpaper;
+package cn.com.qmth.im;
 
 import java.io.IOException;
 import java.util.Map;
@@ -9,6 +9,7 @@ import org.apache.logging.log4j.Logger;
 
 import com.google.common.collect.Maps;
 
+import cn.com.qmth.param.Param;
 import okhttp3.Response;
 
 public class ClearProp {

+ 34 - 0
src/main/java/cn/com/qmth/im/ConsumerDto.java

@@ -0,0 +1,34 @@
+package cn.com.qmth.im;
+
+public class ConsumerDto {
+
+    private CourseDto ic;
+
+    private String batch;
+
+    public CourseDto getIc() {
+        return ic;
+    }
+
+    public void setIc(CourseDto ic) {
+        this.ic = ic;
+    }
+
+    public String getBatch() {
+        return batch;
+    }
+
+    public void setBatch(String batch) {
+        this.batch = batch;
+    }
+
+    public ConsumerDto(CourseDto ic, String batch) {
+        super();
+        this.ic = ic;
+        this.batch = batch;
+    }
+
+    public ConsumerDto() {
+    }
+
+}

+ 32 - 32
src/main/java/cn/com/qmth/importpaper/Course.java → src/main/java/cn/com/qmth/im/Course.java

@@ -1,32 +1,32 @@
-package cn.com.qmth.importpaper;
-
-public class Course {
-	private Long id;
-	private String code;
-	private String name;
-
-	public Long getId() {
-		return id;
-	}
-
-	public void setId(Long id) {
-		this.id = id;
-	}
-
-	public String getCode() {
-		return code;
-	}
-
-	public void setCode(String code) {
-		this.code = code;
-	}
-
-	public String getName() {
-		return name;
-	}
-
-	public void setName(String name) {
-		this.name = name;
-	}
-
-}
+package cn.com.qmth.im;
+
+public class Course {
+	private Long id;
+	private String code;
+	private String name;
+
+	public Long getId() {
+		return id;
+	}
+
+	public void setId(Long id) {
+		this.id = id;
+	}
+
+	public String getCode() {
+		return code;
+	}
+
+	public void setCode(String code) {
+		this.code = code;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+}

+ 35 - 35
src/main/java/cn/com/qmth/importpaper/CourseDto.java → src/main/java/cn/com/qmth/im/CourseDto.java

@@ -1,35 +1,35 @@
-package cn.com.qmth.importpaper;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class CourseDto {
-
-	private String subjectCode;
-
-	private List<Course> courses;
-
-	public String getSubjectCode() {
-		return subjectCode;
-	}
-
-	public void setSubjectCode(String subjectCode) {
-		this.subjectCode = subjectCode;
-	}
-
-	public List<Course> getCourses() {
-		return courses;
-	}
-
-	public void setCourses(List<Course> courses) {
-		this.courses = courses;
-	}
-
-	public void addCourse(Course c) {
-		if (courses == null) {
-			courses = new ArrayList<>();
-		}
-		courses.add(c);
-	}
-
-}
+package cn.com.qmth.im;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class CourseDto {
+
+	private String subjectCode;
+
+	private List<Course> courses;
+
+	public String getSubjectCode() {
+		return subjectCode;
+	}
+
+	public void setSubjectCode(String subjectCode) {
+		this.subjectCode = subjectCode;
+	}
+
+	public List<Course> getCourses() {
+		return courses;
+	}
+
+	public void setCourses(List<Course> courses) {
+		this.courses = courses;
+	}
+
+	public void addCourse(Course c) {
+		if (courses == null) {
+			courses = new ArrayList<>();
+		}
+		courses.add(c);
+	}
+
+}

+ 1 - 1
src/main/java/cn/com/qmth/importpaper/DateUtil.java → src/main/java/cn/com/qmth/im/DateUtil.java

@@ -1,4 +1,4 @@
-package cn.com.qmth.importpaper;
+package cn.com.qmth.im;
 
 import java.text.ParseException;
 import java.text.SimpleDateFormat;

+ 50 - 0
src/main/java/cn/com/qmth/im/DeleteQuestionConsumer.java

@@ -0,0 +1,50 @@
+package cn.com.qmth.im;
+
+import java.io.IOException;
+import java.util.Map;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.log4j.LogManager;
+import org.apache.log4j.Logger;
+
+import com.google.common.collect.Maps;
+
+import cn.com.qmth.multithread.Consumer;
+import cn.com.qmth.param.Param;
+import okhttp3.Response;
+
+public class DeleteQuestionConsumer extends Consumer<DeleteQuestionDto> {
+
+    private static Logger logger = LogManager.getLogger(DeleteQuestionConsumer.class);
+
+    @Override
+    public void consume(DeleteQuestionDto dto) {
+        for (QuestionId c : dto.getIds()) {
+            try {
+                submit(c);
+            } catch (IOException e) {
+                logger.error("删除失败:" + c.getUnitId() + " | " + c.getQuestionId(), e);
+            }
+        }
+    }
+
+    private static void submit(QuestionId ic) throws IOException {
+        Map<String, String> params = Maps.newHashMap();
+        Map<String, String> headers = Maps.newHashMap();
+        headers.put("key", Param.key);
+        headers.put("token", Param.token);
+        Response resp = null;
+        try {
+            resp = OKHttpUtil.call(HttpMethod.DELETE,
+                    Param.host + "/api/ecs_ques/paper/deleteQuestion/" + ic.getUnitId() + "/" + ic.getQuestionId(),
+                    headers, params);
+            if (resp.code() != 200) {
+                logger.error(ic.getUnitId() + " | " + ic.getQuestionId() + ":body:" + resp.body().string());
+                // throw new RuntimeException(ic.getUnitId() + " | " +
+                // ic.getQuestionId() + ":body:" + resp.body().string());
+            }
+        } finally {
+            IOUtils.closeQuietly(resp);
+        }
+    }
+}

+ 22 - 0
src/main/java/cn/com/qmth/im/DeleteQuestionDto.java

@@ -0,0 +1,22 @@
+package cn.com.qmth.im;
+
+import java.util.List;
+
+public class DeleteQuestionDto {
+
+    private List<QuestionId> ids;
+
+    public List<QuestionId> getIds() {
+        return ids;
+    }
+
+    public void setIds(List<QuestionId> ids) {
+        this.ids = ids;
+    }
+
+    public DeleteQuestionDto(List<QuestionId> ids) {
+        super();
+        this.ids = ids;
+    }
+
+}

+ 87 - 0
src/main/java/cn/com/qmth/im/DeleteQuestionProducer.java

@@ -0,0 +1,87 @@
+package cn.com.qmth.im;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.log4j.LogManager;
+import org.apache.log4j.Logger;
+import org.apache.poi.xssf.usermodel.XSSFRow;
+import org.apache.poi.xssf.usermodel.XSSFSheet;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+
+import cn.com.qmth.multithread.Producer;
+import cn.com.qmth.param.Param;
+
+public class DeleteQuestionProducer extends Producer<DeleteQuestionDto, DeleteQuestionConsumer> {
+
+    private static Logger logger = LogManager.getLogger(DeleteQuestionProducer.class);
+
+    @Override
+    protected void produce(Map<String, Object> param) throws Exception {
+        logger.info("***************************任务生产开始");
+        List<QuestionId> ids = readSubject();
+        if (CollectionUtils.isEmpty(ids)) {
+            logger.warn("***************************!!没有需要处理的数据");
+        }
+        logger.info("***************************总题数:" + ids.size());
+        Map<String, List<QuestionId>> map = new LinkedHashMap<>();
+        for (QuestionId id : ids) {
+            List<QuestionId> tem = map.get(id.getCourseCode());
+            if (tem == null) {
+                tem = new ArrayList<>();
+                map.put(id.getCourseCode(), tem);
+            }
+            tem.add(id);
+        }
+        setTotal(map.size());
+        logger.info("***************************总科目数:" + map.size());
+        for (List<QuestionId> dto : map.values()) {
+            offer(new DeleteQuestionDto(dto));
+        }
+        logger.info("***************************任务生产结束");
+    }
+
+    private static List<QuestionId> readSubject() {
+        List<QuestionId> list = new ArrayList<>();
+        XSSFWorkbook wb = null;
+        try {
+            wb = new XSSFWorkbook(Param.dataDir + "/duplicatequestion.xlsx");
+            XSSFSheet sheet = wb.getSheetAt(0);
+            int rows = sheet.getLastRowNum();
+            for (int i = 1; i <= rows; i++) {
+                XSSFRow row = sheet.getRow(i);
+                String valid = row.getCell(9).getStringCellValue().trim();
+                if ("否".equals(valid)) {
+                    QuestionId c = new QuestionId();
+                    String courseCode = row.getCell(1).getStringCellValue().trim();
+                    String uid = row.getCell(7).getStringCellValue().trim();
+                    String qid = row.getCell(8).getStringCellValue().trim();
+                    c.setCourseCode(courseCode);
+                    c.setUnitId(uid);
+                    c.setQuestionId(qid);
+                    list.add(c);
+                }
+            }
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        } finally {
+            if (wb != null) {
+                try {
+                    wb.close();
+                } catch (IOException e) {
+                }
+            }
+        }
+        return list;
+    }
+
+    @Override
+    protected String getTaskName() {
+        return "删除试题";
+    }
+
+}

+ 1 - 1
src/main/java/cn/com/qmth/importpaper/FileUtil.java → src/main/java/cn/com/qmth/im/FileUtil.java

@@ -5,7 +5,7 @@
  * *************************************************
  */
 
-package cn.com.qmth.importpaper;
+package cn.com.qmth.im;
 
 import java.io.File;
 import java.io.FileInputStream;

+ 1 - 1
src/main/java/cn/com/qmth/importpaper/FormFilePart.java → src/main/java/cn/com/qmth/im/FormFilePart.java

@@ -1,4 +1,4 @@
-package cn.com.qmth.importpaper;
+package cn.com.qmth.im;
 
 import java.io.File;
 

+ 1 - 1
src/main/java/cn/com/qmth/importpaper/HttpMethod.java → src/main/java/cn/com/qmth/im/HttpMethod.java

@@ -1,4 +1,4 @@
-package cn.com.qmth.importpaper;
+package cn.com.qmth.im;
 
 import java.util.HashMap;
 import java.util.Map;

+ 2 - 2
src/main/java/cn/com/qmth/importpaper/JsonUtil.java → src/main/java/cn/com/qmth/im/JsonUtil.java

@@ -1,9 +1,9 @@
-package cn.com.qmth.importpaper;
+package cn.com.qmth.im;
 
 import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
 
-import cn.com.qmth.importpaper.DateUtil.DatePatterns;
+import cn.com.qmth.im.DateUtil.DatePatterns;
 
 /**
  * 类注释

+ 103 - 0
src/main/java/cn/com/qmth/im/MyConsumer.java

@@ -0,0 +1,103 @@
+package cn.com.qmth.im;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.log4j.LogManager;
+import org.apache.log4j.Logger;
+
+import com.google.common.collect.Lists;
+import com.google.common.collect.Maps;
+
+import cn.com.qmth.multithread.Consumer;
+import cn.com.qmth.param.Param;
+import cn.com.qmth.run.ImportPaperByCourse;
+import okhttp3.Response;
+
+public class MyConsumer extends Consumer<ConsumerDto> {
+
+    private static Logger logger = LogManager.getLogger(MyConsumer.class);
+
+    @Override
+    public void consume(ConsumerDto dto) {
+        importCoursePaper(dto);
+        ImportPaperByCourse.addDisposeCount();
+    }
+
+    private void importCoursePaper(ConsumerDto dto) {
+        File file = new File(Param.dataDir + "/paper/" + dto.getIc().getSubjectCode() + "/");
+        if (!file.exists()) {
+            return;
+        }
+        File zfile = new File(Param.dataDir + "/paper/" + dto.getIc().getSubjectCode() + ".zip");
+        try {
+            List<File> files = new ArrayList<>();
+            getPaperFile(file, files);
+            if (files.size() == 0) {
+                throw new NoPaperException("1000", "没有试卷信息:" + file.getName());
+            }
+            if (zfile.exists()) {
+                zfile.delete();
+            }
+            FileUtil.doZip(file, zfile);
+            submitZip(dto, zfile);
+        } catch (NoPaperException e1) {
+            logger.debug("忽略:" + e1.getDesc());
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        } finally {
+            if (zfile.exists()) {
+                zfile.delete();
+            }
+        }
+    }
+
+    private void getPaperFile(File file, List<File> ret) {
+        if (file.isFile()) {
+            if (file.getName().endsWith(".json")) {
+                ret.add(file);
+            }
+            return;
+        } else {
+            for (File paperDir : file.listFiles()) {
+                getPaperFile(paperDir, ret);
+            }
+        }
+
+    }
+
+    private void submitZip(ConsumerDto dto, File zfile) {
+        List<String> cs = dto.getIc().getCourses().stream().map(e -> e.getCode()).collect(Collectors.toList());
+        Map<String, String> params = Maps.newHashMap();
+        String courseCodes = StringUtils.join(cs, ",");
+        params.put("rootOrgId", Param.rootOrgId);
+        params.put("batch", dto.getBatch());
+        params.put("courseCodes", courseCodes);
+        Map<String, String> headers = Maps.newHashMap();
+        headers.put("key", Param.key);
+        headers.put("token", Param.token);
+        List<FormFilePart> fileList = Lists.newArrayList();
+        fileList.add(new FormFilePart("dataFile", zfile.getName(), zfile));
+        Response resp = null;
+        try {
+            // OKHttpUtil.initOkHttpClient();
+            resp = OKHttpUtil.call(HttpMethod.POST, Param.host + "/api/ecs_ques/importYunkaiPaper", headers, params,
+                    fileList);
+            if (resp.code() != 200) {
+                throw new Exception(
+                        zfile.getName() + "| courseCodes:" + courseCodes + "| body:" + resp.body().string());
+            } else {
+                logger.debug("成功处理:" + zfile.getName());
+            }
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        } finally {
+            IOUtils.closeQuietly(resp);
+        }
+    }
+}

+ 116 - 0
src/main/java/cn/com/qmth/im/MyProducer.java

@@ -0,0 +1,116 @@
+package cn.com.qmth.im;
+
+import java.io.IOException;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.apache.log4j.LogManager;
+import org.apache.log4j.Logger;
+import org.apache.poi.xssf.usermodel.XSSFRow;
+import org.apache.poi.xssf.usermodel.XSSFSheet;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+
+import cn.com.qmth.multithread.Producer;
+import cn.com.qmth.param.Param;
+
+public class MyProducer extends Producer<ConsumerDto, MyConsumer> {
+
+    private static Logger logger = LogManager.getLogger(MyProducer.class);
+
+    @Override
+    protected void produce(Map<String, Object> param) throws Exception {
+        logger.info("***************************任务生产开始");
+        String sourceDir = Param.dataDir + "/";
+        String batch = param.get("batch").toString();
+        // List<Course> cs = readSubject();
+        Map<String, CourseDto> ics = readSubjectCodes(sourceDir);
+        if (ics.size() == 0) {
+            logger.debug("无数据导入");
+            return;
+        } else {
+            logger.debug(ics.size() + "个课程");
+        }
+        for (CourseDto ic : ics.values()) {
+            offer(new ConsumerDto(ic, batch));
+        }
+        logger.info("***************************任务生产结束");
+    }
+
+    private static Map<String, CourseDto> readSubjectCodes(String sourceDir) {
+        Map<String, CourseDto> map = new LinkedHashMap<>();
+        XSSFWorkbook wb = null;
+        try {
+            wb = new XSSFWorkbook(sourceDir + "subject_info.xlsx");
+            XSSFSheet sheet = wb.getSheetAt(0);
+            int rows = sheet.getLastRowNum();
+            for (int i = 1; i <= rows; i++) {
+                Course c = new Course();
+                XSSFRow row = sheet.getRow(i);
+                String ecCode = row.getCell(0).getStringCellValue().trim();
+                String yunCode;
+                try {
+                    yunCode = row.getCell(1).getStringCellValue().trim();
+                } catch (Exception e) {
+                    yunCode = (row.getCell(1).getNumericCellValue() + "").trim();
+                }
+                String name = row.getCell(2).getStringCellValue().trim();
+                c.setCode(ecCode);
+                c.setName(name);
+                CourseDto ic = map.get(yunCode);
+                if (ic == null) {
+                    ic = new CourseDto();
+                    ic.setSubjectCode(yunCode);
+                    map.put(yunCode, ic);
+                }
+                ic.addCourse(c);
+
+            }
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        } finally {
+            if (wb != null) {
+                try {
+                    wb.close();
+                } catch (IOException e) {
+                }
+            }
+        }
+        return map;
+    }
+
+    @Override
+    protected String getTaskName() {
+        return "试题导入";
+    }
+
+    // private List<Course> readSubject() {
+    // List<Course> list = new ArrayList<>();
+    // XSSFWorkbook wb = null;
+    // try {
+    // wb = new XSSFWorkbook(sourceDir + "subject.xlsx");
+    // XSSFSheet sheet = wb.getSheetAt(0);
+    // int rows = sheet.getLastRowNum();
+    // for (int i = 1; i <= rows; i++) {
+    // Course c = new Course();
+    // XSSFRow row = sheet.getRow(i);
+    // String id = row.getCell(0).getStringCellValue().trim();
+    // String name = row.getCell(1).getStringCellValue().trim();
+    // String code = row.getCell(2).getStringCellValue().trim();
+    // c.setId(Long.valueOf(id));
+    // c.setCode(code);
+    // c.setName(name);
+    // list.add(c);
+    // }
+    // } catch (IOException e) {
+    // throw new RuntimeException(e);
+    // } finally {
+    // if (wb != null) {
+    // try {
+    // wb.close();
+    // } catch (IOException e) {
+    // }
+    // }
+    // }
+    // return list;
+    // }
+}

+ 64 - 64
src/main/java/cn/com/qmth/importpaper/NoPaperException.java → src/main/java/cn/com/qmth/im/NoPaperException.java

@@ -1,64 +1,64 @@
-package cn.com.qmth.importpaper;
-
-import java.util.HashMap;
-import java.util.Map;
-
-public class NoPaperException extends RuntimeException{
-	
-
-	/**
-	 * 
-	 */
-	private static final long serialVersionUID = 2190219930300660360L;
-
-	/**
-	 * 状态码
-	 */
-	private String code;
-
-	/**
-	 * 状态描述
-	 */
-	private String desc;
-
-	/**
-	 * 构造函数
-	 */
-	public NoPaperException(String code, String desc) {
-		super("[code: " + code + "; desc: " + desc + "]");
-		this.code = code;
-		this.desc = desc;
-	}
-
-	/**
-	 * 构造函数
-	 */
-	public NoPaperException(String code, String desc, Throwable cause) {
-		super("[code: " + code + "; desc: " + desc + "]", cause);
-		this.code = code;
-		this.desc = desc;
-	}
-
-	public String getCode() {
-		return code;
-	}
-
-	public String getDesc() {
-		return desc;
-	}
-
-	/**
-	 * @return
-	 */
-	public String toJson() {
-		Map<String, Object> map = new HashMap<String, Object>();
-		map.put("code", code);
-		map.put("desc", desc);
-		return JsonUtil.toJson(map);
-	}
-
-	@Override
-	public String toString() {
-		return toJson();
-	}
-}
+package cn.com.qmth.im;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class NoPaperException extends RuntimeException{
+	
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = 2190219930300660360L;
+
+	/**
+	 * 状态码
+	 */
+	private String code;
+
+	/**
+	 * 状态描述
+	 */
+	private String desc;
+
+	/**
+	 * 构造函数
+	 */
+	public NoPaperException(String code, String desc) {
+		super("[code: " + code + "; desc: " + desc + "]");
+		this.code = code;
+		this.desc = desc;
+	}
+
+	/**
+	 * 构造函数
+	 */
+	public NoPaperException(String code, String desc, Throwable cause) {
+		super("[code: " + code + "; desc: " + desc + "]", cause);
+		this.code = code;
+		this.desc = desc;
+	}
+
+	public String getCode() {
+		return code;
+	}
+
+	public String getDesc() {
+		return desc;
+	}
+
+	/**
+	 * @return
+	 */
+	public String toJson() {
+		Map<String, Object> map = new HashMap<String, Object>();
+		map.put("code", code);
+		map.put("desc", desc);
+		return JsonUtil.toJson(map);
+	}
+
+	@Override
+	public String toString() {
+		return toJson();
+	}
+}

+ 1 - 1
src/main/java/cn/com/qmth/importpaper/OKHttpUtil.java → src/main/java/cn/com/qmth/im/OKHttpUtil.java

@@ -1,4 +1,4 @@
-package cn.com.qmth.importpaper;
+package cn.com.qmth.im;
 
 import java.io.IOException;
 import java.util.List;

+ 35 - 0
src/main/java/cn/com/qmth/im/QuestionId.java

@@ -0,0 +1,35 @@
+package cn.com.qmth.im;
+
+public class QuestionId {
+
+    private String courseCode;
+
+    private String unitId;
+
+    private String questionId;
+
+    public String getUnitId() {
+        return unitId;
+    }
+
+    public void setUnitId(String unitId) {
+        this.unitId = unitId;
+    }
+
+    public String getQuestionId() {
+        return questionId;
+    }
+
+    public void setQuestionId(String questionId) {
+        this.questionId = questionId;
+    }
+
+    public String getCourseCode() {
+        return courseCode;
+    }
+
+    public void setCourseCode(String courseCode) {
+        this.courseCode = courseCode;
+    }
+
+}

+ 1 - 1
src/main/java/cn/com/qmth/importpaper/ReWriteExcel.java → src/main/java/cn/com/qmth/im/ReWriteExcel.java

@@ -1,4 +1,4 @@
-package cn.com.qmth.importpaper;
+package cn.com.qmth.im;
 
 import java.io.File;
 import java.io.FileOutputStream;

+ 64 - 64
src/main/java/cn/com/qmth/importpaper/SSLSocketClient.java → src/main/java/cn/com/qmth/im/SSLSocketClient.java

@@ -1,64 +1,64 @@
-package cn.com.qmth.importpaper;
-
-import javax.net.ssl.*;
-import java.security.KeyStore;
-import java.security.SecureRandom;
-import java.security.cert.X509Certificate;
-import java.util.Arrays;
-
-
-public class SSLSocketClient {
-
-    //获取这个SSLSocketFactory
-    public static SSLSocketFactory getSSLSocketFactory() {
-        try {
-            SSLContext sslContext = SSLContext.getInstance("SSL");
-            sslContext.init(null, getTrustManager(), new SecureRandom());
-            return sslContext.getSocketFactory();
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    //获取TrustManager
-    private static TrustManager[] getTrustManager() {
-        return new TrustManager[]{
-                new X509TrustManager() {
-                    @Override
-                    public void checkClientTrusted(X509Certificate[] chain, String authType) {
-                    }
-
-                    @Override
-                    public void checkServerTrusted(X509Certificate[] chain, String authType) {
-                    }
-
-                    @Override
-                    public X509Certificate[] getAcceptedIssuers() {
-                        return new X509Certificate[]{};
-                    }
-                }
-        };
-    }
-
-    //获取HostnameVerifier
-    public static HostnameVerifier getHostnameVerifier() {
-        return (s, sslSession) -> true;
-    }
-
-    public static X509TrustManager getX509TrustManager() {
-        X509TrustManager trustManager = null;
-        try {
-            TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
-            trustManagerFactory.init((KeyStore) null);
-            TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
-            if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
-                throw new IllegalStateException("Unexpected default trust managers:" + Arrays.toString(trustManagers));
-            }
-            trustManager = (X509TrustManager) trustManagers[0];
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-
-        return trustManager;
-    }
-}
+package cn.com.qmth.im;
+
+import javax.net.ssl.*;
+import java.security.KeyStore;
+import java.security.SecureRandom;
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
+
+
+public class SSLSocketClient {
+
+    //获取这个SSLSocketFactory
+    public static SSLSocketFactory getSSLSocketFactory() {
+        try {
+            SSLContext sslContext = SSLContext.getInstance("SSL");
+            sslContext.init(null, getTrustManager(), new SecureRandom());
+            return sslContext.getSocketFactory();
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    //获取TrustManager
+    private static TrustManager[] getTrustManager() {
+        return new TrustManager[]{
+                new X509TrustManager() {
+                    @Override
+                    public void checkClientTrusted(X509Certificate[] chain, String authType) {
+                    }
+
+                    @Override
+                    public void checkServerTrusted(X509Certificate[] chain, String authType) {
+                    }
+
+                    @Override
+                    public X509Certificate[] getAcceptedIssuers() {
+                        return new X509Certificate[]{};
+                    }
+                }
+        };
+    }
+
+    //获取HostnameVerifier
+    public static HostnameVerifier getHostnameVerifier() {
+        return (s, sslSession) -> true;
+    }
+
+    public static X509TrustManager getX509TrustManager() {
+        X509TrustManager trustManager = null;
+        try {
+            TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
+            trustManagerFactory.init((KeyStore) null);
+            TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
+            if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
+                throw new IllegalStateException("Unexpected default trust managers:" + Arrays.toString(trustManagers));
+            }
+            trustManager = (X509TrustManager) trustManagers[0];
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        return trustManager;
+    }
+}

+ 87 - 0
src/main/java/cn/com/qmth/im/StatusException.java

@@ -0,0 +1,87 @@
+package cn.com.qmth.im;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 状态异常类<br>
+ *
+ * @author WANG
+ */
+public class StatusException extends RuntimeException {
+
+    private static final long serialVersionUID = 5003047488500388819L;
+
+    /**
+     * 追踪ID
+     */
+    private String traceId;
+
+    /**
+     * 状态码
+     */
+    private String code;
+
+    /**
+     * 状态描述
+     */
+    private String desc;
+
+    /**
+     * 构造函数
+     */
+    public StatusException(String code, String desc) {
+        super("[code: " + code + "; desc: " + desc + "]");
+        this.code = code;
+        this.desc = desc;
+    }
+
+    public StatusException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public StatusException(String message) {
+        super(message);
+    }
+
+    /**
+     * 构造函数
+     */
+    public StatusException(String code, String desc, Throwable cause) {
+        super("[code: " + code + "; desc: " + desc + "]", cause);
+        this.code = code;
+        this.desc = desc;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public String getDesc() {
+        return desc;
+    }
+
+    public String getTraceId() {
+        return traceId;
+    }
+
+    public void setTraceId(String traceId) {
+        this.traceId = traceId;
+    }
+
+    /**
+     * @return
+     */
+    public String toJson() {
+        Map<String, Object> map = new HashMap<String, Object>();
+        map.put("code", code);
+        map.put("desc", desc);
+        return JsonUtil.toJson(map);
+    }
+
+    @Override
+    public String toString() {
+        return toJson();
+    }
+
+}

+ 48 - 48
src/main/java/cn/com/qmth/importpaper/Temp.java → src/main/java/cn/com/qmth/im/Temp.java

@@ -1,48 +1,48 @@
-package cn.com.qmth.importpaper;
-
-import java.io.IOException;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Set;
-
-import org.apache.poi.xssf.usermodel.XSSFRow;
-import org.apache.poi.xssf.usermodel.XSSFSheet;
-import org.apache.poi.xssf.usermodel.XSSFWorkbook;
-
-public class Temp {
-	private final static String sourceDir = "d:/guangkai/";
-	public static void main(String[] args) {
-		Set<String> ret=readId();
-		for(String s:ret) {
-			System.out.println(s);
-		}
-	}
-	
-	private static Set<String> readId() {
-		Set<String> list = new LinkedHashSet<>();
-		XSSFWorkbook wb = null;
-		try {
-			wb = new XSSFWorkbook(sourceDir + "ret.xlsx");
-			XSSFSheet sheet = wb.getSheetAt(0);
-			int rows = sheet.getLastRowNum();
-			for (int i = 1; i <= rows; i++) {
-				XSSFRow row = sheet.getRow(i);
-				String code = row.getCell(1).getStringCellValue().trim();
-				list.add(code);
-				if(i==2000) {
-					break;
-				}
-			}
-		} catch (IOException e) {
-			throw new RuntimeException(e);
-		} finally {
-			if (wb != null) {
-				try {
-					wb.close();
-				} catch (IOException e) {
-				}
-			}
-		}
-		return list;
-	}
-}
+package cn.com.qmth.im;
+
+import java.io.IOException;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.poi.xssf.usermodel.XSSFRow;
+import org.apache.poi.xssf.usermodel.XSSFSheet;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+
+public class Temp {
+	private final static String sourceDir = "d:/guangkai/";
+	public static void main(String[] args) {
+		Set<String> ret=readId();
+		for(String s:ret) {
+			System.out.println(s);
+		}
+	}
+	
+	private static Set<String> readId() {
+		Set<String> list = new LinkedHashSet<>();
+		XSSFWorkbook wb = null;
+		try {
+			wb = new XSSFWorkbook(sourceDir + "ret.xlsx");
+			XSSFSheet sheet = wb.getSheetAt(0);
+			int rows = sheet.getLastRowNum();
+			for (int i = 1; i <= rows; i++) {
+				XSSFRow row = sheet.getRow(i);
+				String code = row.getCell(1).getStringCellValue().trim();
+				list.add(code);
+				if(i==2000) {
+					break;
+				}
+			}
+		} catch (IOException e) {
+			throw new RuntimeException(e);
+		} finally {
+			if (wb != null) {
+				try {
+					wb.close();
+				} catch (IOException e) {
+				}
+			}
+		}
+		return list;
+	}
+}

+ 0 - 35
src/main/java/cn/com/qmth/importpaper/ConsumerDto.java

@@ -1,35 +0,0 @@
-package cn.com.qmth.importpaper;
-
-public class ConsumerDto {
-	private CourseDto ic;
-	private String batch;
-
-
-
-	public CourseDto getIc() {
-		return ic;
-	}
-
-	public void setIc(CourseDto ic) {
-		this.ic = ic;
-	}
-	
-	
-
-	public String getBatch() {
-		return batch;
-	}
-
-	public void setBatch(String batch) {
-		this.batch = batch;
-	}
-
-	public ConsumerDto(CourseDto ic,String batch) {
-		super();
-		this.ic = ic;
-		this.batch = batch;
-	}
-
-	
-	
-}

+ 0 - 93
src/main/java/cn/com/qmth/importpaper/DeleteImportPaperQuestion.java

@@ -1,93 +0,0 @@
-package cn.com.qmth.importpaper;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-import org.apache.poi.xssf.usermodel.XSSFRow;
-import org.apache.poi.xssf.usermodel.XSSFSheet;
-import org.apache.poi.xssf.usermodel.XSSFWorkbook;
-
-import com.google.common.collect.Maps;
-
-import okhttp3.Response;
-
-public class DeleteImportPaperQuestion {
-
-	private static Logger logger = LogManager.getLogger(DeleteImportPaperQuestion.class);
-
-	public static void main(String[] args){
-		logger.debug("**********************删除开始");
-		Date start = new Date();
-
-		List<QuestionId> cs = readSubject();
-		int index = 0;
-		for (QuestionId c : cs) {
-			try {
-				submit(c);
-				index++;
-				logger.debug("**********************完成:" + index+" | unit_id:"+c.getUnitId() );
-			} catch (IOException e) {
-				logger.error("删除失败:"+c.getUnitId() + " | " + c.getQuestionId(),e);
-			}
-		}
-
-		Date end = new Date();
-		logger.debug("**********************删除结束  耗时:" + (end.getTime() - start.getTime()));
-		OKHttpUtil.close();
-	}
-
-
-	private static List<QuestionId> readSubject() {
-		List<QuestionId> list = new ArrayList<>();
-		XSSFWorkbook wb = null;
-		try {
-			wb = new XSSFWorkbook(Param.dataDir + "/question.xlsx");
-			XSSFSheet sheet = wb.getSheetAt(0);
-			int rows = sheet.getLastRowNum();
-			for (int i = 1; i <= rows; i++) {
-				QuestionId c = new QuestionId();
-				XSSFRow row = sheet.getRow(i);
-				String uid = row.getCell(0).getStringCellValue().trim();
-				String qid = row.getCell(1).getStringCellValue().trim();
-				c.setUnitId(uid);
-				c.setQuestionId(qid);
-				list.add(c);
-			}
-		} catch (IOException e) {
-			throw new RuntimeException(e);
-		} finally {
-			if (wb != null) {
-				try {
-					wb.close();
-				} catch (IOException e) {
-				}
-			}
-		}
-		return list;
-	}
-
-	private static void submit(QuestionId ic) throws IOException{
-		Map<String, String> params = Maps.newHashMap();
-		Map<String, String> headers = Maps.newHashMap();
-		headers.put("key", Param.key);
-		headers.put("token", Param.token);
-		Response resp = null;
-		try {
-			resp = OKHttpUtil.call(HttpMethod.DELETE,
-					Param.host + "/api/ecs_ques/paper/deleteQuestion/" + ic.getUnitId() + "/" + ic.getQuestionId(), headers,
-					params);
-			if (resp.code() != 200) {
-				logger.error(ic.getUnitId() + " | " + ic.getQuestionId() + ":body:" + resp.body().string());
-//				throw new RuntimeException(ic.getUnitId() + " | " + ic.getQuestionId() + ":body:" + resp.body().string());
-			}
-		} finally {
-			IOUtils.closeQuietly(resp);
-		}
-	}
-}

+ 0 - 41
src/main/java/cn/com/qmth/importpaper/ImportPaperByCourse.java

@@ -1,41 +0,0 @@
-package cn.com.qmth.importpaper;
-
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
-
-public class ImportPaperByCourse {
-
-	private static Logger logger = LogManager.getLogger(ImportPaperByCourse.class);
-	//课程属性批次号
-	//不要修改
-	//此值不要修改。因为第一次导入230517批次的时候未保存批次信息,所以230517批次的不能共用。第二次导入230821批次的保存了批次值,可以后续公用。
-	private final static String batch = "230821";
-	
-	private static AtomicInteger count=new AtomicInteger(0);
-
-	public static void main(String[] args) {
-		logger.debug("导入开始");
-		Date start=new Date();
-		try {
-			Map<String,Object> param=new HashMap<>();
-			param.put("batch", batch);
-			MyProducer pro=new MyProducer();
-			pro.startDispose(MyConsumer.class, 2, param);
-		} catch (Exception e) {
-			logger.error(e.getCause(), e);
-		}
-		Date end=new Date();
-		OKHttpUtil.close();
-		logger.debug("导入结束,耗时:"+((end.getTime()-start.getTime())/1000));
-	}
-
-	public static void  addDisposeCount() {
-		count.addAndGet(1);
-		logger.debug("处理了"+count);
-	}
-}

+ 0 - 95
src/main/java/cn/com/qmth/importpaper/MyConsumer.java

@@ -1,95 +0,0 @@
-package cn.com.qmth.importpaper;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-
-import org.apache.commons.io.IOUtils;
-import org.apache.commons.lang3.StringUtils;
-import org.apache.log4j.LogManager;
-import org.apache.log4j.Logger;
-
-import com.google.common.collect.Lists;
-import com.google.common.collect.Maps;
-
-import cn.com.qmth.multithread.Consumer;
-import okhttp3.Response;
-
-public class MyConsumer extends Consumer<ConsumerDto> {
-	private static Logger logger = LogManager.getLogger(MyConsumer.class);
-	@Override
-	public void consume(ConsumerDto dto) {
-		importCoursePaper(dto);
-		ImportPaperByCourse.addDisposeCount();
-	}
-	private  void importCoursePaper(ConsumerDto dto){
-		File file = new File(Param.dataDir + "/paper/" + dto.getIc().getSubjectCode() + "/");
-		if(!file.exists()) {
-			return;
-		}
-		File zfile = new File(Param.dataDir+"/paper/"+dto.getIc().getSubjectCode()+ ".zip");
-		try {
-			List<File> files = new ArrayList<>();
-			getPaperFile(file, files);
-			if(files.size()==0) {
-				throw new NoPaperException("1000","没有试卷信息:" + file.getName());
-			}
-			if (zfile.exists()) {
-				zfile.delete();
-			}
-			FileUtil.doZip(file, zfile);
-			submitZip(dto,zfile);
-		} catch (NoPaperException e1) {
-			logger.debug("忽略:" + e1.getDesc() );
-		} catch (Exception e) {
-			throw new RuntimeException(e);
-		} finally {
-			if (zfile.exists()) {
-				zfile.delete();
-			}
-		}
-	}
-
-	private  void getPaperFile(File file, List<File> ret) {
-		if (file.isFile()) {
-			if (file.getName().endsWith(".json")) {
-				ret.add(file);
-			}
-			return;
-		} else {
-			for (File paperDir : file.listFiles()) {
-				getPaperFile(paperDir, ret);
-			}
-		}
-
-	}
-	private  void submitZip(ConsumerDto dto,File zfile) {
-		List<String> cs=dto.getIc().getCourses().stream().map(e->e.getCode()).collect(Collectors.toList());
-		Map<String, String> params = Maps.newHashMap();
-		String courseCodes=StringUtils.join(cs,",");
-		params.put("rootOrgId", Param.rootOrgId);
-		params.put("batch", dto.getBatch());
-		params.put("courseCodes",courseCodes);
-		Map<String, String> headers = Maps.newHashMap();
-		headers.put("key", Param.key);
-		headers.put("token", Param.token);
-		List<FormFilePart> fileList = Lists.newArrayList();
-		fileList.add(new FormFilePart("dataFile", zfile.getName(), zfile));
-		Response resp = null;
-		try {
-//			OKHttpUtil.initOkHttpClient();
-			resp = OKHttpUtil.call(HttpMethod.POST, Param.host+"/api/ecs_ques/importYunkaiPaper", headers, params, fileList);
-			if (resp.code() != 200) {
-				throw new Exception(zfile.getName() +"| courseCodes:"+courseCodes+ "| body:" + resp.body().string());
-			}else {
-				logger.debug("成功处理:" + zfile.getName() );
-			}
-		} catch (Exception e) {
-			throw new RuntimeException(e);
-		} finally {
-			IOUtils.closeQuietly(resp);
-		}
-	}
-}

+ 0 - 110
src/main/java/cn/com/qmth/importpaper/MyProducer.java

@@ -1,110 +0,0 @@
-package cn.com.qmth.importpaper;
-
-import java.io.IOException;
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-import org.apache.log4j.LogManager;
-import org.apache.log4j.Logger;
-import org.apache.poi.xssf.usermodel.XSSFRow;
-import org.apache.poi.xssf.usermodel.XSSFSheet;
-import org.apache.poi.xssf.usermodel.XSSFWorkbook;
-
-import cn.com.qmth.multithread.Producer;
-
-
-public class MyProducer extends Producer {
-	private static Logger logger = LogManager.getLogger(MyProducer.class);
-
-	@Override
-	protected void produce(Map<String, Object> param) throws Exception {
-		logger.info("***************************任务生产开始");
-		String sourceDir=Param.dataDir+"/";
-		String batch=param.get("batch").toString();
-//		List<Course> cs = readSubject();
-		Map<String,CourseDto> ics=readSubjectCodes(sourceDir);
-		if (ics.size()==0) {
-			logger.debug("无数据导入");
-			return;
-		} else {
-			logger.debug(ics.size() + "个课程");
-		}
-		for (CourseDto ic : ics.values()) {
-			offer(new ConsumerDto(ic,batch));
-		}
-		logger.info("***************************任务生产结束");
-	}
-	
-	private static Map<String,CourseDto> readSubjectCodes(String sourceDir) {
-		Map<String,CourseDto> map=new LinkedHashMap<>();
-		XSSFWorkbook wb = null;
-		try {
-			wb = new XSSFWorkbook(sourceDir + "subject_info.xlsx");
-			XSSFSheet sheet = wb.getSheetAt(0);
-			int rows = sheet.getLastRowNum();
-			for (int i = 1; i <= rows; i++) {
-				Course c = new Course();
-				XSSFRow row = sheet.getRow(i);
-				String ecCode = row.getCell(0).getStringCellValue().trim();
-				String yunCode;
-				try {
-					yunCode = row.getCell(1).getStringCellValue().trim();
-				} catch (Exception e) {
-					yunCode = (row.getCell(1).getNumericCellValue()+"").trim();
-				}
-				String name = row.getCell(2).getStringCellValue().trim();
-				c.setCode(ecCode);
-				c.setName(name);
-				CourseDto ic=map.get(yunCode);
-				if(ic==null) {
-					ic=new CourseDto();
-					ic.setSubjectCode(yunCode);
-					map.put(yunCode,ic);
-				}
-				ic.addCourse(c);
-				
-			}
-		} catch (IOException e) {
-			throw new RuntimeException(e);
-		} finally {
-			if (wb != null) {
-				try {
-					wb.close();
-				} catch (IOException e) {
-				}
-			}
-		}
-		return map;
-	}
-	
-//	private  List<Course> readSubject() {
-//		List<Course> list = new ArrayList<>();
-//		XSSFWorkbook wb = null;
-//		try {
-//			wb = new XSSFWorkbook(sourceDir + "subject.xlsx");
-//			XSSFSheet sheet = wb.getSheetAt(0);
-//			int rows = sheet.getLastRowNum();
-//			for (int i = 1; i <= rows; i++) {
-//				Course c = new Course();
-//				XSSFRow row = sheet.getRow(i);
-//				String id = row.getCell(0).getStringCellValue().trim();
-//				String name = row.getCell(1).getStringCellValue().trim();
-//				String code = row.getCell(2).getStringCellValue().trim();
-//				c.setId(Long.valueOf(id));
-//				c.setCode(code);
-//				c.setName(name);
-//				list.add(c);
-//			}
-//		} catch (IOException e) {
-//			throw new RuntimeException(e);
-//		} finally {
-//			if (wb != null) {
-//				try {
-//					wb.close();
-//				} catch (IOException e) {
-//				}
-//			}
-//		}
-//		return list;
-//	}
-}

+ 0 - 15
src/main/java/cn/com/qmth/importpaper/Param.java

@@ -1,15 +0,0 @@
-package cn.com.qmth.importpaper;
-
-public class Param {
-	public static String host = "http://192.168.1.249:8008";
-	public static String rootOrgId = "17351";
-	public static String key = "$SS:C_17351_646523";
-	public static String token = "95c77664d77f4ba6b58b940ab5e633c8";
-	
-//	public static String host = "http://192.168.1.249:8008";
-//	public static String rootOrgId = "17351";
-//	public static String key = "$SS:C_17351_646523";
-//	public static String token = "44c75d3e15fa4f2ea5d2f52237d06199";
-	
-	public static String dataDir="d:/yunkai";
-}

+ 0 - 19
src/main/java/cn/com/qmth/importpaper/QuestionId.java

@@ -1,19 +0,0 @@
-package cn.com.qmth.importpaper;
-
-public class QuestionId {
-	private String unitId;
-	private String questionId;
-	public String getUnitId() {
-		return unitId;
-	}
-	public void setUnitId(String unitId) {
-		this.unitId = unitId;
-	}
-	public String getQuestionId() {
-		return questionId;
-	}
-	public void setQuestionId(String questionId) {
-		this.questionId = questionId;
-	}
-	
-}

+ 147 - 93
src/main/java/cn/com/qmth/multithread/Basket.java

@@ -1,102 +1,156 @@
 package cn.com.qmth.multithread;
 
+import java.util.List;
 import java.util.concurrent.ArrayBlockingQueue;
 import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
 
-import org.apache.log4j.Logger;
-
-
-
-public  class  Basket {
-    private static Logger logger = Logger.getLogger(Basket.class);
-	/**
-	 * 数据阻塞队列
-	 */
-	private BlockingQueue<Object> queue;
-	
-	/**
-	 * 多线程计数器,子线程都结束后主线程才继续执行
-	 */
-	private CountDownLatch endGate;
-	
-	/**
-	 * 消费者数量
-	 */
-	private int consumerCount;
-	
-	
-	/**
-	 * 判断线程执行是否有出错,生产者、消费者出错都需要修改此值为true
-	 */
-	private boolean isExcuteError = false;
-	
-	
-	public Basket(int consumerCount) {
-		this.consumerCount=consumerCount;
-		queue = new ArrayBlockingQueue<Object>(consumerCount*2);
-		endGate = new CountDownLatch(consumerCount);
-	}
-
-	/**
-	 * 生产数据,不采用put方法防止消费线程全部异常后生产线程阻塞
-	 * @param value
-	 * @throws InterruptedException
-	 */
-	protected void offer(final Object value) throws InterruptedException {
-		if(isExcuteError) {
-			logger.error("**********************offer isExcuteError threadId:"+Thread.currentThread().getId());
-			throw new StatusException("1000001","线程异常");
-		}else {
-			boolean ret=queue.offer(value, 1, TimeUnit.MINUTES);
-			if(!ret) {
-//				logger.info("**********************offer time out threadId:"+Thread.currentThread().getId()+value);
-				this.offer(value);
-			}
-		}
-	}
-	/**
-	 * 消费数据,不采用take方法防止生产线程全部异常后消费线程阻塞
-	 * @return
-	 * @throws InterruptedException
-	 */
-	protected Object consume() throws InterruptedException {
-		if(isExcuteError) {
-			logger.error("**********************poll isExcuteError  threadId:"+Thread.currentThread().getId());
-			return new EndObject();
-		}else {
-			Object ob=queue.poll(1, TimeUnit.MINUTES);
-			if(ob==null) {
-//				logger.info("**********************poll time out  threadId:"+Thread.currentThread().getId());
-				return this.consume();
-			}else {
-				return ob;
-			}
-		}
-	}
-	
-	protected void await() throws InterruptedException {
-		endGate.await();
-	}
-	protected void countDown() {
-		endGate.countDown();
-	}
-
-	protected boolean isExcuteError() {
-		return isExcuteError;
-	}
-
-	protected void setExcuteError(boolean isExcuteError) {
-		this.isExcuteError = isExcuteError;
-	}
-
-	protected int getConsumerCount() {
-		return consumerCount;
-	}
-
-	protected void setConsumerCount(int consumerCount) {
-		this.consumerCount = consumerCount;
-	}
+import cn.com.qmth.im.Calculator;
+import cn.com.qmth.im.StatusException;
+
+public class Basket {
+
+    private ProcessCount process;
+
+    private String taskName;
+
+    private Integer total = 0;
+
+    private List<String> result = new CopyOnWriteArrayList<>();
+
+    /**
+     * 数据阻塞队列
+     */
+    private BlockingQueue<Object> queue;
+
+    /**
+     * 多线程计数器,子线程都结束后主线程才继续执行
+     */
+    private CountDownLatch endGate;
+
+    /**
+     * 消费者数量
+     */
+    private int consumerCount;
+
+    /**
+     * 判断线程执行是否有出错,生产者、消费者出错都需要修改此值为true
+     */
+    private boolean isExcuteError = false;
+
+    public Basket(int consumerCount, String taskName) {
+        this.consumerCount = consumerCount;
+        this.taskName = taskName;
+        queue = new ArrayBlockingQueue<Object>(consumerCount * 2);
+        endGate = new CountDownLatch(consumerCount);
+    }
+
+    /**
+     * 生产数据,不采用put方法防止消费线程全部异常后生产线程阻塞
+     * 
+     * @param value
+     * @throws InterruptedException
+     */
+    protected void offer(final Object value) throws InterruptedException {
+        if (isExcuteError) {
+            throw new StatusException("线程异常");
+        } else {
+            boolean ret = queue.offer(value, 5, TimeUnit.SECONDS);
+            if (!ret) {
+                this.offer(value);
+            }
+        }
+    }
+
+    /**
+     * 消费数据,不采用take方法防止生产线程全部异常后消费线程阻塞
+     * 
+     * @return
+     * @throws InterruptedException
+     */
+    protected Object consume() throws InterruptedException {
+        if (isExcuteError) {
+            return new EndObject();
+        } else {
+            Object ob = queue.poll(5, TimeUnit.SECONDS);
+            if (ob == null) {
+                return this.consume();
+            } else {
+                return ob;
+            }
+        }
+    }
+
+    protected void endGateReset() {
+        endGate = new CountDownLatch(consumerCount);
+    }
+
+    protected void await() throws InterruptedException {
+        endGate.await();
+    }
+
+    protected void countDown() {
+        endGate.countDown();
+    }
+
+    protected boolean isExcuteError() {
+        return isExcuteError;
+    }
+
+    protected void setExcuteError(boolean isExcuteError) {
+        this.isExcuteError = isExcuteError;
+    }
+
+    protected int getConsumerCount() {
+        return consumerCount;
+    }
+
+    protected void setConsumerCount(int consumerCount) {
+        this.consumerCount = consumerCount;
+    }
+
+    public Integer getTotal() {
+        return total;
+    }
+
+    protected void setTotal(Integer total) {
+        this.total = total;
+    }
+
+    public AtomicInteger getProcess() {
+        return process.getProcess();
+    }
+
+    protected void updateProcess(int add) {
+        process.getProcess().addAndGet(add);
+    }
+
+    public String getProgress() {
+        if (total == 0) {
+            return "0%";
+        }
+        Double d = Calculator.divide(process.getProcess().doubleValue(), total.doubleValue(), 4);
+        Double f = Calculator.multiply(d, 100);
+        return f + "%";
+    }
+
+    public List<String> getMsgs() {
+        return result;
+    }
+
+    public void addMsg(String msg) {
+        result.add(msg);
+    }
+
+    public String getTaskName() {
+        return taskName;
+    }
+
+    protected void setProcess(ProcessCount process) {
+        this.process = process;
+    }
 
 }

+ 79 - 55
src/main/java/cn/com/qmth/multithread/Consumer.java

@@ -1,58 +1,82 @@
 package cn.com.qmth.multithread;
 
-import org.apache.log4j.Logger;
-import org.apache.logging.log4j.ThreadContext;
-
-public abstract class Consumer<T>  extends Thread{
-	private static final Logger logger = Logger.getLogger(Consumer.class);
-	private Basket basket;
-	
-	private String traceId;
-	
-	public Consumer() {
-	}
-	@Override
-	public void run() {
-		ThreadContext.put("TRACE_ID", traceId);
-		logger.info("*******************Consumer:"+Thread.currentThread().getId()+" start");
-		try {
-			while (true) {
-				//先判断是否有异常结束
-				if(basket.isExcuteError()) {
-					break;
-				}
-				//取消费数据
-				Object o= basket.consume();
-				//判断消费数据是否是结束
-				if(o instanceof EndObject) {
-					break;
-				}
-				@SuppressWarnings("unchecked")
-				T t=(T)o;
-//				logger.info("*******************Consumer:"+Thread.currentThread().getId()+" consume");
-				//消费数据实现
-				consume(t);
-			}
-		} catch (Exception e) {
-			basket.setExcuteError(true);
-			logger.info("消费线程处理出错",e);
-		}finally {
-			basket.countDown();
-			logger.info("*******************Consumer:"+Thread.currentThread().getId()+" stop");
-			ThreadContext.clearAll();
-		}
-	}
-	public abstract void consume(T t);
-	public Basket getBasket() {
-		return basket;
-	}
-	public void setBasket(Basket basket) {
-		this.basket = basket;
-	}
-	public String getTraceId() {
-		return traceId;
-	}
-	public void setTraceId(String traceId) {
-		this.traceId = traceId;
-	}
+import java.util.ArrayList;
+import java.util.List;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import cn.com.qmth.im.StatusException;
+
+public abstract class Consumer<T> extends Thread {
+
+    private static final Logger LOG = LoggerFactory.getLogger(Consumer.class);
+
+    private Basket basket;
+
+    private List<Object> ret = new ArrayList<>();
+
+    public Consumer() {
+    }
+
+    @Override
+    public void run() {
+        try {
+            while (true) {
+                // 先判断是否有异常结束
+                if (basket.isExcuteError()) {
+                    break;
+                }
+                // 取消费数据
+                Object o = basket.consume();
+                // 判断消费数据是否是结束
+                if (o instanceof EndObject) {
+                    break;
+                }
+                @SuppressWarnings("unchecked")
+                T t = (T) o;
+                // 消费数据实现
+                consume(t);
+                if (basket.getTotal() > 0) {
+                    basket.updateProcess(1);
+                    processInfo();
+                }
+            }
+        } catch (StatusException e) {
+            LOG.error(e.getMessage(), e);
+            addMsg(e.getMessage());
+            basket.setExcuteError(true);
+        } catch (Exception e) {
+            LOG.error(e.getMessage(), e);
+            basket.setExcuteError(true);
+        } finally {
+            basket.countDown();
+        }
+    }
+
+    protected abstract void consume(T t);
+
+    protected void setBasket(Basket basket) {
+        this.basket = basket;
+    }
+
+    protected Basket getBasket() {
+        return this.basket;
+    }
+
+    protected void addMsg(String msg) {
+        this.basket.addMsg(msg);
+    }
+
+    protected void processInfo() {
+        LOG.info(basket.getTaskName() + " 处理进度" + basket.getProgress());
+    }
+
+    public List<Object> getRet() {
+        return ret;
+    }
+
+    public void addRet(Object r) {
+        ret.add(r);
+    }
 }

+ 1 - 0
src/main/java/cn/com/qmth/multithread/EndObject.java

@@ -2,6 +2,7 @@ package cn.com.qmth.multithread;
 
 /**
  * 消费结束标识对象
+ * 
  * @author xiatian
  *
  */

+ 0 - 30
src/main/java/cn/com/qmth/multithread/Kv.java

@@ -1,30 +0,0 @@
-package cn.com.qmth.multithread;
-
-
-public class Kv {
-    private String key;
-    private String value;
-    
-    public Kv(String key, String value) {
-        super();
-        this.key = key;
-        this.value = value;
-    }
-
-    public String getKey() {
-        return key;
-    }
-    
-    public void setKey(String key) {
-        this.key = key;
-    }
-    
-    public String getValue() {
-        return value;
-    }
-    
-    public void setValue(String value) {
-        this.value = value;
-    }
-    
-}

+ 17 - 0
src/main/java/cn/com/qmth/multithread/ProcessCount.java

@@ -0,0 +1,17 @@
+package cn.com.qmth.multithread;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class ProcessCount {
+
+    private AtomicInteger process = new AtomicInteger(0);
+
+    public AtomicInteger getProcess() {
+        return process;
+    }
+
+    public void setProcess(AtomicInteger process) {
+        this.process = process;
+    }
+
+}

+ 166 - 130
src/main/java/cn/com/qmth/multithread/Producer.java

@@ -1,138 +1,174 @@
 package cn.com.qmth.multithread;
 
+import java.lang.reflect.ParameterizedType;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
 
-import org.apache.log4j.Logger;
-import org.apache.logging.log4j.ThreadContext;
-
-public abstract class Producer {
-	private static final Logger logger = Logger.getLogger(Producer.class);
-	private Basket basket;
-	
-	/**
-	 * 业务参数
-	 */
-	private Map<String, Object> param;
-	
-	/**
-	 * 消费线程class
-	 */
-	private Class<? extends Consumer<?>> consumer;
-	
-	public List<Consumer<?>> consumers=new ArrayList<>();
-	/**
-	 * 	处理开始方法
-	 * @param consumer 消费线程class
-	 * @param consumerCount 消费线程数
-	 * @param param 生产者业务参数
-	 * @throws InstantiationException
-	 * @throws IllegalAccessException
-	 */
-	public void startDispose(Class<? extends Consumer<?>> consumer, int consumerCount,Map<String, Object> param)
-			throws InstantiationException, IllegalAccessException {
-		Basket basket = new Basket(consumerCount);
-		this.basket = basket;
-		this.consumer = consumer;
-		this.param=param;
-		//启动消费者
-		startConsumer();
-		//开始处理
-		dispose();
-	}
-
-	private void dispose() {
-		try {
-			logger.info("*******************Producer:开始处理");
-			// 生产数据
-			produce(param);
-			logger.info("*******************Producer:生产结束");
-			// 发送生产结束信息
-			endConsumer();
-			logger.info("*******************Producer:成功发送生产结束信息");
-			// 等待子线程结束
-			logger.info("*******************Producer:等待消费线程结束");
-			await();
-			logger.info("*******************Producer:消费线程已结束");
-			// 判断子线程是否正常结束
-			if (basket.isExcuteError()) {
-				throw new StatusException("1000001", "处理失败,线程异常");
-			}
-			logger.info("*******************Producer:结束处理");
-		} catch (StatusException e) {
-			// 获取异常时发送异常结束信息
-			endConsumerAsError();
-			throw e;
-		} catch (Exception e) {
-			// 获取异常时发送异常结束信息
-			endConsumerAsError();
-			throw new StatusException("1000002", "处理失败", e);
-		}
-	}
-
-	/**
-	 * 启动消费者
-	 * 
-	 * @param consumer
-	 * @throws InstantiationException
-	 * @throws IllegalAccessException
-	 */
-	private void startConsumer() throws InstantiationException, IllegalAccessException {
-		int count = basket.getConsumerCount();
-		for (int i = 0; i < count; i++) {
-			Consumer<?> co = (Consumer<?>) consumer.newInstance();
-			co.setBasket(basket);
-			co.setTraceId(ThreadContext.get("TRACE_ID"));
-			consumers.add(co);
-			co.start();
-		}
-
-	}
-
-	/**
-	 * 出异常后修改标识
-	 * 
-	 */
-	private void endConsumerAsError() {
-		basket.setExcuteError(true);
-	}
-
-	/**
-	 * 正常结束消费者
-	 * 
-	 * @throws InterruptedException
-	 */
-	private void endConsumer() throws InterruptedException {
-		int count = basket.getConsumerCount();
-		EndObject eo = new EndObject();
-		for (int i = 0; i < count; i++) {
-			basket.offer(eo);
-		}
-
-	}
-
-	/**
-	 * 生产数据
-	 * 
-	 * @param ob
-	 * @throws InterruptedException
-	 */
-	protected void offer(Object ob) throws InterruptedException {
-		synchronized (basket) {
-			basket.offer(ob);
-		}
-	}
-
-	/**
-	 * 等待所有消费者结束
-	 * 
-	 * @throws InterruptedException
-	 */
-	private void await() throws InterruptedException {
-		basket.await();
-	}
-
-	protected abstract void produce(Map<String, Object> param) throws Exception;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
+import cn.com.qmth.im.StatusException;
+
+public abstract class Producer<T, C extends Consumer<T>> {
+
+    private static final Logger LOG = LoggerFactory.getLogger(Producer.class);
+
+    private Basket basket;
+
+    /**
+     * 消费线程class
+     */
+    private List<C> consumers;
+
+    public void startDispose(int consumerCount) {
+        startDispose(consumerCount, null, 0);
+    }
+
+    /**
+     * 处理开始方法
+     */
+    public void startDispose(int consumerCount, Map<String, Object> param) {
+        startDispose(consumerCount, param, 0);
+    }
+
+    public void startDispose(int consumerCount, int total) {
+        startDispose(consumerCount, null, total);
+    }
+
+    public void startDispose(int consumerCount, Map<String, Object> param, int total) {
+        // 启动消费者
+        startConsumer(consumerCount, total, null);
+        // 开始处理
+        dispose(param);
+    }
+
+    public void startDispose(int consumerCount, Map<String, Object> param, int total, ProcessCount pc) {
+        // 启动消费者
+        startConsumer(consumerCount, total, pc);
+        // 开始处理
+        dispose(param);
+    }
+
+    @SuppressWarnings("unchecked")
+    private void startConsumer(int consumerCount, int total, ProcessCount pc) {
+        if (consumerCount <= 0) {
+            consumerCount = 1;
+        }
+        ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass();
+        Class<C> clazz = (Class<C>) pt.getActualTypeArguments()[1];
+        consumers = new ArrayList<>();
+        this.basket = new Basket(consumerCount, getTaskName());
+        basket.setTotal(total);
+        if (pc == null) {
+            basket.setProcess(new ProcessCount());
+        } else {
+            basket.setProcess(pc);
+        }
+        // 启动消费者
+        int count = basket.getConsumerCount();
+        try {
+            for (int i = 0; i < count; i++) {
+                C co = (C) clazz.newInstance();
+                co.setBasket(basket);
+                co.start();
+                consumers.add(co);
+            }
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private void dispose(Map<String, Object> param) {
+        try {
+            // 生产数据
+            produce(param);
+            // 发送生产结束信息
+            endConsumer();
+            // 等待子线程结束
+            await();
+            // 判断子线程是否正常结束
+            if (basket.isExcuteError()) {
+                throw new StatusException("处理失败,线程异常");
+            }
+        } catch (StatusException e) {
+            LOG.error(e.getMessage(), e);
+            // 获取异常时发送异常结束信息
+            endConsumerAsError();
+            throw e;
+        } catch (Exception e) {
+            LOG.error(e.getMessage(), e);
+            // 获取异常时发送异常结束信息
+            endConsumerAsError();
+            throw new StatusException("处理失败", e);
+        }
+    }
+
+    protected abstract void produce(Map<String, Object> param) throws Exception;
+
+    /**
+     * 生产数据
+     * 
+     * @param ob
+     * @throws InterruptedException
+     */
+    protected void offer(T ob) throws InterruptedException {
+        synchronized (basket) {
+            basket.offer(ob);
+        }
+    }
+
+    /**
+     * 出异常后修改标识
+     * 
+     */
+    private void endConsumerAsError() {
+        basket.setExcuteError(true);
+    }
+
+    /**
+     * 正常结束消费者
+     * 
+     * @throws InterruptedException
+     */
+    private void endConsumer() throws InterruptedException {
+        int count = basket.getConsumerCount();
+        EndObject eo = new EndObject();
+        for (int i = 0; i < count; i++) {
+            basket.offer(eo);
+        }
+
+    }
+
+    /**
+     * 等待所有消费者结束
+     * 
+     * @throws InterruptedException
+     */
+    private void await() throws InterruptedException {
+        basket.await();
+    }
+
+    protected abstract String getTaskName();
+
+    public List<String> getMsgs() {
+        return this.basket.getMsgs();
+    }
+
+    public void setTotal(int total) {
+        this.basket.setTotal(total);
+    }
+
+    public Integer getTotal() {
+        return this.basket.getTotal();
+    }
+
+    public AtomicInteger getProcess() {
+        return this.basket.getProcess();
+    }
+
+    public List<C> getConsumers() {
+        return consumers;
+    }
 }

+ 0 - 80
src/main/java/cn/com/qmth/multithread/StatusException.java

@@ -1,80 +0,0 @@
-package cn.com.qmth.multithread;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import cn.com.qmth.importpaper.JsonUtil;
-
-/**
- * 状态异常类<br>
- *
- * @author WANG
- */
-public class StatusException extends RuntimeException {
-	private static final long serialVersionUID = 5003047488500388819L;
-
-	/**
-	 * 追踪ID
-	 */
-	private String traceId;
-
-	/**
-	 * 状态码
-	 */
-	private String code;
-
-	/**
-	 * 状态描述
-	 */
-	private String desc;
-
-	/**
-	 * 构造函数
-	 */
-	public StatusException(String code, String desc) {
-		super("[code: " + code + "; desc: " + desc + "]");
-		this.code = code;
-		this.desc = desc;
-	}
-
-	/**
-	 * 构造函数
-	 */
-	public StatusException(String code, String desc, Throwable cause) {
-		super("[code: " + code + "; desc: " + desc + "]", cause);
-		this.code = code;
-		this.desc = desc;
-	}
-
-	public String getCode() {
-		return code;
-	}
-
-	public String getDesc() {
-		return desc;
-	}
-
-	public String getTraceId() {
-		return traceId;
-	}
-
-	public void setTraceId(String traceId) {
-		this.traceId = traceId;
-	}
-
-	/**
-	 * @return
-	 */
-	public String toJson() {
-		Map<String, Object> map = new HashMap<String, Object>();
-		map.put("code", code);
-		map.put("desc", desc);
-		return JsonUtil.toJson(map);
-	}
-
-	@Override
-	public String toString() {
-		return toJson();
-	}
-
-}

+ 22 - 0
src/main/java/cn/com/qmth/param/Param.java

@@ -0,0 +1,22 @@
+package cn.com.qmth.param;
+
+public class Param {
+
+    // public static String host = "http://localhost:8008";
+    //
+    // public static String rootOrgId = "0";
+    //
+    // public static String key = "$SS:C_0_8";
+    //
+    // public static String token = "bd3f9c9fb55a483992b8f10ddd45d3d0";
+
+    public static String host = "http://192.168.1.249:8008";
+
+    public static String rootOrgId = "17068";
+
+    public static String key = "$SS:C_17068_604791";
+
+    public static String token = "bfe5ccd8f71d4bb4a3f8920e8d7959a3";
+
+    public static String dataDir = "e:/files/guangkai/20241128/";
+}

+ 102 - 0
src/main/java/cn/com/qmth/run/DeleteImportPaperQuestion.java

@@ -0,0 +1,102 @@
+package cn.com.qmth.run;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.apache.poi.xssf.usermodel.XSSFRow;
+import org.apache.poi.xssf.usermodel.XSSFSheet;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+
+import com.google.common.collect.Maps;
+
+import cn.com.qmth.im.HttpMethod;
+import cn.com.qmth.im.OKHttpUtil;
+import cn.com.qmth.im.QuestionId;
+import cn.com.qmth.param.Param;
+import okhttp3.Response;
+
+public class DeleteImportPaperQuestion {
+
+    private static Logger logger = LogManager.getLogger(DeleteImportPaperQuestion.class);
+
+    public static void main(String[] args) {
+        logger.debug("**********************删除开始");
+        Date start = new Date();
+
+        List<QuestionId> cs = readSubject();
+        int index = 0;
+        for (QuestionId c : cs) {
+            try {
+                submit(c);
+                index++;
+                logger.debug("**********************完成:" + index + " | unit_id:" + c.getUnitId());
+            } catch (IOException e) {
+                logger.error("删除失败:" + c.getUnitId() + " | " + c.getQuestionId(), e);
+            }
+        }
+
+        Date end = new Date();
+        logger.debug("**********************删除结束  耗时:" + (end.getTime() - start.getTime()));
+        OKHttpUtil.close();
+    }
+
+    private static List<QuestionId> readSubject() {
+        List<QuestionId> list = new ArrayList<>();
+        XSSFWorkbook wb = null;
+        try {
+            wb = new XSSFWorkbook(Param.dataDir + "/duplicatequestion.xlsx");
+            XSSFSheet sheet = wb.getSheetAt(0);
+            int rows = sheet.getLastRowNum();
+            for (int i = 1; i <= rows; i++) {
+                XSSFRow row = sheet.getRow(i);
+                String valid = row.getCell(9).getStringCellValue().trim();
+                if ("否".equals(valid)) {
+                    QuestionId c = new QuestionId();
+                    String courseCode = row.getCell(1).getStringCellValue().trim();
+                    String uid = row.getCell(7).getStringCellValue().trim();
+                    String qid = row.getCell(8).getStringCellValue().trim();
+                    c.setCourseCode(courseCode);
+                    c.setUnitId(uid);
+                    c.setQuestionId(qid);
+                    list.add(c);
+                }
+            }
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        } finally {
+            if (wb != null) {
+                try {
+                    wb.close();
+                } catch (IOException e) {
+                }
+            }
+        }
+        return list;
+    }
+
+    private static void submit(QuestionId ic) throws IOException {
+        Map<String, String> params = Maps.newHashMap();
+        Map<String, String> headers = Maps.newHashMap();
+        headers.put("key", Param.key);
+        headers.put("token", Param.token);
+        Response resp = null;
+        try {
+            resp = OKHttpUtil.call(HttpMethod.DELETE,
+                    Param.host + "/api/ecs_ques/paper/deleteQuestion/" + ic.getUnitId() + "/" + ic.getQuestionId(),
+                    headers, params);
+            if (resp.code() != 200) {
+                logger.error(ic.getUnitId() + " | " + ic.getQuestionId() + ":body:" + resp.body().string());
+                // throw new RuntimeException(ic.getUnitId() + " | " +
+                // ic.getQuestionId() + ":body:" + resp.body().string());
+            }
+        } finally {
+            IOUtils.closeQuietly(resp);
+        }
+    }
+}

+ 30 - 0
src/main/java/cn/com/qmth/run/DeleteQuestionMulti.java

@@ -0,0 +1,30 @@
+package cn.com.qmth.run;
+
+import java.util.Date;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import cn.com.qmth.im.DeleteQuestionProducer;
+
+/**
+ * 多线程删除小题。一个线程处理一个课程的数据
+ */
+public class DeleteQuestionMulti {
+
+    private static Logger logger = LogManager.getLogger(DeleteQuestionMulti.class);
+
+    public static void main(String[] args) {
+        logger.debug("删除开始");
+        Date start = new Date();
+        try {
+            DeleteQuestionProducer producer = new DeleteQuestionProducer();
+            producer.startDispose(8);
+        } catch (Exception e) {
+            logger.error(e.getCause(), e);
+        }
+        Date end = new Date();
+        logger.debug("删除结束,耗时:" + ((end.getTime() - start.getTime()) / 1000));
+    }
+
+}

+ 45 - 0
src/main/java/cn/com/qmth/run/ImportPaperByCourse.java

@@ -0,0 +1,45 @@
+package cn.com.qmth.run;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+
+import cn.com.qmth.im.MyProducer;
+import cn.com.qmth.im.OKHttpUtil;
+
+public class ImportPaperByCourse {
+
+    private static Logger logger = LogManager.getLogger(ImportPaperByCourse.class);
+
+    // 课程属性批次号
+    // 不要修改
+    // 此值不要修改。因为第一次导入230517批次的时候未保存批次信息,所以230517批次的不能共用。第二次导入230821批次的保存了批次值,可以后续公用。
+    private final static String batch = "230821";
+
+    private static AtomicInteger count = new AtomicInteger(0);
+
+    public static void main(String[] args) {
+        logger.debug("导入开始");
+        Date start = new Date();
+        try {
+            Map<String, Object> param = new HashMap<>();
+            param.put("batch", batch);
+            MyProducer pro = new MyProducer();
+            pro.startDispose(2, param);
+        } catch (Exception e) {
+            logger.error(e.getCause(), e);
+        }
+        Date end = new Date();
+        OKHttpUtil.close();
+        logger.debug("导入结束,耗时:" + ((end.getTime() - start.getTime()) / 1000));
+    }
+
+    public static void addDisposeCount() {
+        count.addAndGet(1);
+        logger.debug("处理了" + count);
+    }
+}

+ 7 - 1
src/main/java/cn/com/qmth/importpaper/ImportPropByCourse.java → src/main/java/cn/com/qmth/run/ImportPropByCourse.java

@@ -1,4 +1,4 @@
-package cn.com.qmth.importpaper;
+package cn.com.qmth.run;
 
 import java.io.File;
 import java.io.IOException;
@@ -19,6 +19,12 @@ import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 
+import cn.com.qmth.im.Course;
+import cn.com.qmth.im.CourseDto;
+import cn.com.qmth.im.FormFilePart;
+import cn.com.qmth.im.HttpMethod;
+import cn.com.qmth.im.OKHttpUtil;
+import cn.com.qmth.param.Param;
 import okhttp3.Response;
 
 public class ImportPropByCourse {