Ver Fonte

大题下小题数量导出

xiatian há 4 anos atrás
pai
commit
8e3f7dae5b
21 ficheiros alterados com 1639 adições e 0 exclusões
  1. 58 0
      src/main/java/cn/com/qmth/dp/examcloud/oe/excel/ColumnSetting.java
  2. 31 0
      src/main/java/cn/com/qmth/dp/examcloud/oe/excel/ExcelProperty.java
  3. 76 0
      src/main/java/cn/com/qmth/dp/examcloud/oe/excel/ExcelUtils.java
  4. 93 0
      src/main/java/cn/com/qmth/dp/examcloud/oe/excel/ExcelWriter.java
  5. 44 0
      src/main/java/cn/com/qmth/dp/examcloud/oe/excel/ExportUtils.java
  6. 13 0
      src/main/java/cn/com/qmth/dp/examcloud/oe/modules/export_questions_count/ExportQuesConsumer.java
  7. 15 0
      src/main/java/cn/com/qmth/dp/examcloud/oe/modules/export_questions_count/ExportQuesProducer.java
  8. 190 0
      src/main/java/cn/com/qmth/dp/examcloud/oe/modules/export_questions_count/ExportQuestionsCountService.java
  9. 32 0
      src/main/java/cn/com/qmth/dp/examcloud/oe/modules/export_questions_count/PaperStatus.java
  10. 44 0
      src/main/java/cn/com/qmth/dp/examcloud/oe/modules/export_questions_count/PaperType.java
  11. 47 0
      src/main/java/cn/com/qmth/dp/examcloud/oe/modules/export_questions_count/RetDto.java
  12. 91 0
      src/main/java/cn/com/qmth/dp/examcloud/oe/modules/export_questions_count/entity/Course.java
  13. 34 0
      src/main/java/cn/com/qmth/dp/examcloud/oe/modules/export_questions_count/entity/IdBase.java
  14. 105 0
      src/main/java/cn/com/qmth/dp/examcloud/oe/modules/export_questions_count/entity/MongoBaseEntity.java
  15. 249 0
      src/main/java/cn/com/qmth/dp/examcloud/oe/modules/export_questions_count/entity/Paper.java
  16. 112 0
      src/main/java/cn/com/qmth/dp/examcloud/oe/modules/export_questions_count/entity/PaperDetail.java
  17. 72 0
      src/main/java/cn/com/qmth/dp/examcloud/oe/modules/export_questions_count/entity/Specialty.java
  18. 103 0
      src/main/java/cn/com/qmth/dp/examcloud/oe/multithread/Basket.java
  19. 73 0
      src/main/java/cn/com/qmth/dp/examcloud/oe/multithread/Consumer.java
  20. 10 0
      src/main/java/cn/com/qmth/dp/examcloud/oe/multithread/EndObject.java
  21. 147 0
      src/main/java/cn/com/qmth/dp/examcloud/oe/multithread/Producer.java

+ 58 - 0
src/main/java/cn/com/qmth/dp/examcloud/oe/excel/ColumnSetting.java

@@ -0,0 +1,58 @@
+package cn.com.qmth.dp.examcloud.oe.excel;
+
+public class ColumnSetting implements Comparable<ColumnSetting> {
+
+    private String header;
+    private String getMethodName;
+    private int width;
+    private int index;
+
+    public ColumnSetting(String header, String getMethodName, int width, int index) {
+        this.header = header;
+        this.getMethodName = getMethodName;
+        this.width = width;
+        this.index = index;
+    }
+
+    public String getHeader() {
+        return header;
+    }
+
+    public void setHeader(String header) {
+        this.header = header;
+    }
+
+    public String getGetMethodName() {
+        return getMethodName;
+    }
+
+    public void setGetMethodName(String getMethodName) {
+        this.getMethodName = getMethodName;
+    }
+
+    public int getWidth() {
+        return width;
+    }
+
+    public void setWidth(int width) {
+        this.width = width;
+    }
+
+    public int getIndex() {
+        return index;
+    }
+
+    public void setIndex(int index) {
+        this.index = index;
+    }
+
+
+    @Override
+    public int compareTo(ColumnSetting columnSetting) {
+        if (index < columnSetting.getIndex())
+            return - 1 ;
+        if (index > columnSetting.getIndex())
+            return 1 ;
+        return 0 ;
+    }
+}

+ 31 - 0
src/main/java/cn/com/qmth/dp/examcloud/oe/excel/ExcelProperty.java

@@ -0,0 +1,31 @@
+package cn.com.qmth.dp.examcloud.oe.excel;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target(ElementType.FIELD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface ExcelProperty {
+	/**
+	 * 导出时列名
+	 */
+    String name() default "";
+    
+	/**
+	 * 导出时列宽
+	 */
+    int width() default 0;
+	/**
+	 * 排序
+	 */
+    int index();
+    /**
+     * 类型
+     * 0:导入(读excel)
+     * 1:导出(写excel)
+     * 2:导入&导出
+     */
+    int type() default 2;
+}

+ 76 - 0
src/main/java/cn/com/qmth/dp/examcloud/oe/excel/ExcelUtils.java

@@ -0,0 +1,76 @@
+package cn.com.qmth.dp.examcloud.oe.excel;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public abstract class ExcelUtils {
+
+	private Class<?> dataClass;
+	private List<ColumnSetting> columnSettings;
+
+	public ExcelUtils(Class<?> dataClass) {
+		this.dataClass = dataClass;
+		this.columnSettings = getColumnSettings(dataClass);
+	}
+
+	public Class<?> getDataClass() {
+		return dataClass;
+	}
+
+	public void setDataClass(Class<?> dataClass) {
+		this.dataClass = dataClass;
+	}
+
+	public List<ColumnSetting> getColumnSettings() {
+		return columnSettings;
+	}
+
+	public void setColumnSettings(List<ColumnSetting> columnSettings) {
+		this.columnSettings = columnSettings;
+	}
+
+	/**
+	 * 提取ExcelProperty注解类的字段信息
+	 * 
+	 * @param dataClass 需要解析 写入excel的数据类型
+	 * @return
+	 */
+	protected List<ColumnSetting> getColumnSettings(Class<?> dataClass) {
+		List<ColumnSetting> columnSettings = new ArrayList<>();
+		// 先在方法上找ExcelProperty注解
+		Method[] methods = dataClass.getDeclaredMethods();
+		for (Method method : methods) {
+			ExcelProperty exportProperty = method.getAnnotation(ExcelProperty.class);
+			if (exportProperty != null && exportProperty.name().trim().length() > 0) {
+				ColumnSetting columnSetting = new ColumnSetting(exportProperty.name(), method.getName(),
+						exportProperty.width(), exportProperty.index());
+				columnSettings.add(columnSetting);
+			}
+		}
+		// 如果方法上找不到注解,再到属性上找
+		if (columnSettings.size() == 0) {
+			Field[] fields = dataClass.getDeclaredFields();
+			for (Field field : fields) {
+				ExcelProperty exportProperty = field.getAnnotation(ExcelProperty.class);
+				if (exportProperty != null && exportProperty.name().trim().length() > 0) {
+					ColumnSetting columnSetting = new ColumnSetting(exportProperty.name(),
+							"get" + toUpperCaseFirstOne(field.getName()), exportProperty.width(),
+							exportProperty.index());
+					columnSettings.add(columnSetting);
+				}
+			}
+		}
+		Collections.sort(columnSettings);
+		return columnSettings;
+	}
+
+	private static String toUpperCaseFirstOne(String s) {
+		if (Character.isUpperCase(s.charAt(0)))
+			return s;
+		else
+			return (new StringBuilder()).append(Character.toUpperCase(s.charAt(0))).append(s.substring(1)).toString();
+	}
+}

+ 93 - 0
src/main/java/cn/com/qmth/dp/examcloud/oe/excel/ExcelWriter.java

@@ -0,0 +1,93 @@
+package cn.com.qmth.dp.examcloud.oe.excel;
+
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.FillPatternType;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.xssf.usermodel.XSSFCellStyle;
+import org.apache.poi.xssf.usermodel.XSSFColor;
+import org.apache.poi.xssf.usermodel.XSSFRichTextString;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+
+import java.awt.Color;
+import java.io.OutputStream;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.List;
+
+public class ExcelWriter extends ExcelUtils {
+
+	private XSSFWorkbook workbook;// 工作簿
+
+	private Sheet sheet; // 工作表
+
+	private Row row = null;// 创建一行
+
+	private Cell cell = null;
+
+	private XSSFCellStyle style;
+
+	private XSSFCellStyle style2;
+
+	public ExcelWriter(Class<?> dataClass, String sheetName) {
+		super(dataClass);
+		// 声明一个工作薄
+		// workbook = new SXSSFWorkbook(100);//使用该方法会有权限问题
+		workbook = new XSSFWorkbook();
+		// 生成一个表格
+		sheet = workbook.createSheet(sheetName);
+		// 设置表格默认列宽度为15个字节
+		sheet.setDefaultColumnWidth((short) 15);
+	}
+
+	private List<ColumnSetting> createColumnSettings() {
+		List<ColumnSetting> columnSettings = this.getColumnSettings();
+		// 产生表格标题行
+		row = sheet.createRow(0);
+		for (short i = 0; i < columnSettings.size(); i++) {
+			cell = row.createCell(i);
+			style = workbook.createCellStyle();
+			style.setFillForegroundColor(new XSSFColor(new Color(227, 239, 217)));
+			style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
+			cell.setCellStyle(style);
+			XSSFRichTextString text = new XSSFRichTextString(columnSettings.get(i).getHeader());
+			cell.setCellValue(text);
+			if (columnSettings.get(i).getWidth() > 0) {
+				sheet.setColumnWidth(i, columnSettings.get(i).getWidth() * 256);
+			}
+		}
+		return columnSettings;
+	}
+
+	/**
+	 * 写入excel
+	 *
+	 * @param dataset 数据集合
+	 * @param out     输出流
+	 * @throws SecurityException
+	 * @throws NoSuchMethodException
+	 * @throws InvocationTargetException
+	 * @throws IllegalArgumentException
+	 * @throws IllegalAccessException
+	 */
+	public void write(Collection<?> dataset, OutputStream out) throws Exception {
+		List<ColumnSetting> columnSettings = this.createColumnSettings();
+		int index = 0;
+		for (Object obj : dataset) {
+			index++;
+			row = sheet.createRow(index);// 创建行
+			// 利用反射,根据javabean属性的先后顺序,动态调用getXxx()方法得到属性值
+			for (short i = 0; i < columnSettings.size(); i++) {
+				cell = row.createCell(i);// 创建列
+				cell.setCellStyle(style2);
+				String methodName = columnSettings.get(i).getGetMethodName();
+				Method method = this.getDataClass().getMethod(methodName, new Class[] {});
+				Object value = method.invoke(obj, new Object[] {});
+				cell.setCellValue(value == null ? "" : value.toString());
+			}
+		}
+		workbook.write(out);
+	}
+
+}

+ 44 - 0
src/main/java/cn/com/qmth/dp/examcloud/oe/excel/ExportUtils.java

@@ -0,0 +1,44 @@
+package cn.com.qmth.dp.examcloud.oe.excel;
+
+import java.io.OutputStream;
+import java.net.URLEncoder;
+import java.util.Collection;
+
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletResponse;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/*
+ * excel导出工具
+ */
+public class ExportUtils {
+
+	private static final Logger log = LoggerFactory.getLogger(ExportUtils.class);
+	
+    private static final String DEFALUT_CONTENT_TYPE = "application/vnd.ms-excel";
+
+    private static final String DEFALUT_EXT = ".xlsx";
+
+    public static void exportEXCEL(String fileName,Class<?> dataClass,
+                             Collection<?> dataset,HttpServletResponse response) throws Exception {
+    	log.debug("导出Excel开始...");
+        response.setHeader("Content-Disposition","inline;filename="+URLEncoder.encode(fileName, "UTF-8")+DEFALUT_EXT);
+        response.setContentType(DEFALUT_CONTENT_TYPE);
+        ServletOutputStream outputStream = response.getOutputStream();
+    	
+        ExcelWriter excelExporter = new ExcelWriter(dataClass,"sheet1");
+        excelExporter.write(dataset,outputStream);
+        outputStream.flush();
+        outputStream.close();
+        log.debug("导出Excel结束");
+    }
+    
+    public static void makeExcel(Class<?> dataClass,Collection<?> dataset,OutputStream outputStream ) throws Exception {
+		log.debug("生成Excel开始...");
+		ExcelWriter excelExporter = new ExcelWriter(dataClass,"sheet1");
+		excelExporter.write(dataset,outputStream);
+		log.debug("生成Excel结束");
+	}
+}

+ 13 - 0
src/main/java/cn/com/qmth/dp/examcloud/oe/modules/export_questions_count/ExportQuesConsumer.java

@@ -0,0 +1,13 @@
+package cn.com.qmth.dp.examcloud.oe.modules.export_questions_count;
+
+import cn.com.qmth.dp.examcloud.oe.multithread.Consumer;
+
+public class ExportQuesConsumer extends Consumer {
+
+	@Override
+	public void consume(Object t) {
+		// TODO Auto-generated method stub
+		
+	}
+
+}

+ 15 - 0
src/main/java/cn/com/qmth/dp/examcloud/oe/modules/export_questions_count/ExportQuesProducer.java

@@ -0,0 +1,15 @@
+package cn.com.qmth.dp.examcloud.oe.modules.export_questions_count;
+
+import java.util.Map;
+
+import cn.com.qmth.dp.examcloud.oe.multithread.Producer;
+
+public class ExportQuesProducer extends Producer {
+
+	@Override
+	protected void produce(Map<String, Object> param) throws Exception {
+		// TODO Auto-generated method stub
+
+	}
+
+}

+ 190 - 0
src/main/java/cn/com/qmth/dp/examcloud/oe/modules/export_questions_count/ExportQuestionsCountService.java

@@ -0,0 +1,190 @@
+package cn.com.qmth.dp.examcloud.oe.modules.export_questions_count;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+import org.apache.poi.xssf.usermodel.XSSFRow;
+import org.apache.poi.xssf.usermodel.XSSFSheet;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.mongodb.core.MongoTemplate;
+import org.springframework.data.mongodb.core.query.Criteria;
+import org.springframework.data.mongodb.core.query.Query;
+import org.springframework.stereotype.Service;
+
+import cn.com.qmth.dp.examcloud.oe.excel.ExportUtils;
+import cn.com.qmth.dp.examcloud.oe.modules.export_questions_count.entity.Paper;
+import cn.com.qmth.dp.examcloud.oe.modules.export_questions_count.entity.PaperDetail;
+
+/**大题下小题数量
+ * @author chenken
+ *
+ */
+@Service
+public class ExportQuestionsCountService {
+
+	@Autowired
+	MongoTemplate mongoTemplate;
+
+	public void start() {
+		Date start=new Date();
+		Query query = new Query();
+		query.addCriteria(Criteria.where("orgId").is("1627").and("paperType").is("GENERATE"));
+		List<Paper> ps = mongoTemplate.find(query, Paper.class, "paper");
+		if (ps != null&&ps.size()>0) {
+			List<String> course= readCourseCode();
+			Map<String, String> courseMap = course.stream().collect(Collectors.toMap(a -> a, a -> a,(k1,k2)->k1));
+			List<Paper> psRet=new ArrayList<>();
+			for (Paper paper : ps) {
+				if(paper.getName().indexOf("2019题源")!=-1&&courseMap.get(paper.getCourseNo())!=null) {
+					psRet.add(paper);
+				}
+			}
+			if (psRet != null&&psRet.size()>0) {
+				Map<String,RetDto> map=new HashMap<>();
+				System.out.println("total:" + psRet.size());
+				int index = 0;
+				for (Paper paper : psRet) {
+					index++;
+					System.out.println("index:" + index);
+					String cName=paper.getCourseName();
+					String cCode=paper.getCourseNo();
+					Query query2 = new Query();
+					query2.addCriteria(Criteria.where("paper.$id").is(paper.getId()));
+//					query2.addCriteria(Criteria.where("paper.$id").is(new ObjectId(paper.getId())));
+					List<PaperDetail> ds = mongoTemplate.find(query2, PaperDetail.class, "paperDetail");
+					if (ds != null&&ds.size()>0) {
+						for (PaperDetail detail : ds) {
+							String qName=detail.getName();
+							Integer count=detail.getUnitCount();
+							String key=cCode+"_"+qName;
+							RetDto dto=map.get(key);
+							if(dto==null) {
+								dto=new RetDto(cName, cCode, qName,0);
+								map.put(key, dto);
+							}
+							dto.setCount(dto.getCount()+count);
+						}
+					}
+				}
+				
+				List<RetDto> ret= new ArrayList<RetDto>();
+				for(RetDto tem:map.values()) {
+					ret.add(tem);
+				}
+				Collections.sort(ret, new Comparator<RetDto>() {
+					@Override
+					public int compare(RetDto o1, RetDto o2) {
+						String c1 = o1.getCourseCode();
+						String c2 = o2.getCourseCode();
+						return c1.compareTo(c2);
+					}
+	
+				});
+				FileOutputStream fos=null;
+				try {
+					File file = new File("d:/ret.xlsx");
+					if(file.exists()) {
+						file.delete();
+					}
+					file.createNewFile();
+					fos = new FileOutputStream(file);
+					ExportUtils.makeExcel(RetDto.class, ret, fos);
+				} catch (Exception e) {
+					e.printStackTrace();
+				} finally {
+					if(fos!=null) {
+						try {
+							fos.close();
+						} catch (IOException e) {
+							// TODO Auto-generated catch block
+							e.printStackTrace();
+						}
+					}
+				}
+			}else {
+				System.out.println("total:" + 0);
+			}
+		}else {
+			System.out.println("total:" + 0);
+		}
+		
+		Date end=new Date();
+		System.out.println("*****************end:" +((end.getTime()-start.getTime())/(1000*60))+"分钟");
+	}
+	
+	private List<String> readCourseCode() {
+		List<String> list = new ArrayList<String>();
+		XSSFWorkbook wb = null;
+		try {
+			wb = new XSSFWorkbook("d:\\CourseCode.xlsx");
+			XSSFSheet sheet = wb.getSheetAt(0);
+			int rows = sheet.getLastRowNum();
+			for (int i = 1; i <= rows; i++) {
+				XSSFRow row = sheet.getRow(i);
+				list.add(row.getCell(1).getStringCellValue());
+			}
+		} catch (IOException e) {
+			e.printStackTrace();
+		} finally {
+			if (wb != null) {
+				try {
+					wb.close();
+				} catch (IOException e) {
+					// TODO Auto-generated catch block
+					e.printStackTrace();
+				}
+			}
+		}
+		return list;
+	}
+
+//	public static void main(String[] args) {
+//		List<RetDto> ret= new ArrayList<RetDto>();
+//		ret.add(new RetDto("cName1", "cCode1", "qName1",21));
+//		ret.add(new RetDto("cName2", "cCode2", "qName2",22));
+//		ret.add(new RetDto("cName3", "cCode3", "qName3",23));
+//		ret.add(new RetDto("cName4", "cCode4", "qName4",24));
+//		ret.add(new RetDto("cName5", "cCode7", "qName5",25));
+//		ret.add(new RetDto("cName1", "cCode1", "qName2",21));
+//		Collections.sort(ret, new Comparator<RetDto>() {
+//			@Override
+//			public int compare(RetDto o1, RetDto o2) {
+//				String c1 = o1.getCourseCode();
+//				String c2 = o2.getCourseCode();
+//				return c1.compareTo(c2);
+//			}
+//
+//		});
+//		FileOutputStream fos=null;
+//		try {
+//			File file = new File("d:/ret.xlsx");
+//			if(file.exists()) {
+//				file.delete();
+//			}
+//			file.createNewFile();
+//			fos = new FileOutputStream(file);
+//			ExportUtils.makeExcel(RetDto.class, ret, fos);
+//		} catch (Exception e) {
+//			e.printStackTrace();
+//		} finally {
+//			if(fos!=null) {
+//				try {
+//					fos.close();
+//				} catch (IOException e) {
+//					// TODO Auto-generated catch block
+//					e.printStackTrace();
+//				}
+//			}
+//		}
+//	}
+}

+ 32 - 0
src/main/java/cn/com/qmth/dp/examcloud/oe/modules/export_questions_count/PaperStatus.java

@@ -0,0 +1,32 @@
+package cn.com.qmth.dp.examcloud.oe.modules.export_questions_count;
+
+/**
+ * Created by songyue on 17/3/15.
+ */
+public enum PaperStatus {
+
+    DRAFT(1L, "待审核"),
+    PASS(2L, "通过"),
+    NOPASS(3L, "不通过");
+
+    private Long id;
+    private String name;
+
+    PaperStatus(Long id, String name) {
+        this.id = id;
+        this.name = name;
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String toString() {
+        return getName();
+    }
+
+}

+ 44 - 0
src/main/java/cn/com/qmth/dp/examcloud/oe/modules/export_questions_count/PaperType.java

@@ -0,0 +1,44 @@
+package cn.com.qmth.dp.examcloud.oe.modules.export_questions_count;
+
+/**
+ * Created by songyue on 17/3/15.
+ */
+public enum PaperType {
+    /**
+     * 导入
+     */
+    IMPORT(1L, "导入"),
+    /**
+     * 组卷
+     */
+    GENERATE(2L, "组卷"),
+    /**
+     * 调卷规则预览卷
+     */
+    PREVIEW(3L, "调卷规则预览卷"),
+    /**
+     * 考生考卷
+     */
+    STUDENT_EXAM(4L, "考生考卷");
+
+    private Long id;
+    private String name;
+
+    PaperType(Long id, String name) {
+        this.id = id;
+        this.name = name;
+    }
+
+    public Long getId() {
+        return id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String toString() {
+        return getName();
+    }
+
+}

+ 47 - 0
src/main/java/cn/com/qmth/dp/examcloud/oe/modules/export_questions_count/RetDto.java

@@ -0,0 +1,47 @@
+package cn.com.qmth.dp.examcloud.oe.modules.export_questions_count;
+
+import cn.com.qmth.dp.examcloud.oe.excel.ExcelProperty;
+
+public class RetDto {
+	@ExcelProperty(name = "课程名称", width = 40, index = 1)
+	private String courseName;
+	@ExcelProperty(name = "课程代码", width = 40, index = 2)
+	private String courseCode;
+	@ExcelProperty(name = "大题名称", width = 40, index = 3)
+	private String quesName;
+	@ExcelProperty(name = "小题数量", width = 40, index = 3)
+	private int count=0;
+	public String getCourseName() {
+		return courseName;
+	}
+	public void setCourseName(String courseName) {
+		this.courseName = courseName;
+	}
+	public String getCourseCode() {
+		return courseCode;
+	}
+	public void setCourseCode(String courseCode) {
+		this.courseCode = courseCode;
+	}
+	public String getQuesName() {
+		return quesName;
+	}
+	public void setQuesName(String quesName) {
+		this.quesName = quesName;
+	}
+	public int getCount() {
+		return count;
+	}
+	public void setCount(int count) {
+		this.count = count;
+	}
+	public RetDto(String courseName, String courseCode, String quesName, int count) {
+		super();
+		this.courseName = courseName;
+		this.courseCode = courseCode;
+		this.quesName = quesName;
+		this.count = count;
+	}
+	
+	
+}

+ 91 - 0
src/main/java/cn/com/qmth/dp/examcloud/oe/modules/export_questions_count/entity/Course.java

@@ -0,0 +1,91 @@
+package cn.com.qmth.dp.examcloud.oe.modules.export_questions_count.entity;
+
+/**
+ * Created by songyue on 16/12/26.
+ */
+public class Course extends IdBase {
+
+    private String code;
+
+    private String name;
+
+    private String orgId;
+
+    private String level;
+
+    private String createTime;
+
+    private String updateTime;
+
+    private String enable;
+
+    public Course() {
+
+    }
+
+    public Course(String name, String code) {
+        this.name = name;
+        this.code = code;
+    }
+
+    public Course(String enable) {
+        this.enable = enable;
+    }
+
+    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;
+    }
+
+    public String getOrgId() {
+        return orgId;
+    }
+
+    public void setOrgId(String orgId) {
+        this.orgId = orgId;
+    }
+
+    public String getLevel() {
+        return level;
+    }
+
+    public void setLevel(String level) {
+        this.level = level;
+    }
+
+    public String getCreateTime() {
+        return createTime;
+    }
+
+    public void setCreateTime(String createTime) {
+        this.createTime = createTime;
+    }
+
+    public String getUpdateTime() {
+        return updateTime;
+    }
+
+    public void setUpdateTime(String updateTime) {
+        this.updateTime = updateTime;
+    }
+
+    public String getEnable() {
+        return enable;
+    }
+
+    public void setEnable(String enable) {
+        this.enable = enable;
+    }
+
+}

+ 34 - 0
src/main/java/cn/com/qmth/dp/examcloud/oe/modules/export_questions_count/entity/IdBase.java

@@ -0,0 +1,34 @@
+/*
+ * *************************************************
+ * Copyright (c) 2019 QMTH. All Rights Reserved.
+ * Created by Deason on 2019-05-05 14:12:35.
+ * *************************************************
+ */
+
+package cn.com.qmth.dp.examcloud.oe.modules.export_questions_count.entity;
+
+import org.springframework.data.annotation.Id;
+
+import java.io.Serializable;
+
+/**
+ * Mongo Object ID
+ *
+ * @author: fengdesheng
+ * @since: 2019/5/5
+ */
+public abstract class IdBase implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @Id
+    protected String id;
+
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+}

+ 105 - 0
src/main/java/cn/com/qmth/dp/examcloud/oe/modules/export_questions_count/entity/MongoBaseEntity.java

@@ -0,0 +1,105 @@
+package cn.com.qmth.dp.examcloud.oe.modules.export_questions_count.entity;
+
+import java.util.Date;
+
+import javax.persistence.Column;
+import javax.persistence.EntityListeners;
+import javax.persistence.Id;
+import javax.persistence.MappedSuperclass;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+
+import org.springframework.data.annotation.CreatedBy;
+import org.springframework.data.annotation.CreatedDate;
+import org.springframework.data.annotation.LastModifiedBy;
+import org.springframework.data.annotation.LastModifiedDate;
+import org.springframework.data.jpa.domain.support.AuditingEntityListener;
+
+import cn.com.qmth.examcloud.api.commons.exchange.JsonSerializable;
+
+@MappedSuperclass
+@EntityListeners(AuditingEntityListener.class)
+public abstract class MongoBaseEntity implements JsonSerializable {
+
+	/**
+	 * 
+	 */
+	private static final long serialVersionUID = -3471392332225060352L;
+	
+    @Id
+    protected String id;
+
+	/**
+	 * 更新时间
+	 */
+	@LastModifiedDate
+	@Column(nullable = true)
+	@Temporal(TemporalType.TIMESTAMP)
+	private Date updateDate;
+
+	/**
+	 * 创建时间
+	 */
+	@CreatedDate
+	@Column(nullable = true, updatable = false)
+	@Temporal(TemporalType.TIMESTAMP)
+	private Date creationDate;
+	
+	/**
+	 * 创建人id
+	 */
+	@CreatedBy
+	@Column(nullable = true, updatable = false)
+	private Long creationBy;
+	
+	
+	/**
+	 * 更新人id
+	 */
+	@LastModifiedBy
+	@Column(nullable = true)
+	private Long updateBy;
+
+	public Date getUpdateDate() {
+		return updateDate;
+	}
+
+	public void setUpdateDate(Date updateDate) {
+		this.updateDate = updateDate;
+	}
+
+	public Date getCreationDate() {
+		return creationDate;
+	}
+
+	public void setCreationDate(Date creationDate) {
+		this.creationDate = creationDate;
+	}
+
+	public String getId() {
+		return id;
+	}
+
+	public void setId(String id) {
+		this.id = id;
+	}
+
+	public Long getCreationBy() {
+		return creationBy;
+	}
+
+	public void setCreationBy(Long creationBy) {
+		this.creationBy = creationBy;
+	}
+
+	public Long getUpdateBy() {
+		return updateBy;
+	}
+
+	public void setUpdateBy(Long updateBy) {
+		this.updateBy = updateBy;
+	}
+
+
+	
+}

+ 249 - 0
src/main/java/cn/com/qmth/dp/examcloud/oe/modules/export_questions_count/entity/Paper.java

@@ -0,0 +1,249 @@
+package cn.com.qmth.dp.examcloud.oe.modules.export_questions_count.entity;
+
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Map;
+
+import org.springframework.data.mongodb.core.index.Indexed;
+
+import cn.com.qmth.dp.examcloud.oe.modules.export_questions_count.PaperStatus;
+import cn.com.qmth.dp.examcloud.oe.modules.export_questions_count.PaperType;
+import cn.com.qmth.examcloud.api.commons.enums.CourseLevel;
+
+/**
+ * @author songyue
+ */
+public class Paper extends MongoBaseEntity {
+    /**
+	 * 
+	 */
+	private static final long serialVersionUID = -8681575737341326402L;
+
+	@Indexed(unique = true)
+    private String name;// 试卷名称
+
+    private String title;// 试卷标题
+
+    private Double totalScore;// 试卷总分
+
+    private String creator;// 创建人id
+
+    private Integer paperDetailCount;// 大题数量
+
+    private Integer unitCount;// 小题数量
+
+    private String createTime;// 创建时间
+
+    private String lastModifyName;// 最后修改人名称
+
+    private String word;// 原始试卷word
+
+    private String html;// 原始试卷html
+
+    private PaperStatus paperStatus;// 试卷状态(待审核、通过、不通过)
+
+    private PaperType paperType;// 试卷类型(导入、组卷)
+
+    @Deprecated
+    private String courseNo;
+
+    @Deprecated
+    private String courseName;
+
+    private Course course;
+
+    private CourseLevel level;
+
+    private String orgId;
+
+    private Map<String, String> params;// 导入试卷属性
+
+    private Specialty specialty;
+
+    private Double difficultyDegree; //难度系数
+
+    private String sameName; //相同大题名 0:不合并,1:合并
+
+    private String examRemark;//考试说明
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public Double getTotalScore() {
+        return totalScore;
+    }
+
+    public void setTotalScore(Double totalScore) {
+        this.totalScore = totalScore;
+    }
+
+    public String getCreator() {
+        return creator;
+    }
+
+    public void setCreator(String creator) {
+        this.creator = creator;
+    }
+
+    public Integer getPaperDetailCount() {
+        return paperDetailCount;
+    }
+
+    public void setPaperDetailCount(Integer paperDetailCount) {
+        this.paperDetailCount = paperDetailCount;
+    }
+
+    public String getCreateTime() {
+        return createTime;
+    }
+
+    public void setCreateTime(String createTime) {
+        this.createTime = createTime;
+    }
+
+    public String getLastModifyName() {
+        return lastModifyName;
+    }
+
+    public void setLastModifyName(String lastModifyName) {
+        this.lastModifyName = lastModifyName;
+    }
+
+    public String getWord() {
+        return word;
+    }
+
+    public void setWord(String word) {
+        this.word = word;
+    }
+
+    public String getHtml() {
+        return html;
+    }
+
+    public void setHtml(String html) {
+        this.html = html;
+    }
+
+    public PaperStatus getPaperStatus() {
+        return paperStatus;
+    }
+
+    public void setPaperStatus(PaperStatus paperStatus) {
+        this.paperStatus = paperStatus;
+    }
+
+    public PaperType getPaperType() {
+        return paperType;
+    }
+
+    public void setPaperType(PaperType paperType) {
+        this.paperType = paperType;
+    }
+
+    public Map<String, String> getParams() {
+        return params;
+    }
+
+    public void setParams(Map<String, String> params) {
+        this.params = params;
+    }
+
+    public String getCourseNo() {
+        return courseNo;
+    }
+
+    public void setCourseNo(String courseNo) {
+        this.courseNo = courseNo;
+    }
+
+    public String getCourseName() {
+        return courseName;
+    }
+
+    public void setCourseName(String courseName) {
+        this.courseName = courseName;
+    }
+
+    public Integer getUnitCount() {
+        return unitCount;
+    }
+
+    public void setUnitCount(Integer unitCount) {
+        this.unitCount = unitCount;
+    }
+
+    public String getOrgId() {
+        return orgId;
+    }
+
+    public void setOrgId(String orgId) {
+        this.orgId = orgId;
+    }
+
+    public Paper() {
+        this.createTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());;
+    }
+
+    public CourseLevel getLevel() {
+        return level;
+    }
+
+    public void setLevel(CourseLevel level) {
+        this.level = level;
+    }
+
+    public Course getCourse() {
+        return course;
+    }
+
+    public void setCourse(Course course) {
+        this.course = course;
+    }
+
+    public Specialty getSpecialty() {
+        return specialty;
+    }
+
+    public void setSpecialty(Specialty specialty) {
+        this.specialty = specialty;
+    }
+
+    public Double getDifficultyDegree() {
+        return difficultyDegree;
+    }
+
+    public void setDifficultyDegree(Double difficultyDegree) {
+        this.difficultyDegree = difficultyDegree;
+    }
+
+    public String getSameName() {
+        return sameName;
+    }
+
+    public void setSameName(String sameName) {
+        this.sameName = sameName;
+    }
+
+    public String getExamRemark() {
+        return examRemark;
+    }
+
+    public void setExamRemark(String examRemark) {
+        this.examRemark = examRemark;
+    }
+
+}

+ 112 - 0
src/main/java/cn/com/qmth/dp/examcloud/oe/modules/export_questions_count/entity/PaperDetail.java

@@ -0,0 +1,112 @@
+package cn.com.qmth.dp.examcloud.oe.modules.export_questions_count.entity;
+
+import org.springframework.data.mongodb.core.mapping.DBRef;
+
+public class PaperDetail extends MongoBaseEntity implements Comparable<PaperDetail> {
+    /**
+	 * 
+	 */
+	private static final long serialVersionUID = -8021835042074266092L;
+
+	@DBRef(lazy = false)
+    private Paper paper;// 关联的试卷
+
+    private Integer number;// 大题序号
+
+    private String name;// 大题名称
+
+    private String title;// 大题描述
+
+    private Double score;// 大题分数
+
+    private Integer unitCount;// 大题下的小题数量
+
+    private String creator;// 创建人id
+
+    private String createTime;// 创建时间
+
+    public Paper getPaper() {
+        return paper;
+    }
+
+    public void setPaper(Paper paper) {
+        this.paper = paper;
+    }
+
+    public Integer getNumber() {
+        return number;
+    }
+
+    public void setNumber(Integer number) {
+        this.number = number;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public Double getScore() {
+        return score;
+    }
+
+    public void setScore(Double score) {
+        this.score = score;
+    }
+
+    public Integer getUnitCount() {
+        return unitCount;
+    }
+
+    public void setUnitCount(Integer unitCount) {
+        this.unitCount = unitCount;
+    }
+
+    public String getCreator() {
+        return creator;
+    }
+
+    public void setCreator(String creator) {
+        this.creator = creator;
+    }
+
+    public String getCreateTime() {
+        return createTime;
+    }
+
+    public void setCreateTime(String createTime) {
+        this.createTime = createTime;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public PaperDetail() {
+
+    }
+
+    @Override
+    public int compareTo(PaperDetail paperDetail) {
+        if (paperDetail != null) {
+            if (this.getNumber() == null) return -1;
+            if (paperDetail.getNumber() == null) return 1;
+            if (this.getNumber() > paperDetail.getNumber()) {
+                return 1;
+            } else if (this.getNumber() < paperDetail.getNumber()) {
+                return -1;
+            } else {
+                return 0;
+            }
+        }
+        return -1;
+    }
+
+}

+ 72 - 0
src/main/java/cn/com/qmth/dp/examcloud/oe/modules/export_questions_count/entity/Specialty.java

@@ -0,0 +1,72 @@
+package cn.com.qmth.dp.examcloud.oe.modules.export_questions_count.entity;
+
+import java.util.Date;
+
+/**
+ * @author weiwenhai
+ * @date 2017.10.25
+ * @describle 题库 专业    同步基础信息的
+ */
+public class Specialty extends IdBase {
+
+    private String code;
+
+    private String name;
+
+    private Long orgId;
+
+    private Date createTime;
+
+    private Date updateTime;
+
+    private Boolean enable;
+
+    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;
+    }
+
+    public Long getOrgId() {
+        return orgId;
+    }
+
+    public void setOrgId(Long orgId) {
+        this.orgId = orgId;
+    }
+
+    public Date getCreateTime() {
+        return createTime;
+    }
+
+    public void setCreateTime(Date createTime) {
+        this.createTime = createTime;
+    }
+
+    public Date getUpdateTime() {
+        return updateTime;
+    }
+
+    public void setUpdateTime(Date updateTime) {
+        this.updateTime = updateTime;
+    }
+
+    public Boolean getEnable() {
+        return enable;
+    }
+
+    public void setEnable(Boolean enable) {
+        this.enable = enable;
+    }
+
+}

+ 103 - 0
src/main/java/cn/com/qmth/dp/examcloud/oe/multithread/Basket.java

@@ -0,0 +1,103 @@
+package cn.com.qmth.dp.examcloud.oe.multithread;
+
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import cn.com.qmth.examcloud.commons.exception.StatusException;
+
+public  class  Basket {
+	private static final Logger logger = LoggerFactory.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;
+	}
+
+}

+ 73 - 0
src/main/java/cn/com/qmth/dp/examcloud/oe/multithread/Consumer.java

@@ -0,0 +1,73 @@
+package cn.com.qmth.dp.examcloud.oe.multithread;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.logging.log4j.ThreadContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import cn.com.qmth.dp.examcloud.oe.modules.export_questions_count.RetDto;
+
+public abstract class Consumer<T>  extends Thread{
+	private static final Logger logger = LoggerFactory.getLogger(Consumer.class);
+	private Basket basket;
+	
+	private Map<String,RetDto> ret;
+	
+	private String traceId;
+	
+	public Consumer() {
+	}
+	@Override
+	public void run() {
+		ret=new HashMap<>();
+		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.error("消费线程处理出错",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;
+	}
+	public Map<String, RetDto> getRet() {
+		return ret;
+	}
+	public void setRet(Map<String, RetDto> ret) {
+		this.ret = ret;
+	}
+	
+}

+ 10 - 0
src/main/java/cn/com/qmth/dp/examcloud/oe/multithread/EndObject.java

@@ -0,0 +1,10 @@
+package cn.com.qmth.dp.examcloud.oe.multithread;
+
+/**
+ * 消费结束标识对象
+ * @author xiatian
+ *
+ */
+public class EndObject {
+
+}

+ 147 - 0
src/main/java/cn/com/qmth/dp/examcloud/oe/multithread/Producer.java

@@ -0,0 +1,147 @@
+package cn.com.qmth.dp.examcloud.oe.multithread;
+
+import java.util.List;
+import java.util.Map;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import cn.com.qmth.examcloud.commons.exception.StatusException;
+
+public abstract class Producer {
+	private static final Logger logger = LoggerFactory.getLogger(Producer.class);
+	private Basket basket;
+	
+	private List<Consumer<?>> consumers;
+	
+	/**
+	 * 业务参数
+	 */
+	private Map<String, Object> param;
+	
+	/**
+	 * 消费线程class
+	 */
+	private Class<? extends Consumer<?>> consumer;
+	/**
+	 * 	处理开始方法
+	 * @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);
+			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;
+
+	public List<Consumer<?>> getConsumers() {
+		return consumers;
+	}
+
+	public void setConsumers(List<Consumer<?>> consumers) {
+		this.consumers = consumers;
+	}
+
+	
+}